r4572 - in trunk/varnish-cache: bin/varnishd include lib/libvarnish

phk at projects.linpro.no phk at projects.linpro.no
Wed Feb 17 14:12:38 CET 2010


Author: phk
Date: 2010-02-17 14:12:07 +0100 (Wed, 17 Feb 2010)
New Revision: 4572

Modified:
   trunk/varnish-cache/bin/varnishd/cache_acceptor.c
   trunk/varnish-cache/include/libvarnish.h
   trunk/varnish-cache/lib/libvarnish/tcp.c
Log:
Try to handle socket state calls that return errno's relating
to the client absconding the TCP connection.

This comes to the fore on Solaris, where not only systemcalls which
push data through sockets (read,write,select...) return these errors,
but also socket-state calls (setsockopt, ioctl, fcntl) do.

Root cause of trouble in #626 & al.



Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor.c	2010-02-17 12:57:24 UTC (rev 4571)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor.c	2010-02-17 13:12:07 UTC (rev 4572)
@@ -105,16 +105,25 @@
 	struct linger lin;
 	struct timeval tv;
 	socklen_t l;
+	int i;
 
 	l = sizeof lin;
-	AZ(getsockopt(fd, SOL_SOCKET, SO_LINGER, &lin, &l));
+	i = getsockopt(fd, SOL_SOCKET, SO_LINGER, &lin, &l);
+	if (i) {
+		TCP_Assert(i);
+		return;
+	}
 	assert(l == sizeof lin);
 	if (memcmp(&lin, &linger, l))
 		need_linger = 1;
 
 #ifdef SO_SNDTIMEO_WORKS
 	l = sizeof tv;
-	AZ(getsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &l));
+	i = getsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &l);
+	if (i) {
+		TCP_Assert(i);
+		return;
+	}
 	assert(l == sizeof tv);
 	if (memcmp(&tv, &tv_sndtimeo, l))
 		need_sndtimeo = 1;
@@ -126,7 +135,11 @@
 
 #ifdef SO_RCVTIMEO_WORKS
 	l = sizeof tv;
-	AZ(getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &l));
+	i = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &l);
+	if (i) {
+		TCP_Assert(i);
+		return;
+	}
 	assert(l == sizeof tv);
 	if (memcmp(&tv, &tv_rcvtimeo, l))
 		need_rcvtimeo = 1;
@@ -168,16 +181,16 @@
 	if (need_test)
 		sock_test(sp->fd);
 	if (need_linger)
-		AZ(setsockopt(sp->fd, SOL_SOCKET, SO_LINGER,
+		TCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_LINGER,
 		    &linger, sizeof linger));
 #ifdef SO_SNDTIMEO_WORKS
 	if (need_sndtimeo)
-		AZ(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
+		TCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
 		    &tv_sndtimeo, sizeof tv_sndtimeo));
 #endif
 #ifdef SO_RCVTIMEO_WORKS
 	if (need_rcvtimeo)
-		AZ(setsockopt(sp->fd, SOL_SOCKET, SO_RCVTIMEO,
+		TCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_RCVTIMEO,
 		    &tv_rcvtimeo, sizeof tv_rcvtimeo));
 #endif
 }
@@ -365,8 +378,9 @@
 	 * Set nonblocking in the worker-thread, before passing to the
 	 * acceptor thread, to reduce syscall density of the latter.
 	 */
-	TCP_nonblocking(sp->fd);
-	if (vca_act->pass == NULL)
+	if (TCP_nonblocking(sp->fd))
+		vca_close_session(sp, "remote closed");
+	else if (vca_act->pass == NULL)
 		assert(sizeof sp == write(vca_pipes[1], &sp, sizeof sp));
 	else
 		vca_act->pass(sp);

Modified: trunk/varnish-cache/include/libvarnish.h
===================================================================
--- trunk/varnish-cache/include/libvarnish.h	2010-02-17 12:57:24 UTC (rev 4571)
+++ trunk/varnish-cache/include/libvarnish.h	2010-02-17 13:12:07 UTC (rev 4572)
@@ -60,12 +60,16 @@
 #define TCP_ADDRBUFSIZE		64
 #define TCP_PORTBUFSIZE		16
 
+#define TCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN)
+
+#define TCP_Assert(a) assert(TCP_Check(a))
+
 void TCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen);
 void TCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen);
 int TCP_filter_http(int sock);
-void TCP_blocking(int sock);
-void TCP_nonblocking(int sock);
-void TCP_linger(int sock, int linger);
+int TCP_blocking(int sock);
+int TCP_nonblocking(int sock);
+int TCP_linger(int sock, int linger);
 #ifdef SOL_SOCKET
 void TCP_name(const struct sockaddr *addr, unsigned l, char *abuf,
     unsigned alen, char *pbuf, unsigned plen);

Modified: trunk/varnish-cache/lib/libvarnish/tcp.c
===================================================================
--- trunk/varnish-cache/lib/libvarnish/tcp.c	2010-02-17 12:57:24 UTC (rev 4571)
+++ trunk/varnish-cache/lib/libvarnish/tcp.c	2010-02-17 13:12:07 UTC (rev 4572)
@@ -154,22 +154,26 @@
  * at least on FreeBSD.
  */
 
-void
+int
 TCP_blocking(int sock)
 {
-	int i;
+	int i, j;
 
 	i = 0;
-	AZ(ioctl(sock, FIONBIO, &i));
+	j = ioctl(sock, FIONBIO, &i);
+	TCP_Assert(j);
+	return (j);
 }
 
-void
+int
 TCP_nonblocking(int sock)
 {
-	int i;
+	int i, j;
 
 	i = 1;
-	AZ(ioctl(sock, FIONBIO, &i));
+	j = ioctl(sock, FIONBIO, &i);
+	TCP_Assert(j);
+	return (j);
 }
 
 /*--------------------------------------------------------------------
@@ -255,7 +259,7 @@
  * Set or reset SO_LINGER flag
  */
 
-void
+int
 TCP_linger(int sock, int linger)
 {
 	struct linger lin;
@@ -264,5 +268,6 @@
 	memset(&lin, 0, sizeof lin);
 	lin.l_onoff = linger;
 	i = setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof lin);
-	assert(i == 0 || errno == EBADF);
+	TCP_Assert(i);
+	return (i);
 }



More information about the varnish-commit mailing list