【读书笔记】Linux高性能服务器编程(第一篇 第二章)

第二章 IP协议详解

2.1 IP服务特点

IP头部信息:IP头部信息出现在每个IP数据报中,用于指定IP通信的源端IP地址,目的端IP地址,指导IP分片和重组,以及指定部分通信行为。

IP数据报的路由和转发:IP数据报的路由和转发发生在除目标机器之外的所有主机和路由器上。它们决定数据报是否应该转发以及如何转发

IP协议是TCP/IP协议族的动力,它为上层提供无状态,无连接,不可靠的服务

无状态(stateless):指IP通信的双方不同步传输数据的状态信息,因此所有IP数据报的发送,传输和接收都是相互独立,没有上下文关系的。IP通信的最大缺点是无法处理乱序和重复的IP数据报。

接收端的IP模块只要收到了完整的IP数据报(如果是IP分片的话,IP模块将先执行重组),就将其数据部分(TCP报文段,UDP报文段和ICMP报文)上交给上层协议;虽然IP数据报头部提供了一个标识字段用以唯一标识一个IP数据报,但它是被用来处理IP分片和重组的,而不是用来指示接受顺序的。

TCP协议能够自己处理乱序的,重复的报文段,TCP递交给上层协议的内容绝对是有序的正确的。

无状态服务的优点:简单,高效。(不用为保持通信的状态而分配内核资源,也不用每次传输数据时都携带状态信息)

UDP,HTTP协议都是无状态协议

无连接(connectionless):IP通信双方都不长久地维持对方的任何信息,上层协议每次发送数据时,都必须指定对方的IP地址。

不可靠:IP协议不能保证IP数据报准确地到达接收端。

很多情况都能导致IP数据报发送失败,如:

1.某个中专路由器发现IP数据报在网络上存活的时间太长(根据TTL判断),那么它将丢弃之,并返回一个ICMP错误消息(超时错误)给发送端。

2.接收端发现收到的IP数据报不正确(通过校验机制),它也将丢弃之,并返回一个ICMP错误消息(IP头部参数错误)给发送端。

无论什么情况,发送端的IP模块一旦检测到IP数据报发送错误,就通知上层协议发送失败,而不会试图重传。因此,使用IP服务的上层协议(例如:TCP)需要自己实现数据确认,超时重传等机制以达到可靠传输的目的。

 

2.2 IPv4头部结构

如图,长度最小20字节,除非含有可变长的选项部分

 

4位版本号:指定IP协议的版本,IPv4值为4(0100)

4位头部长度:标识该IP头部有多少个4字节。因为4位2进制最大为15,所以IP头部最长为15 * 4 = 60个字节 。

8位服务类型:包括一个3位的优先权字段(现已被忽略),4位的TOS字段和1位保留字段(必须设置为0)。

4位的TOS字段分别表示:最小延时,最大吞吐量,最高可靠性和最小费用。其中最多有一个能置为1。应用程序根据实际需要设置它。

例如:ssh和telnet这样的登录程序需要的是最小延时服务,而文件传输程序ftp则需要最大吞吐量服务。

16位总长度:指整个IP数据报的长度,以字节为单位,虽然最大长度为2^16-1个字节,但是MTU为1500字节,长度超过MTU的数据报都将被分片传输。

16位标识:唯一标识主机发送的每一个数据报。初始值由系统随机生成;每发送一个数据报,其值就加1,该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值

3位标志字段的第一位保留。第二位(Don’t Fragment,DF)表示禁止分片,如果设置为1,IP模块将不对数据报进行分片。在禁止分片的情况下,如果IP数据报长度超过了MTU,IP模块将丢弃该数据报并返回一个ICMP差错报文。

第三位(More  Fragment,MF)表示更多分片,除了数据报的最后一个分片外,其他分片都要把该位设置为1。

13位分片偏移:是分片相对原始IP数据报开始处(仅指数据部分)的偏移,实际的偏移值是该值左移3位(乘8)后得到的。因此,除了最后一个IP分片,每个IP分片的数据部分长度必须为8的整数倍(这样才能保证后面的IP分片拥有一个合适的偏移值)。

8位生存时间(Time To Live,TTL)是数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置,数据报在转发过程中每经过一个路由,该值就被路由器减1,当TTL值减为0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文,TTL可以防止数据报陷入路由循环。

8位协议:用来区分上层协议,/etc/protocols 文件定义了所有上层协议对应的protocol字段的数值,例:ICMP是1,TCP是6,UDP是17 。

16位头部校验和由发送端填充,接收端对其使用CRC算法以检验IP数据报头部(仅检验头部)在传输过程中是否损坏。

32位的源端IP地址和目的端IP地址用来标识数据报的发送端和接收端,一般情况下,这两个地址在整个传递过程中保持不变,而不论它中间经过多少个中转路由器。

IPv4最后一个选项字段是可变长的可选信息。这部分最多可包含40字节,因为IP头部最长是60字节。

可用选项:

1.记录路由:告诉数据报途经的所有路由器都将自己的IP地址填入头部的选项部分,这样我们就可以跟踪数据报的传递路径

2.时间戳:告诉每个路由器都将数据报被转发的时间(或时间与IP地址对)填入IP头部的选项部分,这样就可以测量途经路由之间的数据报传输的时间。

3.松散源路由选择:指定一个路由器IP地址列表,数据报发送过程中必须经过其中所有的路由器。IP包必须沿着这些IP地址传送,但是允许在相继的两个IP地址之间跳过多个路由器。

4.严格源路由选择:和松散源路由选择类似,不过数据报只能经过被指定的路由器。IP包必须沿着这些IP地址传送,如果下一跳不在IP地址表中则表示发生错误。


typedef struct _iphdr //定义IP首部

{  

unsigned char h_lenver; //4位首部长度+4位IP版本号  

unsigned char tos;  //8位服务类型TOS  

unsigned short  total_len;  //16位总长度(字节)  

 unsigned short ident;  //16位标识  

unsigned short  frag_and_flags; //3位标志位  

unsigned char ttl; //8位生存时间 TTL  

unsigned char proto; //8位协议 (TCP, UDP 或其他)  

unsigned short checksum; //16位IP首部校验和  

unsigned int sourceIP; //32位源IP地址 

unsigned int destIP; //32位目的IP地址  

}IP_HEADER;

 


2.3 IP分片

当IP数据报的长度超过帧的MTU时,将被分片传输。

分片可能发生在发送端,也可能发生在中转路由器上,而且可能在传输过程中被多次分片,但是只有在最终的目标机器上,这些分片才会被内核中的IP模块重新组装。

一个IP数据报的每个分片都具有自己的IP头部,它们具有相同的数据报标识值,但是具有不同的片偏移,除了最后一个分片,其它分片都将设置MF标志,每个分片的IP头部的总长度字段将被设置为该分片的长度。

MTU最大值为1500字节,因此携带的IP数据报的数据部分最多1480字节(IP头部占用20字节)。

例题:

考虑用IP数据报封装一个1481字节的ICMP报文(包括8字节的ICMP头部,所以其数据部分长度为1473字节),传输时需要分片

解答:

如图:



注意:IP层传递给数据链路层的数据可能是一个完整的IP数据报,也可能是一个IP分片,统称为IP分组。


2.4路由


IP协议的一个核心任务是数据报的路由,即决定发送数据报到目标机器的路径。


2.4.1 IP模块工作流程

如图:


当IP模块接收到来自数据链路层的IP数据报时,它首先对该IP数据报的头部做CRC校验,确认无误之后就分析其头部的具体信息。

1.如果该IP数据报的头部设置了源站选路选项(松散源路由选择或严格源路由选择),则IP模块调用数据报转发子模块来处理该数据报。

2.如果该IP数据报是发送给本机的,则IP模块就根据数据报头部中的协议字段来决定将它派发给哪个上层应用(分用)。

3.如果IP模块发现这个数据报不是发送给本机的,则也调用数据报转发子模块来处理该数据报。

数据报转发子模块将首先检测系统是否允许转发,如果不允许,IP模块就将数据报丢弃

如果允许,数据报转发子模块将对该数据报执行一些操作,然后将它交给IP数据报输出子模块


IP数据报应该发送至哪个下一跳路由(或者目标机器),以及经过哪个网卡来发送,就是IP路由过程,即图中“计算下一跳路由”子模块。


IP模块实现数据报路由的核心数据结构是路由表


所谓路由表,指的是路由器或者其他互联网网络设备上存储的表,该表中存有到达特定网络终端的路径,在某些情况下,还有一些与这些路径相关的度量。

路由表建立的主要目标是为了实现路由协议和静态路由选择。

这个表按照数据报的目标IP地址分类,同一类型的IP数据报将被发往相同的下一跳路由器(或者目标机器)。

IP输出队列中存放的是所有等待发送的IP数据报,其中除了需要转发的IP数据报外,还包括封装了本机上层数据(ICMP数据报,TCP数据报,UDP数据报)的IP数据报。

虚线箭头显示了路由表更新的过程,这一过程是指通过路由协议或者route命令调整路由表,使之更适应最新的网络拓扑结构,称为IP路由策略。

 

2.4.2路由机制


问题:路由表是如何按照IP地址分类的?或者说给定数据报的目标IP地址,它将匹配路由表中的哪一项?


1.查找路由表中和数据报的目标IP地址完全匹配的主句IP地址;如果找到,就使用该路由项;没找到则转步骤2


2.查找路由表中和数据报的目标IP地址具有相同网路ID的网络IP地址(如2-2所示路由表中的第二项),如果找到,就使用该路由项;没有则转步骤3


3.选择默认路由项,这通常意味着数据报的下一跳路由是网关。

 

2.4.3路由表更新

路由表必须能够更新,以反映网络连接的变化,这样IP模块才能准确,高效地转发数据报。

 

2.5 IP转发

不是发送给本机的IP数据报将由数据报转发子模块来处理。

路由器都能执行数据报的转发操作,而主机一般只发送和接收数据报,这是因为主机上/proc/sys/net/ipv4/ip_forward 内核参数默认被设置为0,我们可以通过修改它来使能主机的数据报的转发功能。

 

对于允许IP数据报转发的系统(主机或路由器),数据报转发子模块将对期望转发的数据报执行如下操作:

1.检查数据报头部TTL值,为0就丢弃。

2.查看数据报头部的严格源路由选择选项,如果该选项被设置,则检测数据报目标IP地址是否是本机的某个IP地址,如果不是,则发送一个ICMP源站选路失败报文给发送端。

3.如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的下一跳路由器。

4.将TTL值减1。

5.处理IP头部选项。

6.如果有必要,则执行IP分片操作。

 

2.6重定向

2.6.1 ICMP重定向报文

ICMP重定向报文格式如图:


8位类型字段用于区分报文类型,它将ICMP报文分为两大类:  一类是差错报文,这类报文主要用来回应网络错误(例如:目标不可到达(类型值为3)和重定向(类型值为5) )。

另一类是查询报文,这类报文用来查询网络信息(用ping程序就是使用ICMP报文查看目标是否到达(类型值为8) )。

有的ICMP报文还使用8位代码字段来进一步细分不同的条件。

ICMP报文使用16位校验和字段对整个报文(包括头部和内容部分)进行循环冗余校验(CRC),以检验报文在传输过程中是否损坏。

 

ICMP重定向报文的数据部分含义很明确,它给接收方提供了如下两个信息:

1.引起重定向的IP数据报的源端IP地址。

2.应该使用的路由器的IP地址。


接收主机根据这两个信息就可以断定引起重定向的IP数据报应该使用哪个路由器来转发,并且以此来更新路由表(通常是更新路由表缓冲,而不是直接更改路由表)。


一般来说,主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文。

 

2.7 IPv6头部结构


2.7.1固定头部结构


2.7.2扩展头部结构



注意:IPv6协议并不是IPv4协议的简单扩展,而是完全独立的协议,用以太网帧封装的IPv6数据报和IPv4数据报具有不同的类型值。

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值