1.开头
本次简单介绍下tcp的fastopen,主要谈下存在的问题和适用的场景。
2.tcp 0rtt连接
2.1 为什么需要0rtt
tcp的连接细节在tcp timewait写了很多,这里主要说下fastopen特性。tcp需要建立3次握手后(1rtt),再发送数据,在远距离的传输方面,影响应用的秒开。fastopen就是为了解决握手过程。在发送syn的时候同时可以发送数据,服务器端完成syn请求同时接收数据返回内容,在完成握手的同时发送完成数据。
2.2 fastopen的问题
2.2.1 重放请求
经典的tcp一定要3次握手,少了1次(0rtt模式在收到syn响应,2次握手)会有什么问题呢?客户端可能因之前的握手包延迟到达服务器,导致请求重放,而客户端已经关闭。
这里的重放,不能通过timewait来解决,在客户端主动断开的模式下,timewait发生在客户端。发生这种情况,服务的资源白白浪费,并响应无效结果(客户端已经关闭)。
这里客户端可以保证不接受老的请求,详情可以查看syn的初始化序列号的方法
2.1.2 syn攻击
在普通情况下syn 可以开启cookie方式进行防御syn攻击(这个防御很简单,破解成本很低,只是简单的初始化序号,mss少了的验证),但开启fastopen后,客户端攻击服务器成本更低,造成的资源浪费更大(服务器还需要影响内容)。一个可能的防御手段是把fastopen并发请求队列减小。
2.1.3 其他问题
https://squeeze.isobar.com/2019/04/11/the-sad-story-of-tcp-fast-open/
2.2 什么时候可以启用fastopen
fastopen理想是个好东西,但是世界太复杂的,安全和可靠性通常是开发人员最关心的;所以注定fastopen不能被广泛使用。测试过几家大网站都没开启。
所以fastopen不能随便开启,需要保证3点:
- 服务器支持幂等请求,比如多次get,post这种就放弃fastopen选项
- 保证服务器的syn安全性,比如内网
2.3 fastopen的选项
客户端1,服务器2,同时开启3,Linux内核3.7+。
3. 代码流程图
代码太长了,贴下整体的流程图