OS-X localhost 解析异常

OS-X localhost 解析异常

我将要描述的问题只有在运行一些 Java 单元测试时才会出现。不过,我非常确定问题的根源在于 OS-X 配置,而不是 Java,因此我向超级用户发帖,而不是 StackOverflow。

我们有一个 Java 单元测试,它启动一个嵌入式服务器,然后向 发出请求http://localhost:9324。在我升级到 Yosemite 之前,这些测试曾经通过,但现在却失败了。具体症状和我尝试过的方法:

解析为 AWDL 接口

我查看了 netstat 以查看是什么访问了端口 9324。发现了以下内容:

localhost:platform oliver$ netstat -tn | grep 9324
tcp6       0      0  fe80::b8d2:8eff:.50602 fe80::b8d2:8eff:.9324  SYN_SENT   

因此,由于某种原因,localhost 解析为 IPV6 地址并ifconfig显示它是 的地址awdl0。谷歌搜索显示这是 Apple 用于点对点共享的接口。请注意nslookup localhostdig localhostdscacheutil -q host -a name localhost均按预期返回127.0.0.1。那么,Java 代码以某种方式以不同的方式执行名称解析还是其他原因(所以是的,也许这是一个 Java 问题)???

解析外部地址

通过关闭 AWDL 接口sudo ifconfig awdl0 down可使代码停止挂起,并且 netstat 报告基本正确的信息:

tcp4       0      0  192.168.0.124.52137    192.168.0.124.9324     SYN_SENT   
tcp4       0      0  127.0.0.1.9324         127.0.0.1.52135        ESTABLISHED
tcp4       0      0  127.0.0.1.52135        127.0.0.1.9324         ESTABLISHED

但请注意,由于某种原因,使用localhost地址的本地代码正在命中192.168.0.124,我的外部的IP 地址,代码卡住了SYN_SENT,挂起,永远得不到响应。请注意,这不是防火墙设置造成的,因为我在这次测试中完全禁用了防火墙。

连接被拒绝

尽管外部地址的使用有些奇怪,但看起来使用环回的连接似乎是正确的,但它们会收到ConnectionRefusedJava 的错误。但是,curl http://localhost:9324连接成功并收到响应。

问题

我非常困惑。这可能是 Java 的问题,但我怀疑我的 OS-X 网络设置不知为何出了问题。

哦,这是我的 /etc/resolv.conf:

#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#
nameserver 10.1.10.1
nameserver 2001:558:feed::1
nameserver 2001:558:feed::2

我的 /private/etc/resolv.conf 是相同的。

/etc/hosts 是:

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1   localhost
255.255.255.255 broadcasthost
::1             localhost 
fe80::1%lo0     localhost

下面是输出ifconfig -a

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    options=3<RXCSUM,TXCSUM>
    inet6 ::1 prefixlen 128 
    inet 127.0.0.1 netmask 0xff000000 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
    nd6 options=1<PERFORMNUD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether 3c:15:c2:da:29:0c 
    nd6 options=1<PERFORMNUD>
    media: autoselect (<unknown type>)
    status: inactive
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=60<TSO4,TSO6>
    ether 72:00:04:0f:34:70 
    media: autoselect <full-duplex>
    status: inactive
en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=60<TSO4,TSO6>
    ether 72:00:04:0f:34:71 
    media: autoselect <full-duplex>
    status: inactive
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
    ether 0e:15:c2:da:29:0c 
    media: autoselect
    status: inactive
awdl0: flags=8902<BROADCAST,PROMISC,SIMPLEX,MULTICAST> mtu 1452
    ether ba:d2:8e:05:03:6c 
    nd6 options=1<PERFORMNUD>
    media: autoselect
    status: inactive
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=63<RXCSUM,TXCSUM,TSO4,TSO6>
    ether 3e:15:c2:ad:9e:00 
    Configuration:
        id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
        maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
        root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
        ipfilter disabled flags 0x2
    member: en1 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 5 priority 0 path cost 0
    member: en2 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 6 priority 0 path cost 0
    nd6 options=1<PERFORMNUD>
    media: <unknown type>
    status: inactive
en5: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=23<RXCSUM,TXCSUM,TSO4>
    ether 00:24:9b:0f:3c:02 
    inet6 fe80::224:9bff:fe0f:3c02%en5 prefixlen 64 scopeid 0xc 
    inet 192.168.0.50 netmask 0xffffff00 broadcast 192.168.0.255
    inet6 2601:1c0:c901:980e:224:9bff:fe0f:3c02 prefixlen 64 autoconf 
    inet6 2601:1c0:c901:980e:4041:88e9:46e8:a893 prefixlen 64 autoconf temporary 
    nd6 options=1<PERFORMNUD>
    media: autoselect (1000baseT <full-duplex,flow-control,energy-efficient-ethernet>)
    status: active

答案1

欢迎来到后 IPv4 世界。当您使用 nslookup 或 dig 等实用程序时,默认返回“A”记录。但是,对于支持 IPv6 的现代操作系统和应用程序,它们通常会先检查“AAAA”记录,以查看资源是否可通过 IPv6 获得,然后再求助于 IPv4 资源。

因此,现在的情况是,您同时拥有 IPv4 条目和 IPv6 条目本地主机在您的系统上,它几乎总是会首选 IPv6。

那么,你能做什么呢?嗯,你有几个选择。你可以删除 IPv6 条目本地主机或者完全禁用 IPv6,但这并不是一个理想的解决方案,并且实际上是“向后看”而不是向前迈进。

相反,您可能应该确保您的服务配置为除了 IPv4 之外,还能够在 IPv6 上运行。您可能还需要对 IPv6 防火墙规则进行一些调整以允许该服务。这可以让您为 IPv6 取代 IPv4 成为主流协议的未来做好准备。

答案2

尝试重置discoveryd或刷新其缓存,或者恢复到 mDNSResponder(Yosemite 之前的 DNS 解析器)。

清除缓存的方法如下discoveryd

sudo discoveryutil mdnsflushcache

恢复到 mDNSResponder 的描述如下:

Ars Technica OS X 发现恢复

相关内容