最新消息:

TCP fast open 实践笔记

tcp admin 3487浏览 0评论

什么是 TCP Fast Open

TCP Fast Open 简称 TFO,其目的是缩短 TCP 三次握手的时间。通过加入 cookie,在握手阶段就可以传输数据包,从而将三次握手的延时降低到最低。比较适用于网络延时比较长的场景。

CP Fast Open 流程

首次请求

  1. 客户端发送 syn,并且字段里面请求 cookie (tfo request)
  2. 服务端发送 syn+ack以及cookie
  3. 客户端保存cookie并发送ack
  4. 客户端发送数据

后续请求

  1. 客户端发送 syn、数据以及 cookie
  2. 服务端验证 cookie 并发送 syn+ack
  3. 服务端不必等客户端ack开始发送数据
  4. 客户端发送 ack

延时分析

假设单程延时为 t,如果没有用 TFO,那么需要三次握手后才会开始发送数据,即发送数据延时至少为 2t,而用了 TFO,发送数据延时就是0。当然从用户体验来看,从发起请求到接收到服务端发送过来数据的延时分别是4t和2t。

TFO 的一些问题

由于带了 cookie 有些防火墙认为数据包异常,在这种环境下用起来就会有问题。有报告说某些4G网络就有这种问题。

TCP Fast Open 实践

系统层面

echo 3 > /proc/sys/net/ipv4/tcp_fastopen

其中1表示启用客户端(sendto),2表示启用服务端(bind),3表示两者都启用。

客户端代码

#!/usr/bin/env python
import socket
import sys

MSG_FASTOPEN = 0x20000000

host = sys.argv[1]
print("connecting to host {} ...".format(host))

addr = (host, 8000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 以 Fast Open 方式发送数据,不需要 connect
s.sendto("hello!", MSG_FASTOPEN, addr)

print s.recv(1000)

服务端代码

import socket

TCP_FASTOPEN = 23

def listen():
    connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 设置 TCP Fast Open 队列
    connection.setsockopt(socket.SOL_TCP, TCP_FASTOPEN, 5)
    connection.bind(('0.0.0.0', 8000))
    connection.listen(10)
    while True:
        current_connection, address = connection.accept()
        while True:
            data = current_connection.recv(2048)

            if data:
                current_connection.send(data)
                print data
            current_connection.close()
            break

if __name__ == "__main__":
    try:
        listen()
    except KeyboardInterrupt:
        pass

软件配置

在 haproxy 中,如果要启用 TCP Fast Open,那么需要在 bind 中显式指定。譬如:

bind 0.0.0.0:12345 tfo

参考链接
https://tools.ietf.org/html/rfc7413
https://lwn.net/Articles/508865/

转载请注明:爱开源 » TCP fast open 实践笔记

您必须 登录 才能发表评论!