@@ -18,8 +18,9 @@ use crate::NoneTokenLog;
1818#[ cfg( any( feature = "rustls-aws-lc-rs" , feature = "rustls-ring" ) ) ]
1919use crate :: crypto:: rustls:: { QuicServerConfig , configured_provider} ;
2020use crate :: {
21- DEFAULT_SUPPORTED_VERSIONS , Duration , MAX_CID_SIZE , RandomConnectionIdGenerator , SystemTime ,
22- TokenLog , TokenMemoryCache , TokenStore , VarInt , VarIntBoundsExceeded ,
21+ DEFAULT_SUPPORTED_VERSIONS , Duration , MAX_CID_SIZE , MIN_INITIAL_SIZE ,
22+ RandomConnectionIdGenerator , SystemTime , TokenLog , TokenMemoryCache , TokenStore , VarInt ,
23+ VarIntBoundsExceeded ,
2324 cid_generator:: { ConnectionIdGenerator , HashedConnectionIdGenerator } ,
2425 crypto:: { self , HandshakeTokenKey , HmacKey } ,
2526 shared:: ConnectionId ,
@@ -48,6 +49,7 @@ pub struct EndpointConfig {
4849 pub ( crate ) min_reset_interval : Duration ,
4950 /// Optional seed to be used internally for random number generation
5051 pub ( crate ) rng_seed : Option < [ u8 ; 32 ] > ,
52+ pub ( crate ) min_initial_size : u16 ,
5153}
5254
5355impl EndpointConfig {
@@ -63,6 +65,7 @@ impl EndpointConfig {
6365 grease_quic_bit : true ,
6466 min_reset_interval : Duration :: from_millis ( 20 ) ,
6567 rng_seed : None ,
68+ min_initial_size : MIN_INITIAL_SIZE ,
6669 }
6770 }
6871
@@ -159,6 +162,51 @@ impl EndpointConfig {
159162 self . rng_seed = seed;
160163 self
161164 }
165+
166+ /// Sets the minimum size of the very first Initial flight (handshake packets).
167+ ///
168+ /// If the first Initial packet is smaller than this value, Quinn will pad it
169+ /// up to this size.
170+ ///
171+ /// <div class="warning">
172+ ///
173+ /// According to the QUIC specification (RFC 9000), the Initial packet MUST be
174+ /// at least **1200 bytes**. Setting this value lower than 1200 can make the
175+ /// connection fail when communicating with other QUIC implementations.
176+ ///
177+ /// Setting this value too large may cause the Initial packet to exceed the
178+ /// path MTU, resulting in **handshake failure due to fragmentation loss**.
179+ ///
180+ /// </div>
181+ ///
182+ /// ## Safety
183+ ///
184+ /// Only use this when:
185+ /// - You fully control **both endpoints**, and
186+ /// - You know the **actual path MTU**, and intentionally violate QUIC
187+ /// interoperability requirements.
188+ ///
189+ /// ## Relationship to [`TransportConfig::min_mtu`]
190+ ///
191+ /// - `min_initial_size` affects **only the Initial flight** (handshake packets).
192+ /// It does *not* influence MTU probing or later packet sizes.
193+ ///
194+ /// - `TransportConfig::min_mtu` defines the **minimum allowed MTU** for normal
195+ /// data transmission **after the handshake**. It participates in MTU
196+ /// discovery (PMTUD/PLPMTUD) and controls how aggressively Quinn may lower MTU.
197+ ///
198+ /// | Setting | Affects | Used for |
199+ /// |----------------------------------|-----------------------------|----------------------------------|
200+ /// | `min_initial_size` (this fn) | Initial packets only | Faster handshake / experiments |
201+ /// | `TransportConfig::min_mtu` | Packets after handshake | MTU discovery & connection stability |
202+ ///
203+ /// Do **not** confuse the two:
204+ /// `min_initial_size` increases handshake packet size,
205+ /// while `min_mtu` constrains runtime MTU lowering.
206+ pub unsafe fn min_initial_size ( & mut self , value : u16 ) -> & mut Self {
207+ self . min_initial_size = value;
208+ self
209+ }
162210}
163211
164212impl fmt:: Debug for EndpointConfig {
0 commit comments