use std::net::SocketAddr; use irtt_proto::Params; /// A live session created by an accepted open request. /// /// This slice records only what identifies the session and what was negotiated /// for it. Echo receive state (counts, windows, sequence tracking) and lifetime /// state (activity, deadlines, expiry) belong to the slices that implement /// those behaviors, and are deliberately absent rather than present as /// placeholders. /// /// Deliberately crate-private. The next slices are all but certain to add and /// restructure fields here, and nothing outside the crate needs a session yet; /// publishing internal session state before ECHO even exists would buy nothing /// and commit us to a shape we are about to change. #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct Session { peer: SocketAddr, params: Params, } impl Session { pub(crate) fn new(peer: SocketAddr, params: Params) -> Self { Self { peer, params } } /// The exact source endpoint the open request arrived from. /// /// A session is bound to this endpoint, not merely to its address: the /// address family, the address and the UDP source port all form part of its /// identity, as — by `irtt-rs` policy rather than observed behavior — does /// the IPv6 scope identifier. Close processing requires both a token match /// and an endpoint match before removing a session, and echo processing /// will require the same; `same_endpoint` in `core` is where the comparison /// and its reasoning live. /// /// The address is stored exactly as received, including the flow label that /// identity ignores, so a reply goes back to the endpoint the request /// actually came from. pub(crate) fn peer(&self) -> SocketAddr { self.peer } /// The negotiated parameters the server returned for this session and will /// enforce for it. // // Also awaiting its production consumer: echo replies are built from the // negotiated params. #[allow(dead_code)] pub(crate) fn params(&self) -> &Params { &self.params } }