路径mtu探测在基于udp的程序中很有用,如果大了,会引起ip层分片,导致容易丢包。小了,网络利用率不高。
quic做mtu探测是根据,可以设置ip层包不分片来做的。如果超过了mtu大小会丢失。
所有工作是在定时器里做的,封装为ping包
while(condition){
send current_mtu_pkg_size //定时器做的
if(error)
break;
收到,更新
max_mtu_pkg_acked_size; //这个就是当前最大的pmtu
current_mtu_pkg_size 增加
if(timeout)
break;
}
另外附上设置ip包头DF位代码
int UDPSocketPosix::SetDoNotFragment() {
DCHECK_NE(socket_, kInvalidSocket);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
#if !defined(IP_PMTUDISC_DO)
return ERR_NOT_IMPLEMENTED;
#else
if (addr_family_ == AF_INET6) {
int val = IPV6_PMTUDISC_DO;
if (setsockopt(socket_, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
sizeof(val)) != 0) {
return MapSystemError(errno);
}
int v6_only = false;
socklen_t v6_only_len = sizeof(v6_only);
if (getsockopt(socket_, IPPROTO_IPV6, IPV6_V6ONLY, &v6_only,
&v6_only_len) != 0) {
return MapSystemError(errno);
}
if (v6_only)
return OK;
}
int val = IP_PMTUDISC_DO;
int rv = setsockopt(socket_, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
return rv == 0 ? OK : MapSystemError(errno);
#endif
}