From ae4be5a22cf63caf300c04cc4f1a701aff46b6ce Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Fri, 1 Jul 2022 09:54:13 -0700 Subject: [PATCH] Allow initial maximum UDP payload size to be configured --- quinn-proto/src/config.rs | 21 ++++++++++++++++++++- quinn-proto/src/connection/mod.rs | 2 ++ quinn-proto/src/connection/paths.rs | 7 ++++--- quinn-proto/src/lib.rs | 1 + 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/quinn-proto/src/config.rs b/quinn-proto/src/config.rs index 7f97b9fd7..440e9d15e 100644 --- a/quinn-proto/src/config.rs +++ b/quinn-proto/src/config.rs @@ -7,7 +7,7 @@ use crate::{ cid_generator::{ConnectionIdGenerator, RandomConnectionIdGenerator}, congestion, crypto::{self, HandshakeTokenKey, HmacKey}, - VarInt, VarIntBoundsExceeded, DEFAULT_SUPPORTED_VERSIONS, + VarInt, VarIntBoundsExceeded, DEFAULT_SUPPORTED_VERSIONS, INITIAL_MAX_UDP_PAYLOAD_SIZE, }; /// Parameters governing the core QUIC state machine @@ -34,6 +34,7 @@ pub struct TransportConfig { pub(crate) packet_threshold: u32, pub(crate) time_threshold: f32, pub(crate) initial_rtt: Duration, + pub(crate) initial_max_udp_payload_size: u16, pub(crate) persistent_congestion_threshold: u32, pub(crate) keep_alive_interval: Option, @@ -151,6 +152,23 @@ impl TransportConfig { self } + /// UDP payload size that the network must be capable of carrying + /// + /// Effective max UDP payload size may change over the life of the connection in the future due + /// to path MTU detection, but will never fall below this value. + /// + /// Must be at least 1200, which is the default, and known to be safe for typical internet + /// applications. Larger values are more efficient, but increase the risk of unpredictable + /// catastrophic packet loss due to exceeding the network path's IP MTU. + /// + /// Real-world MTUs can vary according to ISP, VPN, and properties of intermediate network links + /// outside of either endpoint's control. Extreme caution should be used when raising this value + /// for connections outside of private networks where these factors are fully controlled. + pub fn initial_max_udp_payload_size(&mut self, value: u16) -> &mut Self { + self.initial_max_udp_payload_size = value.max(INITIAL_MAX_UDP_PAYLOAD_SIZE); + self + } + /// Number of consecutive PTOs after which network is considered to be experiencing persistent congestion. pub fn persistent_congestion_threshold(&mut self, value: u32) -> &mut Self { self.persistent_congestion_threshold = value; @@ -246,6 +264,7 @@ impl Default for TransportConfig { packet_threshold: 3, time_threshold: 9.0 / 8.0, initial_rtt: Duration::from_millis(333), // per spec, intentionally distinct from EXPECTED_RTT + initial_max_udp_payload_size: INITIAL_MAX_UDP_PAYLOAD_SIZE, persistent_congestion_threshold: 3, keep_alive_interval: None, diff --git a/quinn-proto/src/connection/mod.rs b/quinn-proto/src/connection/mod.rs index 06e497a13..d2f283f4a 100644 --- a/quinn-proto/src/connection/mod.rs +++ b/quinn-proto/src/connection/mod.rs @@ -262,6 +262,7 @@ impl Connection { remote, config.initial_rtt, config.congestion_controller_factory.build(now), + config.initial_max_udp_payload_size, now, path_validated, ), @@ -2626,6 +2627,7 @@ impl Connection { remote, self.config.initial_rtt, self.config.congestion_controller_factory.build(now), + self.config.initial_max_udp_payload_size, now, false, ) diff --git a/quinn-proto/src/connection/paths.rs b/quinn-proto/src/connection/paths.rs index 86d2253f2..c5f6f88fd 100644 --- a/quinn-proto/src/connection/paths.rs +++ b/quinn-proto/src/connection/paths.rs @@ -1,7 +1,7 @@ use std::{cmp, net::SocketAddr, time::Duration, time::Instant}; use super::pacing::Pacer; -use crate::{congestion, packet::SpaceId, INITIAL_MAX_UDP_PAYLOAD_SIZE, TIMER_GRANULARITY}; +use crate::{congestion, packet::SpaceId, TIMER_GRANULARITY}; /// Description of a particular network path pub struct PathData { @@ -36,6 +36,7 @@ impl PathData { remote: SocketAddr, initial_rtt: Duration, congestion: Box, + initial_max_udp_payload_size: u16, now: Instant, validated: bool, ) -> Self { @@ -46,7 +47,7 @@ impl PathData { pacing: Pacer::new( initial_rtt, congestion.initial_window(), - INITIAL_MAX_UDP_PAYLOAD_SIZE, + initial_max_udp_payload_size, now, ), congestion, @@ -55,7 +56,7 @@ impl PathData { validated, total_sent: 0, total_recvd: 0, - max_udp_payload_size: INITIAL_MAX_UDP_PAYLOAD_SIZE, + max_udp_payload_size: initial_max_udp_payload_size, first_packet_after_rtt_sample: None, } } diff --git a/quinn-proto/src/lib.rs b/quinn-proto/src/lib.rs index 891bea561..48b3fae51 100644 --- a/quinn-proto/src/lib.rs +++ b/quinn-proto/src/lib.rs @@ -292,6 +292,7 @@ const LOC_CID_COUNT: u64 = 8; const RESET_TOKEN_SIZE: usize = 16; const MAX_CID_SIZE: usize = 20; const MIN_INITIAL_SIZE: u16 = 1200; +/// const INITIAL_MAX_UDP_PAYLOAD_SIZE: u16 = 1200; const TIMER_GRANULARITY: Duration = Duration::from_millis(1); /// Maximum number of streams that can be uniquely identified by a stream ID