如何知道带有TCP快速打开的sendto()是否实际使用了快速打开? [英] How to know if sendto() with TCP Fast Open actually used Fast Open?

查看:39
本文介绍了如何知道带有TCP快速打开的sendto()是否实际使用了快速打开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux 3.15计算机上编写了一个TCP客户端,该计算机能够使用TCP快速打开:

I write a TCP client on a Linux 3.15 machine, which is able to use TCP Fast Open:

        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快速打开选项的发送,并且它确实绕过了3向握手(已在Google的服务器上进行了测试).

Using tcpdump, I can check the sending of the TCP Fast Open option and that it does bypass the 3-way handshake (tested with Google's servers).

但是,对于 not 不接受TCP快速打开的服务器,sendto仍然成功,并显示消息"TFO连接成功".显然,如果服务器不支持TCP快速打开(再次由tcpdump检查),则Linux内核代码将退回到常规TCP.

However, with servers which does not accept TCP fast open, sendto still succeeds, and the message "TFO connection successful" is displayed. Apparently, the Linux kernel code falls back to regular TCP if the server does not support TCP Fast Open (again, checked with tcpdump).

如何确定我的连接是否使用了TCP Fast Open?

How to find out if my connection used TCP Fast Open or not?

推荐答案

通过查看在Linux内核中添加了TCP快速打开的补丁集,您注意到它并没有添加任何使用快速打开的外部指示.

By looking at the patch set that added TCP fast open in the linux kernel, you notice that it wasn't added any external indication that fast open was used.

您可以间接注意到某些未使用快速打开的情况,以及某些绝对使用快速打开的情况.

You can indirectly notice certain cases where fast open was not used and certain cases where fast open was definitely used.

您确定没有使用快速打开的情况是在成功sendto()连接之后/proc/net/netstat中TCPFastOpenActive计数器的值未增加:

The case that you are sure fast open was not used is when the value of the TCPFastOpenActive counter was not incremented in /proc/net/netstat after a successful sendto() connection:

+   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:

The case that you are sure fast open was used is when you have a non-blocking socket, you already have a fast open cookie and sendto() does not return EINPROGRESS:

对于非阻塞套接字,它返回排队的字节数(和如果Cookie可用,则在SYN数据包中传输).如果是cookie不可用,它将通过快速打开传输无数据的SYN数据包Cookie请求选项,并返回-EINPROGRESS,如connect().

For non-blocking socket, it returns the number of bytes queued (and transmitted in the SYN-data packet) if cookie is available. If cookie is not available, it transmits a data-less SYN packet with Fast Open cookie request option and returns -EINPROGRESS like connect().

对于其余情况,即您没有cookie,但是您能够连接并且TCPFastOpenActive已递增,因此您无法确定是否使用了快速打开(TCPFastOpenActive增量是由您的快速打开引起的)或如果未使用快速打开(TCPFastOpenActive增量不是由您的快速打开引起的).

For the remaining case, that is, you don't have a cookie, but you were able to connect and TCPFastOpenActive was incremented, you can't say if fast open was used (TCPFastOpenActive increment was caused by your fast open) or if fast open was not used (TCPFastOpenActive increment was not caused by your fast open).

http://kernelnewbies.org/Linux_3.6#head-ac78950a7b57d92d5835642926f0e147c680b99c

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id = cf60af03ca4e71134206809ea892e49b92a88896

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/diff/net/ipv4/tcp_output.c?id=783237e8daf13481eeee234997cbbbb823872ac388

这篇关于如何知道带有TCP快速打开的sendto()是否实际使用了快速打开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆