【问题标题】:How to detect if dual stack socket is supported?如何检测是否支持双栈套接字?
【发布时间】:2023-03-12 12:25:02
【问题描述】:

某些操作系统似乎不支持双堆栈套接字。我正在寻找一种可靠的方法来检测是否支持此功能。我目前的建议(尚未测试)是检查 setsockopt 的返回值以在我尝试将套接字置于双堆栈模式时关闭 IPV6_V6ONLY。您认为这可行还是有更好的解决方案?

谢谢

【问题讨论】:

  • 什么是“所有”平台?此功能不在标准 C 中,因此我们需要明确哪些平台需要工作。
  • @JohnZwinck 感谢您的评论。我编辑了我的问题。
  • @Kaba,仍然不清楚 - 例如,setsockopt 并非在所有平台上都存在。覆盖所有平台的唯一方法是通读每个操作系统与底层硬件相关的文档并找到方法。
  • @JohnZwinck 双栈支持验证部分应该适用于Windows和POSIX操作系统(包括Unix、Mac OS X、Linux、Android和iOS)

标签: c sockets ipv6


【解决方案1】:

我想到的一种方法是尝试创建一个仅限 IPv6 的 UDP 套接字并将其连接到一个 IPv4 映射地址。这不会产生任何实际的网络流量,但通过查看代码的行为和分配给套接字的结果本地地址,您可以确定套接字是否实际上仅支持 IPv6。

这里是演示这个想法的 Python 代码。这可以直接映射到执行相同系统调用序列的等效 C 代码:

import socket
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
s.connect(('::ffff:169.254.1.1', 53))
print s.getsockname()

可能的结果:

  1. 由于不支持 IPV6_V6ONLY 选项,setsockopt 失败。
  2. connect 由于套接字仅支持 IPv6 而失败,并且连接识别到您不允许将此类套接字绑定到 IPv4 映射地址。
  3. connect 失败,没有到主机的路由。如果出现这种情况,您将一头雾水,因为您不知道它是在寻找 IPv4 路由还是 IPv6 路由,您必须尝试连接到其他地址才能确定是哪种情况。李>
  4. getsockname 返回一个 IPv4 映射地址,这意味着 IPV6_V6ONLY 并且套接字不是仅 IPv6。
  5. getsockname 返回一个 IPv6 地址而不是 IPv4 映射地址,这意味着套接字是 IPv6-only 并且 connect 使用的代码路径不知道 IPv4 映射地址有什么特殊之处。

我认为无法预测您在各种操作系统上会遇到哪些怪癖。但我非常有信心,我建议的套接字 API 调用序列会揭示任何此类怪癖。因此,您必须在与您相关的目标操作系统上对其进行测试,以了解它们各自的行为方式,结果可能证明简化版本的测试就足够了。

【讨论】:

    猜你喜欢
    • 2011-09-10
    • 2017-07-04
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多