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>