您好,欢迎访问三七文档
网际协议与选路第二讲第5章IP:软件总体结构第6章IP:选路表与选路算法第7章IP:分片与重组22019/12/20第5章IP:软件的总体结构5.1引言本章所关心的是实现网际协议(IP)的软件的组织结构。IP提供的功能看似简单,但它的纷繁难懂使软件的实现过程变得复杂,而其精细微妙之处又使软件很难做到准确无误。在讲解IP的过程中,为了不至于因突然涉及所有部分而使人无法接受,我们将具体实现方案分3章讨论。本章给出了数据结构并描述软件的整体结构,还讨论了IP软件的理论性操作以及通过IP层的数据报流程。在稍后的章节中,还要详述选路和差错处理的细节,展示IP软件中的各段程序代码是如何使用这些数据结构的。32019/12/205.2中心环节单从主机的角度来看,人们会很自然地将IP软件分为两个不同的部分考虑:一部分处理输入,另一部分处理输出。输入部分使用IP首部中的PROTO字段来决定应该由上层协议中的哪个模块来接收传入数据报。输出部分使用一张本地选路表来选择外发数据报要送往的下一跳。它使得IP和上层协议软件之间的沟通变得十分笨拙。另外,网关中的选路过程要比主机中的更复杂。由于一个网关必须将发送来的数据报继续转送到它的下一跳.所以网关中的软件都不能轻易地被划分成输入和输出部分。这样,在IP处理传入数据报时可能会产生输出数据。而当发送来的数据报引起错误时,网关还必须生成ICMP差错信息,这更进一步地使输入和输出的界限模糊。42019/12/205.3lP软件设计思想为保持IP软件的简单性和统一性,在范例中采用的组织结构上的技巧有:●统一的输入队列及统一的选路过程。●独立的IP进程。●本地主机接口。虽然建立网关的必要性引发了许多的设计思想,但针对网关的设计在主机上同样有效,并允许在主机和网关上使用同样的程序。52019/12/205.4IP软件结构和数据报流程5.4.1选择传入数据报的策略在第3章中曾提到过,每个网络接口,包括伪网络接口,都有属于自己的、送往IP进程的数据报队列:图5.1描画出该数据流。如果有多个数据报正在输入队列中等待,IP进程必须选取其中之一,并为其选择路由。IP选取哪一个数据报将决定系统的行为:挑选数据报并为其选择路由的IP程序段实现了一个重要策略;它决定了数据报来源的相对优先级。62019/12/205.4.1选择传入数据报的策略正确的做法是公平分配优先权,使传入和外发数据流在选择路由时享有平等的优先权。我们的实现策略是以循环法(round-robin)来选择数据报,以期达到公平合理。也就是说,它从某个队列中选择出一个数据报,并为其做路由处理之后,继续向前移动并检查下一个队列。如果有K个含有数据报的队列正在等待着路由处理,那么IP在处理完所有K个队列中的第一个数据报之后,才有可能处理到任一队列中的第二个数据报。过程ipgetp实现了循环法选择的策略72019/12/205.4.1选择传入数据报的策略正如程序代码所示,静态变量ifnext用作接口数组的索引。它遍历整个网络接口结构。在每个接口中,它检查状态变量ni_state,以确定接口是否已被打开。当ipgetp发现一个打开的接口中有正在等待的数据报时,它就使用宏NIGET来提取并返回第一个数据报。再次调用ipgetp时.将跨过前一次处理的接口,继续查找:82019/12/205.4.2允许IP进程被阻塞过程ipgetp包含了一种微妙的优化思想:如果所有输入队列都空,IP进程在调用过程ipgetp时被阻塞。一旦有一个数据报到达,IP进程就恢复执行并立刻检查已有数据报到达的那个接口。首先,当与某个特定接口相关联的设备驱动程序在它的输入队列中放入一个数据报时.就向IP进程发送一个报文。其次,ipgetp中的循环语句以调用receive结束,在ipgetp遍历了所有网络接口而没有发现任何数据报之后,它调用receive,receive在信息到达之前为阻塞状态。当ipgetp返回时,它以函数值的形式向主调过程传送一个报文。报文中包含了一个指针,指向已有数据报到达的接口。ipgetp将该接口指针赋值给ifnext,并重新开始遍历92019/12/205.4.2允许IP进程被阻塞既然已经知道了IP所使用的选择数据报的策略,那么来查看一下IP进程的结构;其基本算法非常简单。IP不断地调用ipgetp来选择一个数据报,接着调用一个过程来计算下一跳的地址,并将数据报置入与将要发送该数据报的网络接口相关联的队列中。尽管从概念上看似简单,但许多细节问题使程序代码复杂化。例如,如果数据报来自于某个网络,IP必须验证此数据报的校验和是否正确。如果选路表中没有指定的目的站,IP必须生成一个ICMP“目的站不可达”报文。如果选路表指出该数据报应当被送往产生这个数据报的网络中的某个目的站,IP必须生成一个ICMP“重定向”报文。最后,IP必须处理定向广播这一特殊情况,此时IP向指定的网络发送数据报的副本,并向网关自身的上层协议软件也发送一份副本。IP进程从过程ipproc的执行开始。102019/12/205.4.3IP使用的常量的定义在文件ip.h中定义了IP软件使用的符号常量。另外,它还用结构IP定义了IP数据报的格式。112019/12/205.4.4校验和的计算ipproc利用过程cksum来计算或验证数据报的首部校验和。首部校验和将首部视为16位整数的序列,并把校验和定义为对首都中所有16位整数各求反码,并将结果相加、再对求得的和计算一次二进制反码。得到的和数及反码定义为使用二进制反码算法。大多数设备使用二进制补码算法,因此仅累加得出一个16位的校验和并不能得到正确的结果。为了便于移植并避免以汇编语言编写程序,过程cksum使用了c语言编写。在范例中使用了32位(长整型)算法来累加得到一个和,然后通过向这个整数和中增加所有进位位的办法,将结果折合成一个16位的值。最后,cksum返回结果的反码。122019/12/205.4.5处理定向广播只要一个数据报发送到定向广播地址,则在指定的目的网络中的所有机器都必须接收到一份副本,关键是要记住:定向广播包括了目的网络上的网关和主机,即便是负责在网络上继续向前发送该数据报的网关也不能例外。然而,大多数网络硬件不会将广播分组的副本再次传送回发出这个广播的机器。如果一个网关需要一份广播数据报的副本,那么软件必须采取明确的措施,以保留一份副本。因此,如果一个网关接收到的数据报的目的地址是直接与这个网关相连的某个网络的定向广播地址,那么这个网关必须做两件事:(1)为本机的协议软件复制一份数据报。(2)在指定的网络上广播该数据报。132019/12/205.4.5处理定向广播ipproc为所有的数据报调用ipdbc,其中绝大多数并没有指定要定向广播。ipdbc一开始就检查数据报来源,因为如果该数据报是由本地机器生成的,则不需要复制。然后ipdbc调用isbrc。将数据报的目的地址与这个网关直接相连接的所有网络的定向广播地址相比较,如果均不相同,则说明这是一个非广播数据报,而非广播数据报也不需要复制。在不需要复制的情况下,ipdbc不采取任何行动,直接返回。ipproc将像平常那样选择一个路由并继续向前发送该数据报。如果数据报的目的地址是某个直接与网关相连的网络上的定向广播地址,它必须被复制。其中一份副本送往本地机器软件,另—份以正常方式继续转发。为了复制数据报,ipdbc根据数据报的大小从标准网络缓冲池或大缓冲池中分配一个缓冲区。如果缓冲区分配成功,ipdbc将数据报复制到新缓冲区中,并把新缓冲区放入输出端口,此端口与发送数据报时经过的网络接口相关联。当ipdbc返回后,ipproc将副本原件通过伪网络接口传递给本地机器。142019/12/205.4.6识别一个广播地址IP协议标准规定了三种类型的广播地址:本地网络广播地址(全“1’’)、定向网络广播地址(主机地址段为全“1”的A、B、C三级IP地址)以及一个子网广播地址(主机地址段为全“1”的子网IP地址),遗憾的是,当Berkeley将TCP/IP合并入BSDUNIX时,他们决定使用非标准广播地址,有时称为Berkeley广播,这些广播的格式在应该是全“1”的地方使用了全“0”表示。尽管BerkeIey格式的广播地址肯定是非标准的,但许多从Berkeley程序代码中衍生出来的商用体系已经采纳了这种格式。为了与广泛使用的Berkeley规范兼容,我们的范例代码接收使用全“0”或全“1”两种格式的广播。此程序代码段包含在过程isbrc中。152019/12/205.5lP首部中的字节顺序为了使网际协议独立于运行它的机器,协议标准为首部中所有整型值规定了网络字节顺序在发送一个数据报之前,主机必须将所有整型值从本机字节顺序转换成标准网络字节顺序。而当接收到一个数据报之后,主机必须将这些整型值从标准网络字节顺序转换成本机字节顺序。过程iph2net和iPnet2h执行这一转换任务:ipnet2h在ipproc中被调用,而iph2net在ipfsend、ipproc和ipputp中被调用;实用程序使用函数net2hs(从网络到主机短整型)和hs2net(从主机短整型到网络)为每个字段进行转换。为了优化处理时间,在我们的程序代码中,所有IP地址以网络字节顺序保存,并且不转换协议首都中的地址字段。这样,这段程序代码只需转换不含IP地址的整型字段。162019/12/205.6向lP发送数据报5.6.1发送本地生成的数据报给出一个本地生成的数据报和一个IP目的地址,过程ipsend填写IP首部并将数据报放入本机接口的队列中,IP进程将从这个队列中取出并发送数据报。ipsend填写首部中的每个字段,包括指定的目的地址。为了保证每个外发数据报中标识字段都有唯一的值,ipsend将全局变量ipackid的值赋予该标识字段,然后递增变量ipackid.ipsend完成填写首部的任务之后,调用enq把数据报置入本地主机(伪网络)接口的队列中。注意,虽然网络接口的ni_ipinq队列在正常情况下包含的是传入数据报(也就是来自其他网点的数据报),但从应用软件的角度看,伪网络接口的队列中包含的是“外发”的数据报。最后,在IP进程因等待数据报的到达而处于阻塞状态的情况下,ipsend调用send向IP进程发送一个报文。172019/12/205.6.2发送传入数据报当一个经由网络发送来的数据报到达时,网络接口层的设备驱动程序必须将其放置在适当的IP队列中。它调用ip-in完成这项工作。给出—个指向分组缓冲区的指针,ip-in调用enq将分组置入接口的队列中。如果队列已满,ip-in递增变量IplnDiscards的值,以记录下这个队列的溢出差错,并丢弃分组。最后,在IP进程被阻塞并等待接收数据报的情况下,ip-in向IP进程发送一个报文。182019/12/205.7表格的维护IP软件需要一个时钟机制,用于维护网络数据结构,包括IP选路表和分片重装表。在我们的范例中,使用一个单一的定时器进程来完成这种周期性任务。事实上,定时器进程并不仅用于IP任务中,它还触发ARP高速缓存的超时,并且可被用于其他任何没有严格时延要求的长时间的周期性任务中。在过程slowtimer中的程序代码段,体现了如何轻易地将新任务加入列表中。正如程序代码所示,slowtimer由—个无限循环构成,它重复不断地唤醒一组维护过程。一个特定的维护过程可能花费相当长的时间来完成它的任务,而且一次唤醒与下一次唤醒之间的执行时间也可能不一样长。因此slowtimer计算两次执行之间的实际时延,并将其作为参数递给维护过程。192019/12/205.8小结为简化程序代码,IP作为唯一的、独立的进程执行,并通过一个伪网络接口与本机的高层协议软件交互作用。在没有数据报时,IP进程被阻塞。一旦从任何地方发来一个或多个数据报后.IP进程被唤醒,并处理这些数据报,直至为它们选择路由为止。为了使处理过程公平合理,并避免出现“饥饿状态”,我们在范例中对所有输入数据源,包括对应于本
本文标题:网络协议第二讲
链接地址:https://www.777doc.com/doc-2142121 .html