Bug 119141

Summary: sockets no longer accept connections when listen backlog is zero
Product: Networking Reporter: Karl Tomlinson (bugs+kernel)
Component: IPV4Assignee: Stephen Hemminger (stephen)
Status: NEW ---    
Severity: normal CC: set.intertube
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.4.11-gentoo-r1 Subsystem:
Regression: Yes Bisected commit-id:
Attachments: accept.cpp testcase
LD_PRELOAD workaround

Description Karl Tomlinson 2016-05-27 09:07:45 UTC
Created attachment 217871 [details]
accept.cpp testcase

g++ -std=gnu++0x -Wall accept.cpp && ./a.out

then while the program is running

  netcat -v localhost <port>

Expected (behavior with 3.12, or backlog = 1):
PASS
localhost [127.0.0.1] <port> open

Actual behavior with 4.4.11:
Both programs remain blocking in accept and select (after connect), with no output from netcat.

man 3p listen:

  "A backlog argument of 0 may allow the socket  to  accept  connections,  in
   which case the length of the listen queue may be set to an implementation-
   defined minimum value."

That's not entirely clear, but I've noticed a couple of applications expecting
to accept connections with backlog 0.
Comment 1 Karl Tomlinson 2016-05-31 02:47:42 UTC
Created attachment 218301 [details]
LD_PRELOAD workaround
Comment 2 Karl Tomlinson 2016-06-21 21:29:38 UTC
"If listen() is called with a backlog argument value that is less  than  0,
 the  function  behaves  as  if  it had been called with a backlog argument
 value of 0."

but passing backlog = -1 permits accepting connections while 0 does not.
Comment 3 Paul 2016-11-01 01:26:57 UTC
If using a networked epson scanner, they supply a closed binary (/usr/lib64/iscan/network) which is called during detection of the scanner. That binary listens on a localhost socket with listen()s backlog argument set to 0. Something then tries to connect to that socket. Used to work, now fails as above.

Also,this appears in the logs:
TCP: request_sock_TCP: Possible SYN flooding on port XXXXX. Dropping request.  Check SNMP counters.

I am guessing because one SYN exceeds a backlog of 0.

I just wanted to note that this not just a regression in theory, but it broke my real world application. (I was able to get it working using the LD_PRELOAD hack -- thanks.)