在对家里的互联网偶尔出现的网络“停顿”进行故障排除时,我遇到了这个问题戴尔的技术提示。他们建议使用ping -n
以避免 DNS 解析导致的停顿。这让我开始思考,交换机-n
实际上做了什么?在我看来,如果您 ping DNS 名称,则需要 DNS 解析,但如果您 ping IP,则不需要。
从手册页中:
-n 仅数字输出。不会尝试查找主机地址的符号名称。
如果我 ping 一个 IP 地址,那么ping 8.8.8.8
这里如何进行 DNS 查找?ping -n 8.8.8.8
会有什么不同吗?
答案1
如果我 ping 一个 IP 地址,那么
ping 8.8.8.8
这里如何进行 DNS 查找?ping -n 8.8.8.8
会有什么不同吗?
这可能取决于实现。如果其输出中ping
不-n
包含任何内容,则可能不存在,这就是区别。但有可能两个输出都不包含字符串。dns.google
ping -n
在我的 Ubuntu 18.04.4 LTS 中man 8 ping
显示:
ping
是软件包的一部分iputils
,最新版本的源代码可在 处获得http://www.skbuff.net/iputils/iputils-current.tar.bz2
。
这个确切的地址似乎仍然不起作用http://www.skbuff.net/iputils提供其他链接,包括SourceForge 的一个。我已经下载了iputils-s20151218并阅读代码。
-n
处理方式ping_common.c
:
case 'n':
options |= F_NUMERIC;
break;
那么选项(options & F_NUMERIC
)在以下情况下很重要ping.c
:
pr_addr(__u32 addr)
{
…
if (exiting || (options & F_NUMERIC) ||
!(hp = gethostbyaddr((char *)&addr, 4, AF_INET)))
sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&addr));
else {
…
为了得到gethostbyaddr
,exiting
和都options & F_NUMERIC
必须为假(因为a || b
does 不会评估b
是否a
为真)。后者取决于是否-n
被使用。
gethostbyaddr
是“尝试查找主机地址的符号名称”。请参阅。这是提供 IP 地址时使用的man 3 gethostbyaddr
同一个库调用(请参阅)。getent hosts
man 1 getent
看到不同:
$ getent hosts 8.8.8.8
8.8.8.8 dns.google
$ ping -c 1 dns.google
…
64 bytes from dns.google (8.8.8.8): icmp_seq=1 ttl=120 time=10.6 ms
…
$ ping -n -c 1 dns.google
…
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=11.3 ms
…
$
看起来似乎ping
没有-n
仅仅使用用户提供的字符串;但事实并非如此:
$ getent hosts poczta.wp.pl
193.17.41.99 poczta.wp.pl
$ getent hosts 193.17.41.99
193.17.41.99 poczta.o2.pl
$ ping -c 1 poczta.wp.pl
…
64 bytes from poczta.o2.pl (193.17.41.99): icmp_seq=1 ttl=60 time=9.71 ms
…
$
这里poczta.wp.pl
被解析为193.17.41.99
,然后193.17.41.99
被解析为poczta.o2.pl
(注意o2
而不是wp
)。使用-n
会取消后面的步骤。
对于某些地址,会发生这种情况:
$ getent hosts superuser.com
151.101.1.69 superuser.com
151.101.193.69 superuser.com
151.101.65.69 superuser.com
151.101.129.69 superuser.com
$ getent hosts 151.101.1.69 151.101.193.69 151.101.65.69 151.101.129.69
$ # the output was empty
$ ping -c 1 superuser.com
…
64 bytes from 151.101.1.69 (151.101.1.69): icmp_seq=1 ttl=58 time=37.1 ms
…
$ ping -n -c 1 superuser.com
…
64 bytes from 151.101.1.69: icmp_seq=1 ttl=58 time=36.8 ms
…
$
但如果我提供一个数字地址,那么就不会有区别:
$ getent hosts 8.8.8.8
8.8.8.8 dns.google
$ ping -c 1 8.8.8.8
…
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=10.8 ms
…
$ ping -n -c 1 8.8.8.8
…
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=8.91 ms
…
$
这是因为来自这个片段ping.c
:
if (inet_aton(target, &whereto.sin_addr) == 1) {
hostname = target;
if (argc == 1)
options |= F_NUMERIC;
} else
inet_aton
将 IPv4 数字和点表示法转换为二进制形式。成功时返回1
。如果最后一个参数ping
可以转换,则该片段评估options |= F_NUMERIC
就像-n
被使用过一样。
我实际上ping
从源代码编译了两个版本:原始版本和if … options |= F_NUMERIC;
注释掉的版本。修改后的版本的行为如下:
$ ./ping -c 1 8.8.8.8
…
64 bytes from dns.google (8.8.8.8): icmp_seq=1 ttl=120 time=9.67 ms
…
$ ./ping -n -c 1 8.8.8.8
…
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=8.69 ms
…
$
现在我可以明确地回答这个问题:
做
ping -n 8.8.8.8
了一些不同的事情吗ping 8.8.8.8
?
不。IPv4 数字和点表示法中的地址使ping
(iputils
在 Linux 上)工作得像-n
被使用过一样。
如果我 ping 一个 IP 地址,
ping 8.8.8.8
这里如何进行 DNS 查找?
我创建了一个单独的网络命名空间(以确保尽可能少的流量干扰),其中包含一个 veth 对,然后wireshark
在那里使用。(如果你想复制我的结果并需要有关该过程的帮助,请参阅这个答案,示例2)。
原文如下ping
:
ping -n -c 1 8.8.8.8
生成ICMP echo request
并接收ICMP echo reply
。不涉及 DNS。ping -c 1 8.8.8.8
做同样的事情(这并不奇怪,上面已经解释过了)。
这意味着没有 DNS 查找下面是一些用于比较的测试。
经过我的修改ping
:
ping -n -c 1 8.8.8.8
表现和原版一样。ping -c 1 8.8.8.8
ICMP 后查询 DNS 服务器,并收到响应。这样就得到了dns.google
。
再次回到原文ping
:
ping -n -c 1 dns.google
查询 DNS 服务器并在 ICMP 之前收到响应。这将转换dns.google
为8.8.8.8
或8.8.4.4
。ping -c 1 dns.google
在 ICMP 之前查询 DNS 服务器并接收响应(转换为8.8.8.8
或 转换为8.8.4.4
)以及在 ICMP 之后分别接收响应(转换回来)。
答案2
从手册页中:
-n 仅输出数字。不会尝试查找主机地址的符号名称
所以区别在于输出:
>ping whitehouse.gov
PING whitehouse.gov(g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add)) 56 data bytes
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=1 ttl=52 time=7.38 ms
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=2 ttl=52 time=6.91 ms
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=3 ttl=52 time=21.6 ms
64 bytes from g2a02-26f0-0082-02b2-0000-0000-0000-2add.deploy.static.akamaitechnologies.com (2a02:26f0:82:2b2::2add): icmp_seq=4 ttl=52 time=7.60 ms
>ping -n whitehouse.gov
PING whitehouse.gov(2a02:26f0:82:280::2add) 56 data bytes
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=1 ttl=52 time=10.0 ms
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=2 ttl=52 time=5.63 ms
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=3 ttl=52 time=10.4 ms
64 bytes from 2a02:26f0:82:280::2add: icmp_seq=4 ttl=52 time=12.5 ms