pub struct TransportConfig { /* private fields */ }展开描述
控制 QUIC 核心状态机的参数
默认值应该适合大多数互联网应用。对于禁止对端主动开启流的协议,应将 max_concurrent_bidi_streams 和 max_concurrent_uni_streams 设为 0。
在某些情况下,可以通过针对特定应用和/或网络连接调整这些值来改善性能或资源需求。尤其是数据窗口大小可以针对期望的往返时间、链路容量和可用内存进行调优。调高带宽和延迟会增加最坏情况下的内存消耗,但不会影响较低带宽和延迟下的性能。默认配置针对的是 100Mbps 带宽、100ms 往返时间的链路进行调优。
实现§
源代码§impl TransportConfig
impl TransportConfig
源代码pub fn max_concurrent_bidi_streams(
&mut self,
value: VarInt,
) -> &mut TransportConfig
pub fn max_concurrent_bidi_streams( &mut self, value: VarInt, ) -> &mut TransportConfig
同时处于打开状态的入站双向流的最大数量
必须为非零值,对端才能打开任何双向流。
最坏情况下内存占用与 max_concurrent_bidi_streams * stream_receive_window 成正比,上界则与 receive_window 成正比。
源代码pub fn max_concurrent_uni_streams(
&mut self,
value: VarInt,
) -> &mut TransportConfig
pub fn max_concurrent_uni_streams( &mut self, value: VarInt, ) -> &mut TransportConfig
max_concurrent_bidi_streams 的变体,作用于单向流
源代码pub fn max_idle_timeout(
&mut self,
value: Option<IdleTimeout>,
) -> &mut TransportConfig
pub fn max_idle_timeout( &mut self, value: Option<IdleTimeout>, ) -> &mut TransportConfig
在连接因不活跃而超时之前所允许的最大空闲时长。
实际的空闲超时取本配置与对端自身最大空闲超时两者中的较小值。None 表示无限空闲超时。默认为 30 秒。
警告:若对端或其网络路径出现故障或存在恶意行为,无限的空闲超时可能导致 future 永久挂起!
let mut config = TransportConfig::default();
// Set the idle timeout as `VarInt`-encoded milliseconds
config.max_idle_timeout(Some(VarInt::from_u32(10_000).into()));
// Set the idle timeout as a `Duration`
config.max_idle_timeout(Some(Duration::from_secs(10).try_into()?));源代码pub fn stream_receive_window(&mut self, value: VarInt) -> &mut TransportConfig
pub fn stream_receive_window(&mut self, value: VarInt) -> &mut TransportConfig
对端在任意单个流上未被确认即可发送的字节上限,达到此上限后将被阻塞。
该值至少应设置为预期连接延迟与期望最大吞吐量的乘积。将其设置为小于 receive_window 的值有助于避免单个流独占接收缓冲区——若应用程序在一段时间内不读取大流但仍需要其他流上的数据,就可能出现这种情况。
源代码pub fn receive_window(&mut self, value: VarInt) -> &mut TransportConfig
pub fn receive_window(&mut self, value: VarInt) -> &mut TransportConfig
对端在整个连接的所有流上未被确认即可发送的字节上限,达到此上限后将被阻塞。
该值至少应设置为预期连接延迟与期望最大吞吐量的乘积。设置为较大的值可以在某个流被阻塞时仍允许其他流达到最大吞吐量。
源代码pub fn send_window(&mut self, value: u64) -> &mut TransportConfig
pub fn send_window(&mut self, value: u64) -> &mut TransportConfig
在对端未确认的情况下可发送的最大字节数
当与分配大量流控信用额的对端通信时,该设置给出了内存占用的上界。希望稳健处理大量连接的端点应将其设置得足够低,以确保即使每个连接都使用完整窗口也不会出现内存耗尽。
源代码pub fn send_fairness(&mut self, value: bool) -> &mut TransportConfig
pub fn send_fairness(&mut self, value: bool) -> &mut TransportConfig
是否对具有相同优先级的发送流实现公平排队。
启用后,连接会以轮询方式调度相同优先级的各出站流上的数据;禁用时,流将按写入顺序进行调度。
注意该设置仅影响具有相同优先级的流。较高优先级的流始终优先于较低优先级的流。
对于使用大量小流的工作负载,禁用公平性可以降低碎片化和协议开销。
源代码pub fn packet_threshold(&mut self, value: u32) -> &mut TransportConfig
pub fn packet_threshold(&mut self, value: u32) -> &mut TransportConfig
在 FACK 风格的丢包检测将数据包判定为丢失之前,所允许的包号空间最大重排度。根据 RFC5681,该值不应小于 3。
源代码pub fn time_threshold(&mut self, value: f32) -> &mut TransportConfig
pub fn time_threshold(&mut self, value: f32) -> &mut TransportConfig
在基于时间的丢包检测将数据包判定为丢失之前所允许的时间维最大重排度,以 RTT 的倍数表示
源代码pub fn initial_rtt(&mut self, value: Duration) -> &mut TransportConfig
pub fn initial_rtt(&mut self, value: Duration) -> &mut TransportConfig
在获得首个 RTT 样本之前所使用的 RTT
源代码pub fn initial_mtu(&mut self, value: u16) -> &mut TransportConfig
pub fn initial_mtu(&mut self, value: u16) -> &mut TransportConfig
在运行 MTU 发现之前(参见 TransportConfig::mtu_discovery_config)使用的 UDP 最大负载初始值。
该值至少必须为 1200(即默认值),已知对典型互联网应用是安全的。更大的值更高效,但会增加因超过网络路径 IP MTU 而丢包的风险。如果所设值高于网络路径实际支持的值,丢包最终将触发黑洞检测并将其降至 TransportConfig::min_mtu。
源代码pub fn min_mtu(&mut self, value: u16) -> &mut TransportConfig
pub fn min_mtu(&mut self, value: u16) -> &mut TransportConfig
网络保证支持的最大 UDP 负载大小。
至少必须为 1200(即默认值),且应小于等于 TransportConfig::initial_mtu。
实际 MTU 会因 ISP、VPN 以及两端都无法控制的中转网络链路属性而异。在私网以外、这些因素完全不可控的环境中调高该值必须格外小心。如果所设值高于网络路径实际支持的值,将导致无法预测的灾难性丢包且无法恢复。请优先使用 TransportConfig::initial_mtu 配合 TransportConfig::mtu_discovery_config 来设定一个能稳健适配网络的最大 UDP 负载大小。
源代码pub fn mtu_discovery_config(
&mut self,
value: Option<MtuDiscoveryConfig>,
) -> &mut TransportConfig
pub fn mtu_discovery_config( &mut self, value: Option<MtuDiscoveryConfig>, ) -> &mut TransportConfig
指定 MTU 发现配置(详见 MtuDiscoveryConfig)。
默认启用。
源代码pub fn pad_to_mtu(&mut self, value: bool) -> &mut TransportConfig
pub fn pad_to_mtu(&mut self, value: bool) -> &mut TransportConfig
将携带应用层数据的 UDP 数据报填充至当前最大 UDP 负载大小
默认禁用。包含丢包探测包的 UDP 数据报不受填充影响。
启用此选项有助于缓解网络观察者的流量分析,但会增加带宽占用。在不启用此缓解措施的情况下,在某些条件下观察者可以推断出应用数据报的精确明文大小以及流写入突发的总大小。这要求要么连接处于非拥塞状态,要么应用数据报过大以至于无法合并。
源代码pub fn ack_frequency_config(
&mut self,
value: Option<AckFrequencyConfig>,
) -> &mut TransportConfig
pub fn ack_frequency_config( &mut self, value: Option<AckFrequencyConfig>, ) -> &mut TransportConfig
指定 ACK 频率配置(详见 AckFrequencyConfig)
如果对端不支持 ACK 频率 QUIC 扩展,所提供的配置将被忽略。
默认为 None,表示不控制对端的 ACK 频率。即便设为 None,本地端仍支持 ACK 频率 QUIC 扩展,并可以以其他方式使用它。
源代码pub fn persistent_congestion_threshold(
&mut self,
value: u32,
) -> &mut TransportConfig
pub fn persistent_congestion_threshold( &mut self, value: u32, ) -> &mut TransportConfig
在网络被认为正在经历持续拥塞之前,连续 PTO(Probe Timeout)的次数。
源代码pub fn keep_alive_interval(
&mut self,
value: Option<Duration>,
) -> &mut TransportConfig
pub fn keep_alive_interval( &mut self, value: Option<Duration>, ) -> &mut TransportConfig
在发送 keep-alive 包之前允许的不活跃时长
keep-alive 包可以防止一条虽然空闲但本身健康的连接因超时而被关闭。
设为 None 表示禁用(默认)。对于任意一条连接,只要任一端启用了 keep-alive,该连接就能保持。生效前提是该值必须小于两端 idle_timeout 的较小值。
源代码pub fn crypto_buffer_size(&mut self, value: usize) -> &mut TransportConfig
pub fn crypto_buffer_size(&mut self, value: usize) -> &mut TransportConfig
可被缓冲的乱序加密层数据最大数量
源代码pub fn allow_spin(&mut self, value: bool) -> &mut TransportConfig
pub fn allow_spin(&mut self, value: bool) -> &mut TransportConfig
是否允许实现在本连接上设置 spin bit
启用后,被动的网络观察者即可轻松判断连接的往返时延,这对网络管理有用,但会牺牲少量隐私。
源代码pub fn datagram_receive_buffer_size(
&mut self,
value: Option<usize>,
) -> &mut TransportConfig
pub fn datagram_receive_buffer_size( &mut self, value: Option<usize>, ) -> &mut TransportConfig
入站应用层数据报可缓冲的最大字节数;设为 None 则禁收入站数据报
对端被禁止发送大于此值的单个数据报。若对端发来但应用层尚未消费的所有数据报总大小超过此值,则旧的数据报将被丢弃,直到不再超过为止。
源代码pub fn datagram_send_buffer_size(
&mut self,
value: usize,
) -> &mut TransportConfig
pub fn datagram_send_buffer_size( &mut self, value: usize, ) -> &mut TransportConfig
出站应用层数据报可缓冲的最大字节数
虽然数据报会尽快发出,但应用生成数据的速度仍可能超过链路甚至底层硬件的发送能力。该设置限制了这种情况下可能消耗的内存量。当发送缓冲区已满又要发送新数据报时,旧的数据报将被丢弃,直到腾出足够的空间。
源代码pub fn congestion_controller_factory(
&mut self,
factory: Arc<dyn ControllerFactory + Sync + Send>,
) -> &mut TransportConfig
pub fn congestion_controller_factory( &mut self, factory: Arc<dyn ControllerFactory + Sync + Send>, ) -> &mut TransportConfig
如何构造新的 congestion::Controller
通常为某个 congestion::Controller 的引用计数化配置,例如 congestion::NewRenoConfig。
§Example
let mut config = TransportConfig::default();
config.congestion_controller_factory(Arc::new(congestion::NewRenoConfig::default()));源代码pub fn enable_segmentation_offload(
&mut self,
enabled: bool,
) -> &mut TransportConfig
pub fn enable_segmentation_offload( &mut self, enabled: bool, ) -> &mut TransportConfig
当运行环境支持时,是否启用“Generic Segmentation Offload”来加速发送
默认为 true。
在发送大量具有相同包头的数据包(例如在一条连接上传输大批量数据)时,GSO 可以显著降低 CPU 占用。但并非所有网卡驱动或抓包工具都支持。当不可用时,quinn-udp 会尝试自动关闭 GSO,但这可能在启动时引入偶发丢包,使性能暂时下降。