r4566 - trunk/varnish-cache/lib/libvarnish

phk at projects.linpro.no phk at projects.linpro.no
Tue Feb 16 22:12:23 CET 2010


Author: phk
Date: 2010-02-16 22:12:23 +0100 (Tue, 16 Feb 2010)
New Revision: 4566

Modified:
   trunk/varnish-cache/lib/libvarnish/tcp.c
Log:
Pretend to use variable, even if kernel is deficient.



Modified: trunk/varnish-cache/lib/libvarnish/tcp.c
===================================================================
--- trunk/varnish-cache/lib/libvarnish/tcp.c	2010-02-16 21:11:05 UTC (rev 4565)
+++ trunk/varnish-cache/lib/libvarnish/tcp.c	2010-02-16 21:12:23 UTC (rev 4566)
@@ -61,6 +61,45 @@
 
 #include "libvarnish.h"
 
+/*--------------------------------------------------------------------
+ * Recognize errno's we see when the remote end closed the connection.
+ *
+ * This "magic" is mostly needed because solaris wrongly returns EBADF
+ * when they should return ECONNRESET upon receiving a TCP-RST from the
+ * far end.
+ *
+ * My theory is, that some genius decided that since the socket is now
+ * officially useless, and since they already have found and locked
+ * the socket/pcb, they might as well get rid off it right away.
+ *
+ * On next use from the program, EBADF happens to be the errno, but since
+ * all programs just call strerror(), who cares ?
+ *
+ * Well, I do.  EBADF is the canonical "Programmer goofed" errno, and
+ * it should not be issued for other reasons.
+ *
+ * An interesting question here, is if the kernel might conceiveably
+ * reallocate the fd# before the application closes it, on the mistaken
+ * belief that it is unused ?  That would be bad news...
+ *
+ */
+
+int
+TCP_Errno(void)
+{
+
+	switch (errno) {
+	case ECONNRESET:
+    	case ENOTCONN:
+#if defined (__SVR4) && defined (__sun)
+	case EBADF:
+#endif
+		return (1);
+	default:
+		return (0);
+	}
+}
+
 /*--------------------------------------------------------------------*/
 
 void
@@ -232,9 +271,8 @@
 void
 TCP_close(int *s)
 {
-	assert (close(*s) == 0 ||
-	    errno == ECONNRESET ||
-	    errno == ENOTCONN);
+
+	assert (close(*s) == 0 || TCP_Errno());
 	*s = -1;
 }
 
@@ -246,6 +284,8 @@
 	timeout.tv_usec = (int)(1e6 * (seconds - timeout.tv_sec));
 #ifdef SO_RCVTIMEO_WORKS
 	AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout));
+#else
+	(void)s;
 #endif
 }
 



More information about the varnish-commit mailing list