Possible bug in `tcp(7)` regarding `TCP_USER_TIMEOUT`

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

The manpage for TCP (`man 7 tcp`, [1]) reads, in the paragraphs about
`TCP_USER_TIMEOUT`:

[1] https://man7.org/linux/man-pages/man7/tcp.7.html

```
This option can be set during any state of a TCP
connection, but is effective only during the synchronized
states of a connection (ESTABLISHED, FIN-WAIT-1, FIN-
WAIT-2, CLOSE-WAIT, CLOSING, and LAST-ACK).
```

When I read that, I understand that that option should only apply to
established TCP connections, and should not apply when trying to
establish a TCP connection.

I wrote a simple program to test that:

```
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

// We'll skip error-checking since this is just for testing purposes.

void do_connect(int with_tcp_user_timeout) {
    struct addrinfo hint;
    struct addrinfo *ai;
    int sock;
    time_t start;
    time_t end;
    unsigned int timeout = 10000;

    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = IPPROTO_TCP;
    getaddrinfo("10.0.42.16", "5432", &hint, &ai);

    sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    if (with_tcp_user_timeout) {
        setsockopt(
            sock, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout,
            sizeof(timeout)
        );
    }

    printf(
        "Attempting to connect, with_user_tcp_timeout = %d... ",
        with_tcp_user_timeout
    );
    fflush(stdout);

    start = time(NULL);
    connect(sock, ai->ai_addr, ai->ai_addrlen);
    end = time(NULL);
    printf("Done!\n");

    freeaddrinfo(ai);

    printf(
        "with_tcp_user_timeout = %d, took %ld seconds\n",
        with_tcp_user_timeout, end - start
    );
}

int main(void) {
    // Let's connect with TCP_USER_TIMEOUT first for faster useful
    // first data.
    do_connect(1);
    do_connect(0);

    exit(EXIT_SUCCESS);
}
```

This program gives me the following output:

```
$ gcc main.c -Wall -Wextra -Werror && ./a.out
Attempting to connect, with_user_tcp_timeout = 1... Done!
with_tcp_user_timeout = 1, took 10 seconds
Attempting to connect, with_user_tcp_timeout = 0... Done!
with_tcp_user_timeout = 0, took 130 seconds
```

So it seems like that option does apply when trying to establish a
connection! This above output was obtained with Linux 5.15.8 and gcc
9.3.0.

Am I reading the manpage wrong, or is the manpage wrong? Or is this
just an "undocumented behavior" that shouldn't be relied on and can
be removed without warning in future releases?

Thanks,
João Sampaio




[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux