tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: TCP connections clogging up accf_http(9) (was: ESTABLISHED sockets with no fd open? (was: generating ECONNRESET with no syscall?))



On Fri, May 20, 2016 at 06:33:58AM +0000, Michael van Elst wrote:
> tls%panix.com@localhost (Thor Lancelot Simon) writes:
> 
> >I'm not seeing where your limit of 193 for the length of that queue
> >is coming from, or I would fix the issue right now.
> 
> 
> That's the sockets listen queue. It can handle a default of SOCONNMAX=128
> connections but the check in sonewconn is:

Gah, I missed the math there.  Of course.

The attached patch (untested, not even compiled!) may work.  I believe it
is strictly fair: the longer a cxn sits idle, sending no valid request,
the more likely it is to be passed through to the application, which may
in turn drop it.

Thor

Index: uipc_socket2.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.119
diff -u -p -r1.119 uipc_socket2.c
--- uipc_socket2.c	19 May 2014 02:51:24 -0000	1.119
+++ uipc_socket2.c	20 May 2016 14:09:09 -0000
@@ -260,7 +260,29 @@ sonewconn(struct socket *head, bool sore
 	KASSERT(solocked(head));
 
 	if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) {
-		/* Listen queue overflow. */
+		/*
+		 * Listen queue overflow.  If there is an accept filter
+		 * active, pass through the oldest cxn it's handling.
+		 */
+		if (head->so_accf != NULL) {
+			struct socket *so2, *next;
+
+			/* Pass the oldest connection waiting in the
+			   accept filter *
+			for (so2 = TAILQ_FIRST(&head->so_q0);
+			     so2 != NULL; so2 = next) {
+				next = TAILQ_NEXT(so2, so_qe);
+				if (so2->so_upcall == NULL) {
+					continue;
+				}
+				so2->so_upcall = NULL;
+				so2->so_upcallarg = NULL;
+				so2->so_options &= ~SO_ACCEPTFILTER;
+				so2->so_rcv.sb_flags &= ~SB_UPCALL;
+				soisconnected(so2);
+				break;
+			}
+		}
 		return NULL;
 	}
 	if ((head->so_options & SO_ACCEPTFILTER) != 0) {


Home | Main Index | Thread Index | Old Index