因为 ICMP 现在应该很普及了,所以觉得很奇怪为什么预设要用 UDP 不用 ICMP,查了一下才发现 RFC792 曾经有规定不准机器在收到 ICMP 后回 ICMP,原文如下:

RFC792 Introduction

看原文的意思,可能是希望看到 ICMP 封包中的 Type 或 Code 字段,就知道这个 ICMP 在表达什么,而不希望有巢状的结构,要一层一层打开来才能看到。

Van Jacobson 在 1987 年开发了 traceroute 这个程式,但是受限于 RFC792 的规定,在当时大部分 router 的实作中都不会在收到 ICMP Echo Request TTL=0 的时候回送一个 ICMP Time Exceeded,导致这个程式很少能够正常运作。

调整成不准机器收到 ICMP Error 后回 ICMP Error,后来 ICMP 版本的 traceroute 才能比较正常的运作,但 traceroute 预设的 UDP 模式也就这样保留到现在了。(Windows 的 tracert 预设是送 ICMP)

在查资料的过程,也有查到有人说 traceroute 如果要送 ICMP 就需要使用到 raw_socket,就需要 root privilege,因为这个原因才把 UDP 当作预设的模式使用。

虽然这个方向我感觉不是 traceroute 预设走 UDP 模式的主要原因,但也因此发现了一些有趣的事阿。