Skip to contentSkip to conversation

New: backlog parameter of listen is not working with TCP

Bugme-new Andrew Morton 2 participants 2 messages Jul 1, 2009 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]/

#1 lore raw

(switched to email. Please respond via emailed reply-to-all, not via the bugzilla web interface).

Quoted 36 lines · On Wed, 1 Jul 2009 18:39:07 GMT [email protected] wrote:

http://bugzilla.kernel.org/show_bug.cgi?id=13688

Summary: backlog parameter of listen is not working with TCP
Product: Networking
Version: 2.5
Kernel Version: 2.6
Platform: All
OS/Version: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
AssignedTo: [email protected]
ReportedBy: [email protected]
Regression: No

Created an attachment (id=22171)
--> (http://bugzilla.kernel.org/attachment.cgi?id=22171)
little test server

When creating a server I usually create a socket, bind it to any address and call listen to limit the queue size, then I call accept in a loop to handle clients one by one.

In a particular case I wanted to serve only 1 client and refuse the other connection attempts. I tried any value for the backlog parameter, whatever I use the server is not refusing any connection, though the queue should be full. The SYN+ACK handshake is completed everytime.

To be sure this is a bug I checked this with BSD and Windows, I can confirm that it refuses connections if the max queue size specified with backlog is reached (Note that backlog is not exactly the queue size with these systems, there is a 3/2 factor, I don't know why).

Quoted 8 lines

Maybe this implementation for linux kernel is wanted even if it is not posix compliant, but I did not find anywhere why this is working like this. If this is not a bug, could someone explain me the usefullness of the backlog parameter?

I attached a little test program with which anyone should be able to test this by connecting multiple telnet to.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>

int main(void)
{
int servsock = 0;
int clientsock = 0;
struct sockaddr_in servaddr;
struct sockaddr_in clientaddr;
socklen_t clientaddrlen;
struct in_addr client_addr;

   servsock = socket(AF_INET, SOCK_STREAM, 0);

   //fcntl(servsock, F_SETFL, O_NONBLOCK);

   if(servsock != -1)
   {
      servaddr.sin_family = AF_INET;
      servaddr.sin_port = htons(6256);
      inet_aton("0.0.0.0", &client_addr);
      servaddr.sin_addr = client_addr;
      if(bind(servsock, &servaddr, sizeof(servaddr)) != -1)
      {
         if(listen(servsock, 0) != -1)
         {
            while(1)
            {
               printf("waiting for clients\n");
               clientsock = accept(servsock, &clientaddr, &clientaddrlen);
               if(clientsock != -1)
               {
                  printf("client accepted, now sleep 60 sec\n");
                  sleep(60);
                  printf("60 sec have elapsed, closing connection\n");
                  close(clientsock);
               }
               else
               {
                  printf("accept error: retrying in 1 sec...\n");
                  sleep(1);
               }
            }
         }
         else
         {
            printf("listen failed\n");
         }
      }
      else
      {
         printf("bind failed\n");
      }
   }
   else
   {
      printf("socket creation failed\n");
   }

return 0;
}

#2 lore raw
Quoted 6 lines · Andrew Morton
Quoted 3 lines · On Wed, 1 Jul 2009 18:39:07 GMT [email protected] wrote:

http://bugzilla.kernel.org/show_bug.cgi?id=13688
Summary: backlog parameter of listen is not working with TCP
Product: Networking

[..]

Quoted 8 lines
Quoted 8 lines

When creating a server I usually create a socket, bind it to any address and call listen to limit the queue size, then I call accept in a loop to handle clients one by one.

In a particular case I wanted to serve only 1 client and refuse the other connection attempts. I tried any value for the backlog parameter, whatever I use the server is not refusing any connection, though the queue should be full. The SYN+ACK handshake is completed everytime.

The behaviour depends on net.ipv4.tcp_abort_on_overflow sysctl. If its on, new connections are reset once the backlog is exhausted.