IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> TCP序列号回绕问题 -> 正文阅读

[网络协议]TCP序列号回绕问题

我求求你们能别抄来抄去的吗?每次搜个问题全是重复的博客!

参考:

  • http://m.blog.chinaunix.net/uid-24683784-id-5746959.html
  • https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/description-tcp-features

简介

这篇笔记记录了TCP如何处理序列号回绕问题。

措施

主要有两种措施用于解决序列号回绕问题:

  • 限制TCP窗口大小
  • 时间戳机制

限制TCP窗口大小

处理回绕问题的关键在于,在回绕发生时,如何判断两个序列号的先后关系

在内核中,判断先后关系的代码如下:(代码在Linux源码的include/net/tcp.h)

   266 /*
   267  * The next routines deal with comparing 32 bit unsigned ints
   268  * and worry about wraparound (automatic with unsigned arithmetic).
   269  */
   270 
   271 static inline bool before(__u32 seq1, __u32 seq2)
   272 {
   273         return (__s32)(seq1-seq2) < 0;
   274 }
   275 #define after(seq2, seq1)   before(seq1, seq2)

可以看到,内核中判断两个序列号的先后关系实现得非常简单,相减然后强转成有符号32位整数,然后判断是否小于0即可。

通过一个例子来看这个方法的正确性,TCP序列号是一个32位无符号整数,范围是[0, 4294967295],现在假设要比较两个序列号:

  • seq1 = 4294967295
  • seq2 = 4294967296,超过了可表示的范围,回绕为0

调用before(seq1, seq2)时,seq1-seq2的结果是4294967295,然后强制转换成有符号整数,4294967295 转换成了-1,小于0,于是函数输出seq1在seq2前面,这和真实情况一致。

不过这种比较是有条件的,例如,仍然取:

  • seq1 = 4294967295
  • seq2 = 4294967296 + 4294967294,超过了可表示的范围,回绕为4294967294

这次before(seq1,seq2)返回的结果就与事实不符了。

上面的算法能使用的前提是:回绕的范围不能太大。

准确地说,回绕的范围不能超过2**31,或者说,回绕之后的值,一定要小于2**31

那这个前提在TCP里面能满足吗?

可以!TCP窗口的最大值是1GB = 2**30 B < 2**31 B 所以使用上面的算法在实际情况中能够解决TCP的回绕问题,正确地区分出哪个序列号在前,哪个在后。

时间戳机制

理论上来说,上面的算法可以区分两个序列号,但是实际上可能出现这样的情况:

  • 客户端发送了一个包A给服务器,序列号范围在[seq1, seq2]之间

  • 由于网络原因,这个包A过了很久都没有到达服务器

  • 服务器流量很大,序列号回绕了一次,序列号范围又回到了[seq1, seq2]

  • 包A历经千辛万苦终于到达服务器

  • 问题来了:这个包A是当前的有效包?还是回绕之前的包?

这个问题可以使用时间戳来解决,通过判断报文段的时间戳,可以判断报文段是否是过时的。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-10-06 12:35:11  更:2021-10-06 12:36:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年9日历 -2024/9/21 9:17:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码