[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