getaddrinfo 在 Linux 上不返回 IPv6,但在 Macbook 上会返回

getaddrinfo 在 Linux 上不返回 IPv6,但在 Macbook 上会返回

我有一个简单的设置。我添加1.2.3.4 yahoo.com到我的 /etc/hosts 文件中。

我没有将 google.com 的任何条目添加到 /etc/hosts 文件中。

在 Macbook 上,我得到 1.2.3.4 和 yahoo.com 的原始 IPv6 地址作为响应。

这是演示:

x@macbook:~ $ getent hosts yahoo.com
1.2.3.4 yahoo.com
x@macbook:~ $ cat /etc/hosts | grep yahoo.com
1.2.3.4 yahoo.com
x@macbook:~ $ python test.py
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('142.251.36.14', 443)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2a00:1450:400e:801::200e', 443, 0, 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('1.2.3.4', 443)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:24:120d::1:0', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:124:1507::f000', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:24:120d::1:1', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:44:3507::8001', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:44:3507::8000', 443, 0, 0)), (<AddressFamily.AF_INET6: 30>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2001:4998:124:1507::f001', 443, 0, 0))]
x@macbook:~ $ cat test.py
import socket
print(socket.getaddrinfo("google.com", 443, 0, socket.SOCK_STREAM))
print(socket.getaddrinfo("yahoo.com", 443, 0, socket.SOCK_STREAM))

Linux 上的类似设置:

root@linux:~# getent hosts yahoo.com
1.2.3.4         yahoo.com
root@linux:~# getent ahosts yahoo.com
1.2.3.4         STREAM yahoo.com
1.2.3.4         DGRAM
1.2.3.4         RAW
root@linux:~# cat /etc/hosts |grep yahoo.com
1.2.3.4 yahoo.com
root@linux:~# python test.py
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('142.251.39.110', 443)), (<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('2a00:1450:400e:810::200e', 443, 0, 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('1.2.3.4', 443))]
root@linux:~# cat test.py
import socket
print(socket.getaddrinfo("google.com", 443, 0, socket.SOCK_STREAM))
print(socket.getaddrinfo("yahoo.com", 443, 0, socket.SOCK_STREAM))

在 Linux 上,我可以从 DNS 获取 google.com 的 IPv4 和 IPv6。但是,我无法从 DNS 获取 yahoo.com 的 IPv6 地址。它在 Macbook 上正常工作。有人知道为什么输出不一致吗?

答案1

我对 MacOS 的行为感到有点惊讶,因为 Linux 的行为似乎更直观一些。

Linux 本身不处理 DNS,这实际上是用户空间库,例如 glibc(我注意到您在问题中标记了这一点)。 Linux 上 glibc 下的 DNS 解析由以下命令控制NS开关 (Alpine Linux 和类似的 musl C 不使用 nsswitch,所以你可能会得到不同的结果)

MacOS不使用nsswitch,至少它没有/etc/nsswitch.conf。好像有它自己的系统

在 Linux 下使用 glibc 发生的情况是,通过/etc/nsswitch.conf咨询来确定如何查找主机yahoo.com


在大多数情况下,默认值nsswitch.conf类似于:

hosts:          files mdns_minimal [NOTFOUND=return] dns

这意味着名称解析将按顺序尝试:

  • /etc/主机
  • MDNS(本地网络上的多播 DNS)
  • 域名系统

当找到结果时它就会停止。因此,通过yahoo.com在 中添加 IPv4 地址/etc/hosts,glib C 将停在那里并且永远不会发出 DNS 请求。

相关内容