With SO_REUSEPORT kernel assigns connection to process not in accept()

2

I have a server that runs as multiple processes, using SO_REUSEPORT to provide parallelism. A server process can be assigned a connection, however, even when it is busy processing, which effectively single-threads requests. This does not appear to be the documented behavior of SO_REUSEPORT.

To rule out my code I downloaded a simple TCP server from https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/tcpserver.c and modified it as follows:

/* added SO_REUSEPORT */ setsockopt(parentfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, (const void )&optval , sizeof(int)); . . . / sleep before close */ sleep(10); close(childfd);

I run 2 instances of this (on the same port) under strace, and access them via curl several second apart. I see the second curl connection can wind up waiting for the first server, even though that server is sleeping and the other server is waiting in an accept().

This would appear to be a flaw in the implementation of SO_REUSEPORT (according to several articles the semantics should be "the SO_REUSEPORT implementation distributes connections evenly across all of the threads (or processes) that are blocked in accept() on the same port."

Kernel is: Linux version 3.14.27-25.47.amzn1.x86_64 (mockbuild@gobi-build-60001) (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) ) #1 SMP Wed Dec 17 18:36:15 UTC 2014

Michael Lindner

Posted 2017-03-13T16:28:07.910

Reputation: 21

No answers