[master] 4d047a9 Accept-filters on FreeBSD has been broken for ages, fix them.

Poul-Henning Kamp phk at varnish-cache.org
Mon Feb 27 12:16:04 CET 2012


commit 4d047a90b19f8821262567b793e535639b1b701a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Feb 27 11:14:45 2012 +0000

    Accept-filters on FreeBSD has been broken for ages, fix them.
    
    Add accept-filter param which controls if we attempt kernel
    filteringer.
    
    Apply filters after listen() when we do.
    
    Report failuers with VSL(SLT_Error)
    
    Disable filters in pipe-lining test-case.
    
    Fixes	#1101

diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index 07e7f5e..3ca79c1 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -292,6 +292,7 @@ vca_acct(void *arg)
 #endif
 	struct listen_sock *ls;
 	double t0, now;
+	int i;
 
 	THR_SetName("cache-acceptor");
 	(void)arg;
@@ -302,6 +303,13 @@ vca_acct(void *arg)
 		AZ(listen(ls->sock, cache_param->listen_depth));
 		AZ(setsockopt(ls->sock, SOL_SOCKET, SO_LINGER,
 		    &linger, sizeof linger));
+		if (cache_param->accept_filter) {
+			i = VTCP_filter_http(ls->sock);
+			if (i)
+				VSL(SLT_Error, ls->sock,
+				    "Kernel filtering: sock=%d, ret=%d %s\n",
+				    ls->sock, i, strerror(errno));
+		}
 	}
 
 	hack_ready = 1;
diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h
index 5c65f6e..6e502fd 100644
--- a/bin/varnishd/common/params.h
+++ b/bin/varnishd/common/params.h
@@ -108,6 +108,8 @@ struct params {
 	/* VCL traces */
 	unsigned		vcl_trace;
 
+	unsigned		accept_filter;
+
 	/* Listen address */
 	char			*listen_address;
 
diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c
index 0f91d05..8661b73 100644
--- a/bin/varnishd/mgt/mgt_child.c
+++ b/bin/varnishd/mgt/mgt_child.c
@@ -53,7 +53,6 @@
 #include "vev.h"
 #include "vlu.h"
 #include "vss.h"
-#include "vtcp.h"
 #include "vtim.h"
 
 #include "mgt_cli.h"
@@ -239,12 +238,6 @@ open_sockets(void)
 
 		mgt_child_inherit(ls->sock, "sock");
 
-		/*
-		 * Set nonblocking mode to avoid a race where a client
-		 * closes before we call accept(2) and nobody else are in
-		 * the listen queue to release us.
-		 */
-		(void)VTCP_filter_http(ls->sock);
 		good++;
 	}
 	if (!good)
diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c
index 9e42e06..31ef010 100644
--- a/bin/varnishd/mgt/mgt_param.c
+++ b/bin/varnishd/mgt/mgt_param.c
@@ -877,6 +877,10 @@ static const struct parspec input_parspec[] = {
 		"default.",
 		0,
 		"off", "bool" },
+	{ "accept_filter", tweak_bool, &mgt_param.accept_filter, 0, 0,
+		"Enable kernel accept-filters, if supported by the kernel.",
+		MUST_RESTART,
+		"on", "bool" },
 	{ "listen_address", tweak_listen_address, NULL, 0, 0,
 		"Whitespace separated list of network endpoints where "
 		"Varnish will accept requests.\n"
diff --git a/bin/varnishtest/tests/b00013.vtc b/bin/varnishtest/tests/b00013.vtc
index 57250ad..8ae90c4 100644
--- a/bin/varnishtest/tests/b00013.vtc
+++ b/bin/varnishtest/tests/b00013.vtc
@@ -9,10 +9,10 @@ server s1 {
 	txresp -body "foobar"
 } -start 
 
-varnish v1 -vcl+backend {} -start
+varnish v1 -arg "-p accept_filter=false" -vcl+backend {} -start
 
 client c1 {
-	send "GET /foo HTTP/1.1\n\nGET "
+	send "GET /foo HTTP/1.1\r\n\r\nGET "
 	rxresp
 	expect resp.status == 200
 	expect resp.http.content-length == 3
diff --git a/configure.ac b/configure.ac
index 952b71b..7e5e57e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -328,6 +328,15 @@ fi
 AM_MISSING_HAS_RUN
 AC_CHECK_PROGS(PYTHON, [python3 python3.1 python3.2 python2.7 python2.6 python2.5 python2 python], [AC_MSG_ERROR([Python is needed to build Varnish, please install python.])])
 
+AC_CHECK_DECL([SO_ACCEPTFILTER],
+    AC_DEFINE(HAVE_ACCEPT_FILTERS,1,[Define to 1 if you have accept filters]),
+    ,
+    [
+#include <sys/types.h>
+#include <sys/socket.h>
+    ]
+)
+
 # Older Solaris versions define SO_{RCV,SND}TIMEO, but do not
 # implement them.
 #
diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c
index e361738..8bb19d4 100644
--- a/lib/libvarnish/vtcp.c
+++ b/lib/libvarnish/vtcp.c
@@ -130,33 +130,46 @@ VTCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen)
 
 /*--------------------------------------------------------------------*/
 
+#ifdef HAVE_ACCEPT_FILTERS
+
 int
 VTCP_filter_http(int sock)
 {
-#ifdef HAVE_ACCEPT_FILTERS
+	int retval;
 	struct accept_filter_arg afa;
-	int i;
 
 	memset(&afa, 0, sizeof(afa));
 	strcpy(afa.af_name, "httpready");
-	errno = 0;
-	i = setsockopt(sock, SOL_SOCKET, SO_ACCEPTFILTER,
-	    &afa, sizeof(afa));
-	/* XXX ugly */
-	if (i)
-		printf("Acceptfilter(%d, httpready): %d %s\n",
-		    sock, i, strerror(errno));
-	return (i);
+	retval = setsockopt(sock, SOL_SOCKET, SO_ACCEPTFILTER,
+	    &afa, sizeof afa );
+	return (retval);
+}
+
 #elif defined(__linux)
+
+int
+VTCP_filter_http(int sock)
+{
+	int retval;
 	int defer = 1;
-	setsockopt(sock, SOL_TCP,TCP_DEFER_ACCEPT,(char *) &defer, sizeof(int));
-	return (0);
+
+	retval = setsockopt(sock, SOL_TCP,TCP_DEFER_ACCEPT,
+	    &defer, sizeof defer);
+	return (retval);
+}
+
 #else
+
+int
+VTCP_filter_http(int sock)
+{
+	errno = EOPNOTSUPP;
 	(void)sock;
-	return (0);
-#endif
+	return (-1);
 }
 
+#endif
+
 /*--------------------------------------------------------------------
  * Functions for controlling NONBLOCK mode.
  *



More information about the varnish-commit mailing list