![结论](https://linux22.com/image/1510969/%E7%BB%93%E8%AE%BA.png)
我知道网络使用多条路径;它们显示在 traceroute 中,但不显示在 mtr 中。mtr 是否以某种方式坚持使用第一条路径?这是怎么回事?
$ traceroute google.com
traceroute to google.com (216.58.210.46), 30 hops max, 60 byte packets
1 gateway (172.16.9.1) 1.303 ms 1.332 ms 1.421 ms
2 host-92-31-0-1.as13285.net (92.31.0.1) 14.965 ms 15.810 ms 16.978 ms
3 xe-11-2-0-bragg001.bre.as13285.net (78.151.225.39) 19.456 ms 20.785 ms 23.052 ms
4 host-78-151-225-14.static.as13285.net (78.151.225.14) 24.255 ms host-78-151-229-20.as13285.net (78.151.229.20) 25.979 ms host-78-151-225-18.static.as13285.net (78.151.225.18) 27.059 ms
5 host-78-144-8-57.as13285.net (78.144.8.57) 33.513 ms host-78-144-12-213.as13285.net (78.144.12.213) 35.825 ms host-78-144-10-37.as13285.net (78.144.10.37) 35.374 ms
6 72.14.214.222 (72.14.214.222) 38.005 ms 72.14.242.127 (72.14.242.127) 35.820 ms 72.14.214.222 (72.14.214.222) 34.968 ms
7 216.239.54.251 (216.239.54.251) 37.260 ms 64.233.174.83 (64.233.174.83) 22.876 ms 216.239.54.251 (216.239.54.251) 25.085 ms
8 108.170.232.105 (108.170.232.105) 25.606 ms 108.170.232.103 (108.170.232.103) 27.050 ms 28.886 ms
9 lhr25s11-in-f46.1e100.net (216.58.210.46) 29.601 ms 30.552 ms 31.896 ms
$ mtr --report google.com
Start: Wed Oct 26 11:07:33 2016
HOST: localhost.localdomain Loss% Snt Last Avg Best Wrst StDev
1.|-- gateway 0.0% 10 1.2 1.6 1.1 2.7 0.5
2.|-- host-92-31-0-1.as13285.ne 0.0% 10 16.8 15.3 14.0 18.3 1.2
3.|-- xe-11-2-0-bragg001.bre.as 0.0% 10 19.2 16.5 14.9 19.2 1.1
4.|-- host-78-151-225-30.static 0.0% 10 16.3 16.2 15.7 16.6 0.0
5.|-- host-78-144-12-147.as1328 0.0% 10 23.1 23.1 22.3 25.2 0.7
6.|-- 72.14.242.127 0.0% 10 23.3 23.9 23.0 26.1 1.0
7.|-- 216.239.54.251 0.0% 10 22.5 22.8 21.9 25.3 0.8
8.|-- 108.170.232.105 0.0% 10 22.1 22.5 22.0 23.2 0.0
9.|-- lhr25s11-in-f46.1e100.net 0.0% 10 23.3 23.4 22.7 24.3 0.0
答案1
实际上,现代 Linux 中的 traceroute 具有与 mtr 行为相匹配的选项(反之亦然)。我们可以看到这只是一个默认问题。
traceroute
是原始的。原始方法的细节可以从文档,但没有必要将其说清楚。由于 Linux traceroute 添加了多个选项,因此描述了差异。
默认
传统的、古老的路由跟踪方法。默认使用。
探测数据包是具有所谓“不可能”目标端口的 UDP 数据报。第一个探测的“不可能”端口是 33434,然后对于每次探测,它都会增加一。
icmp
目前最常用的方法是使用 icmp echo 数据包进行探测。如果您可以 ping(8) 目标主机,则 icmp tracerouting 也适用。
mtr
的默认值似乎是 icmp,“目前最常用的方法”。
结论
多路径路由应使来自同一连接的数据包保持在同一路径上。这样可以避免乱序交付,而乱序交付可能是非常不希望出现的。它通过查看源和目标的地址和端口来实现这一点。(连同协议。这些值被描述为“5 元组”)。
traceroute
的默认值会为每个探测更改 UDP 端口,因此它们会改变路径。
mtr
默认使用 ICMP 回显,它没有端口号,因此它的探测将全部遵循相同的路径。
如果您在 中请求 UDP 或 TCP 跟踪路由,mtr
则会显示不同的路径。与 相比,可能存在其他差异traceroute
,但在这方面它的行为恰好相似。
题外话:为什么不使用 icmp?
因此,Linuxtraceroute
刻意忠实于原版,包括其默认模式的选择。但最初选择的原因尚不完全清楚。
我记得读过man tracepath
:
商业 [IPv4] 路由器在 icmp 错误消息中返回的信息不够多。当它们更新时,这种情况可能会改变。目前 [tracepath] 使用 Van Jacobson 的技巧,扫描一系列 UDP 端口以维护跟踪历史记录。
但重点是tracepath
使用较新的设施来避免需要 root 权限。提到的问题是 ICMP 错误回复不会包含任何有效载荷UDP数据包。ICMP 回显数据包的有效负载会被包括在内(但生成这样的探测需要root)。
Traceroute 会改变(增加)每个发出的探测的 UDP 目标端口号,以便可靠地将 ICMP TTL 超出消息与各个探测相匹配。由于 UDP 端口紧跟在 IP 标头之后,因此可以依赖它们包含在 ICMP TTL 超出消息的“原始数据包”部分中,即使 ICMP 标准仅要求原始数据包 IP 标头后面的前八个八位字节包含在 ICMP 消息中(但允许发送更多)。
当使用 ICMP ECHO 请求时,可以使用序列号字段来消除探测歧义,该字段恰好位于 8 八位字节边界之前。
计划评审技术 (PERT)继续建议
据信这是因为当时有些网关(当时称为路由器)拒绝发送 ICMP(TTL 超出)消息来响应 ICMP 消息,如 RFC 792“Internet 控制消息协议”的介绍中所述。因此 UDP 变体更加健壮。
这源代码注释解释 UDP 端口的使用,但不要解释 UDP over ICMP echo 的使用。严格解读表明还有另一种可能性
因为 icmp 不是为 icmp 发送的
在上下文中,关键是 icmp 错误永远不会作为对 icmp 的响应而发送回复,以避免无限循环响应。实现将此应用于所有 icmp 数据包(而不仅仅是响应)当然是合理的。评论还提到了各种实现错误,用户必须牢记这些错误才能解释 traceroute 结果。
然而,Van Jacobson 自己也有可能混淆了这一点。人们可能只是假定任何 icmp 数据包都不会返回 icmp 错误,忽略了这并不一定适用于 icmp echo 请求。
不要用这个作为编码示例。我试图找到一个路由问题,这段代码在 48 小时不睡觉后突然出现。我很惊讶它竟然能编译,更不用说运行了。