使用AF_UNSPEC的缺点/风险是什么?

What would be the disadvantages/risks of using AF_UNSPEC?

本文关键字:是什么 缺点 AF UNSPEC 使用      更新时间:2023-10-16

From Beej's Guide to Network programming

可以在ai_family字段中强制使用IPv4或IPv6,或者将其保留为AF_UNSPEC以使用任何内容。这很酷,因为你的代码可以是IP版本无关的。

正如标题所说-总是使用AF_UNSPEC而不是指定IPv4或IPv6的缺点(或风险,如果有的话)是什么?

或者只有一个原因——如果指定了版本,这将保证这个且只支持这个版本?


一点背景-我考虑在客户端-服务器(c++)应用程序中添加对IPv6的支持,两个版本都应该支持。所以我想知道是否可以使用AF_UNSPEC,或者更好地从字符串中"识别"地址并使用AF_INET6AF_INET,具体取决于地址。

您必须区分客户端和服务器应用程序。

在客户端,这很简单:只需调用getaddrinfo()并按顺序尝试每个答案,直到您获得连接。

在服务器上,事情有点困难:

  • 有些系统的IPv4和v6堆栈是相互连接的,在那里只监听IPv6就足够了。也许套接字必须启用侦听。
  • 其他系统,如Windows XP,有分离的堆栈,这种连接是不可能的。在这种情况下,您必须同时使用多个套接字。让我集中讨论以下内容:

即使在服务器上,也可以使用getaddrinfo()。在这里,您可以在提示中使用AI_PASSIVE标志。然后你就会得到结果。在这些情况下,您将不得不监听,也许启用IPV6_V6ONLY标志。

accept()应该完成非阻塞或select()poll()(不确定后者是否可能)。

事情应该是这样的:

应用程序应该与第三层无关。连接到另一个系统应该通过名称来完成。名称应该解析为一个或多个地址,应用程序应该连接到它们,而不需要查看正在使用的实际协议。这样,网络配置是网络和系统管理员的责任。如果在网络中引入IPv6,则应用程序甚至不会注意到差异而继续工作。

一些现实问题:

有时IPv6配置不好,防火墙不知道如何处理IPv6, IPv6只在本地网络中使用,没有连接到互联网,等等。这应该不是问题,但有时您会遇到糟糕的实现或配置。为了解决这个问题,IETF正在起草一份名为happy-eyeballs的草案。它确保用户不会注意到这些问题。看看那份草稿。使用该草案中指定的技术将确保您的应用程序对所有用户都有效。

使用AF_UNSPEC的风险之一是您将客户端暴露于来自恶意DNS服务器的更大响应,该服务器可能试图使用CVE-2015-7547导致堆栈缓冲区溢出,并导致恶意代码由客户端执行。事实上,对于getaddrinfo中已知的缺陷,一个建议的解决方案是防止使用AF_UNSPEC,详见bug报告。DNS响应大于2K的溢出缺陷从2.9开始影响glibc,并在2.23中修复。