截至撰写本文时,我正在运行最新版本的 Windows 10(1903),并且我有一个有效的双栈连接。如果我从命令行 ping 双栈设备的主机名,Windows 会首选 IPv4 地址。如果我关闭 IPv4,它将使用 IPv6 地址。根据众多来源(包括这个答案),Windows 应该优先选择 IPv6。
答案1
正如所述这个答案之后,我按照以下步骤获取网络堆栈的跟踪:
netsh trace start provider=Microsoft-Windows-TCPIP level=5 keywords=ut:TcpipRoute
ping -n 1 www.google.com
netsh trace stop
netsh trace convert %TEMP%\NetTraces\NetTrace.etl
生成的文本文件包含以下行:
[2]0910.3710::2019-08-10 01:27:15.198580000 [Microsoft-Windows-TCPIP]IP: Address pair (::ffff:10.0.12.67, ::ffff:172.217.7.132) is preferred over (fd85:741f:6df1:212:50df:dc26:f469:4d4c, 2607:f8b0:4004:800::2004) by SortOptions: 0, Reason: Prefer Matching Label (Rule D 5.0).
其中关键的是
Reason: Prefer Matching Label
这在RFC 3484第 5 节“源地址选择”。基本上,前缀可以有“标签”,并且源和目标标签匹配的源/目标地址对优先于源和目标标签不匹配的对。
我可以通过运行以下命令在计算机上查看前缀/标签映射
netsh interface ipv6 show prefixpolicies
我明白了
Precedence Label Prefix
---------- ----- --------------------------------
50 0 ::1/128
40 1 ::/0
35 4 ::ffff:0:0/96
30 2 2002::/16
5 5 2001::/32
3 13 fc00::/7
1 12 3ffe::/16
1 11 fec0::/10
1 3 ::/96
由于我的源 IPv6 地址 fd85:741f:6df1:212:50df:dc26:f469:4d4c 是 ULA 地址(我使用 NPt 允许两个不同的 WAN 连接之间进行故障转移),它属于 fc00::/7 并获得标签 13。我的目标地址在 ::/0 内并获得标签 1。它们不匹配,因此更喜欢 IPv4,它们都属于 ::ffff:0:0/96 并获得标签 4。
为了解决这个问题,我只需要添加一个前缀策略,将我的源地址的标签设置为 1。我可以通过在管理命令提示符中运行以下命令来执行此操作:
netsh interface ipv6 add prefixpolicy fd00::/8 3 1
这为 fd00::/8(整个 ULA 前缀)添加了一个策略,其优先级为 3,标签为 1。以下是更新后的前缀策略表:
Precedence Label Prefix
---------- ----- --------------------------------
50 0 ::1/128
40 1 ::/0
35 4 ::ffff:0:0/96
30 2 2002::/16
5 5 2001::/32
3 13 fc00::/7
3 1 fd00::/8
1 12 3ffe::/16
1 11 fec0::/10
1 3 ::/96
现在,当我 ping 双栈主机名时,它更喜欢 IPv6 地址。