Skip site navigation (1)Skip section navigation (2)
Date:      15 Apr 2002 06:24:51 -0000
From:      Yusuf Goolamabbas <yusufg@outblaze.com>
To:        freebsd-net@freebsd.org
Subject:   What does FreeBSD do when listen queue is full ?
Message-ID:  <20020415062451.13653.qmail@yusufg.portal2.com>

next in thread | raw e-mail | index | archive | help
We are using sendmail 8.11.6 patched to support mysql lookups.
This is on FreeBSD 4.4-stable (cvsup'ed early December 2001)

Recently my colleague turned on ConnectionRateThrottle and set it for a
value of 20

Shortly he would observe that connections would get reset immediately
after the client connected (but before the sendmail banner was shown)

[yusufg@yusufg yusufg]$ telnet target.sendmail.server smtp
Trying a.b.c.d...
Connected to target.sendmail.server
Escape character is '^]'.
Connection closed by foreign host.

At that time, neither MaxChildren nor load average had reached their
threshold which would make sendmail close its listening
socket. Sendmail's behaviour on reaching ConnectionRateThrottle
threshold is to sleep for 1 second which is likely to cause the listen
queue to back up

This would not occur on all connections but would occur quite frequently
and this behaviour would go away if we did not use ConnectionRateThrottle

tcpdump traces showed that the target sendmail server was sending an RST
packet immediately after sending a SYN-ACK in response to our SYN

Subsequently, we changed the listen backlog to 128 via
DAEMON_OPTIONS(`Port=smtp, Name=MTA, Listen=128')
and turned ConnectionRateThrottle back on with a value of 20. Now, the
immediate reset is triggered but quite infrequently

I thought that FreeBSD might be sending a RESET when the listen queue is
full but that would be contrary to what the listen(2) man page says

'If a connection request arrives with the queue full the client may
receive an error with an indication of ECONNREFUSED, or, if the
underlying protocol supports retransmission, the request may be ignored
so that retries may succeed.'

My understanding of the term 'underlying protocol' was that it
referred to TCP/IP which support retransmission and thus when the
listen queue is full, requests are ignored

Another colleague/myself looked through the FreeBSD sources and made
the following observations

When a new connection request comes in, tcp_input does a few things
first and then calls sonewconn (implemented in uipc_socket2.c) to
create a socket to queue the incoming request. The first thing
sonewconn does is to check if the socket queue length is > 3/2 *
so_qlimit, and if so, it returns a NULL pointer.

If a NULL pointer is returned, sodropablereq (implemented in
uipc_socket2.c) is called to randomly select a connection from the
socket's queue of incomplete connection for dropping.  If a connection
is selected for dropping, the function tcp_drop (implemented in
tcp_subr.c) is called to drop the selected connection. tcp_drop will
send a RST to the peer if the selected connection is in a synchronized
state (i.e., SYN received and we have sent a SYN + ACK).

Is this a correct reading/interpretation of the code, thus does it
imply that FreeBSD 4.4-stable sends an RST under certain conditions
when the listen queue is full. In that case, the man page can be
modified to mention this

In 4.5-RELEASE, there seems to be no caller for sodropablereq, however
the function is declared in sys/sys/socketvar.h and defined in
sys/kern/uipc_socket2.c. Maybe it can be deleted from the source tree

I have yet to read J.Lemon's Usenix paper on syncache and figure out
how that affects tcp input processing

Regards, Yusuf

-- 
Yusuf Goolamabbas
yusufg@outblaze.com

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020415062451.13653.qmail>