Thread (1 message) 1 message, 1 author, 2018-05-23

Re: Expected result when racing listen(2) on two sockets bound to the same address

From: Kirill Tkhai <hidden>
Date: 2018-05-23 12:44:31
Also in: lkml

Hi,

On 23.05.2018 14:15, Alexander Kurtz wrote:
[Please keep me CC'ed; I'm not subscribed to the list]

Hi!

The program shown below (also available at [0]) does the following:

 * Create two sockets
 * Enable SO_REUSEADDR on both
 * Bind both sockets to [::1]:12345
 * Spawn two threads which both call listen(2) on one socket each
 * Check that at least one thread succeeded

Unfortunately, when running this program on Linux 4.16, it is sometimes
possible that neither thread succeeds in calling listen(2):

    $ uname -a
    Linux shepard 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux
    $ time make
    cc -Wall -Wextra -pedantic -Werror -O3    listenrace.c  -lpthread -o listenrace
    for i in `seq 10000`; do ./listenrace; done
    listenrace: listenrace.c:58: main: Assertion `result1 == 0 || result2 == 0' failed.
    Aborted
    listenrace: listenrace.c:58: main: Assertion `result1 == 0 || result2 == 0' failed.
    Aborted
    listenrace: listenrace.c:58: main: Assertion `result1 == 0 || result2 == 0' failed.
    Aborted

    real	0m8.201s
    user	0m6.801s
    sys	0m2.141s
    $ 

As can be seen, on 3 runs (out of 10000) calling listen(2) failed in
*both* threads. Is this to be expected (i.e. "don't do this then") or
could this be some race condition in the Linux kernel?
At the first sight, it is in kernel and is expected:

inet_csk_listen_start()
{
	/* There is race window here: we announce ourselves listening,
	 * but this transition is still not validated by get_port().
	 * It is OK, because this socket enters to hash table only
	 * after validation is complete.
	 */
        inet_sk_state_store(sk, TCP_LISTEN);
        if (!sk->sk_prot->get_port(sk, inet->inet_num)) {

}

CC netdev.

Kirill
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help