feat(server): bound negotiated packet lengths
This commit is contained in:
7 files changed
+361
-53
No files matched your search
@@ -8,17 +8,36 @@
|
||||
/// server is not expected to reproduce.
|
||||
pub const DEFAULT_MAX_SESSIONS: usize = 1024;
|
||||
|
||||
/// Default bound on the executable echo datagram size of one session, in bytes.
|
||||
///
|
||||
/// This is `irtt-rs` resource policy, not an interoperability requirement and
|
||||
/// not a protocol constant. The server specification records upstream defaulting
|
||||
/// to *unlimited*, which leaves a remotely negotiated allocation unbounded; that
|
||||
/// is explicitly not a compatibility target.
|
||||
///
|
||||
/// 65,507 is the largest payload an IPv4 UDP datagram can carry, so it is the
|
||||
/// conservative ceiling above which no negotiated length could be emitted as one
|
||||
/// datagram on any address family. It bounds a session's echo buffer to roughly
|
||||
/// 64 KiB, and it is already the maximum a normal `irtt-rs` client will ask for,
|
||||
/// so ordinary traffic never meets it.
|
||||
///
|
||||
/// It is **not** an MTU and promises nothing about what a path will carry. Path
|
||||
/// and interface policy is a separate, later concern; this value exists to keep
|
||||
/// allocation bounded, not to predict fragmentation.
|
||||
pub const DEFAULT_MAX_PACKET_LENGTH: usize = 65_507;
|
||||
|
||||
/// Configuration for a [`ServerCore`](crate::ServerCore).
|
||||
///
|
||||
/// Fields are private and set through consuming builder methods, so later
|
||||
/// slices can add configuration without breaking construction. Only the
|
||||
/// settings this OPEN/session slice actually uses exist yet; parameter
|
||||
/// restriction knobs, lifetime policy and rate limits arrive with the slices
|
||||
/// that implement them.
|
||||
/// settings this OPEN/session slice actually uses exist yet; the remaining
|
||||
/// parameter restriction knobs, lifetime policy and rate limits arrive with the
|
||||
/// slices that implement them.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ServerConfig {
|
||||
hmac_key: Option<Vec<u8>>,
|
||||
max_sessions: usize,
|
||||
max_packet_length: usize,
|
||||
}
|
||||
|
||||
impl ServerConfig {
|
||||
@@ -45,6 +64,32 @@ impl ServerConfig {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the maximum echo datagram size a session may negotiate, in bytes.
|
||||
///
|
||||
/// This governs the *executable* echo datagram of a session, not the size of
|
||||
/// the open exchange: a requested positive Length above this value is
|
||||
/// reduced to it during negotiation, and an open whose mandatory echo field
|
||||
/// block would not fit is silently refused, since the server could not emit
|
||||
/// a compliant reply for it. Authentication counts toward that field block.
|
||||
/// The echo slice will additionally use this limit to admit inbound echo
|
||||
/// request datagrams by their received length.
|
||||
///
|
||||
/// The value is trusted local configuration, like
|
||||
/// [`with_max_sessions`](Self::with_max_sessions): an operator may
|
||||
/// deliberately raise it far past what any path carries, and that is their
|
||||
/// resource choice to make. What must stay bounded is the *default*, which
|
||||
/// is why there is deliberately no unlimited setting.
|
||||
///
|
||||
/// Zero is accepted and is not a synonym for unlimited. No session can
|
||||
/// describe an echo packet smaller than its mandatory field block, so a zero
|
||||
/// maximum silently refuses every session-creating open — and every no-test
|
||||
/// open too, since both are validated against the same effective session.
|
||||
#[must_use]
|
||||
pub fn with_max_packet_length(mut self, max_packet_length: usize) -> Self {
|
||||
self.max_packet_length = max_packet_length;
|
||||
self
|
||||
}
|
||||
|
||||
/// The configured HMAC key, if this server authenticates.
|
||||
#[must_use]
|
||||
pub fn hmac_key(&self) -> Option<&[u8]> {
|
||||
@@ -56,14 +101,22 @@ impl ServerConfig {
|
||||
pub fn max_sessions(&self) -> usize {
|
||||
self.max_sessions
|
||||
}
|
||||
|
||||
/// The maximum echo datagram size a session may negotiate, in bytes.
|
||||
#[must_use]
|
||||
pub fn max_packet_length(&self) -> usize {
|
||||
self.max_packet_length
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
/// An unauthenticated server bounded to [`DEFAULT_MAX_SESSIONS`] sessions.
|
||||
/// An unauthenticated server bounded to [`DEFAULT_MAX_SESSIONS`] sessions,
|
||||
/// each negotiating at most [`DEFAULT_MAX_PACKET_LENGTH`] bytes per echo.
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
hmac_key: None,
|
||||
max_sessions: DEFAULT_MAX_SESSIONS,
|
||||
max_packet_length: DEFAULT_MAX_PACKET_LENGTH,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user