在IPv6网络中,IPV6_V6ONLY标志用于确保套接字仅使用IPv6,特别是IPv4-to-IPv6映射不会用于该套接字。在许多操作系统上,IPV6_V6ONLY默认情况下未设置,但在某些操作系统(例如Windows 7)上,默认设置为。
我的问题是:引入这面旗帜的动机是什么?是否存在导致问题的IPv4-to-IPv6映射,因此人们需要一种方法来禁用它?在我看来,如果有人不想使用IPv4到IPv6的映射,他们可能根本就没有指定IPv4映射的IPv6地址。我在这里缺少什么?
答案 0 :(得分:10)
并非所有支持IPv6的平台都支持双栈套接字,因此问题就变成了需要最大限度地提高IPv6兼容性的应用程序如何知道支持双栈,或者当它不支持时分离绑定?唯一的通用答案是IPV6_V6ONLY。
忽略IPV6_V6ONLY或在具有双栈功能的IP堆栈之前写入的应用程序可能会发现在双栈环境中与V4分离的绑定失败,因为IPv6双栈套接字绑定到IPv4以防止IPv4套接字绑定。由于协议或应用程序级别寻址问题或IP访问控制,应用程序也可能不期望IPv4 over IPv6。
这种或类似情况很可能促使MS等人默认为1,即使RFC3493声明0为默认值。 1理论上最大化向后兼容性。特别是Windows XP / 2003不支持dualstack套接字。
不幸的是,还不缺少需要传递较低层信息才能正常运行的应用程序,因此该选项对于规划最符合要求和现有代码库的IPv4 / IPv6兼容性策略非常有用。
答案 1 :(得分:4)
最常提到的原因是服务器具有某种形式的ACL(访问控制列表)。例如,想象一下具有以下规则的服务器:
Allow 192.0.2.4
Deny all
它在IPv4上运行。现在,有人在具有IPv6的计算机上运行它,并且根据某些参数,IPv6套接字上接受IPv4请求,映射为:: 192.0.2.4,然后不再与第一个ACL匹配。突然间,访问将被拒绝。
在您的应用程序中显式(使用IPV6_V6ONLY)将解决问题,无论操作系统具有什么默认值。
答案 2 :(得分:3)
我不知道为什么会违约;但无论默认是什么,它都是我总是会明确指出的那种旗帜。
关于它为什么首先存在,我想它允许你保留现有的仅IPv4服务器,并且只在同一端口上运行新服务器,但仅用于IPv6连接。或者新服务器可以简单地将客户端代理到旧服务器,从而使IPv6功能轻松,轻松地添加到旧服务中。
答案 3 :(得分:2)
对于Linux,在编写侦听相同服务端口上的IPv4和IPv6套接字的服务时,例如在端口2001,你必须调用setsockopt(s,SOL_IPV6,IPV6_V6ONLY,& one,sizeof(one));在IPv6套接字上。如果不这样做,IPv4套接字的bind()操作将失败并显示“Address in in use”。
答案 4 :(得分:1)
有一些合理的方法可以使用(名称不详的)“IPv4映射”地址来绕过配置不当的系统,或者糟糕的堆栈,甚至在配置良好的系统中可能只需要大量的防错。开发人员可能希望使用此标志通过不使用API的这一部分来使其应用程序更安全。
请参阅:http://ipv6samurais.com/ipv6samurais/openbsd-audit/draft-cmetz-v6ops-v4mapped-api-harmful-01.txt
答案 5 :(得分:0)
想象一种协议,其在会话中包括网络地址,例如FTP的数据通道。使用IPv6时,您将发送IPv6地址,如果收件人恰好是IPv4映射地址,则无法连接到该地址。
答案 6 :(得分:0)
有一个非常常见的例子,即行为的二元性是一个问题。带有getaddrinfo()
标记的标准AI_PASSIVE
调用提供了传递 nodename 参数并返回要监听的地址列表的可能性。 nodename 接受以NULL字符串形式的特殊值,并暗示侦听通配符地址。
在某些系统上,0.0.0.0
和::
按此顺序返回。默认情况下启用双栈套接字并且未设置套接字IPV6_V6ONLY
时,服务器将连接到0.0.0.0
,然后无法连接到双栈::
,因此(1) )仅适用于IPv4和(2)报告错误。
我认为订单有误,因为预计IPv6会更受欢迎。但即使您首次尝试双堆栈::
然后仅使用IPv4 0.0.0.0
,服务器仍会报告第二次呼叫的错误。
我个人认为双栈插槽的整个想法是错误的。在我的项目中,我宁愿总是明确设置IPV6_V6ONLY
来避免这种情况。有些人显然认为这是一个好主意,但在这种情况下,我可能会明确取消IPV6_V6ONLY
并将NULL
直接翻译为0.0.0.0
,绕过getaddrinfo()
机制。