TCP SACK 介绍 转载
一、SACK选项
默认情况下TCP采取的是累积确认机制,这时如果发生了报文乱序到达,接收方只会重复确认最后一个按序到达的报文段,为此发送方的处理只能是重复按序到达接收方的报文段之后的那个报文段,因而它无法准确知道哪些报文段到达了,哪些没有到达。
考虑以下情景,发送方的窗口状态如下:
如上图所示,主机A通过TCP发送10个长度都为100字节的报文段给主机B,其序号分别为0,100,200,300,400,500,600,00,800,900(图中以数字0-9代替)。主机B收到了序号为0和序号为100的报文段,但是序号为200,300,400的丢失了。之后主机B又收到了报文段500,600,700,800,900。当收到后续这些分组时,主机B只能对报文段100继续进行确认,即发送确认号为200的ACK。主机A收到这样的确认时,能重传的唯一报文段就是报文段200,在报文段200的确认被收到之前发送窗口是无法移动的,这时状况就会很糟糕,发送方每重传一个丢失的报文段,接收方就确认一个(由于是累积确认的,所以情况可能更糟,接收方每次都在等待一段时间后才发送确认),然后发送窗口向前移动一个,这个过程一直持续到报文段200,300,400都被接收方到。显然这种工作方式效率很低,降低了吞吐量。
SACK是TCP选项,它使得接收方能告诉发送方哪些报文段丢失,哪些报文段重传了,哪些报文段已经提前收到等信息。根据这些信息TCP就可以只重传哪些真正丢失的报文段。
需要注意的是只有收到失序的分组时才会可能会发送SACK,TCP的ACK还是建立在累积确认的基础上的。也就是说如果收到的报文段与期望收到的报文段的序号相同就会发送累积的ACK,SACK只是针对失序到达的报文段的。
SACK包括了两个TCP选项,一个选项用于标识是否支持SACK,是在TCP连接建立时时发送;另一种选项则包含了具体的SACK信息。
1.SACK允许选项
该选项格式如下所示:
它的工作机制类似于窗口扩大选项和事件戳选项,只能应用于SYN报文段,在连接建立阶段,主动发起连接的一方在它的SYN中指定选项。只有在它从另一方的SYN中收到了这个选项之后,FAK机制才会被使能。
2.SACK选项
SACK选项的格式如下图所示:
该选项长度可变,但由于整个TCP选项长度不超过40字节,所以实际最多不超过4组边界值。
该选项参数告诉发送哪些报文段是已经接收到并缓存的不连续的报文段,发送方可根据此信息检查究竟是哪个块丢失,从而发送相应的报文段。
- LeftEdgeofBlock:不连续块的第一个报文段的序列号
- RightEdgeofBlock:不连续块的最后一个报文段的序列号之后的序列号。
3.SACK的产生
SACK由接收方产生并通告给发送方,其产生有以下几种情形:
3.1中间有丢包或延迟时的SACK
如果接收方接收到的报文段序号大于所期待的序号,说明有报文段被丢弃或者出现了大的延迟,此时可以发送SACK通知发送方。
为反映接收方的接收缓存和网络传输情况,SACK中的第一个块必须描述是那个报文段触发了该SACK的发送,接收方应该尽可能地在SACK选项部分中填写尽可能多的块信息,让发送方能了解当前网络传输情况的最新信息。
3.2对重复发送包的SACK(D-SACK)
RFC2883中对SACK进行了扩展。SACK中的信息描述的是收到的报文段,这些报文段可能是正常接收的,也可能是重复接收的,通过对SACK进行扩展,D-SACK可以在SACK选项中描述它重复收到的报文段。但是需要注意的是D-SACK只用于报告接收端收到的最后一个报文与已经接收了的报文的重复部分,比如(来自RFC):
Transmitted Received ACK Sent
Segment Segment (Including SACK Blocks)
500-999 500-999 1000
1000-1499 (data packet dropped)
1500-1999 (delayed)
2000-2499 (data packet dropped)
2500-2999 (delayed)
3000-3499 (data packet dropped)
3500-3999 3500-3999 1000, SACK=3500-4000
1000-1499 (data packet dropped)
1500-2999 1500-1999 1000, SACK=1500-2000, 3500-4000
2000-2499 1000, SACK=2000-2500, 1500-2000, 3500-4000
1500-2999 1000, SACK=1500-2000, 1500-3000, 3500-4000
可以看出最后一个SACK的第一个块是一个D-SACK,它包含的范围是1500-2000,而不是1500-2500。
在D-SACK使用了SACK同样的工作过程,它只是SACK的一个协议扩展。当使用D-SACK时,选项中的第一个字段的含义是“重复收到的报文段的序号”。其规则:
- length后的第一个block(也就是第一个4字节)将包含重复收到的报文段的序号。
- 如果D-SACK报告的报文段的序号在累积确认的报文段之后(并且不是期望收到的报文段,因为这是SACK工作的基础,也是D-SACK的基础),则在这个SACK选项中跟在D-SACK之后的第一个非D-SACK块将按照SACK的格式描述该报文段(被D-SACK确认的报文段,但是它所报告的可能比D-SACK报告的大,比如例子中的最后一个S-ACK)
- 跟在D-SACK之后的SACK将按照SACK的方式工作。
- 如果有多个被重复接收的报文段,则D-SACK只包含其中第一个。
如果收到了D-SACK,就表明接收方接收到了重复的报文段,这可能意味着网络中出现了复制或者是发送方过早重传了,或者是ACK丢失导致了不必要的重传。
4.发送方对SACK的响应
TCP的发送方(实际上也就是连接的双方,因为TCP是全双工的)需要维护一个未被确认的重传报文段队列,报文段未被确认前是不能释放的。重传送队列中的每个报文段都有一个标志位“SACKed”标识该报文段是否被SACK过,对于已经被SACK过的块,在重传时将被跳过。
发送方根据接收到的SACK的信息设置重传队列中的报文段的sacked标记。
当支持D-SACK时,发送方通过如下方式来判断是一个SACK还是一个D-SACK:
- 如果SACK中的第一个block指定的序列号小于被累积确认的最后一个序列号,则是一个D-SACK
- 如果SACK中的第一个block指定的序列号落在了其后的block描述的某个范围之内(因为SACK的格式是用两个值描述一个报文段的序号范围),则就是一个D-SACK。
TCP SACK 介绍 转载的更多相关文章
- Python基础教程之udp和tcp协议介绍
Python基础教程之udp和tcp协议介绍 UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但 ...
- Linux内核中TCP SACK机制远程DoS预警通告
漏洞描述 2019年6月18日,RedHat官网发布报告:安全研究人员在Linux内核处理TCP SACK数据包模块中发现了三个漏洞,CVE编号为CVE-2019-11477.CVE-2019-114 ...
- 关于Linux TCP "SACK PANIC" 远程拒绝服务漏洞的修复
Linux 内核被曝存在TCP "SACK PANIC" 远程拒绝服务漏洞(漏洞编号:CVE-2019-11477,CVE-2019-11478,CVE-2019-11479),攻 ...
- VPN理论简单介绍(转载)
标签:VPN理论简单介绍 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lvnian.blog.51cto.com/715528 ...
- 【NS2】各种TCP版本 之 TCP Tahoe 和 TCP Reno(转载)
实验目的 学习TCP的拥塞控制机制,并了解TCP Tahoe 和 TCP Reno的运行方式. 基础知识回顾 TCP/IP (Transmission Control Protocol/Interne ...
- 基于Socket的UDP和TCP编程介绍
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- Linux各目录及每个目录的详细介绍(转载)
[常见目录说明] 目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里. /etc 存放系统管理和配置文件 /home 存放所有用户文件的根目录,是用户主目录的基点 ...
- IPv4和IPv6简单对比介绍(转载)
原链接:https://baijiahao.baidu.com/s?id=1570208896149974&wfr=spider&for=pc 在配置计算机网络,特别是内网的时候,有时 ...
- python正则表达式re模块详细介绍--转载
本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以是Unicode字符,这点不用担心,python会处理地和Ascii字符一样漂亮. 正则表达式使用反斜杆( ...
随机推荐
- (三)第一个 Hibernate项目
1.创建java工程,并导入hibernate所需要的jar包 2.通过IDE构建一个基础的Hibernate工程. 产生 hibernate.cfg.xml的框架总配置文件. H ...
- java 传入用户名和密码并自动提交表单实现登录到其他系统
不用单点登录,模拟远程项目的登录页面表单,在访问这个页面的时候自动提交表单到此项目的登录action,就可以实现登录到其他系统. ssh框架项目 1.以下是本地系统的action代码: import ...
- Go map使用
前言 map 是在 Go 中将值(value)与键(key)关联的内置类型.通过相应的键可以获取到值. 在一个map里所有的键都是唯一的,而且必须是支持==和!=操作符的类型,切片.函数以及包含切片的 ...
- js 四 windows对象
1 window 对象 1 window对象的属性 window对象的属性,又都是对象类型的 1 screen 对象 访问screen 对象 et: console.log(window.screen ...
- MySQL操作规范总结
来源:静以致远√团团 用户权限管理创建用户命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password';说明:Username所创建的用户名hos ...
- Tornado目录
第一篇:白话tornado源码之一个脚本引发的血案 第二篇:白话tornado源码之待请求阶段 第三篇:白话tornado源码之请求来了 第四篇:白话tornado源码之褪去模板外衣的前戏 第五篇:白 ...
- SPI学习笔记1
SPI 简介 SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口.是 Motorola首先在其 MC68HCXX 系列处理器上定义的. SPI ...
- 搭建简单的mongod服务器
1.首先,创建一个叫做mongodb_simple的目录,进入到目录中. 2.创建文件夹:data,用来存储数据库的数据文件. 3.创建文件夹:log,用来存储数据库的日志文件. 4.创建文件夹:bi ...
- Ubuntu系统---NVIDIA 驱动安装
Ubuntu系统---NVIDIA 驱动安装 第一次安装“NVIDIA 驱动”,小小的激动,因为终于可以玩GPU了.预想一块GPU,盼望太久,差点放弃,感谢J姐让我捡个漏.但是,第一次新的试错过程,网 ...
- CSRF(cross-site request forgery )跨站请求攻击
CSRF(cross-site request forgery )跨站请求伪造,攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,通过 ...