Traceroute程序的操作


以前我们描述了I P记录路由选项(R R) 。为什么不使用这个选项而另外开发一个新的应用程序?有三个方面的原因 。首先 , 原先并不是所有的路由器都支持记录路由选项 , 因此该选项在某些路径上不能使用(Tr a c e r o u t e 程序不需要中间路由器具备任何非凡的或可选的功能) 。
其次 , 记录路由一般是单向的选项 。发送端设置了该选项 , 那么接收端不得不从收到的I P 首部中提取出所有的信息 , 然后全部返回给发送端 。在7 . 3节中 , 我们看到大多数P i n g服务器的实现(内核中的I C M P回显应答功能)把接收到的R R清单返回 , 但是这样使得记录下来的I P地址翻了一番(一来一回) 。这样做会受到一些限制 , 这一点我们在下一段讨论(Tr a c e r o u t e 程序只需要目的端运行一个U D P模块—其他不需要任何非凡的服务器应用程序) 。
最后一个原因也是最主要的原因是 , I P首部中留给选项的空间有限 , 不能存放当前大多数的路径 。在I P首部选项字段中最多只能存放9个I P地址 。在原先的A R PA N E T中这是足够的 , 但是对现在来说是远远不够的 。
Tr a c e r o u t e 程序使用I C M P报文和I P首部中的T T L字段(生存周期) 。T T L字段是由发送端初始设置一个8 bit 字段 。推荐的初始值由分配数字R F C指定 , 当前值为6 4 。较老版本的系统经常初始化为1 5或3 2 。我们从第7章中的一些p i n g程序例子中可以看出 , 发送I C M P回显应答时经常把T T L设为最大值2 5 5 。
每个处理数据报的路由器都需要把T T L的值减1或减去数据报在路由器中停留的秒数 。由于大多数的路由器转发数据报的时延都小于1秒钟 , 因此T T L最终成为一个跳站的计数器 , 所经过的每个路由器都将其值减1 。
RFC1009 [Braden and Postel 1987]指出 , 假如路由器转发数据报的时延超过1秒 , 那么它将把T T L值减去所消耗的时间(秒数) 。但很少有路由器这么实现 。新的路由器需求文档RFC[Almquist 1993]为此指定它为可选择功能 , 答应把T T L看成一个跳站计数器 。
T T L字段的目的是防止数据报在选路时无休止地在网络中流动 。例如 , 当路由器瘫痪或者两台路由器之间的连接丢失时 , 选路协议有时会去检测丢失的路由并一直进行下去 。在这段时间内 , 数据报可能在循环回路被终止 。T T L字段就是在这些循环传递的数据报上加上一个生存上限 。
当路由器收到一份I P数据报 , 假如其T T L字段是0或1 , 则路由器不转发该数据报(接收到这种数据报的目的主机可以将它交给应用程序 , 这是因为不需要转发该数据报 。但是在通常情况下 , 系统不应该接收T T L字段为0的数据报) 。相反 , 路由器将该数据报丢弃 , 并给信源机发一份I C M P“超时”信息 。Tr a c e r o u t e 程序的要害在于包含这份I C M P信息的I P报文的信源地址是该路由器的I P地址 。
我们现在可以猜想一下Tr a c e r o u t e 程序的操作过程 。它发送一份T T L字段为1的I P数据报给目的主机 。处理这份数据报的第一个路由器将T T L值减1 , 丢弃该数据报 , 并发回一份超时I C M P报文 。这样就得到了该路径中的第一个路由器的地址 。然后Tr a c e r o u t e 程序发送一份T T L值为2的数据报 , 这样我们就可以得到第二个路由器的地址 。继续这个过程直至该数据报到达目的主机 。但是目的主机哪怕接收到T T L值为1的I P数据报 , 也不会丢弃该数据报并产生一份超时I C M P报文 , 这是因为数据报已经到达其最终目的地 。那么我们该如何判定是否已经到达目的主机了呢?
Tr a c e r o u t e 程序发送一份U D P数据报给目的主机 , 但它选择一个不可能的值作为U D P端口号(大于30 000) , 使目的主机的任何一个应用程序都不可能使用该端口 。因为 , 当该数据报到达时 , 将使目的主机的U D P模块产生一份“端口不可达”错误(见6 . 5节)的I C M P报文 。这样 , Tr a c e r o u t e 程序所要做的就是区分接收到的I C M P报文是超时还是端口不可达 , 以判定什么时候结束 。

推荐阅读