网络(2) : 常用的TCP Option(MSS)

一、常用tcp options

TCP协议头:

下面简单介绍TCP OPTIONS,长度不定,但长度必须以是32bits的整数倍。常见的选项包括MSS、SACK、Timestamp等等,最初的TCP只定义了扩展头部结尾(EOL), 没有扩展头部(NOP),最大分段长度(MSS), 其他字段都是后期扩展的. 每一个扩展头部必须在一开始包含1Byte的类型说明和1Byte的长度说明.扩展头部结尾(EOL)的出现纯属是因为TCP报文必须32Bit对齐.

如下表:

1.EOL 字段

格式:

用EOL代表TCP选项列表字段的结束,是所以TCP选项的结束而不是每一个选项后都要加EOL。

使用情况:只有选项列表结束后没有与TCP header length所标注大小相同时使用。因此也不一定放在tcp头部的末尾.举个例子,假如Header Length指定的TCP头长为40bytes,其中第29-38bytes为TSOPT选项,则可以在第39byte处添加一个EOL选项指示选项列表结束,可以看到EOL并没有位于TCP头的结束位置的第40byte。对于最后一个byte RFC793协议规定需要以0来填充。注意这个EOL后面填充的0已经不属于TCP选项的一部分了。

2.NOP 字段

主要是用来补充其他选项对齐。可以用在其他选项之间,或者结尾。比如为了使3字节的WSOPT选项4字节对齐,在选项开始添加一个NOP选项填充。但是发送端斌并不保证对齐。

3.MSS字段

TCP期待从对端收到的最大报文长度。也是对端可以发送的报文长度,仅指TCP数据,不包含TCP和ip头部,双方在各自的SYN包中描述自己希望的MSS大小, 如果没有描述, 则默认为536Byte,

MSS代表的是TCP的负载数据的大小。RFC6691明确规定在MSS选项中传递的MSS值为MTU减去IP基本头(ipv4为20bytes,IPV6为40bytes)和TCP基本头(20bytes)的值,不考虑扩展头。发送端负责发送数据前在这个MSS值的基础上扣除扩展头长度得出真实传输数据的长度。

MSS 不是一种协商, 而是一种自己的上限, 自己不会再接受比MSS更大的报文。

4.WSOPT (最大可扩展14bit, 和原有的窗口拼接可以达到2^30Byte, 约为1GB)

我们在介绍TCP头结构的时候提到过Window Size字段,这个字段占16位,最大为2^16-1,在长肥管道中,当发送端TCP需要通告更大的接收窗口的时候,就需要通过WSOPT选项了。当使用WSOPT选项的时候,接收窗口的实际大小则为Window Size<<shift.cnt,其中shift.cnt按照协议最大只能为14,当接收端接收到的shift.cnt大于14的时候,则按照14来处理Window Size

        WSOPT选项只能在SYN包中发送,因此当TCP连接建立起来后,window scale就固定了。一般在TCP实现上会有一个最大接收缓存,进而决定了最大接收窗口和window scale。WSOPT选项将原有的16位Window Size扩展到近30位大小(大约1GB)可以有效提升TCP允许使用的接收缓存,进而提升长肥网络的性能。

        如果要使能window scale,需要发送端在SYN包中发送WSOPT选项,接收端在SYN-ACK包中同样发送WSOPT。注意协商window scale过程中协议要求不能对SYN和SYN-ACK报文头中的window size应用WSopt选项。WSOPT中的shift.cnt可以为0,标识window scale factor为1(即2^0=1),即接收窗口的实际大小即为Window Size。如果发送端发送了WSOPT选项但是没有收到对端的WSOPT选项,则需要将自己的window scale factor设置为1。

        发送端和接收端都各有一个接收窗口和一个发送窗口,因此总共四个窗口,共维护4个scale factor。假设发送端接收窗口的scale factor为R,发送窗口的scale factor为S,则对应的接收端的接收窗口scale factor为R,发送窗口scale factor为S。在协商好两端的scale factor后,之后接收到的数据包中的Window Size字段自动进行scale factor,发送出去的数据包中的这个字段则为实际接收窗口右移scale factor后的结果。

5.SACK

选择性确认功能有助于提升TCP传输的效率.双方会在握手时提供自己是否支持SACK的选项.每一个SACK会占用一对32bit空间, 因此会总共占用(2 + 8 * n)个字节, 扩展头部一般最多放3个选择确认区间.(假定现代TCP会通常使用Timestamp特性)

6.时间戳选项

每一个报文可以携带当前的时间戳, 当得到一个往返信息时, 节点可以计算最新的RTT.

因为常规的TCP连接对于一个窗口只会计算一次RTT, 使用时间戳选项后, TCP连接可以获得更加细粒度的RTT计算

时间戳的另外一个作用是防止先前的报文干扰,不常见的是, 时间戳还可以作为Seq序号的辅助. 考虑当一个大带宽传输时, Seq序号只有32位, 记录4GB大小的内容, 可能某个内容正在网络传输时, 下一个相同的Seq序号的报文也同时到达, 对方节点可以根据Timestamp作为区分的一个参考依据.

Timestamp不需要双方同步, 只要将自己的Timestamp单项递增即可

7.UTO User Timeout Option 用户超时选项

这个选项指定了超过多长时间没有数据发送就关闭连接. 遵循如下公式:

实际超时时间 = min(本地系统最大超时时间, max( 本端宣告UTO, 远端宣告UTO, 最小超时时间))

8.TCP 认证选项

这个选项携带的是报文经过加密后的hash计算结果, 其并不包含预分发密钥, 因此应用需要自己解决如何生成共识密钥的过程, 这个认证选项只能作为判断报文是否被修改的一个依据.

9.路径MTU探测

根据SYN时互相提供的MTU或者默认值作为发送参数后, (由于路由的变化)双方可以根据连接过程中产生的ICMP报文来动态缩小MSS. 如果缩小后一定时间没有继续缩小, 可以逐渐增长.

但是防火墙阻挡或者某些主机不回应ICMP报文, 会引发TCP的black hole效应, 一个解决方法是TCP发现这种情况时尝试主动做小报文片段.

10.RST刺客

如上图所示, 当四次挥手已经顺利完成, Client已经进入TIME_WAIT阶段等待2MSL的时候, 此时Server发来一个之前的报文, Client进行ACK确认, 但是由于Server已经释放了链接, 并不能理解这个ACK报文, 因此发回来一个RST报文, 当Client收到RST的时候, TIME_WAIT阶段被强制终止。

系统常见的解决方法是: 在TIME_WAIT阶段不会应答任何RST报文

11.Server上的TCP

连接排队

系统为每一个TCP的端口提供了两个队列

  1. 向上层递交的队列: 如果应用层不能及时处理这些连接, 那么这些连接就会在队列中排队保存
  2. 三次握手未完成的队列: 如果系统不能及时处理, 或者1中的队列已满, 那么系统可能会将这些半连接保存成队列, 也有可能直接发送RST拒绝服务.

应用只有当连接建立完成之后才能知道服务的对象是谁, 因此在连接建立完成之前没有权利去拒绝服务,只有在建立完成后才能FIN或者RST


参考:

https://www.cnblogs.com/lshs/p/6038494.html

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值