IP协议详解——Linux高性能服务

IP协议是TCP.IP协议族的核心协议,也是socket网络编程基础之一。

IP服务的特点

IP协议是TCP/IP协议族的动力,为上层提供无状态、无连接、不可靠的服务。
无状态:IP通信双方不同步传输数据的状态信息,使得所有IP数据报的发送、传输、接收相互独立。

  • 缺点:无法处理乱序的、重复的数据报(因为IP数据报之间没有任何联系,接收端只要接收到完整IP数据报/IP分片的重组,就将数据部分【TCP报文段、UDP数据报或ICMP数据报】给上层协议),从上层看数据是乱序/重复的。
  • 优点:简单、高效。不需要为保持通信状态分配内核资源、不需要每次传输数据携带状态信息
  • 使用:UDP协议、HTTP协议都是无状态协议。对于HTTP而言,一个浏览器的连续几次访问网页间没有关联,都被Web服务器独立处理。

无连接:IP通信双方都不长久地维持对方的任何信息,上层协议每次发送数据时都必须明确指定对方的IP地址。
不可靠:IP协议无法保证IP数据报准确送到接收端,只是承诺尽最大努力。使IP报发送失败情况:

  • 某中转站发现数据报在网络上存活时间过长,丢弃并返回ICMP错误消息给发送端(超时错误)
  • 接收端经过校验机制发现收到的IP数据报不正确,丢弃并返回ICMP错误信息给发送端(IP头部参数错误)

所以使用IP服务的上层协议要自己进行数据确认、超时重传等机制达到可靠传输。

IPV4头部结构

  • 4位版本号指定IP协议的版本。对IPv4来说,其值是4.其他IPv4协议的扩展版本(如SIP协议和PIP协议),则具有不同的版本号(头部结构也与上图不同)
  • 4位头部长度标识IP头部有多少个32bit字【4字节】。因为4位最大能表示15,所以IP头部最长是60字节。
  • 8位服务类型(TOS)包括一个3位的优先权字段(现在已经被忽略),4位的TOS字段和1位保留字段(必须置0)。4位的TOS字段分别表示:最小延时、最大吞吐量、最高可靠性和最小费用。其中最多有一个能置为1,应用程序应该根据实际需要来设置它。比如像ssh和telnet这样的登录程序需要的是最小延时的服务,而文件传输程序ftp则需要最大吞吐量的服务。
  • 16位总长度(是指整个IP数据报的长度,以字节为单位,因此IP数据报的最大长度为65535 (216-1)字节。但由于MTU的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP数据报(或分片)的长度都远远没有达到最大值。后面3个字段描述了如何实现分片。
  • 16位标识唯一地标识主机发送的每一个数据报。其初始值由系统随机生成:每发送一个数据报,其值就加1。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值
  • 3位标志字段的第一位保留。第二位(DF) 表示“禁止分片”。如果设置了这个位,IP 模块将不对数据报进行分片。在这种情况下,如果IP数据报长度超过MTU的话,IP 模块将丢弃该数据报并返回一个ICMP差错报文。第三位(MF)表示“更多分片”。除了数据报的最后一个分片外,其他分片都要把它置1。
  • 13位分片偏移是分片相对原始IP数据报开始处(仅指数据部分)的偏移。实际的偏移值是该值左移3位(乘8)后得到的。由于这个原因,除了最后一个IP分片外,每个IP分片的数据部分的长度必须是8的整数倍(这样才能保证后面的IP分片拥有一个合适的偏移值)。
  • 8位生存时间(TTL)是数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置(常为64)。数据报在转发过程中每经过一个路由,该值就被路由器减1。当TTL值减为0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文。TTL值可以防止数据报陷人路由循环
  • 8位协议(protocol) 用来区分上层协议,/etc/protocols 文件定义了所有上层协议对应的protocol字段的数值。其中,ICMP是1, TCP是6,UDP是17. /etc/protocols文件是RFC 1700的一个子集。
  • 16位头部校验和(header checksum)由发送端填充,接收端对其使用CRC算法来检验IP数据报头部在传输过程中是否损坏。
  • 32位的源端IP地址和目的端IP地址用来标识数据报的发送端和接收端。一般情况下,这两个地址在整个数据报的传递过程中保持不变,而不论它中间经过多少个中转路由器。
  • IPv4最后一个选项字段是可变长的可选信息。这部分最多包含40字节,因为IP头部最长是60字节(其中包含前面20字节的固定部分)。可用的IP选项包括:记录路由、时间戳、松散源路由选择、严格源路由选择。

记录路由:告诉数据报途经的所有路由器都将自己的IP地址填人IP头部的选项部分,这样我们就可以跟踪数据报的传递路径。
时间戳:告诉每个路由器都将数据报被转发的时间(或时间与IP地址对)填人IP头部的选项部分,这样就可以测量途经路由之间数据报传输的时间。
松散源路由选择:指定一个路由器IP地址列表,数据报发送过程中必须经过其中所有的路由器。
严格源路由选择:和松散源路由选择类似,不过数据报只能经过被指定的路由器。

dcpdump观察IPV4头部结构

可执行telnet命令登陆本机。注意telnet服务器程序使用的端口是23,telnet客户端程序使用临时端口号41621与服务器通信。

若没有下载telnet使用yum install telnet下载

抓包操作:

抓取的数据包:

抓包使用了-x选项,输出为数据包的二进制码。数据包包含60字节,其中前20字节IP头部,后40字节TCP头部,不包含应用程序数据:

发现:telnet服务选择使用最小延时的服务,默认传输层协议为TCP协议。

IP分片

我们知道,当IP数据报长度超过MTU时会被分片传输。分片可能发生在发送端,也可能在中转路由器上,且在传输过程中可能被多次分片。最终在目标机器上这些分片才会被内核中的IP模块重新组装
IP头部中的数据报标识、标志和片偏移为IP的分片和重组提供了足够信息。一个IP报每个分片都有自己的IP头部,具有相同的标识值,不同的片偏移。除最后一个分片,每个分片都设置为MF标志,每个分片的IP头部总长度字段被设置为该分片长度。
以太网帧的MTU为1500字节,出去IP头部占用20字节,携带的IP数据报数据部分最多为1480字节。
如下图,用IP数据报封装一1481字节的ICMP报文(8字节的ICMP头部)

第一个IP分片并非最后一个分片,头部需要设置MF;IP模块组合ICMP报文时只需要一份ICMP头部即可。

IP路由

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

IP模块工作流程


IP模块接收到数据链路层的IP数据报时首先对数据报头部进行CRC校验,无误便分析头部具体信息。
若该IP数据报头部设置了源站选路选项/数据报不是发给本机的,则IP模块调用数据报转发(子模块)处理该数据报;若头部中目标IP为本机某地址/广播地址,那么数据报是发给本机的,IP模块就根据数据报头部中协议字段决定将其派发给哪个上层应用(分用)。
数据转发子模块检测系统是否允许转发,若不允许,IP模块将数据报丢弃;若允许,进行一些操作后将其交给IP报输出(子模块)
IP数据报应该发送至哪个下一跳路由/目标机器,以及经过哪个网卡来发送,就是IP路由过程,即图中“计算下跳路由”子模块。IP 模块实现数据报路由的核心数据结构是路由表。这个表按照数据报的目标IP地址分类,同一类型的IP数据报将被发往相同的下一跳路由器/目标机器。

路由机制

route/netstat命令查看路由表。

第一个目标地址default,默认路由项;路由项标志中含G,即路由的下一跳为网关,地址:192.168.1.1。
另一路由项目标地址192.168.1.0,指的是本地局域网,网关地址*则数据报不需要中转,可直接发送到目标机器。
内容及含义:

路由表是如何按照IP地址分类的呢?或者说给定数据报的目标IP地址,它将匹配路由表中的哪一项呢?这就是IP的路由机制,分为3个步骤:

  1. 查找路由表中和数据报的目标IP地址完全匹配的主机IP地址。如果找到,就使用该路由项,没找到则转下一步.
  2. 查找路由表中和数据报的目标IP地址具有相同网路ID的网络IP地址(如上表中的第二项)。如果找到,就使用该路由项,没找到则转下一步。
  3. 选择默认路由器,这时数据报的下一跳路由是网关。
路由表更新

路由表更新才能反映网络连接的变化,IP模块才能准确高效的转发数据报。
通过route命令或其他工具手工修改路由表,是静态的路由更新方式。对于大型的路由器,它们通常通过BGP (,边际网关协议). RIP (路由信息协议)、 OSPF等协议来发现路径,并更新自已的路由表。这种更新方式是动态的、自动的。

IP转发

路由器一般都能执行数据报的转发操作,主机一般只发送和接受数据报,这是因为主机上/proc/sys/net/ipv4/ip_forward内核参数默认为0【可以修改他使主机有数据报转发功能】

echo 1 > /proc/sys/net/ipv4/ip_forward

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

  1. 检查数据报头部的TTL值。如果TTL值已经是0,则丢弃该数据报。
  2. 查看数据报头部的严格源路由选择选项。如果该选项被设置,则检测数据报的目标IP地址是否是本机的某个IP地址。如果不是,则发送-一个ICMP源站选路失败报文给发送端。
  3. 如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的下一跳路由器
  4. 将TTL值-1
  5. 处理IP头部选项
  6. 若有必要,执行IP分片操作
重定向
ICMP重定向报文

ICMP重定向报文格式:

ICMP重定向报文类型值为5,代码字段有4个可选值,从而区分不同重定向类型。
主机重定向代码值为1。
ICMP重定向报文的数据部分含义很明确,给接收方提供两个信息:

  • 引起重定向的IP数据报(图中原始IP数据报)的源端IP地址。
  • 应该使用的路由器的IP地址。

接受主机根据上面信息断定重定向的IP数据报应使用哪个路由器转发,以此更新路由表(更新路由表缓存而不直接更新路由表)
一般情况下,主机只能接收ICMP重定向报文,路由器只能发送ICMP重定向报文

主机重定向实例

机器ernest-laptop网关为kongming20,且后者可以进行数据报转发,因此ernest-laptop通过kongming20访问因特网

主机ernest-laptop收到ICMP重定向报文后更新路由表缓冲,用新的路由方式发送后续数据报

IPv6头部结构

IPv6协议在解决IPv4地址不够用问题的基础上,做了很大改进(eg:增加多播和流的功能,为网络上多媒体内容的质量提供精细的控制;引入自动配置功能,让局域网管理更方便;增加了专门的网络安全功能)

IPv6固定头部结构


4位版本号 指定IP协议的版本。对IPv6来说,其值是6。
8位通信类型指示数据流通信类型或优先级,和IPv4中的Tos类似。
20位流标签是IPv6新增加的字段,用于某些对连接的服务质量有特殊要求的通信,比如音频或视频等实时数据传输。
16位净荷长度指的是IPv6扩展头部和应用程序数据长度之和,不包括固定头部长度。
8位下一个包头指出紧跟IPv6固定头部后的包头类型,如扩展头(如果有的话)或某个上层协议头(eg:TCP, UDP,ICMP)。它类似于IPv4头部中的协议字段,且相同的取值有相同的含义。
8位跳数限制和IPv4中的TTL含义相同。
IPv6用128位来表示IP地址,使得IP地址的总量达到了2128个。
32位表示的IPv4地址一般用点分十进制来表示,而IPv6地址则用十六进制字符串表示,比如“FE80:0000:0000:0000:1 234:5678:0000:0012”。可见,IPv6地 址用“:”分割成8组,每组2字节但这种方式过于麻烦。通常用零压缩法将其简写,也就是省略连续的、全零的组。比如,上面的例子使用零压缩法可表示“FE80::1 234:5678:0000:0012”.不过零压缩法对一个IPv6地址只能使用一次, 比如上面的例子中,字节组“5678"后面的全零组就不能再省略,否则我们就无法计算每个“::”之间省略了多少个全零组。

IPv6拓展头部结构

可变长的扩展头部使得IPv6能支持更多的选项,并且很便于将来的扩展需要。它的长度可以是0,表示数据报没使用任何扩展头部。一个数据报可以包含多个扩展头部,每个扩展头部的类型由前一个头部(固定/扩展)中的下一个报头字段指定。目前可以使用的扩展头部如表:

最后,IPv6并非是IPv4的简单扩展,他是完全独立的协议。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值