Endpoint identity documented the IPv6 scope identifier as an established component alongside family, address and port. The server specification does list the zone, but its remaining-unknowns section records that multi-zone behavior could not be tested on a single-host platform, so no evidence settles how a reference server compares scoped addresses. Presenting the choice as verified compatibility overstated what is known, which the crate's own guidance forbids. Say what it is instead: a deliberate policy taken under a recorded unknown. Two peers reachable at the same link-local address in different zones are genuinely different peers, so treating the zone as identity is the conservative reading — the failure it prevents is one peer closing another's session, and the failure it risks is a scoped client having to reopen. The excluded flow label is labelled the same way, and `irtt-server` guidance now carries the rule so the echo slice reuses this comparison rather than inventing a second one. Behavior is unchanged; this is documentation and a test comment.
55 lines
2.1 KiB
Rust
55 lines
2.1 KiB
Rust
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
|
|
}
|
|
}
|