《TCP/IP具体解释卷2:实现》笔记--IP的分片和重装
IP首部内有三个字段实现分片和重装:标识字段(ip_id)、标志字段(ip_off的3个高位比特)和偏移字段(ip_off的13个低位
比特)。标志字段由3个1bit标志组成。比特0是保留的必须为0,;比特1是“不分片”(DF)标志;比特2是“很多其它分片”(MF)标志。
Net/3中,标志和偏移字段结合起来,由ip_off訪问,例如以下图所看到的:
ip_off的其它13bit指出在原始数据报内分片的位置,以8字节为单位计算。因此,除最后一个分片外,其它的分片都希望是一个
8字节倍数的数据,从而使后面的分片从8字节边界開始。下图显示了在原始数据报内的字节偏移关系,以及在分片的IP首部内
分片的偏移。
除最后一个分片外,设置了其余分片的MF比特。
ip_id唯一地标识某个特定数据报的分片。源系统用同样的源地址(ip_src)、目的地址(ip_dst)和协议(ip_p)值,作为
数据报在互联网上生命期的值,把每一个数据报的ip_id设置成一个唯一的值。
1.分片
在ip_output函数(IP:网际协议章节)中,假设分组正好适合选定出接口的MTU,就在一个链路级帧中发送它。否则,必须对
分组分片,并在多个帧中将其发送,分组能够是一个完整的数据报或者它自己也是前边系统创建的分片。分片的代码主要
分三部分:
1.确定分片大小
假设DF被设置,则ip_output丢弃该分组,并返回,假设该数据报是在本地生成的,则运输层协议把该错误传回该进程,假设
分组是被转发的,则生成ICMP目的不可达差错报文。
Net/3没有实现“路径MTU发现”算法。
每一个新的分片中包括:一个IP首部,某些原始分组中的选项以及最多len长度的数据。当中len的计算是用接口的MTU减去分组
首部的长度后,去掉低位的3比特后成为8字节倍数。
2.构造分片表
从第二个分片開始构造分片表,在表生成后,原来的分组被转换成第一个分片(降低一次mbuf的生成),对于每个分片,
ip_output函数採取下面动作:
分配一个新的分组缓存
↓
从原来的分组中把IP首部和IP选项拷贝到新的分组,并非全部的选项都会被复制,假设IPOPT_COPIED指示copied比特被
置位,则会把选项拷贝到芯片中。
↓
设置MF比特和偏移字段(ip_off)
↓
为分片设置长度
↓
从原始分组中把数据拷贝到该分组中
↓
调整新创建的分片的mbuf分组首部,使其具有正确的全长,把新分片的接口指针清零,把ip_off转换成网络字节序,计算新
分片的检验和。将该分片通过mbuf的m_nextpkt与前面的分片链接起来。
3.构造第一个分片并发送分片
将末尾多余的数据截断后,原来的分组就被转换成第一个分片,同一时候设置MF比特、把ip_len和ip_off转换成网络字节序,计算
新的检验和。在这个分片中,保留全部的IP选项。在目的地址重装时,仅仅保留数据报的第一个分片的IP选项。某些选项,如
源路由选项,必须被拷贝到每一个分片中,即使在重装时都被丢弃了。
最后将每一个分片进行发送。在发送期间遇到全部错误都会使后面的分片被丢弃。
2.重装
ipintr重装分片,并把数据报整个地交给运输层处理。ipintr须要尝试把分片重装成一个完整的数据报。
Net/3在一个全局双向链表ipq上记录不完整的数据报。能够在链表的不论什么地方插入和删除,并不限制一定要在末尾。ipintr
函数对表进行线性搜索,为当前分片找到合适的数据报。记住分片是由4元组{ip_id、ip_src、ip_des和ip_p}唯一标识的。ipq
的每一个入口是一个分片表,假设ipintr赵大牌一个匹配,则fp指向匹配的表。ipq的数据结构例如以下:
很多工作是由ip_reass做的。假设ip_reass通过把当前分片与曾经收到的分片组合在一起,能重装成一个完整的数据报,它就返回
指向该重装好的数据报的指针。假设没有重装好,则ip_reass保存该分片,ipintr去处理下一个分片。
假设重装处理产生一个完整的数据包,ipintr就把这个完整的数据报上传给合适的运输层。
3.ip_reass函数
ipintr把一个要处理的分片和一个指针传给ip_reass,当中指针指向的是ipq中匹配的重装首部。ip_reass可能重装成功并返回
一个完整的数据报,可能把该分片链接到数据报的重装链表上,等待其它分片到达后重装。每一个重装链表的表头是一个ipq结构。
用来标识一个数据报分片的四个段,ip_id、ip_src、ip_dst和ip_p,被保存在每一个重装链表表头的ipq结构中。Net/3用next和prev
构造数据报链表,用ipq_next和ipq_prev构造分片的链表。
到达分组的IP首部被放到重装链表之前,首先被转换成一个ipasfrag结构。
ip_reass在一个由ipf_next和ip_prev连接起来的双向循环链表上,收集某个数据报的分片。下图显示了分片首部链表ipq和
分片ipasgrag之间的关系。
上图没有显示重装结构的全部复杂性。重装全然依靠把指针指向底层mbuf上的三个不同的结构。下图显示了mbuf、ipq结构、
ipasfrag结构和ip结构之间的关系。
图中含有大量的信息:
1.全部结构都放在一个mbuf的数据区内。
2.ipq链表由next和prev连接起来的ipq结构组成。每一个ipq结构保存了唯一标识一个IP数据报的四个字段。
3.当作为分片链表的头訪问时,每一个ipq结构被看成是一个ipasfrag结构。这些分片由ipf_next和ipf_prev链接起来,分别
覆盖了ipq结构的ipq_next和ipq_prev成员。
4.每一个ipasfrag结构都覆盖了到达分片的ip结构,与分片一起到达的数据在缓存中跟在该结构之后。
下图从逻辑的观点说明重装结构,该图显示了三个数据报的重装,以及ipq链表和ipasfrag结构之间的关系,阴影部分为缺少
的分片。
以下分几个部分说明重装
1.创建重装表
假设没有符合条件的ipq,则用新的数据报的第一个分片创建一个重装表。它分配一个mbuf来存放新表的头(一个ipq结构),
并把该结构插入到重装表的链表中。
2.重装超时
在Net/3中,使用生命期字段ipq_ttl来管理重超时,重装超过的初始值设置为60,每次内容调用ip_slowtimo时,ipq_ttl就减去1,
而内核每500ms调用ip_slowtimo一次。假设系统在接受到数据报的任一分片30秒后,还没有组装好一个完整的IP数据报,那么
系统就丢弃该IP重装链表。
3.数据报标识符
在目的主机上,分片包括的字节范围可能会互相覆盖,发生这样的情况的原因是,当一个运输层协议重传某个数据报时,採用
与原来数据报不同的路由,并且分片的模式也可能不同,这就导致在目的主机上的项目覆盖。传输协议必须强制IP使用原来
ID字段,确保目的主机识别该数据报是重传的。
Net/3并不为运输层协议提供机制保证在重传的数据报中重用IP ID字段。在准备新数据时,ip_output通过添加全局整数ip_id
来赋一个新值。虽然如此,Net/3系统也能让运输层用同样ID字段重传IP数据报的系统上接收重叠分片。
下图说明分片可能会以不同的方式与已经到达的分片重叠。分片是依照它们到达目的主机的顺序编号的,重装的分片在图底部
显示,分片的阴影部分是被丢弃的多余字节。
4.重建数据报首部
ip_reass把ip指向链表的第一个分片,将ipasfrag结构恢复成ip结构。并将整个分组从重装链表中移走,丢弃表头的ipq结构,
调整缓存中的m_len和m_data,将前面被隐藏起来的第一个分片的首部和选项包括进来。
5.计算分组长度
计算缓存链中数据的字节数,并把值保存在m_pkthdr.len中。
《TCP/IP具体解释卷2:实现》笔记--IP的分片和重装的更多相关文章
- 《TCP/IP具体解释卷2:实现》笔记--IP多播
D类IP地址(224.0.0.0到239.255.255.255)不识别互联网内的单个接口,但识别接口组,被称为多播组. 单个网络上的组成员利用IGMP协议在系统之间通信. 多播路由器用多播选录协议. ...
- 《TCP/IP具体解释卷2:实现》笔记--UDP:用户数据报协议
用户数据报协议.即UDP,是一个面向数据报的简单运输层协议:进程的每次输出操作仅仅产生一个UDP数据报,从而发送 一个IP数据报. 进程通过创建一个Internet域内的SOCK_DGRAM类型的插口 ...
- 《TCP/IP具体解释卷2:实现》笔记--协议控制块
协议层使用协议控制块(PCB)存放各UDP和TCP插口所要求的多个信息片.Internet协议维护Internet协议控制块 (internet protocol control block)和TCP ...
- 《TCP/IP具体解释卷2:实现》笔记--ICMP:Internet控制报文协议
ICMP在IP系统间传递差错和管理报文,是不论什么IP实现必须和要求的组成部分.能够把ICMP分成两类:差错和查询.查询报文 是用一对请求和回答定义的.差错报文通常包括了引起错误的IP包的第一个分片的 ...
- 《TCP/IP具体解释卷2:实现》笔记--IP:网际协议
本章介绍IP分组的结构和主要的IP处理过程,包含输入,转发和输出. 下图显示了IP层常见的组织形式. 在之前的文章中.我们看到了网络接口怎样把到达的IP分组放到IP输入队列ipintrq中去,并怎样调 ...
- TCP/IP具体解释--UDP数据报中的IP分片
1.UDP首部 2.UDP分片 在第二章,讲链路层是,提到过以太网.刨除数据帧帧头.最多传输的长度为1500.也就是说,假设一个ip数据报,长度大于1500,则须要分片. 分片方法: 在ip头中3位标 ...
- 《TCP/IP具体解释卷2:实现》笔记--接口层
接口层包含在本地网上发送和接收分组的硬件与软件. 我们用设备驱动程序来表示与硬件及网络接口通信的软件,网络接口是指在一个特定网络上硬件与设备驱动器之间的接口. Net/3接口层试图在网络协议和连接到一 ...
- 《TCP/IP具体解释卷2:实现》笔记--选路请求和选路消息
内核的各种协议并不直接使用前面提供的函数来訪问选路树,而是调用几个函数:rtalloc和rtallocl是完毕路由表查询的两个 函数:rtrequest函数用于加入和删除路由表项:另外大多数接口在接口 ...
- 《TCP/IP具体解释卷2:实现》笔记--域和协议
Net/3组把协议关联到一个域,而且用一个协议族常量来标识每一个域.Net/3还通过全部的编址方法将协议分组. 在一个域中 的每一个协议使用同类地址.而且每种地址仅仅被一个域使用.作为结果,一个域能通 ...
随机推荐
- bisect维护已排序的序列
#!/usr/bin/env python # -*- coding:utf-8 -*- # author:love_cat import bisect # 用来处理已经排序好的序列,升序 # 二分查 ...
- c# 防止重复运行 弹出已运行窗口并传递消息
最近在写一款软件 软件是用来接收其他程序传递过来的命令行,并形成列表 大概的最终效果就像下图一样 原本为了程序美观是打算用listbox自绘列表,字和图片都绘制好了发现自己不会绘制按钮 所以最终采用了 ...
- 正则表达式之Regex.Replace()用法
正则表达式替换匹配到的字符串 string txt = "AAA12345678AAAA"; //匹配到的连续数字的前4位用*替换 string m =Regex.Replace( ...
- C# web server的开发流程
http://blog.csdn.net/h0322/article/details/4776819
- centos 部署web项目
Linux下安装Tomcat服务器和部署Web应用 一.上传Tomcat服务器
- Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划
Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...
- Spring 依赖注入(控制反转)介绍
耦合性是软件工程中的一个重要概念.对象之间的耦合性就是对象之间的依赖性.对象之间的耦合越高,维护成本越高.因此对象的设计应使类和构件之间的耦合最小. spring Ioc思想 控制翻转也就是sprin ...
- [JZOJ3105]拼图
题目大意: 给你一个起始串$a(|a|\leq 300)$,一个目标串$b(|b|\leq 300)$,以及$n(n\leq 8)$个小串$s_0,s_2,\ldots,s_{n-1}(|s_i|\ ...
- JAVA和.NET工作流相关项目收集
.NET以自主实现为主, 暂未发现使用WWF框架开发的开源工作流, java以BPM系为主 . .NET: RoadFlow : http://www.cqroad.cn/ 使用了百度编辑器扩展 ...
- 【MySQL性能优化】MySQL常见SQL错误用法
https://yq.aliyun.com/articles/72501?utm_content=m_14899