【问题标题】:Select a listening addresses for IPv6 server (Dual stack)为 IPv6 服务器选择一个监听地址(双栈)
【发布时间】:2014-01-08 10:27:04
【问题描述】:

对某些人来说,这似乎是一个奇怪的问题。但我已经搜索并没有找到任何答案。

当我想要一个双栈服务器时,我需要在 INADDR_ANY 上监听 IPv4 和 in6addr_any 对于 IPv6。

如果我有多个网卡,那么我需要选择是要全部收听,还是指定要收听的网卡。

对于这个确切的建议,我使用带有可配置主机名的getaddrinfo 方法。如果host_name 没有配置,那么我用NULL 调用getaddrinfo,并获得两个“ANY”地址。如果我使用 IP(v6 或 v4)配置它,我只会得到一个地址,这也很好。

但是当我使用我的hostname 作为配置的主机名时,在 Windows 机器上我从getaddrinfo 获取 3 个地址:一个 IPv4 地址和两个 IPv6 地址。第一个被 ipconfig 视为“链接本地 IPv6 地址”,第二个被视为“隧道适配器 6TO4 适配器:”部分下的“IPv6 地址”。 地址排序如下:

  1. 本地 IPv6 链路
  2. IPv6 地址
  3. IPv4

所以,如果我正在监听所有地址,那么双堆栈实际上是三重堆栈。如果我采用第一个 IPv6 地址(因为它是配置了 host_name 的 IPv4 服务器中的约定),我只在“链接本地 IPv6 地址”上侦听,该地址比“IPv6 地址”更难访问,并且许多客户端可以' t 连接到它,而他们可以连接到 IPv4 地址。

现在我正试图进一步复杂化。我已将手机连接到 USB 并激活 USB Tethering。当我通过getaddrinfo 解析地址时,我得到了 5 个地址: 按此顺序:

  1. USB IPv6 链路本地
  2. 以太网 IPv6 链路本地
  3. IPv6 地址
  4. USB IPv4
  5. 以太网 IPv4

所以我的问题是:

  1. 如果只是 IPv4,我会说我只使用第一个 IPv4。并且不关心其余的。但是当使用 IPv6 时,看起来最后一个 IPv6 是最合适的。有什么约定吗?

  2. 如果我有多网络机器,我需要选择第一个网络,并同时监听 IPv4 和 IPv6,但这里的结果是混合的。再说一遍,有什么约定吗?

  3. 我需要监听所有 IPv6 地址吗?在这种情况下,我将收听一个我不收听相应 IPv4 的 IPv6 地址。我希望避免它。

感谢您的帮助或评论。 但是请不要建议只听“ANY”,因为我不能。

【问题讨论】:

  • 为什么不能听“ANY”?在对getaddrinfo() 的调用中,您为hints.ai_flags 传递了哪些标志?根据getaddrinfo(3)上的Linux手册页,使用的排序功能基于RFC 3484,但我不知道Windows是否也使用相同的排序。
  • 因为如果你有两个网络并且你希望你的服务器只在一个网络上运行,那么你想要获取本地地址来监听。当您将主机名提供给getaddrinfo 时,它会解决它。你可以给每个网卡的主机名。

标签: c++ c networking cross-platform getaddrinfo


【解决方案1】:

链接本地地址仅在网段内有效,并且通常仅适用于您的机器到通信链路另一端的机器。例如,您的 USB 链接本地地址仅适用于您的手机和计算机之间的通信,但不能用于此之外;您的链路本地以太网 IPv6 地址将可用于同一集线器/交换机上的所有计算机,但不能超出路由器(有点类似于私有 IPv4 地址)。如果这不是您预期的用例,我建议您直接忽略链接本地地址。

自动分配的链接本地地址是使用非常特定的模式和掩码创建的,因此您可以通过编程方式检测它们。链路本地 IPv6 地址在 fe80::/64 范围内(意味着地址的第一个字节是 fe80:0000:0000:0000,其余 8 个字节可以是任何值),链路本地 IPv4 地址范围从 169.254.1.0 到 169.254。 255.255.

还要注意all hosts configure all IPv6-capable interfaces with a link-local address,即使他们被分配了另一个地址,也会保留它,所以没有摆脱它。

【讨论】:

  • 忽略本地链接是个好主意。但如果我有 2 个网卡?如何判断哪个 IPv6 地址与哪个 IPv4 地址匹配?我应该取第一个“not fe80::”和第一个“not 168.192.x.x”吗?
  • Linux/UNIX 机器没有给我链接本地地址。你有什么理由吗?
  • 没有按接口匹配 IPv4 和 IPv6 地址的约定,但您可以使用ask Windows to enumerate interfaces and the IP addresses associated with them 而不是使用getaddrinfo
  • 我猜地址顺序是有意义的。直到现在,我总是在多结果案例中选择第一个地址。但在这里它打破了这个规则。
  • 这不是我愿意做出的假设。 最有可能,地址将按某种逻辑顺序排列,因为否则会更麻烦,但从长远来看,寻找其中的模式可能比遍历接口更麻烦。对于 Linux,我真的不知道,我的 Linux 计算机有一个链接本地地址。也许您的计算机配置为在获取全局地址后将其删除。
【解决方案2】:

老帖子,我知道,你最后是怎么解决的?我真的很想知道。

为此,我建议您避免使用该选项,绑定到任何通配符 "::"bind(.., "::", ..) 并使用一些防火墙或包过滤器规则来排除您不想要的连接。

【讨论】:

  • 这很大程度上取决于您的配置。我发现的唯一方法是解析ifconfig 结果,或者使用给定名称手动设置/etc/hosts ,每个都在其他网卡上。
猜你喜欢
  • 2018-05-27
  • 1970-01-01
  • 2013-11-05
  • 2011-11-21
  • 2013-07-23
  • 1970-01-01
  • 2013-04-01
  • 2021-07-14
  • 2016-11-03
相关资源
最近更新 更多