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

C++ 使用AF_UNSPEC的缺点/风险是什么?,c++,c,sockets,unix,network-programming,C++,C,Sockets,Unix,Network Programming,从 您可以在ai_family字段中强制它使用IPv4或IPv6,或者将其保留为AF_unsec以使用任何内容。这很酷,因为您的代码可以是IP版本无关的 正如标题所说,总是使用AF_unsec,而不是指定IPv4或IPv6,会有什么缺点(或风险,如果有的话) 或者这仅仅是因为一个原因-如果指定了版本,这将保证只支持这个版本 一点背景知识-我考虑在客户机-服务器(C++)应用程序中添加对IPv6的支持,这两个版本都应该得到支持。因此我想知道使用AF_unsec是否合适,或者最好从字符串中“识别”

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

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

或者这仅仅是因为一个原因-如果指定了版本,这将保证只支持这个版本



一点背景知识-我考虑在客户机-服务器(C++)应用程序中添加对IPv6的支持,这两个版本都应该得到支持。因此我想知道使用
AF_unsec
是否合适,或者最好从字符串中“识别”地址,然后根据地址使用
AF_INET6
AF_INET

事情应该是这样的:

应用程序应该是第三层不可知的。应按名称连接到另一个系统。名称应解析为一个或多个地址,应用程序应连接到这些地址,而无需查看实际使用的协议。这样,网络配置由网络管理员和系统管理员负责。如果在网络中引入IPv6,那么应用程序将继续工作,甚至不会注意到差异

一些现实问题:


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

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

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

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

  • 有些系统的IPv4和v6协议栈是相互连接的,只要在IPv6上监听就足够了。可能必须启用套接字才能同时侦听这两个消息
  • 其他系统,如Windows XP,在不可能进行这种连接的地方有单独的堆栈。在那里,您必须同时使用多个插座。让我集中谈谈以下几点
即使在服务器上,也可以使用
getaddrinfo()
。在这里,您可以在提示中使用标志
AI_PASSIVE
。然后你会得到结果。在这些问题上,您将不得不倾听,可能需要启用
IPV6\u V6ONLY
标志


accept()
应以非阻塞方式进行,或使用
select()
poll()
(不确定后者是否可行)。

使用AF_unsec的风险之一是,您将客户端暴露于恶意DNS服务器的较大响应中,该服务器可能试图使用CVE-2015-7547造成堆栈缓冲区溢出,并导致客户端执行恶意代码。事实上,对于getaddrinfo中的已知缺陷,一个建议的解决方法是防止使用错误报告中详细说明的AF_Unsec。大于2K的DNS响应的溢出缺陷从2.9开始影响glibc,并在2.23中修复。这会影响大多数当前安装的Linux发行版。

谢谢。我将其中一个标记更改为
unix
。所以,我的问题是关于linux的。我尝试了
AF_unsec
,它似乎对这两个版本都非常有效。我只是想知道我是否可以像这样使用它,或者它更好地处理几个插座。我写了一个结论…啊,我现在明白了。我花了很多时间才明白你的确切意思:我只是对网络编程有点陌生。谢谢,+1并被接受(尽管这实际上并没有回答标题中的问题,但帮助我理清了思路:)