Linux高性能服务器编程第二章IP协议详解
Linux高性能服务器编程第二章IP协议详解
Hoshea ZhangIP协议是TCP/IP协议族的核心协议,也是socket网络编程的基础之一,本章节从两部分较为深入地探讨IP协议:
IP头部信息
IP头部信息出现在每个IP数据报中,用于指定IP通信的源端数据IP地址、目的端IP地址、指导IP分片和重组、以及指定部分通信行为
IP数据报的路由和转发
IP数据报的路由和转发发生在除目标机器之外的所有主机和路由器上,他们决定数据报是否应该转发以及如何转发
IP服务的特点
IP协议是TCP/IP协议族的动力,他为上层协议提供无状态、无连接、不可靠的服务。
无状态
指IP通信双方不同步传输数据的状态信息,因此所有IP数据报的发送、传输和接收都是相互独立,没有上下文关系的。缺点是无法处理乱序和重复的IP数据报。
优点是简单高效,无须为保持通信的状态分配一些内核资源,也不需要每次传输数据时都携带状态信息。
无连接
指IP通信双方都不长久维持对方的任何信息,这样上层协议每次发送数据的时候,都必须明确指定对方的IP地址
不可靠
不能保证IP数据报准确地到达接收端,他只是承诺尽最大努力。发送端的IP模块一旦检测到IP数据报发送失败,就通知上层协议发送失败,而不会试图重传。因此使用IP服务的上层协议(比如TCP)需要自己实现数据确认、超时重传等机制来达到可靠传输的目的。
头部结构
IPV4头部结构
长度通常为20字节,除非有可变长的选项部分
4位版本号指定IP协议版本,对IPV4来说值为4
4位头部长度标识该IP头部有多少个32bit字(4字节),因为四位最大为15,所有IP头部最长60字节
8位服务类型包括一个3位的优先权字段(已被忽略),4位的TOS字段和1位的保留字段(必须置零)。
4位TOS字段表示最小延时,最大吞吐量,最高可靠性和最小费用,其中最多有一个能置为1,比如像ssh和telnet的登陆程序需要最小延时的服务,ftp则需要最大吞吐量的服务
16位总长度是指整个IP数据报的长度,以字节为单位,因此IP数据报最大长度为65535(2^16^-1)字节,但由于MTU的限制,长度超过MTU的数据报将会被分片传输,因此实际传输的IP数据报远远没有达到最大值
16位标识唯一的标识主机发送的每一个数据报,初始值由系统随机生成,每发送一个数据报其值就+1,该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值
3位标志字符第一位保留,第二位表示禁止分片,第三位表示更多分片,除了数据报的最后一个分片外,其他分片都要置1
13位分片偏移,是指分片和原始IP数据报开始处(数据部分)的便宜,实际的偏移值是该值左移3位得到的(×8),因此除了最后一个IP分片外,每个IP分片数据长度必须是8的整数倍
8位生存时间指的是数据报到达目的地之前允许经过的路由器跳数,被发送端设置,一般为64,每经过以恶搞路由就-1,TTL减为0的时候路由器将丢弃数据报,并向源端发送一个ICMP报文
8位协议用来区分上层协议,比如ICMP是1,TCP是6,UDP是17
16位头部校验和由发送端填充,接收端对其使用CRC算法以检验IP数据报头部、
32位的源端IP地址和目的端IP地址用来标识数据报的发送端和接收端,一般情况下这两个地址在整个数据报的传递过程中保持不变,而不论他中间经过多少个中转路由器
最后一个选项字段是可变长的可选信息
IP分片
如图所示
IP路由
IP模块工作流程
如下图所示:
我们从右往左来分析该图。当IP模块接收到来自数据链路层的IP数据报时,它首先对该数据报的头部做CRC校验,确认无误之后就分析其头部的具体信息。
如果该IP数据报的头部设置了源站选路选项(松散源路由选择或严格源路由选择),则IP模块调用数据报转发子模块来处理该数据报。如果该IP数据报的头部中目标IP地址是本机的某个IP地址,或者是广播地址,即该数据报是发送给本机的,则IP模块就根据数据报头部中的协议字段来决定将它派发给哪个上层应用(分用)。如果IP模块发现这个数据报不是发送给本机的,则也调用数据报转发子模块来处理该数据报。
数据报转发子模块将首先检测系统是否允许转发,如果不允许,IP模块就将数据报丢弃。如果允许,数据报转发子模块将对该数据报执行一些操作,然后将它交给IP数据报输出子模块。我们将在后面讨论数据报转发的具体过程。
IP数据报应该发送至哪个下一跳路由(或者目标机器),以及经过哪个网卡来发送,就是IP路由过程,即图中“计算下一跳路由”子模块。IP模块实现数据报路由的核心数据结构是路由表。这个表按照数据报的目标IP地址分类,同一类型的IP数据报将被发往相同的下一跳路由器(或者目标机器)。我们将在后面讨论IP路由过程。
IP输出队列中存放的是所有等待发送的IP数据报,其中除了需要转发的IP数据报外,还包括封装了本机上层数据(ICMP报文、TCP报文段和UDP数据报)的IP数据报。
图中的虚线箭头显示了路由表更新的过程。这一过程是指通过路由协议或者route命令调整路由表,使之更适应最新的网络拓扑结构,称为IP路由策略。
路由表更新
路由表必须能够更新,以反映网络连接的变化,这样IP模块才能准确、高效地转发数据报。route命令可以修改路由表。
通过route命令或其他工具手工修改路由表,是静态的路由更新方式。对于大型的路由器,它们通常通过BGP (Border Gateway Protocol,边际网关协议)、RIP (RoutingInformation Protocol,路由信息协议)、OSPF等协议来发现路径,并更新自己的路由表。这种更新方式是动态的、自动的。
IP转发
前文提到,不是发送给本机的P数据报将由数据报转发子模块来处理。路由器都能执行数据报的转发操作,而主机一般只发送和接收数据报,这是因为主机上/proc/sys/net/ipv4/ip_forward 内核参数默认被设置为0。我们可以通过修改它来使能主机的数据报转发功能
对于允许IP数据报转发的系统(主机或路由器),数据报转发子模块将对期望转发的数据报执行如下操作:
- 检查数据报头部的TTL值。如果TTL值已经是0,则丢弃该数据报。
- 查看数据报头部的严格源路由选择选项。如果该选项被设置,则检测数据报的目标IP地址是否是本机的某个IP地址。如果不是,则发送一个ICMP源站选路失败报文给发送端。
- 如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的下一跳路由器。
- 将TTL值减1。
- 处理IP头部选项。
- 如果有必要,则执行IP分片操作。
重定向
ICMP重定向
格式如下所示:
ICMP重定向报文的数据部分含义很明确,它给接收方提供了如下两个信息:
- 引起重定向的IP数据报的源端IP地址。
- 应该使用的路由器的IP地址。
接收主机根据这两个信息就可以断定引起重定向的P数据报应该使用哪个路由器来转发,并且以此来更新路由表(通常是更新路由表缓冲,而不是直接更改路由表)。
IPV6
这里不阐述了