[experimental-ims] 35f8ce5 Add proper handling of TCP timeouts on client side

Geoff Simmons geoff at varnish-cache.org
Mon Jan 9 21:52:30 CET 2012


commit 35f8ce5db8b3cf1025369bf4dbf6cd71a7556748
Author: Tollef Fog Heen <tfheen at varnish-software.com>
Date:   Mon Nov 7 14:05:36 2011 +0100

    Add proper handling of TCP timeouts on client side
    
    Retry if we hit a TCP timeout if some data was sent and only error out
    when we get an error or no data was sent in the time period.

diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c
index 0790ab2..5673b54 100644
--- a/bin/varnishd/cache_wrw.c
+++ b/bin/varnishd/cache_wrw.c
@@ -123,7 +123,37 @@ WRW_Flush(struct worker *w)
 			wrw->iov[wrw->ciov].iov_len = 0;
 		}
 		i = writev(*wrw->wfd, wrw->iov, wrw->niov);
-		if (i != wrw->liov) {
+		while (i != wrw->liov && i > 0) {
+			/* Remove sent data from start of I/O vector,
+			 * then retry; we hit a timeout, but some data
+			 * was sent.
+
+			 XXX: Add a "minimum sent data per timeout
+			 counter to prevent slowlaris attacks
+			*/
+			size_t used = 0;
+
+			WSL(w, SLT_Debug, *wrw->wfd,
+			    "Hit send timeout, wrote = %ld/%ld; retrying",
+			    i, wrw->liov);
+
+			for (int j = 0; j < wrw->niov; j++) {
+				if (used + wrw->iov[j].iov_len > i) {
+					/* Cutoff is in this iov */
+					int used_here = i - used;
+					wrw->iov[j].iov_len -= used_here;
+					wrw->iov[j].iov_base = (char*)wrw->iov[j].iov_base + used_here;
+					memmove(wrw->iov, &wrw->iov[j],
+						(wrw->niov - j) * sizeof(struct iovec));
+					wrw->niov -= j;
+					wrw->liov -= i;
+					break;
+				}
+				used += wrw->iov[j].iov_len;
+			}
+			i = writev(*wrw->wfd, wrw->iov, wrw->niov);
+		}
+		if (i <= 0) {
 			wrw->werr++;
 			WSL(w, SLT_Debug, *wrw->wfd,
 			    "Write error, retval = %d, len = %d, errno = %s",



More information about the varnish-commit mailing list