确定何时尝试 IPv6 连接以及何时使用 IPv4
我正在开发一个连接到用户指定的公共服务器的网络客户端程序。如果用户给我一个要连接的主机名,该主机名同时具有 IPv4 和 IPv6 地址(通常是同时具有 A
和 AAAA
记录的 DNS 名称),我不确定我应该如何决定应该连接到哪个地址。
问题在于,机器同时支持 IPv4 和 IPv6,但只能通过 IPv4 进行全球连接,这是很常见的。最常见的情况是仅配置 IPv6 链路本地地址。目前我能想到的最佳替代方案是:
- 首先尝试 IPv6 地址 - 如果连接失败,请尝试 IPv4 地址;或者
- 只是让用户将其指定为配置设置(“prefer_ipv6”与“prefer_ipv4”)。
我看到选项 1 的问题是连接可能不会立即失败 - 可能需要相当长的时间才会超时。
I'm working on a network client program that connects to public servers, specified by the user. If the user gives me a hostname to connect to that has both IPv4 and IPv6 addresses (commonly, a DNS name with both A
and AAAA
records), I'm not sure how I should decide which address I should connect to.
The problem is that it's quite common for machines to support both IPv4 and IPv6, but only to have global connectivity over IPv4. The most common case of this is when only IPv6 link-local addresses are configured. At the moment the best alternatives I can come up with are:
- Try the IPv6 address(es) first - if the connection fails, try the IPv4 address(es); or
- Just let the user specify it as a config setting ("prefer_ipv6" versus "prefer_ipv4").
The problem I can see with option 1 is that the connection might not fail straight away - it might take quite a while to time out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
请尝试 IPv6。在绝大多数安装中,如果由于某种原因无法成功创建 IPv6 连接,尝试创建 IPv6 连接将立即失败:
当然,在某些情况下可能会出现问题,例如,如果配置了全局(或隧道)地址,并且某些内容错误地过滤掉了 ICMPv6 错误消息。您不必担心这种情况 - IPv4 连接可能因某种原因被破坏。
当然,您是否真的需要首先尝试 IPv6 地址是有争议的 - 您不妨再尝试一下。一般来说,您应该按照从 getaddrinfo 返回地址的顺序尝试地址。如今,系统支持配置选项,让管理员可以决定从 getaddrinfo 返回地址的顺序。
Please do try IPv6. In the significant majority of installations, trying to create an IPv6 connection will fail right away if it can't succeed for some reason:
There are of course cases where things can break, e.g. if a global (or tunnel) address is configured, and something falsely filters out ICMPv6 error messages. You shouldn't worry about this case - it may be just as well that IPv4 connectivity is somehow broken.
Of course, it's debatable whether you really need to try the IPv6 addresses first - you might just as well try them second. In general, you should try addresses in the order in which they are returned from getaddrinfo. Today, systems support configuration options that let administators decide in what order addresses should be returned from getaddrinfo.
在提出问题之后,IETF 通过 RFC6555 提出了该问题的答案,又名快乐眼球。
相关点是客户端和服务器可能都具有 IPv4 和 IPv6,但中间的一跳可能没有,因此不可能可靠地预测哪条路径将起作用。
Subsequent to the question being asked the IETF has proposed an answer to this question with RFC6555, a.k.a. Happy Eyeballs.
The pertinent point being the client and server may both have IPv4 and IPv6 but a hop in between may not so it is impossible to reliably predict which path will work.
由于
getaddrinfo()
,您应该让系统范围的配置来决定。就像 Java 一样。要求每个应用程序都尝试满足每个可能的 IPv6(错误)配置确实是不可扩展的!如果配置错误,用户会更直观地看到所有或没有应用程序崩溃。另一方面,您希望尝试大量记录令人烦恼的延迟和超时,以便用户可以快速确定责任所在。就像所有其他理想情况下的延迟一样,包括(非常常见的)DNS 超时。
You should let the system-wide configuration decide thanks to
getaddrinfo()
. Just like Java does. Asking every single application to try to cater for every single possible IPv6 (mis)configuration is really not scalable! In case of a misconfiguration it is much more intuitive to the user if all or none applications break.On the other hand you want to try to log annoying delays and time-outs profusely, so users can quickly identify what to blame. Just like every other delays ideally, including (very common) DNS time-outs.
这个演讲有解决方案。总结一下;
解决方案是同时独立地查找 AAAA 和 A 记录,并独立连接到解析的地址。首先使用成功的连接。
最简单的方法是允许网络 API 使用按名称连接网络 API 为您完成此操作。例如,在 Java 中:
幻灯片注释此时显示:
This talk has the solution. To summarize;
The solution is to lookup AAAA and A records simultaneously and independently, and to connect independently to the resolved addresses. Use whatever connection succeeds first.
The easiest way to do this is to allow the networking API do it for you using connect-by-name networking APIs. For example, in Java:
The slide notes say at this point:
一些想法:
我说首先尝试 IPv4,因为这是一个建立和测试得更好的协议。
Some ideas:
I say to try IPv4 first because that is the protocol which is better established and tested.