跳到主要内容

MtuDiscoveryConfig

搜索

结构体 MtuDiscoveryConfig 

源代码
pub struct MtuDiscoveryConfig { /* private fields */ }
展开描述

控制 MTU 探测的各个参数。

§为什么要做 MTU 探测

QUIC 在设计上有意保证:在握手阶段,客户端与服务器之间的网络路径能够传输有效载荷为 1200 字节且不分片的 UDP 数据包。换句话说,连接建立后我们就知道该路径的最大传输单元(MTU)至少为 1200 字节(再加上 IP 与 UDP 头部)。因此,QUIC 端点可以放心地把待发数据切成 1200 字节的数据包(如果端点发送更大的包,可能会因过大而被丢弃)。

然而,发送数据包本身会带来显著的开销。如果同样一份信息能用更少的包发完,就能获得更高的吞吐。所需发送的数据包数量与 MTU 成反比:MTU 越大,单包可承载的字节越多,传输给定数据量所需的包数也就越少。

大多数网络的 MTU 都大于 1200 字节。通过 MTU 探测,端点可以探知路径的 MTU;若发现 MTU 更大,便可开始发送更大的数据包。

§MTU 探测的实现细节

Quinn 通过 DPLPMTUD(Datagram Packetization Layer Path MTU Discovery)实现 MTU 探测,详见 RFC 9000 第 14.3 节。该方法会发送填充到特定大小的 QUIC 数据包(称为 PMTU probe),然后观察对端是否回应 ACK。如果收到 ACK,则说明该探测包成功到达对端,也即该路径的 MTU 至少为该包的大小。如果探测包丢失,会再重发 2 次;3 次都失败时,便认定该路径的 MTU 小于该包的大小。

MTU 探测按一定周期运行(默认每 600 秒一次),该周期通过 MtuDiscoveryConfig::interval 指定。第一次探测发生在握手刚结束后;后续探测的调度起点是上一次探测完成的时间,到达 interval 之后再次运行。

由于 MTU 的搜索空间非常大(最小为 1200,最大为 65527),Quinn 采用二分查找以尽量减少探测次数。首次探测时,搜索下界为 TransportConfig::initial_mtu;后续探测时,下界为当前已探测到的 MTU。上界则取 MtuDiscoveryConfig::upper_bound 与握手阶段从对端收到的 max_udp_payload_size 传输参数中的较小者。

§黑洞检测

如果在某个时刻网络路径不再接受探测到的那个尺寸的数据包,那么丢包最终会触发黑洞检测,并将探测到的 MTU 重置为 1200。此时将等待 MtuDiscoveryConfig::black_hole_cooldown 时间后再次触发 MTU 探测(忽略原先基于 MtuDiscoveryConfig::interval 设置的定时器)。

§对端之间的相互作用

A 到 B 的路径 MTU 与 B 到 A 的路径 MTU 不一定相同。因此,连接中的每个对端都需要独立地运行 MTU 探测,才能发现各自方向的路径 MTU。

实现§

源代码§

impl MtuDiscoveryConfig

源代码

pub fn interval(&mut self, value: Duration) -> &mut MtuDiscoveryConfig

指定在完成 MTU 探测之后,需等待多长时间才会开启新一轮 MTU 探测。

默认为 600 秒,符合 RFC 8899 的建议。

源代码

pub fn upper_bound(&mut self, value: u16) -> &mut MtuDiscoveryConfig

指定 MTU 探测所搜索的最大 UDP 有效负载大小的上限。

默认为 1452,以保证在使用 IPv4 与 IPv6 时不超过以太网的 MTU。允许的最大值为 65527,对应 IPv6 上允许的最大 UDP 有效负载。

无论实际网络路径的 MTU 如何,使用一个任意大的上限都是安全的,唯一的代价是 MTU 探测可能需要更长时间才能完成。

源代码

pub fn black_hole_cooldown( &mut self, value: Duration, ) -> &mut MtuDiscoveryConfig

指定在检测到“黑洞”之后,MTU 探测需等待多长时间才会再次运行。默认为一分钟。

在发生拥塞时,黑洞检测可能被误触发,因此在一段较短时间后再次尝试 MTU 探测是合理的。

源代码

pub fn minimum_change(&mut self, value: u16) -> &mut MtuDiscoveryConfig

指定用以终止 MTU 探测阶段的最小 MTU 变化量。默认为 20。

trait 实现§

源代码§

impl Clone for MtuDiscoveryConfig

源代码§

fn clone(&self) -> MtuDiscoveryConfig

返回值的副本。 更多信息
1.0.0 · 源代码§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. 更多信息
源代码§

impl Debug for MtuDiscoveryConfig

源代码§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

使用给定的格式化器格式化此值。 更多信息
源代码§

impl Default for MtuDiscoveryConfig

源代码§

fn default() -> MtuDiscoveryConfig

Returns the “default value” for a type. 更多信息

自动 trait 实现§

blanket 实现§

源代码§

impl<T> Any for T
where T: 'static + ?Sized,

源代码§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
源代码§

impl<T> Borrow<T> for T
where T: ?Sized,

源代码§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
源代码§

impl<T> BorrowMut<T> for T
where T: ?Sized,

源代码§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. 更多信息
源代码§

impl<T> CloneToUninit for T
where T: Clone,

源代码§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 更多信息
源代码§

impl<T> From<T> for T

源代码§

fn from(t: T) -> T

原样返回该参数。

源代码§

impl<T> Instrument for T

源代码§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. 更多信息
源代码§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. 更多信息
源代码§

impl<T, U> Into<U> for T
where U: From<T>,

源代码§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换行为完全由 From<T> for U 的实现决定。

源代码§

impl<T> ToOwned for T
where T: Clone,

源代码§

type Owned = T

The resulting type after obtaining ownership.
源代码§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. 更多信息
源代码§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 更多信息
源代码§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

源代码§

type Error = Infallible

The type returned in the event of a conversion error.
源代码§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
源代码§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

源代码§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
源代码§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。
源代码§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

源代码§

fn vzip(self) -> V

源代码§

impl<T> WithSubscriber for T

源代码§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. 更多信息
源代码§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. 更多信息
源代码§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

源代码§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

源代码§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,