Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

listen() ignores the backlog argument?

I have the following problem:

I have sockfd = socket(AF_INET, SOCK_STREAM, 0)

After I set up and bind the socket (let's say with sockfd.sin_port = htons(666)), I immediately do:

listen(sockfd, 3);

sleep(50); // for test purposes

I'm sleeping for 50 seconds to test the backlog argument, which seems to be ignored because I can establish a connection* more than 3 times on port 666.

*: What I mean is that I get a syn/ack for each Nth SYN (n>3) sent from the client and placed in the listen queue, instead of being dropped. What could be wrong? I've read the man pages of listen(2) and tcp(7) and found:

The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of incomplete connection requests. The maximum length of the queue for incomplete sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When syncookies are enabled there is no logical maximum length and this setting is ignored. See tcp(7) for more information.

, but even with sysctl -w sys.net.ipv4.tcp_max_syn_backlog=2 and sysctl -w net.ipv4.tcp_syncookies=0, I still get the same results! I must be missing something or completely missunderstand listen()'s backlog purpose.

like image 715
Markoff Chaney Avatar asked Feb 24 '11 22:02

Markoff Chaney


People also ask

What does the listen () function do?

The listen() call indicates a readiness to accept client connection requests. It transforms an active socket into a passive socket. Once called, socket can never be used as an active socket to initiate connection requests. Calling listen() is the third of four steps that a server performs to accept a connection.

What are the arguments in listen () system call?

Listen() System Call. The listen() system call prepares a connection-oriented server to accept client connections. The first parameter is the socket descriptor from the socket() call, sockfd. The second parameter specifies the number of requests that the system queues before it executes the accept() system call.

What is backlog in listen?

The backlog has an effect on the maximum rate at which a server can accept new TCP connections on a socket. The rate is a function of both the backlog value and the time that connections stay on the queue of partially open connections.

What is listen in Linux?

listen() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept(2). The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM or SOCK_SEQPACKET.


2 Answers

The backlog argument to listen() is only advisory.

POSIX says:

The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket's listen queue.

Current versions of the Linux kernel round it up to the next highest power of two, with a minimum of 16. The revelant code is in reqsk_queue_alloc().

like image 196
caf Avatar answered Oct 09 '22 02:10

caf


Different operating systems provide different numbers of queued connections with different backlog numbers. FreeBSD appears to be one of the few OSes that actually has a 1-to-1 mapping. (source: http://books.google.com/books?id=ptSC4LpwGA0C&lpg=PA108&ots=Kq9FQogkTr&dq=berkeley%20listen%20backlog%20ack&pg=PA108#v=onepage&q=berkeley%20listen%20backlog%20ack&f=false )

like image 25
gpcz Avatar answered Oct 09 '22 02:10

gpcz