8.5IP源站选路选项通常IP路由是动态的,即每个路由器都要判断数据报下面该转发到哪个路由器。应用程序对此不进行控制,而且通常也并不关心路由。它采用类似Traceroute程序的工具来发现实际的路由。源站选路(sourcerouting)的思想是由发送者指定路由。它可以采用以下两种形式:•严格的源路由选择。发送端指明IP数据报所必须采用的确切路由。如果一个路由器发现源路由所指定的下一个路由器不在其直接连接的网络上,那么它就返回一个“源站路由失败”的ICMP差错报文。•宽松的源站选路。发送端指明了一个数据报经过的IP地址清单,但是数据报在清单上指明的任意两个地址之间可以通过其他路由器。Traceroute程序提供了一个查看源站选路的方法,我们可以在选项中指明源站路由,然后检查其运行情况。一些公开的Traceroute程序源代码包中包含指明宽松的源站选路的补丁。但是在标准版中通常并不包含此项。这些补丁的解释是“VanJacobson的原始Traceroute程序(1988年春)支持该特性,但后来因为有人提出会使网关崩溃而将此功能去除。”对于本章中所给出的例子,作者将这些补丁安装上去,并将它们设置成允许宽松的源站选路和严格的源站选路。图8-6给出了源站路由选项的格式。图8-6IP首部源站路由选项的通用格式这个格式与我们在图7-3中所示的记录路由选项格式基本一致。不同之处是,对于源站选路,我们必须在发送IP数据报前填充IP地址清单;而对于记录路由选项,我们需要为IP地址清单分配并清空一些空间,并让路由器填充该清单中的各项。同时,对于源站选路,只要为所需要的IP地址数分配空间并进行初始化,通常其数量小于9。而对于记录路由选项来说,必须尽可能地分配空间,以达到9个地址。对于宽松的源站选路来说,code字段的值是0x83;而对于严格的源站选路,其值为0x89。len和ptr字段与7.3节中所描述的一样。源站路由选项的实际称呼为“源站及记录路由”(对于宽松的源站选路和严格的源站选路,分别用LSRR和SSRR表示),这是因为在数据报沿路由发送过程中,对IP地址清单进行了更新。下面是其运行过程:•发送主机从应用程序接收源站路由清单,将第1个表项去掉(它是数据报的最终目的地址),将剩余的项移到1个项中(如图8-6所示),并将原来的目的地址作为清单的最后一项。指针仍然指向清单的第1项(即,指针的值为4)。•每个处理数据报的路由器检查其是否为数据报的最终地址。如果不是,则正常转发数据报(在这种情况下,必须指明宽松源站选路,否则就不能接收到该数据报)。•如果该路由器是最终目的,且指针不大于路径的长度,那么(1)由ptr所指定的清单中的下一个地址就是数据报的最终目的地址;(2)由外出接口(outgoinginterface)相对应的IP地址取代刚才使用的源地址;(3)指针加4。可以用下面这个例子很好地解释上述过程。在图8-7中,我们假设主机S上的发送应用程序发送一份数据报给D,指定源路由为R1,R2和R3。图8-7IP源路由示例在上图中,#表示指针字段,其值分别是4、8、12和16。长度字段恒为15(三个IP地址加上三个字节首部)。可以看出,每一跳IP数据报中的目的地址都发生改变。当一个应用程序接收到由信源指定路由的数据时,在发送应答时,应该读出接收到的路由值,并提供反向路由。HostRequirementsRFC指明,TCP客户必须能指明源站选路,同时,TCP服务器必须能够接收源站选路,并且对于该TCP连接的所有报文段都能采用反向路由。如果TCP服务器下面接收到一个不同的源站选路,那么新的源站路由将取代旧的源站路由。39字节4字节4字节4字节4字节8.5.1宽松的源站选路的traceroute程序示例使用traceroute程序的-g选项,可以为宽松的源站选路指明一些中间路由器。采用该选项可以最多指定8个中间路由器(其个数是8而不是9的原因是,所使用的编程接口要求最后的表目是目的主机)。在图8-4中,去往NIC,即nic.ddn.mil的路由经过NASAScienceInternet。在图8-8中,我们通过指定路由器enss142.UT.westnet.net(192.31.39.21)作为中间路由器来强制数据报通过NSFNET:图8-8采用宽松源站选路通过NSFNET到达nic.ddn.mil的traceroute程序在这种情况下,看起来路径中共有16跳,其平均RTT大约是350ms。而图8-4的通常选路则只有13跳,其平均RTT约为322ms。默认路径看起来更好一些(在建立路径时,还需要考虑其他的一些因素。其中一些必须考虑的因素是所包含网络的组织及政治因素)。前面我们说看起来有16跳,这是因为将其输出结果与前面的通过NSFNET(图8-5)的示例比较,发现在本例采用宽松源路由,选择了3个路由器(这可能是因为路由器对源站选路数据报产生ICMP超时差错报文上存在一些差错)。在netb和butch路由器之间的gateway.tuc.noao.edu路由器丢失了,同时,位于Gabby和enss142.UT.west.net之间的Westgate.Telcom.Arizona.edu和uu-ua.AZ.westnet.net两个路由器也丢失了。在这些丢失的路由器上可能发生了与接收到宽松的源站选路选项数据报有关的程序问题。实际上,当采用NSFNET时,信源和NIC之间的路径有19跳。本章习题8.5继续对这些丢失路由器进行讨论。同时本例也指出了另一个问题。在命令行,我们必须指定路由器enss142.UT.westnet.net的点分十进制IP地址,而不能以其域名代替。这是因为,反向域名解析(14.5节中描述的通过IP地址返回域名)将域名与IP地址相关联,但是前向解析(即给出域名返回IP地址)则无法做到。在DNS中,前向映射和反向映射是两个独立的文件,而并非所有的管理者都同时拥有这两个文件。因此,在一个方向是工作正常而另一个方向却失败的情况并不少见。还有一种以前没有碰到过的情况是在TTL字段为8的情况下,对于第一个RTT,打印一个星号。这表明,发生超时,在5秒内未收到本次探查的应答信号。将本图与图8-4相比较,还可以得出一个结论,即路由器nsn-FIX-pe.sura.net同时与NSFNET和NASAScienceInternet相连。8.5.2严格的源站选路的traceroute程序示例在作者的traceroute程序版本中,-G选项与前面所描述的-g选项是完全一样的,不过此时是严格的源站选路而不是宽松的源站选路。我们可以采用这个选项来观察在指明无效的严格的源站选路时其结果会是什么样的。从图8-5可以看出来,从作者的子网发往NSFNET的数据报的正常路由器顺序是netb,gateway,butch和gabby(为了便于查看,后面所有的输出结果中,均省略了域名后缀.tuc.noao.edu和.telcom.arizona.edu)。我们指定了一个严格源路由,使其试图将数据报从gateway直接发送到gabby,而省略了butch。我们可以猜测到其结果会是失败的,正如图8-9所给出的结果。图8-9采用严格源站路由失败的traceroute程序这里的关键是在于TTL字段为3的输出行中,RTT后面的!S。这表明traceroute程序接收到ICMP“源站路由失败”的差错报文:即图6-3中type字段为3,而code字段为5。TTL字段为3的第二个RTT位置的星号表示未收到这次探查的应答信号。这与我们所猜想的一样,gateway不可能直接发送数据报给gabby,这是因为它们之间没有直接的连接。TTL字段为2和3的结果都来自于gateway,对于TTL字段为2的应答来自gateway,是因为gateway接收到TTL字段为1的数据报。在它查看到(无效的)严格的源站选路之前,就发现TTL已过期,因此发送回ICMP超时报文。TTL字段等于3的行,在进入gateway时其TTL字段为2,因此,它查看严格的源站选路,发现它是无效的,因此发送回ICMP源站选路失败的差错报文。图8-10给出了与本例相对应的tcpdump输出结果。该输出结果是在sun和netb之间的SLIP链路上遇到的。我们必须在tcpdump中指定-v选项以显示出源站路由信息。这样,会输出一些像数据报ID这样我们并不需要的结果,我们在给出结果中将这些不需要的结果删除掉。同样,用SSRR表示“严格的源站及记录路由”。首先注意到,sun所发送的每个UDP数据报的目的地址都是netb,而不是目的主机(westgate)。这一点可以用图8-7的例子来解释。类似地,-G选项所指定的另外两个路由器(gateway和gabby)以及最终目(westgate)成为第一跳的SSRR选项。从这个输出结果中,还可以看出,traceroute程序所采用的定时时间(第15行和16行之间的时间差)是5秒。图8-10失败的严格源站选路traceroute程序的tcpdump输出结果8.5.3宽松的源站选路traceroute程序的往返路由我们在前面已经说过,从A到B的路径并不一定与从B到A的路径完全一样。除非同时在两个系统中登录并在每个终端上运行traceroute程序,否则很难发现两条路径是否不同。但是,采用宽松的源站选路,就可以决定两个方向上的路径。这里的窍门就在于指定一个宽松的源站路由,该路由的目的端和宽松路径一样,但发送端为目的主机。例如,在sun主机上,我们可以查看到发往以及来自bruno.cs.colorado.edu的结果如图8-11所示。发出路径(TTL字段为1~11)的结果与返回路径(TTL字段为11~21)不同,这很好地说明了在Internet上,选路可能是不对称的。该输出同时还说明了我们在图8-3中所讨论的问题。比较TTL字段为2和19的输出结果:它们都是路由器gateway.tuc.noao.edu,但两个IP地址却是不同的。由于traceroute程序以进入接口作为其标识,而我们从两条不同的方向经过该路由器,一条是发出路径(TTL字段为2),另一条是返回路径(TTL字段为19),因此可以猜想到这个结果。通过比较TTL字段为3和18、4和17的结果,可以看到同样的结果。图8-11显示非对称路径的traceroute程序