我在一台能够使用TCP Fast Open的Linux 3.15机器上编写一个TCP客户端:
status = sendto(sd, (const void *) data, data_len, MSG_FASTOPEN, (const struct sockaddr *) hostref->ai_addr, sizeof(struct sockaddr_in)); if (status < 0) { fprintf(stderr, "sendto: %s\n", strerror(errno)); exit(EXIT_FAILURE); } fprintf(stdout, "TFO connection successful to %s\n", text_of(hostref->ai_addr));
使用tcpdump,我可以检查TCP快速打开选项的发送,并且它可以绕过三次握手(用Google服务器testing)。
但是,对于不接受TCP快速打开的服务器,sendto仍然成功,并显示“TFO连接成功”消息。 显然,如果服务器不支持TCP Fast Open(再次使用tcpdump检查),则Linux内核代码会回退到常规TCP。
如何找出我的连接是否使用TCP Fast Open?
通过查看在Linux内核中添加了TCP快速打开的补丁集,您注意到它没有添加任何使用快速打开的外部指示。
您可以间接地注意到某些情况下没有使用快速打开的情况,以及某些确定使用快速打开的情况。
您确定快速打开的情况下未使用的是在成功的sendto()连接之后,TCPFastOpenActive计数器的值在/ proc / net / netstat中不增加:
+ if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE); + goto done; + }
您确定使用快速打开的情况是,当您使用非阻塞套接字时,您已经有了一个快速打开的cookie,并且sendto()不会返回EINPROGRESS:
对于非阻塞套接字,如果cookie可用,则返回排队的字节数(并在SYN数据包中传输)。 如果cookie不可用,它将使用Fast Open cookie请求选项传输无数据SYN数据包,并返回-EINPROGRESS(如connect())。
对于剩余的情况,也就是说,您没有cookie,但是您可以连接并且TCPFastOpenActive增加了,您不能说是否使用了快速打开(TCPFastOpenActive增量是由快速打开导致的),或者如果快速打开没有使用(TCPFastOpenActive增量不是由您的快速打开造成的)。
http://kernelnewbies.org/Linux_3.6#head-ac78950a7b57d92d5835642926f0e147c680b99c