网络层

网络层负责将数据包从源节点传送到目的节点,这中间可能会经过许多中间节点,也可能会穿过多个网络。这是网络层和数据链路层不同的地方,数据链路层只负责在相邻两个节点之间传送数据。网络层的主要功能是:路由选择、拥塞控制、网络互联和计费。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

1.    网络层设计问题

网络层的主要设计问题包括网络层向传输层提供的服务,以及通信子网的内部设计。

 

(1)面向连接的服务与无连接服务
无连接服务:以Internet阵营为代表,认为通信子网本质上是不可靠的,用户肯定需要自己做差错控制和流量控制的工作,既然如此,通信子网干脆只提供最基本的数据传输服务就行了,即只负责将分组正确路由到目的节点,除此之外不提供差错控制、顺序控制、流量控制等其它功能。从这个思想出发,那么通信子网是无连接的,每个分组是一个独立的传输单位,携带完整的地址,在每个节点被独立传输,分组之间彼此没有联系。
面向连接的服务:以电信公司阵营为代表,认为通信子网应该提供可靠的面向连接的服务,在这里服务质量是一个重点需要考虑的因素。只有在通信前建立连接,才能进行服务协商并预留足够的资源,才能保证象话音、视频等一类实时业务获得它们所需要的服务质量。
这两派意见的焦点在于是否需要建立连接,至于是否需要保证数据传输的可靠其实是可选的。提供无连接服务的典型代表是因特网,提供面向连接服务的典型代表是电话网和ATM网络。事实上,由于实时多媒体应用的不断普及,服务质量的问题越来越受到关注,而因特网在这方面的局限性也日益凸现,因此因特网也在不断地改进,IPv6就引入了面向连接的特性。

 

(2)无连接服务的实现
在提供无连接服务的通信子网中,每个分组被独立地传输,分组常被称为数据报,而通信子网则称为数据报子网。
       用例子来说明数据报子网的工作原理:
l         主机的网络层从传输层接收一个消息。
l         将消息封装成分组,发送给距它最近的路由器。若消息太大,超过了分组的最大长度,还需要先将消息划分成较小的数据块,再分别封装成分组。
l         每个路由器都有一张路由表,记录各个已知的目的地址及这些地址所在的输出线路。每当从网络端口收到一个分组,首先判断自己是否是分组的目的地,是就将分组交给合适的上层实体去处理;否则用分组的目的地址查找路由表,从相应的输出线路转发分组。
l         如果分组长度超过了输出链路上的最大传输单元(称MTUMaximum Transfer Unit),路由器的网络层必须将分组分成较小的片段,每个片段封装成分组,独立传输。
l         目的主机的网络层将收到的分组交给传输层;如果分组被划分成了若干个片段,目的主机先将各个片段重组,再交给传输层。
l         路由器中的路由模块负责生成和维护路由表(使用路由算法),转发模块负责查找转发表和转发分组。转发表是根据路由表生成的、便于快速查找的数据结构。

 

(3)面向连接服务的实现
在提供面向连接服务的通信子网中,通信前首先需要建立一条从源节点到目的节点的传输通路(也称为连接),相关的数据包都沿着这条通路传输,传输结束后要释放这条通路。
建立连接的目的是避免在每收到一个分组后,都要去查找庞大的转发表。其基本思想是,将从源主机到目的主机的路径记录在沿途经过的每一个路由器中,此后,该连接上的所有分组都在这条路径上传输。由于在同一条物理链路上可能存在多条连接,因此需要为每条连接分配一个标识。每个分组必须携带其所属连接的标识,这样路由器检查分组头中的连接标识就知道分组属于哪个连接了。
连接标识只具有局部意义,即同一条连接在不同的物理链路上可能被分配不同的连接标识。为此,路由器必须为经过它的所有连接建立一张连接表,对于每一条连接,记录其输入链路及在这条链路上的连接标识,还有输出链路及在输出链路上的连接标识。路由器在转发分组时,必须用输出链路上的连接标识替换分组头中的连接标识。
从源主机到目的主机的连接称为虚电路,这是因为它只是表示了从源主机到目的主机的一条通路,与实际的物理通路(如固定地占用一个频道或时间片)并不相同。
除了连接建立分组需要携带完整的网络层地址之外,其它分组只需要携带一个连接标识(虚电路号)。
用例子来说明虚电路子网的工作原理:
l          源节点向目的节点发送一个连接建立分组,分组中携带完整的源地址和目的地址,并在源节点与源路由器之间的线路上选择一个当前未用的虚电路号,携带在分组头中;
l          每一个中间节点收到连接建立分组后,根据分组的目的地址查找路由表,选择一条合适的输出线路,然后在输出线路上选择一个当前未用的虚电路号,替换分组头中的虚电路号,并在节点的虚电路表中记录下这条连接(输入线路,输入虚电路号,输出线路,输出虚电路号),最后从输出线路上转发该分组;
l          这个过程不断重复直至到达目的节点,如果目的节点同意建立连接,则会发回一个连接确认分组,该分组沿着相反的路径返回源节点,虚电路就建立起来了,这条虚电路是全双工的;
l          随后,源节点在发送的每一个分组中都放入该分组所属的虚电路号,每个中间节点用输入线路和输入虚电路号查找虚电路表,用输出虚电路号替换分组头中的虚电路号,并从输出线路上转发分组,该过程不断重复直至分组到达目的节点;
l          传输结束后,任何一方都可以发出一个连接拆除分组,收到该分组的节点删除虚电路表中的相应表项,并向下转发分组,当连接拆除分组到达另一方时,虚电路就被拆除了。

 

(4)虚电路子网与数据报子网的比较
虚电路子网与数据报子网各有其长处和短处:
l          在虚电路子网中,每个分组(除连接建立分组之外)只需要携带较短的虚电路号而不是一个完整的目的地址,这可以节省带宽,但却需要占用一部分内存空间来存放虚电路表;数据报子网刚好相反,它使用较小的内存空间,但要消耗较多的带宽。
l          虚电路的建立需要花费一定的时间,但虚电路建立后,查找虚电路表进行分组转发是很快的;数据报子网虽然不需要连接建立时间,但每一个分组到达路由器时都要查找路由表转发,这个过程复杂得多也慢得多。
l          由于在建立虚电路时可以预留资源,所以虚电路子网在提供服务质量保证和避免拥塞方面较数据报子网优越。
l          由于节点或线路故障会使所有经过故障点的虚电路中断,而数据报却可以轻易地绕过故障点继续传输,因此数据报子网在健壮性方面较虚电路子网优越,而且数据报子网易于实现负载均衡。

 

2.    路由算法

路由器的主要任务是转发分组。在数据报网络中,路由器通过查找转发表来获得转发信息;而在虚电路网络中,路由器通过查找虚电路表获得转发信息。构建转发表和虚电路表的基础是路由器中维护的路由表。路由表是由路由算法建立起来的一张表,通常包含了从目的地址到分组转发路径上下一跳地址的映射。
在我们考虑的互连网络环境中,每个终端节点通常有一台默认路由器(default router)。每当该终端欲与其它网络中的终端通信时,它总是将分组发送给它的默认路由器。我们将源主机的默认路由器称为源路由器,把目的主机的默认路由器称为目的路由器,则为一个分组选择从源主机到目的主机路由的问题归结为从源路由器到目的路由器的路由问题。我们可将路由问题描述为:给定一组路由器和连接路由器的一组链路,寻找一条从源路由器到目的路由器的最佳路径。
什么是最佳路径呢?一般说来,视不同的应用而定,评价一条路径的好坏可能包括路径的物理长度、链路数据速率、分组传输延迟、通信费用、安全性等等。事实上,路径选择往往还要考虑到一些全局指标的优化,如网络吞吐量最大、平均包延迟最小、平均通信费用最低、网络负载均衡、路由稳定、健壮等等。显然,没有哪一条路径能够满足以上所有的指标,路由算法总是试图在几种重要的指标之间取得较好的折衷。为此,一般的做法是根据特定应用的需要使用一个代价函数将链路状态(如速率、延迟、费用等)映射为一个代价值,而路由问题就归结为寻找一条从源路由器到目的路由器的代价最小的路径。
一般来说,路由优化较多考虑最小化分组延迟和最大化网络吞吐量,但这是一对矛盾。人们通常所做的一个折衷是最小化分组经过的跳数(hop),因为减少跳数常常会减小分组穿过网络的延迟,同时也会消耗较少的带宽资源,从而提高吞吐量。
按照路由算法使用的网络状态信息是全局信息还是局部信息,路由算法可以分为全局路由算法和分布式路由算法。全局路由算法由于使用全局状态信息易于获得较优路径,但状态信息交换需要消耗较多的网络带宽,分布式路由算法则相反。
按照路由表是预先配置的还是动态生成的,路由算法可以分为静态路由算法和动态路由算法。静态路由算法根据网络流量的一般特性预先(离线)计算好路由表,在网络初始化时下载到路由器中,此后不再改变。静态路由算法简单易行,但适应性差,只适用于负载稳定、拓扑变化不大的网络。动态路由算法随时根据网络当前的拓扑结构和流量特点计算路由表,适应性强,但算法复杂,实现难度大,而且容易引起路由循环及路由振荡等问题。

 

(1)最优化原则
最优化原则:如果路由器J位于路由器I和路由器K的最佳路径上,那么从路由器J到路由器K的最佳路径也落在这条路径上。(用反证法可以证明)
推论:从所有源节点到一个指定目的节点的最佳路径形成了以目的节点为根的树,这棵树称为汇集树。
所有路由算法的目的都是要发现和使用汇集树,但由于网络是动态变化的,每个节点对网络的了解可能是不全面的,因此它们不一定总能找到汇集树,但汇集树可以用来衡量一个路由算法的好坏,看它能在多大程度上找到和使用汇集树。

 

(2)最短路径路由选择
研究路由算法常用的一种技术是将通信子网抽象为一张图,图中的顶点代表路由器,边代表通信线路(常称为链路),权代表链路的距离,这样在一对给定的路由器之间寻找一条最佳路由的问题,就转变成在图中一对给定的顶点间寻找一条最短通路的问题。在这里“距离”是一个广义的概念,它可以指跳数、物理距离、队列长度、传输延迟等等。一般情况下,权重是距离、带宽、平均流量、通信代价、平均队列长度、延迟及其它相关因素的函数,通过改变权重函数,路由算法就可以找出满足各种特定要求的最佳路由。
有好几种算法可以求图中两顶点之间的最短通路,以下介绍的是Dijkstra算法。Dijkstra算法的基本思想是,从源(目的)点开始,首先求离源(目的)点最近的通路,然后求离源(目的)点次近的通路,依次类推,直至有一条通路到达目的(源)顶点,则这条通路就是源点与目的顶点之间的最短通路。例见图5-7,程序算法见图5-8

 

(3)扩散法
扩散法是一种静态路由算法,每一个输入的分组都被从除输入线路之外的所有其它线路上转发出去。扩散法显然会产生大量的分组副本,因此必须有一些办法来抑制无限的转发。
一种办法是在分组头中携带一个跳数计数器,分组每到一个节点其跳数计数器就减1,当计数器为0时分组被丢弃。计数器的初始值可以设为通信子网的直径,即相距最远的两个节点之间的跳数。
另一种办法是记住哪些分组已经转发过了,从而确保一个分组不会被同一个节点转发两次。这要求源路由器从主机收到一个分组后,将一个序号放入分组头中,同时每一个路由器对于每一个源路由器都要维护一张序号表,记录从每一个源路由器上已经收到的分组的序号。每当一个路由器收到来自某个源路由器的分组时,就用分组的序号去查找该源路由器的序号表,如果序号已在表中则该分组被丢弃。为了防止序号表过大,序号表中还应增设一个计数器k,表示序号直至k的分组都已经转发过了,从而不需要保留序号小于k的序号。
扩散法的一种较实用的变形是选择性扩散,在这种算法中分组只朝着大致正确的方向转发,而不是转发到除输入线路外的所有线路上。
尽管扩散法在很多应用中都不实用,但它确实也有一些适用的地方。比如由于扩散法的鲁棒性(robustness)很好,它在战场的军事网络中特别有用;其次扩散法在本质上是一种广播式的路由算法,因此在一些要求广播传输的应用中也很有用,如分布式数据库的同步更新;在无线网络中位于发送站功率范围内的所有站都能收到发送站发送的消息,这其实也是一种扩散的形式,这个特性常被一些算法所利用;由于扩散法总能找到最短通路,因此其它路由算法都可以和扩散法进行比较,以衡量各自的算法性能。

 

4)距离矢量路由算法
       距离矢量(Distance VectorDV)路由算法是一种应用广泛的动态路由算法,曾被早期的ARPANETDECnetNovellIPX采纳作为路由算法,目前因特网中的RIP协议和BGP协议使用的也是这个算法。
       路由问题本质上是图论中的一个问题。以节点代表路由器,边代表路由器之间的链路,权代表链路的代价,路由的基本问题是找出任意两个节点之间代价最小的路径。路径的代价等于组成这条路径的所有边的代价之和。
       距离矢量算法解决这个问题的基本思想是:假设源节点知道自己到每个邻居节点的链路代价(即距离),以及每个邻居节点到目的节点的最小代价,则最小代价路径问题就是求源节点的一个邻居节点,使得通过该邻居节点到达目的节点的代价最小。用数学语言描述就是:dx(y) = minp{c(x,p) + dp(y)}pN(x),其中xy分别为源节点和目的节点,N(x)x的直接邻居集合,dx(y)为从xy的最小代价路径的代价,c(x,p)x到其直接邻居p的链路代价。该方程称为Bellman-Ford方程,因此DV算法也称为分布式Bellman-Ford算法。
为求解此问题,DV算法要求每个节点知道自己到所有邻居节点的距离(即c(x,p)),这是完全可以做到的。这里的距离是一个广义的概念,可以指到目的节点的跳数、到目的节点所需的时间、或者到目的节点的分组队列长度等。若按跳数计算距离,则相邻节点间的距离等于1;若以延迟计算距离,则每个节点只需和各个邻居节点交换特殊的“回声”分组,根据发送和接收到分组的时间差就可以推算出到各个邻居节点的延迟时间;若以分组队列长度计算距离,则只需统计一下去往该节点的分组数量即可。对于非相邻的节点,初始时可假设距离为无穷大。
其次,DV算法要求每个节点知道其邻居节点到目的节点的最小距离,这需要通过邻居节点之间的消息交换来实现。DV算法要求每个节点(设为x)维护一张路由表,网络中每个节点在此表中占有一个表项,并以节点作为路由表的索引。每个表项包括两部分内容:去往该目的节点(设为y)的最佳输出线路(用下一跳节点p进行标识)以及估计到该目的节点的最短距离(即dx(y))。每个节点定期地和它的所有邻居节点交换路由表中的距离列表(即距离矢量),通报从本节点到其它各个节点的估算距离。每个节点利用从邻居节点收到的距离矢量,使用Bellman-Ford方程更新自己的距离矢量,并计算新的路由表。
若某个节点x与邻居p的距离为m(即c(x,p)),p发布的距离矢量中py表示节点py之间的距离(dp(y)),则x判断自己通过p到达y的距离为 m+py;利用每个邻居节点发来的距离矢量进行同样计算,x可以找到到达y的最佳输出线路;同样可以找到到达所有其它节点的最佳输出线路,更新路由表。例见图5-9。注意在计算新路由表时,完全没有用到老的路由表。
       距离矢量路由算法的一个问题是算法有时收敛很慢,特别是它对坏消息的响应很慢,比如图5-10中的例子。出现这个问题的根本原因在于每个路由器发布的路由消息不完全是可靠的,特别是它不知道自己是否正在这条路径上。人们一直在努力解决这个问题,但至今为止仍然没有一个理想的解决方案。

 

5)链路状态路由算法
       链路状态路由算法于1979年代替了ARPANET中的距离矢量路由算法,现在各种各样的链路状态路由算法得到了非常广泛的应用,如OSPFIS-IS等。
LS算法的基本思想是,每个节点利用可靠的方法获知其邻居节点以及到各邻居节点的链路的代价,通过与网络内其它节点交换这些信息来获得关于全网的拓扑信息,即网中所有的节点、链路和链路的代价,将这些拓扑信息抽象成一张带权图,然后用图论的方法计算出到各个目的节点的最短路径。链路状态路由算法包括以下五个部分:
l         发现邻居,获知邻居的网络地址;
l         测量到每个邻居的延时;
l         将以上信息构造成链路状态分组;
l         向所有节点发送链路状态分组;
l         计算到每个节点的最短路径。

 

发现邻居:
当路由器启动时,首先在它的每一条输出线路上发送一个特殊的HELLO分组,收到HELLO分组的路由器必须尽快返回一个应答,告知自己的全局唯一地址。

 

       测量线路延时:
       最直接的方法是路由器在线路上发送一个特殊的ECHO分组,收到ECHO分组的路由器必须立即发回一个应答,通过测量发送与接收之间的时间(来回时间)并除以2,可以得到单向的线路延时。可以多测几组数据,求平均线路延时。显然在这里我们假设延时是对称的,但实际上并不总是这样。
       在计算线路延时时要不要考虑线路上的负载,这是一个颇有争议的问题。如果考虑线路上的负载,那么发送时间应从ECHO分组放入队列时算起;如果不考虑线路负载,那么发送时间应从ECHO分组到达队头时算起。考虑线路负载意味着当两条线路的带宽相同时,路由器将选择负载较轻的线路作为最佳输出线路,这种选择能导致良好的性能。但这会使轻负载的线路很快超载,从而另一条线路又成为最佳选择,这样容易引起路由表的剧烈振荡,导致不稳定路由和其它潜在问题的产生。只考虑带宽不考虑负载就不会出现这种问题,但完全不考虑负载也是不合理的,它会使流量都集中到高带宽的线路上,而低带宽的线路却很空闲。以上问题的根源在于路由器总是选择最佳线路转发分组,这很容易引起负载不均衡,因此较明智的做法是将负载按一定比例分布到多条线路上。
      
       构造链路状态分组:
       一旦收集到了各个邻居节点的地址及到各个邻居的线路延时之后,就可以构造一个链路状态分组来携带这些信息。首先是发送方地址,然后是分组序号和寿命,最后是一个邻居列表,每个表项包括一个邻居地址和到这个邻居的延时。
       什么时候构造链路状态分组比较合适呢?一种办法是周期性地产生链路状态分组,另一种办法是仅在发现网络拓扑发生改变时才产生,如邻居集合发生了变化,或到邻居的线路延时发生了变化。

 

       发送链路状态分组:
       该算法最复杂的部分是如何可靠地发送链路状态分组。当分组被发送和安装后,首先得到分组的路由器就会用它来改变自己的路由表,此时不同的路由器可能会使用不同的网络拓扑版本,这可能导致不一致、路由环路、不可达节点和其它问题。
       为了可靠地发送链路状态分组,采用了扩散法。每个分组携带一个序号,每当发送一个新的分组时,分组序号就加1。每个路由器维护一张由(源路由器,序号)对组成的列表,记录从每个源路由器收到的最新的分组序号。当一个链路状态分组到来时,用分组中的源路由器地址和序号查表,如果这是一个新的链路状态分组,就用扩散法将其转发出去,否则将分组丢弃。
       采用序号来区分新旧分组是会有一些问题的,一是当序号折回时,新的分组都会被丢掉;二是当路由器发生崩溃并重起后,只能从序号0开始发送,这些分组也会被丢弃;三是当序号在传输过程中出错时,如4变成了65540,则其后大量的分组都会被丢掉。
为解决序号折回的问题,使用了32比特长的序号,这样即使每隔一秒发送一个链路状态分组,也需要137年的时间才会发生序号折回。针对后两个问题,解决的办法是在分组中增加一个寿命域,不管分组在网络中的什么地方,其寿命均每隔一秒减1,当寿命减为0时分组被丢弃。
还有一些改进的措施可增加算法的鲁棒性。当一个链路状态分组进入一个路由器并需要扩散时,该分组并不马上放到传输队列里,而是放到一个临时区域中等待一小段时间。如果在该分组被发送前,来自同一个源路由器的另一个链路状态分组到来,则将这两个分组的序号进行比较。如果序号相同,就丢弃后来的分组;如果序号不同,则序号小的分组被丢弃。为防止分组在路由器到路由器的传输线路上出错,所有链路状态分组都必须被确认。当线路空闲时,临时区域被循环扫描,从中选择一个分组或确认进行发送。
路由器将收到的链路状态分组存放在分组缓冲器中,使用图5-14所示的数据结构。每一行对应一个最近收到的但还未处理完毕的链路状态分组,除记录该分组的源路由器、序号、寿命、数据以外,对应每一条输出线路还有发送和确认两个标志位,用来指示是否要在这条线路上转发或确认这个分组。解释例5-14

 

       计算新路由:
       一旦一个路由器收集齐了一整套链路状态分组,它就可以建立完整的通信子网图,在这张图中每条链路均被报告了两次,这两个值可以分开用,也可以求平均值。图建立起来后,就可以运行Dijkstra算法求路由器到任何目的路由器的最短通路。

 

6)分级路由选择
       当网络变得很大时,要求每个路由器都知道到所有其它路由器的路径是不可能的,路由表会变得非常庞大,需要占用大量的内存,花费大量的CPU时间用于路由表的查找和维护,消耗大量的带宽用于路由信息的交换,这时采用分级路由选择是必然的。
       采用分级路由选择时,将路由器划分到不同的区域中,每个路由器知道到区域内所有其它路由器的路由,但不知道其它区域内的路由细节。当需要将分组转发到其它区域时,路由器只是简单地将分组发给区域内的网关路由器去处理。当将不同的网络互联在一起时,每个网络自然成为一个区域。当网络规模非常大时,两级往往是不够的,需要分成多级,每一级路由器都知道本级内如何路由,但必须通过上一级路由器将分组转发到本级之外的节点。
       一个两级网络的例子。分级路由选择使得路由表的大小显著减小,但可能会因此增加某些节点的路径长度,当网络规模很大时这个代价是值得的。研究表明,有N个路由器的通信子网的最佳级数为lnN,每个路由器需要的表项总数为elnN,由分级路由选择引起的有效平均路由长度的增长是很小的,完全可以接受。
       划分区域的一种很自然的方法是按管理域(也称自治域,AS)进行划分,因为每个组织都要求按自己的意愿运行和管理网络,或对外部隐藏网络的内部组织等。对于较大的自治域,还可以进一步将自治域划分成区(area)。区是OSPF的术语,一个区是从管理上配置成相互交换路由信息的路由器的集合。通过将域划分成区,可使单个域变得更大而又不会加重域内路由协议的负担。
       图示是一个划分成4个区的域。主干网区是一个特殊的区(也称区0),不同区之间的通信都要通过主干网区进行。既是主干网区也是非主干网区成员的路由器称为区边界路由器(Area Boarder RouterABR),R1R2R3都是区边界路由器。当分组要从一个非主干网区传送到另一个非主干网区时,分组首先到达与源网络相连的一个ABR,然后穿过主干网区到达与目的网络相连的一个ABR,最后从该ABR进入目的网络。分组在非主干网区内的转发使用区内路由表,这是由同一个区内的路由器通过彼此交换链路状态信息生成的。为使源ABR能够准确地将分组转发到目的ABR,每个ABR汇总从其所在的非主干网区了解到的路由信息,计算到该区中每个网络的路由代价,然后将这些信息发送给区0的所有节点。与此同时,每个ABR也汇总从其它ABR收到的路由信息,并将这些信息通知到自己所在的非主干网区。这样,域中所有的路由器都知道如何到达域中的每个网络。当非主干网区中有多个ABR时,比如R1R2均是区2中的ABR,由于这些ABR发布的路由代价不相同,通过运行最短路径算法可知哪一个ABR是最佳的。比如,对于区1中的目的地来说,显然R1是比R2更好的选择。

 

7)广播路由
有些应用需要将消息发送给网络中所有的主机。将一个分组同时发送给所有目的节点,这称为广播,有多种方法可以实现广播发送。
第一种方法是用单播的方式向每一个目的主机单独发送一个分组。这种方法浪费带宽,而且要求源主机知道网络中所有的目的主机。
第二种方法是扩散法,这种方法会产生较多的分组副本,需要采取一些措施限制过多的扩散。
第三种方法是多目的路由,它要求每个分组携带一个目的地清单,每到一个路由器时,路由器检查所有的目的地址以确定一个最小的输出线路集合,在该集合的每一条线路上转发分组的一个副本,分组中仅携带使用该线路的目的地。当经过足够多次的转发后,每个分组将仅携带一个目的地,此时可将它当作普通的分组对待。多目的路由可以节省带宽的消耗,但仍要求源主机知道网络中所有的目的主机。
第四种方法使用通信子网的生成树来转发分组,生成树是通信子网的一个子集,它包括所有的路由器但不存在回路,每个路由器仅将收到的分组转发到除输入线路以外的所有生成树线路上。这种方法生成的分组副本数最少,消耗的带宽最少,但它要求每个路由器知道通信子网的一棵生成树,这个条件并不总是能够满足的(如采用距离矢量路由算法的通信子网)。
第五种方法是反向路径转发,它只使用节点内部的路由表来转发广播分组,除此之外不需要任何其它的知识,而且它产生的分组副本数比扩散法要少得多,性能与使用生成树的方法差不多。
反向路径转发的基本思想是,当广播分组到达路由器时,路由器检查分组的源地址与输入线路,若输入线路与路由表中去往该地址的输出线路相同,则该分组很可能是来自该源路由器的第一个分组拷贝,于是路由器扩散转发该分组,否则将分组丢弃。例见图5-20。这种方法的好处是算法合理、有效、易于实现且开销不大。

 

8)多播路由
       在有些应用中,分散在各地的一些用户需要以小组的方式协同工作,一个用户需要向小组内的其它成员发送消息。如果组内成员很少,可以用单播的方式向每个成员发送消息;如果组包含了网络中的绝大部分用户,那么可以用广播的方式发送;如果组内成员绝对数量较多,但与全体用户数相比相对数量又很少,那么以上两种方式均不经济,这时候采用多播方式发送是最合适的。将一个分组发送给组内的所有成员,这称为多播。
       目前的网络适配器(Network Interface CardNIC)都支持物理网络中的多播实现。NIC允许CPU描述和改变要监听的多播地址集合,由于NIC的存储空间有限,许多NIC限定多播地址集合的大小为64。实际上,一个典型的应用在任何时候只加入一到两个多播组(如接收一个音频流和/或一个视频流),而一个节点上任何时候最多只有几个应用加入多播,因此大多数计算机系统只同时使用几个多播地址。
       当多播帧到来时,将帧头中的多播地址与地址集合中的64个地址逐一比较是一件费时的工作,一般的NIC都没有足够的计算能力在短时间内完成。为此,NIC硬件采用了一种优化的实现方法。NIC维护一个64比特的矢量,并用一个哈希函数将多播地址映射成[063]之间的一个数。从本质上说,这是将所有可能的多播地址划分成64个组,每个组对应矢量中的一个比特。对于CPU指定要监听的每个多播地址计算一个哈希值,并将矢量中对应比特的值置为1。当一个多播帧到达时,NIC计算该地址的哈希值,然后检查矢量中对应比特的值。若该比特的值为1,则接收该帧,否则丢弃。在这个方案中,NIC不会漏掉任何一个该接收的多播帧,但可能会收下一个地址不匹配的帧,虽然这种概率是很低的。进一步的检查工作由CPU完成,即CPU收到一个多播帧后要检查其目的地址是否匹配。
       在互联网中实现多播传输的基本思想是:(1)所有欲接收相同分组的节点构成一个多播组(multicast group),每个组分配一个唯一的多播地址,发送给该组的分组均以该多播地址为目的地址。(2)网络中任何一个主机都可以选择加入或离开这个组,网络中运行的组管理协议负责建立、维护和删除多播组。(3)网络中运行一个多播路由协议,负责为每个组建立多播转发树,多播转发树是能够到达该组所有成员主机的路径树。(4)当一个多播分组到达中间路由器时,中间路由器根据相对应的多播树转发分组。(5)当多播分组到达“最后一跳”路由器(与多播组的成员主机位于相同的物理网络上)时,使用物理网络的底层多播功能将分组发送到目的主机。
       可以通过扩展已有的单播路由算法(链路状态和距离矢量算法)来实现多播路由。在链路状态路由算法中,每个节点知道整个网络的拓扑信息,能够计算出从本节点到任一其它节点的最短路径。为支持多播路由,节点只需要再知道每个多播组的成员分布(连接)在哪些链路上即可。为此,可令所有参与多播的主机定期在局域网上通报其所属的多播组,路由器监视这些消息,记录在每一条直连链路(局域网)上监听到的多播组,然后将每条链路对应的多播组集合作为链路的状态在网上广播。一旦知道了每个多播组所涉及的链路,每个路由器就可以计算出从任一源节点到任一多播组的最短路径多播树。需要注意的是,每个路由器必须有能力保存从每个源节点到每个多播组的最短路径多播树。显然这样的代价很高,因此,实际中路由器只计算并缓存当前活跃的(源节点,多播组)所对应的最短路径多播树。
       扩展距离矢量路由算法要复杂一些,因为节点不知道整个网络的拓扑结构。在距离矢量路由算法中,每个节点只和相邻节点交换距离矢量,知道到每个目的节点的最短路径上的下一跳,但无法知道每个多播组和哪些链路有关。对距离矢量路由算法的扩展包括两个方面。第一,由于节点不知道哪些链路连接了一个多播组的成员,因此需要设计一种广播转发机制,确保多播分组能够到达每一个局域网。第二,由于广播转发无法避开那些没有多播组成员的局域网,造成大量的无用传输,因此需要设计一种路径剪枝(prune)机制,将那些不包含组成员主机的网络排除在外。
广播转发可采用逆向路径转发机制。为删除不包括组成员主机的网络,剪枝过程从叶子网络开始。参与多播的主机定期在其局域网上通报所属的多播组,连接在局域网上的路由器监听并汇总这些消息。当路由器收到一个发往组G的分组而它并没有从局域网上监听到组G的报告时,该路由器向其上游路由器(即在分组到来的输入链路上)发送一个剪枝消息,上游路由器从路径树中删除这个分支。如果一台路由器从它的每个下游路由器都收到剪枝消息,则它向上游路由器转发一个剪枝消息。这个过程递归进行,直至所有的无关分支都被删除,最终得到一棵以源S为根的组G的多播树。第一个应用于因特网并受到最广泛支持的多播路由协议DVMRPDistance-Vector Multicast Routing Protocol)就是采用了这种逆向路径转发加路径剪枝的多播路由算法。该算法的缺点是可扩展性较差,若网络中有n个多播组,每个组平均有m个成员,则对于每个组需要保存m棵剪枝的生成树,总共需要保存mn棵剪枝的生成树。当网络中有大量的多播组存在时,需要消耗大量的内存。另外,如果绝大部分路由器都不需要参与多播发送,那么将多播分组广播到所有路由器,直到那些路由器发送剪枝消息明确要求将其删除,就不是一个好的设计选择。
为解决多播路由的可扩展性问题,提出了基于核心的多播树。每个多播组只建立一棵由所有组成员共享的多播树,核心即为树根节点。当需要向该组发送多播分组时,多播分组首先被发送到核心节点,然后由核心节点进行转发。由于每个多播组只建立一棵共享树,内存的消耗大大减少了。共享树的缺点是分组转发路径可能不是最优的,分组从源节点到核心节点再到目的节点的路径,可能比从源节点直接到目的节点的路径要长得多。这是共享树为实现可扩展性而付出的性能代价。
第二种广泛应用于因特网并专为解决可扩展性问题而开发的多播路由协议是PIMProtocol-Independent Multicast)。PIM将多播路由问题划分为稠密模式和稀疏模式两种情况,稠密模式是指区域中的许多或大多数路由器都涉及多播路由过程,而稀疏模式是指只有很小一部分路由器涉及多播路由过程。在稠密模式中,PIM采用广播与剪枝相结合的多播路由算法,类似于DVMRP的思想。在稀疏模式中,PIM采用共享树的方法。但PIM的一个新颖之处是,当源节点的数据流量比较大时,可以从共享树切换到特定源树,以提高分组转发的效率。
PIM稀疏模式中,每个多播组要选择一个汇集点(Rendezvous PointRP)。RP的选择过程非常复杂,在后面的讨论中假设所有路由器都知道某个给定多播组的RP的单播地址。当一个路由器S从其所在的局域网上监听到多播组G的通报时,路由器用单播方式向组GRP发送一个Join消息。Join消息在到达RP之前要经过一系列的路由器,这些路由器均在转发表中创建一条共享树的记录,称为(*G)记录(*表示所有发送方)。其中,Join消息到达的接口被标记为转发多播组G的分组的接口,向RP进一步转发Join消息的接口被标记为本节点允许接收多播组G的分组的唯一接口。当Join消息到达RP时,就完成了从SRP的分支建立过程。随着更多的路由器向RP发送Join消息,新的分支被添加到共享树上,最终形成一棵以RP为根的共享树。当一个主机希望发送一个分组到组G时,它构造一个目的地址为G的多播地址的分组,发送给局域网上一个指定的多播路由器(称指派路由器)。指派路由器用单播的方式将分组发送给RP(使用隧道技术),然后由RP在共享树上转发。当树的下游路由器(在转发方向上远离核心节点)观察到从某个源主机发来的数据量很大时,可以向源主机发送一个Join消息。Join消息按最短路径传向源节点,沿途经过的每个路由器都在转发表中创建树的(SG)状态,最终得到一棵以源节点为根而不是以RP为根的多播转发树。此后,由该源主机发往组G的多播分组均沿这棵特定源树转发。

 

9)移动主机路由
       所谓移动主机是指改变了网络接入点的主机。有两类移动用户,一类是迁移用户,他们基本上是静态的,但经常需要从一个固定网络转移到另一个固定网络,但在转移的过程中不进行通信;另一类是漫游用户,他们不断地改变网络接入点,而且在移动的过程中仍然需要保持通信。后一种移动在处理上需要考虑的最主要问题是如何在移动的过程中保持通信的连续性及服务质量。
       移动网络需要解决的第一个问题就是如何找到移动的主机,以下是一种可能的路由方法。为了随时跟踪移动的主机,要求每个主机都有一个家乡网络以及在家乡网络上的一个家乡地址,这个家乡地址是一个永久地址,其它节点总是能够通过这个地址找到主机的,同时当主机连接在外地网络时还有一个在外地网络有效的临时地址(称为转交地址)。每个网络中有一个家乡代理,还有一个或几个外地代理。家乡代理为那些家乡地址在本网络但目前游离在外的移动用户服务,包括记录用户当前的转交地址,以及将发至家乡地址的数据包转发到用户的转交地址等。外地代理为那些家乡地址不在本网但目前连在本网上的用户服务,主要是为外地节点提供转交地址,并作为这些节点的缺省路由器,为他们转发数据包。
       当一个移动用户进入到一个外地网络时,它必须获得一个转交地址,然后向家乡代理注册,并请求外地代理的路由服务。具体过程如下:
l         每个外地代理定期地广播一个分组,宣布自己的存在及地址;
l         移动节点通过接收这些分组并分析外地代理的地址,可以判断自己是否处于外地网络上以及是否切换了网络,如果在外地网络上则使用外地代理地址作为自己的转交地址;
l         移动节点向外地代理发送一个注册消息,给出自已的家乡地址、家乡代理地址及认证信息等;
l         外地代理向家乡代理转发该注册消息;
l         家乡代理对注册消息进行认证,若有效则将移动节点的家乡地址及转交地址保存在绑定表中,然后发回一个注册应答消息;
l         外地代理收到有效的注册应答后,将移动节点记录在自己的转发表中。
其他节点使用移动节点的家乡地址向移动节点发送数据包,数据包的转发过程如下:
l         数据包首先被路由到移动节点的家乡网络上,被家乡代理截获;
l         家乡代理查找绑定表,获得移动节点当前的转交地址(即外地代理地址);
l         家乡代理将原始数据包封装到一个新的数据包中,新的数据包的源地址是家乡代理地址,而目的地址是移动节点的转交地址,将数据包发送出去(隧道方式);
l         外地代理收到数据包后去除封装,取出原始的数据包,封装在链路层帧中转发给移动节点。
移动节点向其它节点发送数据包时,数据包由外地代理负责路由,其过程与在家乡网络中一样。
       该算法还有几种修改或演进的版本:
(1)    当家乡代理将第一个数据包转发给移动节点之后,就向通信的另一方发送一个消息,告知移动节点当前的转交地址,此后通信的另一方就直接用移动节点的转交地址发送数据。
(2)    移动节点可以在外地网络申请一个专门的临时地址作为转交地址(称配置转交地址),而不使用外地代理地址,这样可以提高安全性,而且外地代理不会变成通信的瓶颈。
移动IPv4可以使用外地代理转交地址和配置转交地址,而移动IPv6只使用配置转交地址。在移动IPv4中,数据包总是先被路由到家乡网络上,再由家乡代理转发到转交地址上,而在移动IPv6中,家乡代理会将转交地址通知给移动节点的通信对端,然后通信对端直接用转交地址发移动节点发送数据。

 

10)对等网络中的路由查找
       对等网络近年来成为一个引人注目的研究课题。和传统的客户-服务器模式不同,对等网络是完全分布式的,网络中的每个节点既是服务器又是客户机,网络中不存在集中控制或等级。在一个典型的对等系统中,每个用户都有一些其他用户感兴趣的信息,如免费软件、音乐、图片等。当用户数量很大时,一个用户可能无法全部知道其他用户提供的信息,也不知道在哪儿才能找到自己感兴趣的东西。因此这里的问题是,在一个完全分布的环境中(即不存在集中的数据库或集中式的索引),用户如何找到包含自己感兴趣的信息的节点。
       问题提取:假定每个用户都有一个或几个其他用户感兴趣的数据项,每个数据项都用一个ASCII字符串来命名,一个可能的用户只知道ASCII字符串,而想知道是否有人有这个数据项的拷贝,有的话这些用户的IP地址是什么。
       已经提出了很多种算法来解决这个问题,本书要介绍的是Chord系统。
l          每个用户节点的IP地址被散列成一个m比特的数字,该数字称为节点标识,Chord系统使用的哈希函数(hash)是SHA-1m=160
l          概念上,所有<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2m个节点标识按升序组织在一个大圆中,其中有些节点对应了实际的节点,但大多数节点都不存在。函数successor (k)给出按顺时针方向排在节点k后面的第一个实际节点的节点标识。
l          记录的名字name(如文件名、歌曲名等)也用SHA-1散列成一个160比特的数字,称为关键字key,即key = hash (name)
l          当一个用户希望将名字为name的记录与其他用户共享时,他建立一个元组(name, my-IP-address),并请求节点标识为successor (hash (name))的节点保存这个元组。如果在多个节点上都有这个记录的拷贝,那么这些记录的元组都会保存在同一个节点上。采用这种方法,所有记录的索引将会随机地分布到各个节点上。
l          如果某个用户希望查找name,他首先用key = hash (name)找到关键字key,然后用successor (key)找到保存记录元组的节点的IP地址,然后从记录元组中获知保存记录的节点的IP地址(my-IP-address)。
以上算法的关键之处在于如何找到successor (key)IP地址。

 

3.    拥塞控制

大量分组在短时间内进入通信子网(或其局部)并由此造成网络处理能力下降的现象称为拥塞。拥塞发生的根本原因是网络的负载超出了网络的处理能力,网络的处理能力是指节点的存储能力(内存容量)、计算能力(CPU速度)和数据传输能力(线路带宽),这些能力也称为网络的资源。如果拥塞发生后不及时采取措施,会造成拥塞的急剧恶化,最后导致网络完全不能工作。拥塞控制的任务就是尽量避免拥塞的发生,并在出现拥塞迹象的时候及时采取措施缓解拥塞。
拥塞控制与流量控制不同的是,拥塞控制着眼于通信子网,它要保证进入网络的数据量不超出网络的处理能力,而流量控制着眼于接收终端,它要保证进入接收端的数据量不超出接收端的处理能力。但两者又都有相似之处,它们都需要控制源节点的数据发送。
       拥塞控制有开环和闭环两种方法。开环方法是通过对系统进行精心设计来确保拥塞不会出现,闭环方法则建立在反馈环路的基础上,它通过实时的监测并在拥塞出现时采取积极的应对措施来减少拥塞。
由于拥塞是由负载与资源的不匹配引起的,因此很显然解决的方法就是两个:增加资源和减小负载。增加资源可以是启用备用设备或线路,但这种方法并不是任何时候都奏效,特别是当没有备用资源可用时,因此最主要的解决方法就是减小负载。以下介绍的拥塞控制措施均属于闭环方法,且都是采用了控制负载的方法。

 

接纳控制(admission control
       该方法只适用于虚电路子网。它的基本思想是,虚电路的建立必须获得网络的许可,当网络中出现拥塞症状时,网络将不允许任何虚电路建立,或者只允许那些通过非拥塞区域的虚电路建立。其实,这种方法就是要求主机与网络在通信前对数据流的特征及要求的资源达成共识,如果有足够的资源可以预留给虚电路,这条虚电路就允许建立,否则就拒绝。当主机不以超过合同承诺的速率发送数据流时,由于网络中总是有足够的资源可以处理这些数据,拥塞就不会发生。

 

警告比特
       当路由器发现它的一条线路超载时(即链路利用率、队列长度等指示拥塞的参数超过了一个预定的门限),会在所有使用这条线路的分组上打上一个警告标记(设置一个警告位),当该分组到达接收端时,接收端将该标记拷贝到给发送端的应答中,发送端将相应地减小发往这个目标的数据速率。

 

抑制分组
       当路由器发现它的一条线路超载后,每当收到一个使用这条线路的分组,就会向分组的发送端发送一个抑制分组,要求减少发往这个方向的数据包,同时给分组打上标记继续下传,该分组在随后的传输中不再产生新的抑制分组。发送端收到抑制分组后,按一定比例减小发往相应目标的数据。由于在抑制分组到达发送端之前又有一些数据包进入了网络,而这些包在经过拥塞的线路时又会产生新的抑制分组,因此发送端在收到一个抑制分组后会忽略随后一段时间的抑制分组,如果在这段时间后仍然收到抑制分组,表明拥塞状况没有解除,继续降低发送速率。拥塞状况解除后再逐渐提高发送速度。

 

逐跳抑制分组
       在一个高速的网络中,等到抑制分组到达发送端后再由发送端降低速率,往往不能及时缓解拥塞的状况。为提高反应速度,要求接到抑制分组的上游节点立即减小发往拥塞线路的数据量,这就要求上游节点要有较大的内存来缓冲上游来的数据。但是当它的上游节点收到抑制分组并立即减小发往它的数据量时,该节点的存储压力就会减轻。逐跳抑制分组的好处是能够迅速减少发往拥塞区域的数据量,从而迅速缓解拥塞的症状。

 

负载丢弃
       当以上方法均不能有效缓解拥塞状况时,可以干脆丢弃部分分组。在这儿如何明智地丢弃是一个难题,因为在多媒体应用中,不同的分组具有不同的重要性,如音频数据比视频数据重要;在实时应用中,新的数据比老的数据有价值,因为老的数据即使到达接收端也可能因超时而变得无用了;而在按序接收数据包的应用中(如基于TCP的应用),老的数据包又比新的数据包有价值,因为在前面的数据没收到之前后面的数据也不会接收。由于路由器对于数据包的内容一无所知,因此路由器不可能知道哪些包更重要,除非应用程序给自己的数据包打上丢弃优先级,这样路由器在需要时可以选择丢弃。这同时又要求有合理的计费措施,否则没有一个应用愿意将自己的数据包标记为可以优先丢弃。在没有以上所说的配套措施之前,路由器一般随机选取拥塞线路上的一个分组丢弃。

 

随机及早检测(RED
       在实际的系统中,不是等内存溢出了再丢弃分组,那就太迟了,一般在线路利用率(或队列长度、内存利用率等)超过一定的门限时就开始丢弃分组。在一些误码率较低的网络里,丢包通常源于这种情况,因此有些协议(如TCP)的拥塞控制算法就将超时作为拥塞的标志,在发现超时后立即降低发送速率,就是这个道理。但是当丢包主要是由于链路误码而不是拥塞时,不能用这种方法。
       随机及早检测(Random Early DetectionRED)于20世纪90年代早期提出,主要与TCP协议配合使用进行拥塞控制。RED算法的基本思想是:每个路由器监视自己的分组队列长度,当队列长度达到第一个门限值(称最小阈值)时,开始按照某个丢弃概率p丢弃到来的分组;当队列长度达到第二个门限值(称最大阈值)时,丢弃每一个到达的分组。RED采用的是一种隐式反馈的方法,即当它发现有拥塞出现的苗头时只是丢弃分组,并不向源节点发送显式的通知消息。与RED配合使用的TCP协议是通过发送端超时来判断网络拥塞的,因此当一个分组被丢弃时,发送端将发生超时,并立即降低发送速度。
RED算法有两个丢弃门限,当队列长度到达第一个门限时就开始按一定概率丢弃分组。这样做的目的是在拥塞尚不严重时就通知源节点提早放慢发送速度,这也是随机及早检测名字的由来。当队列长度到达第二个门限时,表明拥塞已经非常严重了,因此把所有到来的分组全部丢弃。
需要注意的是,RED算法中与丢弃门限进行比较的队列长度是平均队列长度而不是瞬间队列长度,这是因为平均队列长度更能准确捕获拥塞的动向。平均队列长度是用以下的加权动态平均值来计算的:
AvgLen = (1- Weight)×AvgLen + Weight×SampleLen
其中,AvgLen为平均队列长度,Weight为权重,SampleLen为测量时刻的瞬间队列长度。在大多数软件实现中,每当一个新的分组到达时,就测量一次队列长度。另外,丢弃概率p是平均队列长度和上一次丢弃距今时间的函数,分组队列越长,丢弃间隔越大,则丢弃的可能性也越大

 

4.    服务质量

传统的网络应用(如文件传输、电子邮件、Web浏览等)基本上都是非实时应用,它们对延时没有非常严格的要求,数据包的延时完全依网络负载的轻重而定,但对传输的可靠性要求很高,所以协议栈中几乎每一层上都有差错控制和流量控制措施。
       随着多媒体应用的出现,这种网络服务(称尽力服务,best effort)已经不能满足应用的需要。多媒体应用要求数据包的传输延迟及延迟抖动是可控的,即能够控制在应用指定的范围内,而不管这时网络负载有多重。应用对网络服务提出的各种要求,如可靠性、带宽、传输延迟、延迟抖动等,称为应用要求的服务质量QoSQuality of Service)。
       如何提供应用要求的服务质量是目前因特网的一个难题,因为因特网在设计之初根本就没有考虑到这种需求。这个问题在学术界已经研究了很久,在工业界也已经做出了一些尝试,但离完全解决还有相当的距离。
      
       在同一对源和目的之间传输的分组流(packet stream)称为流(flow)。分组流对网络服务提出的要求称为服务质量,通常包括可靠性、延迟、延迟抖动和带宽。    实现服务质量的技术一般有以下一些:
l         过量提供资源:有人提出当通信技术高度发展以后(如密集波分多路复用技术大量使用),每个应用可获得远远超出其需求的带宽,因而服务质量总是能够保证的。
l         接收端缓冲:这主要针对一些多媒体下载播放服务。接收端收到一定时长的数据后再播放,这样可以有效地消除延迟抖动,获得较好的播放效果。
l         资源预留:为分组流在经过的路径上预留带宽、内存和CPU时间。
l         接纳控制:仅当路径上的剩余资源满足分组流的资源需求才建立连接。
l         流量×××:发送端调节(平滑)输出流量的技术,以避免数据过快地进入网络。在接收端监视和控制流量的技术称为流量管制,将不符合流量规范的分组丢弃。流量×××常用的方法有漏桶算法和令牌桶算法,前者令数据以恒定速率进入网络,后者允许数据有一定的突发性。
l         分组调度:按照一定的服务准则发送每个流中的分组,以保证满足每一个流的服务质量。常见的服务准则为公平队列及其各种变异版本。
       目前这个领域有代表性的研究成果有三个:综合服务,区分服务和多协议标记交换。综合服务以流为单位提供服务质量,控制粒度细,处理开销大,可扩展性差,不宜用于骨干网中。区分服务将要求相同服务质量的流归于一类,以类为单位提供服务质量;控制粒度粗,处理开销小,扩展性好,目前用于骨干网中。多协议标记交换是工业界为加快数据包转发而提出的一种方法,边缘路由器将分组分类,在包头中加上类标签,此后的路由器只要按照标签进行转发就可以了。

 

5.    网络互联

不同的网络互联需要克服网络间的许多差异,图5-43列出了可能的一些差异,但要完全克服这些差异是很困难的,有时甚至是不可能的。
网络互联可以在各个层次上进行,常见的网络互联设备有网桥、多协议路由器、传输网关和应用网关,它们分别在数据链路层、网络层、传输层和应用层上互联网络。本节侧重讨论网络层上的网络互联问题,它与链路层上的网络互联不同的是,链路层设备(网桥)根据帧的目的MAC地址转发帧,而网络层设备(多协议路由器)根据分组的目的地址转发分组。
网络互联的形式
一般而言,网络互联有面向连接和无连接两种形式:
(1)    级联虚电路:在源节点和目的节点之间建立一条穿过各个中间网络的虚电路,虚电路的建立、拆除及数据包的传输过程与单个通信子网内的虚电路一样,如图5-45。当各个中间网络均支持虚电路方式时可以使用这种互联方式。
(2)    无连接网络互联:和数据报方式一样,每个分组被独立传输和路由,如图5-46
从一般意义上说,让两个不同类型的网络互联是非常困难的,然而有一种特殊的情形处理起来却很方便,那就是源节点和目的节点处于同一类型的两个网络上,而中间隔了另一种类型的网络,如图5-47。解决的方法就是称为隧道的技术,当数据包进入中间网络时,在入口处被整个地封装在一个中间网络分组的载荷中进行传输,当外层分组到达出口时,再取出其中的原始数据包并传送到目的网络,这种方式避免了分组在进出中间网络时进行协议转换。例5-47中数据包的传输过程如下:
l         主机1构造一个IP数据包,其目的IP地址为主机2IP地址,然后将IP包封装到一个以太帧中发送给路由器R1R1为源网络接入WAN的多协议路由器)。
l         R1收到IP分组,根据网间选路(internetwork routing)判断应将IP包发给距离主机2最近的路由器R2R2为目的网络接入WAN的多协议路由器),于是R1构造一个WAN分组,将IP包整个放入WAN分组的载荷域中,WAN分组的源地址和目的地址分别设为R1R2WAN中的地址,然后将分组在WAN中发送。
l         R2收到这个WAN分组后取出其中的IP分组,通过路由表查找得知主机2位于同一个物理网络上,于是将IP包封装到一个以太帧中发送给主机2
l         主机2将收到的IP分组交给网络层。

 

网间选路
       从理论上说,网络间的选路和单个通信子网内的选路是类似的。首先是将互联网络抽象为一张图,顶点代表多协议路由器,通信子网抽象为一条链路,表示连接在同一个子网上的多协议路由器可以互相直接访问到,如图5-49。图构成后,这组多协议路由器就可以使用已知的一些路由算法(如距离矢量、链路状态等)建立到其它多协议路由器的路由。这给出了两层次的选路算法,在每个子网内使用内部网关协议,在网络间使用外部网关协议,由于各个网络是相互独立的(通常称为自治系统AS),因此在各个子网内可以使用不同的路由算法。
       实际上,网间选路与网内选路非常不同,它还要考虑纯路由算法以外的许多其它因素。域间路由的复杂性在于:(1)因特网的规模极其庞大且结构非常复杂;(2)每个域可以运行自己的内部路由协议,并使用自己的代价计算方案;(3)一个域可能不信任来自某个域的路由信息;(4)一个域可能不愿意为其它域转发分组。因此,域间路由只能是找到一条可达的路径,要想找到最优路径根本是不可能的。因特网中最流行的域间路由协议是BGPBoarder Gateway Protocol)。每个自治域的管理者至少选择一个节点作为“BGP代言人”(BGP speaker),这个BGP代言人与其它自治域中的BGP代言人交换可达性信息,即通报通过各自的AS可到达的网络。与域内路由只确定下一跳节点不同的是,域间路由是以AS枚举列表的形式通知到达某个特定网络的完全路径。以下图为例,AS2BGP代言人通报的可达性信息是“网络128.96192.4.153192.4.32192.4.3可从AS2直接到达”,主干网AS1收到后通报的可达性信息是“网络128.96192.4.153192.4.32192.4.3可经路径<AS1AS2>到达”,AS1还可以通报“网络192.12.69192.4.54192.4.23可经路径<AS1AS3>到达”。BGP的一项重要任务是防止建立带环的路径,采用AS枚举的方法可以很容易地检测出路径是否带环。
一个分组穿过互联网络的典型过程如下:
l         在本地局域网上,分组首先被发送到本地多协议路由器;
l         在本地多协议路由器上,选路软件查表确定将分组转发给哪个多协议路由器;如果那个多协议路由器可以通过分组自身的网络协议到达,分组就被直接转发出去;否则将分组通过隧道方式转发过去;
这个过程不断重复,直至分组到达目的网络。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

 

分片
       每个网络都有一个最大分组长度的限制,因此当一个较大的分组需要通过一个最大分组长度较小的网络时,就必须把分组分成较小的片段再传输。
       在什么地方重组分组,有两种截然不同的做法。第一种方法是在片段将要离开当前传输的网络时进行重组,这种方法要求属于同一个分组的所有片段从同一个出口出去。这种方法的好处是分片对于下一个网络是透明的,即不要求目的主机具有重组的功能,而且当分组退出小分组网络后,长分组分片的开销就不存在了;缺点是如果分组在经过多个中间网络时反复地进行分片和重组的话,会增加很多的开销,而且它要求所有片段必须从同一个出口出去。第二种方法是仅在目的主机上重组,它的好处是免除了中间路由器重组的开销,且允许各个片段走不同的路;缺点是分组会在网络中越分越小,增加了片段的封装开销,而且要求目的主机必须有重组的功能。ATM采用了第一种方法,IP采用了第二种方法。
       如何对片段进行编号,这是需要解决的第二个问题,编号必须是无二义的。一般来说每个片段必须携带原始分组号和段号,还要有指示是否是最后一个片段的标志。IP规定了一个基本的片段长度(8字节),除了最后一个片段外,每个片段的长度必须是基本片段长度的整倍数,段号规定为是该片段在原始分组中的偏移量,分组头的MF标志指示是否是最后一个片段,使用这种编号方法可无二义地重组一个分组。

 

6. Internet的网络层

因特网实际上是由一群相互连接的自治系统(AS)以一种较松散的分级结构组成,见图5-44,将这些自治系统连接在一起的是因特网的网络层协议──IP协议

 

IP报头
       IP数据报由报头和数据两部分组成,报头由20字节长的固定头和最长为40字节的可变长度选项头组成,固定头的格式如图5-53所示。
l         VersionIP协议的版本号,目前使用的IP协议的版本号为4,所以称为IPv4,而IPv6的版本号为6
l         IHL:报头长度。
l         Type of service:用于表示服务类型。
l         Total length:数据报的总长度,最大长度是65535字节。
l         Identification:数据报的标识,当将一个大的数据报进行分片时,每片都必须携带数据报的标识。
l         DF:标志位,指示中间路由器不要将数据报分片,因为目的机器没有组装能力。
l         MF:标志位,当MF=1时表示该片段不是最后一片。
l         段偏移:表示该片段在数据报中的位置,除了最后一个片段外,所有片段必须是8字节的整数倍。
l         TTL:分组寿命,实际上是一个跳数计数器。
l         Protocol:指示应将数据报交给哪个协议实体处理。
l         Header checksum:头校验,计算时令该域为全0,然后将报头中所有16位字进行二进制反码求和,其结果即为头校验。对该算法的另一种描述是:将报头看成是由16比特的整数组成的序列(相邻的一对字节组成一个16比特的整数),将这些16比特的整数求和,若有进位加到和的低位,对结果求反码,即为检查和。分组每到一个节点,该域都要重新计算一遍。
l         源地址和目的地址:源节点和目的节点的IP地址。
l         选项:规定了五种可选项,采用TLVType, Length, Value)格式表示。

 

IP地址
       因特网上的每个网络接口都有一个唯一的IP地址,因此有多个端口的设备(如路由器、多穴主机等)会有多个IP地址,每个端口对应一个。IPv4IP地址是一个32比特的数,最初采用分类编址方案,其结构如图5-55所示,现在则采用无类编址方案。
       在分类编址方案中,IP地址分为五类,其中ABC三类为单播地址,D类地址为多播地址,E类地址备用。ABC三类地址由三部分组成:地址类型标志、网络号和主机号。当建立一个新的网络时,通常必须向ICANN申请一个网络地址,也即一个网络号,主机号则由网络管理员规定。IP地址通常采用点分十进制表示法表示,即每个字节表示为一个十进制数,字节之间用圆点隔开。
       使用这种编址方案,那么IP地址是自标识的,也就是说根据地址的前几位就可以确定该地址属于哪一类,并且对于三类单播地址来说可以很快抽取出网络号和主机号,这一点非常重要,因为在因特网中是使用网络号来进行数据报的路由的。
       网络号或主机号为0-1的地址是特殊地址,从不分配给某个单独的主机:
l         具有有效的网络号但主机号全为0的地址保留给网络本身;
l         具有有效的网络号但主机号全为1的地址保留作为定向广播,即在网络号指定的网络中广播;
l         32位全1的地址称为本地广播地址,表示仅在发送节点所在的网络中广播;
l         32位全0的地址指示本机;
l         网络号为0但主机号有效的地址指代本网中的主机。
l         形如127.xx.yy.xx的地址保留作为回路测试,发送到这个地址的分组不输出到线路上,而是送回内部的接收端。

 

 

子网
在一个较大的组织中,如果每个部门在建网时独立地申请网络地址,那么这个组织将会拥有多个网络,这给网络的管理带来很多不便。一种较好的方法是该组织申请一个较大的网络,然后在内部划分成几个较小的网络(子网),分配给各个部门,这样各个子网可以独立管理,而对外仍是一个统一的大网。
       如下图所示,一个申请了B类地址的组织内部有两个物理网络,管理员给一个物理网络上的机器分配形式为128.10.1.X的地址,给另一个物理网络上的机器分配形式为128.10.2.X的地址,其中X是地址的最后8位,用于标识一个特定的主机。只有本地路由器R知道有两个物理网络存在,并且知道如何转发去往这两个网络的分组,因特网上的其它路由器只知道一个网络128.10.0.0,它们将所有目的地址为128.10.xx.yy的分组选路到R,再由R根据地址的第三个字节决定把分组转发到哪一个物理网络上。从概念上说,添加子网仅略微改变了IP地址的解释,子网编址把32比特IP地址分成网络部分和本地部分,其中网络部分标识某个网点,它可能有多个物理网络,并且本地部分标识了该网点的一个物理网络和主机。
<?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />
       划分子网的方法是将主机号进一步划分成子网号和主机号,如图5-58所示。子网内的路由器负责在子网内转发分组,而子网间的转发由主路由器完成。各个路由器如何知道目的地址属于哪个子网呢?这需要通过子网掩码来实现。子网掩码由网络管理员根据子网的划分情况进行设置,子网掩码也是一个32比特的数,只是对应主机号的位上都为0。每个节点将数据包的目的地址与子网掩码相与,即可抽取出地址中的网络号+子网号部分。子网掩码也用点分十进制数表示。

 

IP数据报转发
当一个位于主机上的应用程序需要通信时,TCP/IP协议将产生一个或多个IP数据报。当主机发送这些数据报时必须进行转发决策,即使主机只与一个网络相连接也需要进行转发决策。因为如果目的主机与源主机在同一个物理网络上(如在同一个局域网中),则源主机将数据包封装在链路层帧中直接发送给目的主机(帧的目的地址为目的主机的MAC地址);如果目的主机与源主机不在同一个物理网络上,则源主机需要将数据包封装成帧后发送给本网的一台路由器(帧的目的地址为路由器的MAC地址)。
上述第一种情况称为直接交付(direct delivery),指在同一个物理网络上把数据包从一台机器直接传输到另一台机器,直接交付不涉及到路由器。第二种情况称为间接交付(indirect delivery),指目的站不在一个直接连接的网络上时,必须将数据包发给一个路由器进行处理。对于路由器来说也存在直接交付与间接交付的问题,当路由器位于传输路径上的最后一站时(即与目的主机在同一个物理网络上),采用直接交付将数据包发给目的主机,其它中间路由器采用间接交付将数据包发送给下一跳路由器。
如何判断目的站是否在同一个直连的网络上呢?很简单,发送站使用子网掩码从数据包的目的IP地址中抽取出网络前缀部分,再和自己的IP地址的网络前缀部分进行比较,如果相同表明两者处于同一个直连网络上,可以进行直接交付,否则必须使用间接交付。
每个节点(包括主机和路由器)都有一个转发表,每个表项记录了一个可能的目的地址以及如何到达该目的地址的信息。当主机或路由器中的IP选路软件需要发送数据报时,就查询转发表来决定怎么转发。转发表中应存有什么信息呢?
由于IP地址的分配使得所有连到给定网络上的机器共享一个相同的网络前缀,而在同一个物理网络上采用直接交付非常高效,这意味着转发表中仅需要包含网络前缀的信息而不需要整个IP地址,也就是说转发表中的一个表项可以是一个目的网络而不是一个特定的目的主机。
       IP路由使用的是“下一跳路由”的思想,即只在转发表中存储去往目的地址的下一跳路由器,而不是一条完整的到达目的地址的路径。下一跳路由器必须是通过单个网络可达的,这一点非常重要,强调这一点是为了保证数据包能够通过物理网络到达下一跳路由器。
       转发表中可以将多个表项统一到默认情况,即IP转发软件首先在转发表中查找目的网络,如果表中没有路由,则把数据包发给一个默认路由器,这称为缺省(默认)路由。当一个网点的本地地址集很小,并且只有一个到互联网的连接时,缺省路由尤其有用。比如对于连到单一物理网络并只通过唯一路由器连接到互联网的主机,其转发表中只需要有两个表项,一个为本地网络,另一个为缺省路由。
       尽管因特网中主要是基于网络而不是单个主机进行选路,但多数IP选路软件允许作为特例指定每个主机的路由,这在有些场合是很有用的,这称为特定主机路由。
       综上所述,IP转发表中包含三类路由:特定主机路由、网络前缀路由和缺省路由,可以通过子网掩码来区分这三类路由。以下是两个转发表的例子。

       IP转发算法如下:
       从数据包中提取目的IP地址D,并计算网络前缀N
       if D与自己的任何一个IP地址匹配
         then 将数据包交给protocol域指定的协议实体处理
         else if N与自己的任何一个直连的网络的地址匹配
           then 通过该网络把数据包直接交付到目的节点D
         else if 表中包含到D的特定主机路由
              then 把数据包发送到表中指定的下一跳
         else if 表中包含到网络N的一个路由
              then 把数据包发送到表中指定的下一跳
         else if 表中包含一个缺省路由
              then 把数据包发送到表中指定的默认路由器
  else 宣告选路出错,向数据包的源地址发送一条ICMP Unreachable消息。

 

       我们说IP选路算法所选择的IP地址是“下一跳”地址,是因为它指明了下一步把数据报发往何处。那么IP把下一跳地址存储在哪里呢?不在数据报中,这里没有为它保留空间。事实上,IP根本不保存下一跳地址。在执行选路算法之后,IP把数据报及下一跳地址传给一个网络接口软件,该软件对发送数据报必须经过的物理网络负责。这个接口软件把下一跳地址绑定到一个物理地址,使用这个物理地址形成一个帧,把数据报放在该帧的数据部分,并把结果发送出去。在用下一跳地址找到一个物理地址后,网络接口软件就丢弃了下一跳地址。

 

无类域间路由CIDR
       随着因特网的迅速扩张,IP编址方案的缺陷已经显露出来。问题之一是地址分级不合理,B类网络太大造成地址浪费,而C类网络太小又不实用,因此地址紧缺的现象日益严重。问题之二是按照目前以ABC类网络进行路由的方法,路由表暴涨,不仅占用太多的内存,也会在交换路由信息时消耗太多的带宽。
       CIDR的基本思想是抛弃类的概念,以可变长分块的方式分配所剩的IP地址。比如一个网络需要2000个地址,就给它一个连续2048个地址的地址块。但该地址块必须在2048字节的边界,以保证每个地址具有相同的子网掩码,从而外界可将它们看成是一个具有21位网络前缀的一个网络。
       用图5-59的例子说明CIDR的地址分配及路由匹配方法,路由匹配采用最长前缀匹配法,即如有多条路由匹配,则选择具有最长前缀的那一条。
       当位于路由器同一条输出线路上的几个目的网络的地址块可以合并成一个更大的地址块时(即具有更短的网络前缀),则在路由器中可以使用一个聚合入口来代替这几个网络的入口,从而进一步减小路由表的大小和加快查表的速度。
为此,RFC 1519将剩余的地址进行了统一分配,将世界划分为4个区,每个区分配一大块地址(约3200万个),具体如下:
地址194.0.0.0195.255.255.255给欧洲
地址198.0.0.0199.255.255.255给北美
地址200.0.0.0201.255.255.255给中美和南美
地址202.0.0.0203.255.255.255给亚洲和太平洋地区
这样分配的好处是,如果欧洲外部的路由器发送目的地址为194.xx.yy.zz195.xx.yy.zz的分组,只需将它送到标准欧洲网关即可,实际上3200万个地址在路由表中被压缩成了一项,大大减小了路由表。其它区域类似。

 

地址解析协议ARP
       IP地址是用于在网络层寻址的,数据链路层寻址用的是物理地址。当目的节点与源节点在同一个物理网络上,或者数据包到达目的路由器时,源节点或目的路由器需要用直接交付方式将数据包发送给目的节点。方法是将数据包封装在一个数据链路层帧中发送,帧的目的地址为目的节点的MAC地址,目的节点的网卡识别出该帧,取出其中的数据包交给目的节点的网络层。
在这里,MAC地址是与网卡联系在一起的物理地址,而IP地址是与节点所在网络相关的逻辑地址,源节点或目的路由器已知目的节点的IP地址,它们如何知道目的节点的MAC地址呢?这就是ARP需要解决的问题。
ARP的基本思想是:当主机A想要知道与IP地址IB对应的MAC地址时,它广播一个ARP请求分组,请求IP地址为IB的主机用物理地址PB作出响应。包括B在内的所有主机都会收到这个请求,但只有主机B识别出它的IP地址,并发出一个包含其物理地址的ARP应答分组,ARP应答是封装在单播帧中发送的。
为降低通信开销,使用ARP的计算机维护着一个高速缓存,存放最近获得的IP地址到物理地址的绑定。也就是说,当一台计算机发送一个ARP请求并接收到一个ARP应答时,就在高速缓存中保存IP地址及对应的物理地址,便于以后查询。当发送分组时,计算机首先在缓存中寻找所需的绑定,如果没有再广播ARP请求。若高速缓存中的绑定超过20分钟没有更新,就自动删除。
ARP协议还有以下改进:
l          A在向B发送的ARP请求中也包含了AIP地址与物理地址,以便B从请求中提取A的地址绑定,便于过后向A发送应答。
l          A广播它的请求时,网上所有机器都接收到了该请求,它们可以从中取出A的地址绑定更新自己的ARP缓存。
l          每台计算机启动时主动广播自己的地址绑定,通常以ARP查找自己的IP地址的形式完成,这样不会有应答,但网上其它主机都会在它们的ARP缓存中加进这个地址绑定。如果真收到了应答,表明两台机器分配了相同的IP地址,新机器会通知系统管理员,并停止启动。
在以太网上,ARP请求分组是封装在以太帧中发送的,帧头中的类型字段为080616。用于IP地址到以太网地址转换的ARP/RARP报文格式如下图所示。
       硬件类型:指明硬件接口类型,对于以太网该值为“1
       协议类型:指明高层协议地址类型,对于IP地址该值为080016
       硬件地址长度:对于以太网该值为6(以字节为单位);
       协议地址长度:对于IP地址该值为4
       操作:指明是ARP请求(1)、ARP响应(2)、RARP请求(3)还是RARP应答(4);
       发送方及目标的硬件地址和IP地址。

当发出ARP请求时,发送方用目标IP地址字段提供目标IP地址。目标主机填入所缺的目标硬件地址,然后交换目标和发送方地址对中数据的位置,并把操作改成应答,就变成了ARP应答。

 

反向地址解析协议RARP
       通常一台计算机的IP地址保存在一张配置表中并存于本地硬盘,当系统启动时读配置文件,即可知道自己的IP地址。但是对于一个无盘工作站,它又将IP地址保存在哪里呢?无盘工作站在启动时可以从本地获得自己的物理地址,因此这里的问题变为:如何根据已知的物理地址获得与其绑定的IP地址?反向地址解析协议RARP就是用来解决这个问题的。
       RARP的基本思想是:网络中有一个RARP服务器,保存有本网中各个无盘工作站的地址绑定。一个新启动的无盘工作站广播一个RARP请求分组,分组中给出自己的物理地址。RARP服务器查找地址绑定表,然后用单播方式发回一个RARP应答分组,分组中包含所请求的IP地址。
       RARP的报文格式与ARP报文同,同样封装在以太帧中发送,帧头的类型字段为803516

 

自举BOOTP和动态主机配置DHCP
       RARP响应中只包含很少的信息,而工作站自举还需要其它一些配置信息,为此设计了自举协议BOOTPBOOTP按照客户-服务器模式工作,使用UDP(传输层协议)和IP协议。当工作站希望获取配置信息时,广播一个BOOTP请求消息,BOOTP服务器接收到请求后,查找相应的配置信息,如工作站IP地址、存有工作站内存映像的文件服务器的IP地址、子网掩码、缺省路由器的IP地址等,将这些消息放入一个BOOTP响应消息中,将应答发回给工作站。
       由于工作站不知道BOOTP服务器的IP地址,它采用了广播发送,IP包的目的地址为全1的广播地址,而源地址为全0的地址。当BOOTP服务器收到使用全0地址发送的数据包后,它使用广播返回响应,或者使用到来的数据帧中的硬件地址通过单播返回响应。如果使用后一种方法,需要从携带BOOTP请求消息的帧中获取源MAC地址,然后在ARP缓存中添加该工作站的地址绑定。如果不允许应用程序修改ARP缓存,则只能使用广播。
       BOOTP的缺点是它必须手工配置服务器中的数据库信息,当一台新的机器进入一个网络时,网络管理员首先要手工添加配置信息,该机器才能被正确配置。为了进行自动配置,IETF设计了动态主机配置协议DHCP,这是目前为止使用最多的主机配置协议。DHCP提供了一种无需手工介入,计算机就可以加入到一个新网络并获得一个IP地址的机制。
DHCP也使用一个配置服务器,但该服务器不需要和请求的计算机在同一个局域网中,为此每个局域网上需要有一个DHCP中继,如图5-63。一个新启动的工作站广播一个DHCP发现分组(使用全1IP地址),DHCP中继负责截获所有的DHCP广播,然后采用单播方式向DHCP服务器发送。DHCP服务器可从一个地址池中分配一个地址给请求的工作站,然后用DHCP应答分组发回。DHCP分配给主机的地址可以是永久的也可以是临时的(租用的),若是租用的,计算机必须在租期将到期时与DHCP服务器协商以使租期延期,否则该主机将不能再使用该IP地址。

 

IP包的分片
       每种硬件技术均规定了它使用的帧所能携带的最大数据量,这种限制称为最大传输单元MTU,如以太网的MTU等于1500字节。在含有多种异构网络的互连网中,MTU限制带来的问题是,一个较长的数据包无法通过MTU较小的中间网络。
IP路由器使用分片技术来解决这个问题。当到来的数据报长度超过其输出线路所属网络的MTU时,路由器将数据报分成许多较小的片段。每个片段被封装成数据报,独立传输。封装片段使用的报头取自原始数据报的报头。
路由器利用MTU和报头长度计算每一报片允许包含的最大数据字节数(必须是8字节的整倍数),并对原始数据报的数据部分进行分片。在每个报片前使用原始报头的拷贝,修改原始头部中的某些字段,如总长度、标志位、片偏移(以字节为单位的偏移量除以8)等,重新计算头校验,然后发送。当一个片段到达一个具有更小MTU的网络时,需要进一步分片,所有分片都在目的主机重组,中间路由器不做重组的工作。
将到来的报片重新组装一个完整数据报的过程称为重组,重组是在目的主机中进行的。目的主机使用源地址和分组标识来确定属于同一个数据报的片段,根据MF标志判断是否最后一个报片已经到达。当MF=0的报片到达时,根据该报片的片偏移字段和总长度字段可以计算出原始数据报的总长度。当所有报片都已到达时,按照各报片在原始数据报中的偏移量进行组装。
IP协议的尽力投递模式使得数据报的重组非常复杂。尽力投递会出现以下几种复杂的情况:
(1)       乱序投递:由于报片在传递过程中可能改变路由,因此各个报片可能乱序到达。特别是,有些路由器会优先传输短包,所以最后一个报片可能最先到达。
(2)       重复:由于高层协议重传的缘故,网络中会出现重复的数据报。当重传数据报沿着不同的路径传输时,其分片情况可能与原始数据报的分片不同,也就是说不同的报片之间数据有重叠。
(3)       丢失:来自同一个数据报的一个或几个报片可能在传输过程中丢失,而IP不会重传丢失的报片。
为便于数据报重组,接收主机为每个数据报分配一个缓冲区,用于存放数据报的报片。由于分片可能乱序到达,且分片之间可能有数据重叠,接收节点需要记录哪些数据已经收到了。图5-25是数据报重组使用的数据结构,其中缓冲区用于存放报片中携带的数据,链表用于说明哪些数据片段已经收到了。
当属于某个数据报的报片到达时,节点将报片拷贝到分配给该数据报的缓冲区中并更新链表。报片在缓冲区中的存放位置等于报片偏移量乘以8,即报片在原始数据报中的字节位置。更新链表操作可能涉及到创建一个新的节点(插入的数据片段与已有的数据片段不连续)、修改一个节点(插入的数据片段与某一个数据片段连起来)或者删除一个节点(插入的数据片段将两边的数据片段连起来)。考虑到报片在传输过程中可能丢失,为避免接收端的重组缓冲区长时间不能释放,接收端为一个新的数据报建立重组缓冲区时启动一个重组定时器。当定时器超时后,释放该数据报的重组缓冲区及相关的数据结构。

 

ICMP协议
       因特网控制消息协议ICMPInternet Control Message Protocol)由主机或路由器用来传递网络层上的一些信息,最典型的应用是错误通报,比如报告目的网络不可达、TTL0IP头部检查和出错等。ICMP通常被认为是IP协议的一部分,但从结构上说ICMP位于IP协议之上,因为ICMP消息是封装在IP分组中传输的。
       ICMP消息包括typecodechecksum和内容。type域用于指明消息的类型,ICMP共定义了15种消息。code域用于对某类消息作进一步的区分。比如,type3的消息为目的不可达错误消息,每个消息又用code域进一步说明是网络不可达、主机不可达、还是端口不可达等16种不同的情况。checksumICMP消息的检查和。消息的内容取决于消息的typecode
       ICMP消息有询问和错误报告两类。询问用来请求一些信息,如无盘工作站的子网掩码或远程主机的应答(测试远程主机是否可达)等,通常采用请求-响应模式进行交互。错误报告消息用来向源节点报告错误信息,不需要响应,消息内容中通常包含引起该错误的IP数据报的报头及载荷的前8个字节。载荷的前8个字节刚好包含了TCPUDP的端口号及TCP段序号,这使得收到ICMP消息的节点可根据报头中协议字段指定的协议与相应的协议实体进行联系,并根据TCPUDP端口号与相应的用户进程进行联系。
       Ping程序就是利用类型为80ICMP消息(分别称为回声请求和回声响应)来完成测试功能的。程序工作时定期向目的主机发送ICMP回声请求,并接收目的主机的回声响应。Ping同时还计算出从发出请求到收到响应的来回时间,这个时间反映了远程主机距用户的距离或网络当前的负载状况。通常将发送回声请求的Ping程序称为客户,将要求给出回声响应的主机称为服务器,大多数TCP/IP实现都支持在内核中实现ping服务器。
       Traceroute也是利用ICMP消息来发现路径的。Traceroute程序向目标发送不同TTL值的ICMP消息,当IP包的TTL减为0时,路由器会向源节点发送一个ICMP错误报告。程序先发送TTL1的回声请求,并在随后的每次发送时将TTL1,直到目标节点响应或 TTL达到最大值,通过检查中间路由器发回的ICMP超时消息来确定路由。

 

IPv6
       提出IPv6的主要目的是想增加地址空间、简化分组的转发处理、实现多播功能、实现移动通信功能、增加服务质量支持和提供更好的安全性等。IPv6保持了IPv4的优良特性,但克服了它的一些缺点,并且增加了新的特性。总的来说,IPv6IPv4是不兼容的,但它与其它所有因特网协议都是兼容的。
       IPv6使用128位的地址,采用冒号十六进制表示法,即每16位以十六进制的形式写成一组,组之间用冒号分隔,如8000:0:0:0:123:4567:89AB:CDEF。当地址中包含连续多组0时,可以采用零压缩技术,将连续的多组0压缩为一对冒号,如以上地址可以表示为8000::123:4567:89AB:CDEFIPv4地址转换成IPv6地址时,前96位都为0,如::192.31.20.46
       IPv6的地址空间很大,可支持很多种地址分配方法,如可为不同的协议族、不同的组织、不同的地理区域等分配不同的地址块,每个地址块内部还可以有自己的编址方法,使用起来非常灵活方便。IPv6是具有多层结构的地址,虽然地址的划分是不固定的,但基本上可以将高层地址想象为一个ISP,下一层地址想象对应一个组织(如公司),再下一层对应一个网站,如此等等。
       IPv6有三种地址类型:单播地址,多播地址和任播地址(anycast),没有广播地址,因为广播可以看成是特殊的多播。任播对应于一个共享地址前缀的计算机集合,发送到该地址的数据包会沿着最短路径被路由,然后到达这个集合中的某一台计算机。
IPv6数据包格式
       IPv6数据包以一个基本头开始,后面跟着零个或多个扩展头,然后是数据。IPv6的基本头长为40个字节,格式见图5-68
l         Version:版本号为6
l         Traffic class:指明分组所属的数据流的特性;
l         Flow label:流标识,有服务质量要求的应用使用该标识指示分组所属的流;
l         Payload length:数据域的长度;
l         Next header:用于指定跟在当前头部后面的信息的类型。例如,如果数据包中含有一个扩展头,则next header指出该扩展头的类型;如果没有扩展头,则指出载荷域中携带的数据的类型。
l         Hop limit:对应于IPv4TTL域。

 

IPv4固定头相比,IPv6的基本头中去掉了以下一些域:
l         去掉了IHL域,因为IPv6的基本头总是40字节长,而每个扩展头都有长度指示。
l         去掉了协议域,因为Next header域可以指出载荷中的数据类型。
l         去掉了所有与分片相关的域,因为在IPv6中路由器不负责分片,主机必须保证分组的长度可以穿过每一个中间网络。
l         去掉了头校验,因为计算校验和太花时间,加之现在网络非常可靠,链路层和传输层上往往又都有校验和,因此不值得增加这个开销。
为了加快分组的转发速度和增加协议的可扩展性,IPv6引入了扩展头的概念。IPv6的基本头中只包含分组传输必需的最少信息,而将一些扩展功能放到扩展头中,这样大多数分组可以避免使用不需要的头部,从而可以加快分组的处理速度,也减少内存和带宽的消耗。有了扩展头后,增加协议功能也变得非常容易,只需定义一种新的扩展头就可以了,而那些不支持这种扩展功能的路由器只需简单地跳过这个扩展头就可以了。
以因特网今天的规模及其分散式的管理形式,要想让所有的主机和路由器一夜之间全部从IPv4过渡到IPv6是不可能的。IPv6的部署只能是渐进的,即一开始只有一些主机和路由器部署了IPv6,然后这个范围逐渐扩大。那么如何将这些孤立的“IPv6岛”整合到IPv4世界中呢?RFC 2893描述了两种方法:双栈操作和隧道技术。
       双栈操作就是IPv6节点也有完整的IPv4实现,这样的节点称为IPv6/IPv4节点。IPv6/IPv4节点具有IPv6IPv4两种地址,并能判断对方使用什么协议,当与IPv4节点互操作时使用IPv4数据报,当与IPv6节点互操作时使用IPv6数据报。在双栈方法中,如果发送方或接收方中有一个是仅支持IPv4的,必须使用IPv4数据报;若双方均支持IPv6,则不应相互发送IPv4数据报。
5-29说明了这种情况,AFIPv6网络中的两个主机,BE是两个IPv6/IPv4节点,CD是仅支持IPv4的路由器,AF之间交换IPv6数据报。然而,当B将数据报转发给C时,B必须将IPv6数据报转换成IPv4数据报。当然,IPv6数据报中的数据可以拷贝到IPv4数据报的数据域,并进行适当的地址映射,但IPv6报头中一些IPv6特定的字段(如流标签)在IPv4报头中无对应部分,这些字段的信息将会丢失。因此,即使EF能够交换IPv6数据报,从DEIPv4数据报并不含有从A发出的初始IPv6数据报中的所有字段。
       另一种双栈方法——隧道技术可以解决上述问题。为在IPv4网络中传输IPv6数据报,节点BBE(两个IPv6/IPv4节点)之间建立一条隧道,即将IPv6数据报封装到一个IPv4数据报的载荷中,并将IPv4数据报的源地址和目的地址分别标记为BEIPv4地址,然后将数据报发送给隧道中的第一个节点C。该IPv4数据报将像任何其它的IPv4数据报一样从C到达EE取出IPv6数据报,将其转发给F,就好像它是从一个直接相连的IPv6邻居那里收到的一样。