博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP系列06—连接管理—5、TCP fastopen(TFO)
阅读量:5251 次
发布时间:2019-06-14

本文共 2374 字,大约阅读时间需要 7 分钟。

一、TFO背景

        当前web和web-like应用中一般都是在三次握手后开始数据传输,相比于UDP,多了一个RTT的时延,即使当前很多应用使用长连接来处理这种情况,但是仍然由一定比例的短连接,这额外多出的一个RTT仍然对应用的时延有非常大的影响。TFO就是在这种背景下面提出来的。

        TFO(TCP fast open)是TCP协议的experimental update,它允许服务器和客户端在连接建立握手阶段交换数据,从而使应用节省了一个RTT的时延。但是TFO会引起一些问题,因此协议要求TCP实现必须默认禁止TFO。需要在某个服务端口上启用TFO功能的时候需要应用程序显示启用。

二、TFO过程

1.在使用TFO之前,client首先需要通过一个普通的三次握手连接获取FOC(Fast Open Cookie)

  • 1.client发送一个带有Fast Open选项的SYN包,同时携带一个空的cookie域来请求一个cookie

  • 2.server产生一个cookie,然后通过SYN-ACK包的Fast Open选项来返回给client

  • 3.client缓存这个cookie以备将来使用TFO连接的时候使用

2.执行TFO

  • 1.client发送一个带有数据的SYN包,同时在Fast Open选项中携带之前通过正常连接获取的cookie

  • 2.server验证这个cookie。如果这个cookie是有效的,server会返回SYN-ACK报文,然后这个server把接收到的数据传递给应用层。如果这个cookie是无效的,server会丢掉SYN包中的数据,同时返回一个SYN-ACK包来确认SYN包中的系列号

  • 3.如果cookie有效,在连接完成之前server可以给client发送响应数据,携带的数据量受到TCP拥塞控制的限制(RFC5681,后面文章会介绍拥塞控制)。

  • 4.client发送ACK包来确认server的SYN和数据,如果client端SYN包中的数据没有被服务器确认,client会在这个ACK包中重传对应的数据

  • 4.剩下的连接处理就类似正常的TCP连接了,client一旦获取到FOC,可以重复Fast Open直到cookie过期。

       通过整个过程,我们可以看到TFO的核心是一个安全cookie,服务器使用这个cookie来给客户端鉴权。一般来说这个cookie应该能鉴权SYN包中的源IP地址,并且不能被第三方伪造。为了保证安全,过一段时间后,server应该expire之前的cookie,并重新生成cookie。cookie验证通过,server在发送SYN-ACK的时候,如果有待发送数据也同样可以携带数据。

      client在缓存cookie的时候,协议同样建议缓存Maximum Segment Size(MSS),MSS代表了对端能接收的最大TCP段,这样client在执行TFO的时候,SYN包可以携带的数据量大小就有了一个参考。即使缓存了MSS,也建议client SYN包中数据不要超过典型的MSS,即IPV4的1460bytes和IPV6的1440bytes。如果没有缓存MSS,则SYN包中的数据大小限制在默认的MSS,IPV4为536bytes(RFC1122),IPV6为1220bytes(RFC2460)。

     client在收到服务器SYN包但是没有ACK之前自己发出的数据时候,或者ICMP错误或者根本没有收到SYN-ACK响应的时候,client至少应该要在对应的连接路径上临时禁止TFO功能。

        TFO场景下,client在超时重传SYN包以及server超时重传SYN-ACK报文的时候应该去掉Fast Open选项和对应的数据,以免因为不兼容TFO而导致连接建立失败。

三、SYN包重复递交数据

        在TFO下随着SYN发送的数据有可能重复递交到应用层。例如在IP层不可靠传输的情况下,发送端的一个SYN包被传输成了两个SYN包,而在接收端,接收到第一个SYN包后,接收端把随SYN的数据传递到应用层,紧接着这个连接由发送端发起关闭TCP连接的操作,接收端不会进入TIME_WAIT保护状态(后面在介绍TIME_WAIT),然后继续收到第二个重复包则可能会将随SYN传输的数据再次传向应用层。因此如果应用层不能忍受这种包重复,则不能开启TFO特性。

四、wireshark抓包

在下面的wireshark抓包中,限于篇幅,仅简单介绍一下几个相关的包,详细的报文内容请下载wireshark的抓包文件打开后自行查看

No1:首先client发起普通连接,在SYN包中带有一个FOC选项,向server请求cookie (No1表示wireshark截图中序号为No1的报文,后续文章使用类似表示)

No2:server端回复SYN-ACK包,其中携带一个FOC选项,cookie域为0x1a39d8e2100b247e

紧接着client发送一个"hello"消息后关闭连接

No7:client重新发起一个连接,可以看到这个SYN包的Len=5,实际上我发送了"world",正好是5bytes,随着syn包发送到了server,注意这次cilent的端口是57522和第一次连接的端口57520并不同,但是仍然可以使用第一次获取的FOC发送数据,因此FOC是与client端口无关的。

补充说明

1.TFO介绍 

2.RFC7413 

3.原始的RFC793协议也是允许TCP在握手过程中传递数据的,但是在连接建立前不能递交给应用层,linux实现上并不支持在非TFO场景下握手过程中携带数据。

转载于:https://www.cnblogs.com/lshs/p/6038488.html

你可能感兴趣的文章
day22 01 初识面向对象----简单的人狗大战小游戏
查看>>
mybatis源代码分析:深入了解mybatis延迟加载机制
查看>>
Flask三剑客
查看>>
Hibernate-缓存
查看>>
【BZOJ4516】生成魔咒(后缀自动机)
查看>>
提高PHP性能的10条建议
查看>>
svn“Previous operation has not finished; run 'cleanup' if it was interrupted“报错的解决方法...
查看>>
熟用TableView
查看>>
Java大数——a^b + b^a
查看>>
poj 3164 最小树形图(朱刘算法)
查看>>
服务器内存泄露 , 重启后恢复问题解决方案
查看>>
android一些细节问题
查看>>
KDESVN中commit时出现containing working copy admin area is missing错误提示
查看>>
利用AOP写2PC框架(二)
查看>>
【动态规划】skiing
查看>>
java定时器的使用(Timer)
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>
简单的数据库操作
查看>>