#ipv6 #ipv4 #networking

happy-eyeballs

实现Happy Eyeballs的库,即使在IPv4或IPv6连接有问题的情况下也能保持良好的用户体验

3个不稳定版本

0.2.1 2023年5月8日
0.2.0 2023年4月2日
0.1.0 2023年3月28日

#22 in #ipv6

Download history 1/week @ 2024-04-18 9/week @ 2024-04-25 211/week @ 2024-07-25

每月211次下载

0BSD许可证

40KB
861

Get it on Codeberg

Happy Eyeballs   文档 最新版本 许可证

Happy Eyeballs是一种技术,用于在从双栈(IPv4和IPv6)客户端连接时提供良好的用户体验。

此crate实现了RFC 8305中描述的Happy Eyeballs连接设置。它提供了对std::net::TcpStream::connect和异步使用tokio::net::TcpStream::connectasync_std::net::TcpStream::connect的默认替代。

基本用法

只需调用happy_eyeballs::connect代替TcpStream::connect

fn main() -> Result<(), std::io::Error> {
    let socket_addr= ("www.example", 80);
    let tcp_stream = happy_eyeballs::connect(socket_addr)?;
    println!("Connected: {tcp_stream:?}");
    Ok(())
}

功能标志

限制

DNS请求提前进行

《happy_eyeballs::connect》函数的第一步是将主机名解析为所有IP地址。在解析过程完成之前,它不会发起连接尝试。

RFC指出

实现不应在等待两种答案返回后才尝试建立连接。如果一个查询失败或返回时间显著更长,等待第二个地址族可能会显著延迟第一个地址族的连接建立。因此,客户端应将DNS解析视为异步操作

地址排序不可配置,并优先考虑IPv6。

解析过程完成后,happy-eyeballs将结果地址重新排列,使IPv6和IPv4交替出现。最好使用目标地址选择。尽管如此,由于底层实现通常调用getaddrinfo(3),它受到操作系统提供的某些可配置性的影响。但happy_eyeballs::connect()将强制IPv6优先,并使IPv6和IPv4交替。

IPv4/IPv6地址交替很简单。

目前,happy-eyeballs交替尝试IPv6然后是IPv4。RFC建议通过“首选地址族计数”来配置这种交替

实现是无状态的

目前,算法每次都做同样的事情。如果早期地址证明是无法访问或无响应的,它仍将在后续连接中按相同的首选顺序重试。

将客户端变得更加有状态会更好

如果客户端从同一主机或前缀的其他连接收集了历史RTT数据,则可以使用此信息来影响其[连接尝试]延迟。

如果客户端是有状态的,并且具有访问每个地址的路由的预期往返时间(RTT)的历史记录,则它应在规则8和9之间添加一个目标地址选择规则,优先选择RTT较低的地址。如果客户端跟踪过去使用过的地址,则它应在RTT规则和规则9之间添加另一个目标地址选择规则,优先选择使用过的地址。

另请参阅

我们使用一个度量标准比较了双栈主机的IPv4和IPv6连接性,该度量标准测量了传输控制协议(TCP)连接到多个流行Web服务的建立时间。我们见证了几个案例,其中在IPv6上的连接建立时间和其变化更高。

依赖关系

~0–10MB
~104K SLoC