2002-11-28 02:51:17

by Philippe Troin

[permalink] [raw]
Subject: Wierd listen/connect: accept queue never fills up

[Andi, I've CC'ed you since you're listed as the author of the `new
listen' code in net/ipv4/tcp_ipv4.c]

Seen on linux 2.4.20rc2.

This program is always able to establish new connections to itself:
the accept queue never fills up and connections always succeed
(although they take quite some time after the first four):

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(void)
{
int fd;
struct sockaddr_in sin;
socklen_t sinlen;

if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
perror("socket"), exit(1);

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sin.sin_port = htons(0);
if (bind(fd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
perror("bind"), exit(1);
if (listen(fd, 1) == -1)
perror("listen"), exit(1);

sinlen = sizeof(sin);
getsockname(fd, (struct sockaddr*)&sin, &sinlen);

while (1)
{
int fdc;

if ((fdc = socket(PF_INET, SOCK_STREAM, 0)) == -1)
perror("socket"), exit(1);
printf("%c", connect(fdc, (struct sockaddr*)&sin, sinlen) == -1
? 'F' : '.');
fflush(stdout);
}

exit(0);
}

I've tried enabling and disabling tcp_syncookies, without any effect.

The same program starts returning errors after two successful connects
on Solaris and one on HP-UX. Linux keeps returning new connections...

Phil.


2002-11-28 03:30:16

by Ivan Pulleyn

[permalink] [raw]
Subject: Re: Wierd listen/connect: accept queue never fills up



What was the sysctl value for net.ipv4.tcp_syn_max_backlog set to
while running this test? That's the value you are testing, not the
listen() queue size.

Ivan...


On 27 Nov 2002, Philippe Troin wrote:

> [Andi, I've CC'ed you since you're listed as the author of the `new
> listen' code in net/ipv4/tcp_ipv4.c]
>
> Seen on linux 2.4.20rc2.
>
> This program is always able to establish new connections to itself:
> the accept queue never fills up and connections always succeed
> (although they take quite some time after the first four):
>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
>
> int main(void)
> {
> int fd;
> struct sockaddr_in sin;
> socklen_t sinlen;
>
> if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
> perror("socket"), exit(1);
>
> sin.sin_family = AF_INET;
> sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
> sin.sin_port = htons(0);
> if (bind(fd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
> perror("bind"), exit(1);
> if (listen(fd, 1) == -1)
> perror("listen"), exit(1);
>
> sinlen = sizeof(sin);
> getsockname(fd, (struct sockaddr*)&sin, &sinlen);
>
> while (1)
> {
> int fdc;
>
> if ((fdc = socket(PF_INET, SOCK_STREAM, 0)) == -1)
> perror("socket"), exit(1);
> printf("%c", connect(fdc, (struct sockaddr*)&sin, sinlen) == -1
> ? 'F' : '.');
> fflush(stdout);
> }
>
> exit(0);
> }
>
> I've tried enabling and disabling tcp_syncookies, without any effect.
>
> The same program starts returning errors after two successful connects
> on Solaris and one on HP-UX. Linux keeps returning new connections...
>
> Phil.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

--

----------------------------------------------------------------------
Ivan Pulleyn
Sixfold Technologies, LLC
Chicago Technology Park
2201 West Campbell Drive
Chicago, IL 60612

email: [email protected]
voice: (866) 324-5460 x601
fax: (312) 421-0388
----------------------------------------------------------------------

2002-12-03 01:36:49

by Philippe Troin

[permalink] [raw]
Subject: Re: Wierd listen/connect: accept queue never fills up

Ivan Pulleyn <[email protected]> writes:

> What was the sysctl value for net.ipv4.tcp_syn_max_backlog set to
> while running this test? That's the value you are testing, not the
> listen() queue size.

The value of net.ipv4.tcp_syn_max_backlog does not matter. Even if I
set it to zero, I can create several hundred of connections without
accept()'ing any. And netstat show them all in the CONNECTED state.

That looks bad to me.

Phil.

> On 27 Nov 2002, Philippe Troin wrote:
>
> > [Andi, I've CC'ed you since you're listed as the author of the `new
> > listen' code in net/ipv4/tcp_ipv4.c]
> >
> > Seen on linux 2.4.20rc2.
> >
> > This program is always able to establish new connections to itself:
> > the accept queue never fills up and connections always succeed
> > (although they take quite some time after the first four):
> >
> > #include <stdio.h>
> > #include <sys/types.h>
> > #include <sys/socket.h>
> > #include <netinet/in.h>
> >
> > int main(void)
> > {
> > int fd;
> > struct sockaddr_in sin;
> > socklen_t sinlen;
> >
> > if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
> > perror("socket"), exit(1);
> >
> > sin.sin_family = AF_INET;
> > sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
> > sin.sin_port = htons(0);
> > if (bind(fd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
> > perror("bind"), exit(1);
> > if (listen(fd, 1) == -1)
> > perror("listen"), exit(1);
> >
> > sinlen = sizeof(sin);
> > getsockname(fd, (struct sockaddr*)&sin, &sinlen);
> >
> > while (1)
> > {
> > int fdc;
> >
> > if ((fdc = socket(PF_INET, SOCK_STREAM, 0)) == -1)
> > perror("socket"), exit(1);
> > printf("%c", connect(fdc, (struct sockaddr*)&sin, sinlen) == -1
> > ? 'F' : '.');
> > fflush(stdout);
> > }
> >
> > exit(0);
> > }
> >
> > I've tried enabling and disabling tcp_syncookies, without any effect.
> >
> > The same program starts returning errors after two successful connects
> > on Solaris and one on HP-UX. Linux keeps returning new connections...
> >
> > Phil.

2002-12-03 08:17:53

by Margit Schubert-While

[permalink] [raw]
Subject: Re: Wierd listen/connect: accept queue never fills up

From the Linux kernel doc :

tcp_max_syn_backlog
-------------------
Length of the per socket backlog queue. Since Linux 2.2 the backlog specified
in listen(2) only specifies the length of the backlog queue of already
established sockets. When more connection requests arrive Linux starts to drop
packets. When syncookies are enabled the packets are still answered and the
maximum queue is effectively ignored.


Margit