Skip to content

Commit ad8d6d7

Browse files
committed
feat(quinn-proto): export min_initial_size
Signed-off-by: loongtao.zhang <[email protected]>
1 parent eee334d commit ad8d6d7

File tree

3 files changed

+60
-12
lines changed

3 files changed

+60
-12
lines changed

quinn-proto/src/config/mod.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ use crate::NoneTokenLog;
1818
#[cfg(any(feature = "rustls-aws-lc-rs", feature = "rustls-ring"))]
1919
use crate::crypto::rustls::{QuicServerConfig, configured_provider};
2020
use 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

5355
impl 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

164212
impl fmt::Debug for EndpointConfig {

quinn-proto/src/connection/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use tracing::{debug, error, trace, trace_span, warn};
1616

1717
use crate::{
1818
Dir, Duration, EndpointConfig, Frame, INITIAL_MTU, Instant, MAX_CID_SIZE, MAX_STREAM_COUNT,
19-
MIN_INITIAL_SIZE, Side, StreamId, TIMER_GRANULARITY, TokenStore, Transmit, TransportError,
20-
TransportErrorCode, VarInt,
19+
Side, StreamId, TIMER_GRANULARITY, TokenStore, Transmit, TransportError, TransportErrorCode,
20+
VarInt,
2121
cid_generator::ConnectionIdGenerator,
2222
cid_queue::CidQueue,
2323
coding::BufMutExt,
@@ -634,7 +634,7 @@ impl Connection {
634634
// Finish current packet
635635
if let Some(mut builder) = builder_storage.take() {
636636
if pad_datagram {
637-
builder.pad_to(MIN_INITIAL_SIZE);
637+
builder.pad_to(self.endpoint_config.min_initial_size);
638638
}
639639

640640
if num_datagrams > 1 || pad_datagram_to_mtu {
@@ -857,7 +857,7 @@ impl Connection {
857857
buf.write(frame::FrameType::PATH_RESPONSE);
858858
buf.write(token);
859859
self.stats.frame_tx.path_response += 1;
860-
builder.pad_to(MIN_INITIAL_SIZE);
860+
builder.pad_to(self.endpoint_config.min_initial_size);
861861
builder.finish_and_track(
862862
now,
863863
self,
@@ -912,7 +912,7 @@ impl Connection {
912912
// Finish the last packet
913913
if let Some(mut builder) = builder_storage {
914914
if pad_datagram {
915-
builder.pad_to(MIN_INITIAL_SIZE);
915+
builder.pad_to(self.endpoint_config.min_initial_size);
916916
}
917917

918918
// If this datagram is a loss probe and `segment_size` is larger than `INITIAL_MTU`,
@@ -1026,7 +1026,7 @@ impl Connection {
10261026
SpaceId::Data,
10271027
"PATH_CHALLENGE queued without 1-RTT keys"
10281028
);
1029-
buf.reserve(MIN_INITIAL_SIZE as usize);
1029+
buf.reserve(self.endpoint_config.min_initial_size as usize);
10301030

10311031
let buf_capacity = buf.capacity();
10321032

@@ -1054,7 +1054,7 @@ impl Connection {
10541054
// to at least the smallest allowed maximum datagram size of 1200 bytes,
10551055
// unless the anti-amplification limit for the path does not permit
10561056
// sending a datagram of this size
1057-
builder.pad_to(MIN_INITIAL_SIZE);
1057+
builder.pad_to(self.endpoint_config.min_initial_size);
10581058

10591059
builder.finish(self, now, buf);
10601060
self.stats.udp_tx.on_sent(1, buf.len());

quinn-proto/src/endpoint.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use thiserror::Error;
1515
use tracing::{debug, error, trace, warn};
1616

1717
use crate::{
18-
Duration, INITIAL_MTU, Instant, MAX_CID_SIZE, MIN_INITIAL_SIZE, RESET_TOKEN_SIZE, ResetToken,
19-
Side, Transmit, TransportConfig, TransportError,
18+
Duration, INITIAL_MTU, Instant, MAX_CID_SIZE, RESET_TOKEN_SIZE, ResetToken, Side, Transmit,
19+
TransportConfig, TransportError,
2020
cid_generator::ConnectionIdGenerator,
2121
coding::BufMutExt,
2222
config::{ClientConfig, EndpointConfig, ServerConfig},
@@ -430,7 +430,7 @@ impl Endpoint {
430430
.map(DatagramEvent::Response);
431431
};
432432

433-
if datagram_len < MIN_INITIAL_SIZE as usize {
433+
if datagram_len < self.config.min_initial_size as usize {
434434
debug!("ignoring short initial for connection {}", dst_cid);
435435
return None;
436436
}

0 commit comments

Comments
 (0)