From phk at FreeBSD.org Mon Sep 2 06:49:07 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 2 Sep 2019 06:49:07 +0000 (UTC) Subject: [master] 7ff636dca free array returned by backtrace_symbols(3) Message-ID: <20190902064907.C296D6148@lists.varnish-cache.org> commit 7ff636dca1dc3e94ce19edba4ff38d4d9267726b Author: Guillaume Quintard Date: Wed Aug 28 12:32:43 2019 -0700 free array returned by backtrace_symbols(3) diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 2580b4ada..c45dfc4c0 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -646,6 +646,7 @@ pan_backtrace(struct vsb *vsb) VSB_printf(vsb, "%s", p); } VSB_printf (vsb, "\n"); + free(strings); } VSB_indent(vsb, -2); } From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] e23359291 Allow a NULL value in http_Proto Message-ID: <20190903100405.3727CAC10C@lists.varnish-cache.org> commit e23359291de6cb32144ae0ca7ae3cd688eb4ca3a Author: Martin Blix Grydeland Date: Thu Aug 15 10:44:00 2019 +0200 Allow a NULL value in http_Proto The proto field is optional in HTTP, so it may not be set. Set the proto to 0 also for a NULL value instead of segfaulting if it were NULL. diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index f1b40c861..ec65a9cb6 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -232,7 +232,8 @@ http_Proto(struct http *to) fm = to->hd[HTTP_HDR_PROTO].b; - if ((fm[0] == 'H' || fm[0] == 'h') && + if (fm != NULL && + (fm[0] == 'H' || fm[0] == 'h') && (fm[1] == 'T' || fm[1] == 't') && (fm[2] == 'T' || fm[2] == 't') && (fm[3] == 'P' || fm[3] == 'p') && From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] 1b508d154 Add bounds-checking to vct_iscrlf and vct_skipcrlf Message-ID: <20190903100405.09E8FAC109@lists.varnish-cache.org> commit 1b508d15475de456d77a412a54650b7259617b3b Author: Alf-Andr? Walla Date: Tue Aug 13 12:52:39 2019 +0200 Add bounds-checking to vct_iscrlf and vct_skipcrlf The macros vct_iscrlf() and vct_skipcrlf() may look at one or two bytes after its pointer value, causing OOB reads. This would allow http1_dissect_hdrs to wrongly see a CRLF when one wasn't there (the last LF left over in the bufer from the previous request). Change the macros to inline functions, and harden them by always sending the end pointer so that they can't overflow. vct_iscrlf() will return an int value of 0 for no [CR]LF, 1 for LF and 2 for CRLF. vct_skipcrlf() will return the pointer having been skipped 0, 1 or 2 bytes. diff --git a/bin/varnishd/cache/cache_vrt_filter.c b/bin/varnishd/cache/cache_vrt_filter.c index ddc0f2510..2f75dfda0 100644 --- a/bin/varnishd/cache/cache_vrt_filter.c +++ b/bin/varnishd/cache/cache_vrt_filter.c @@ -34,12 +34,12 @@ #include #include -#include "vct.h" - #include "cache_varnishd.h" #include "cache_vcl.h" #include "vrt_obj.h" +#include "vct.h" + #include "cache_filter.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 15090bdcf..c64a56853 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -120,31 +120,31 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, /* Find end of next header */ q = r = p; - if (vct_iscrlf(p)) + if (vct_iscrlf(p, htc->rxbuf_e)) break; while (r < htc->rxbuf_e) { if (!vct_isctl(*r) || vct_issp(*r)) { r++; continue; } - if (!vct_iscrlf(r)) { + if (!vct_iscrlf(r, htc->rxbuf_e)) { VSLb(hp->vsl, SLT_BogoHeader, "Header has ctrl char 0x%02x", *r); return (400); } q = r; assert(r < htc->rxbuf_e); - r += vct_skipcrlf(r); + r = vct_skipcrlf(r, htc->rxbuf_e); if (r >= htc->rxbuf_e) break; - if (vct_iscrlf(r)) + if (vct_iscrlf(r, htc->rxbuf_e)) break; /* If line does not continue: got it. */ if (!vct_issp(*r)) break; /* Clear line continuation LWS to spaces */ - while (vct_islws(*q)) + while (q < htc->rxbuf_e && vct_islws(*q)) *q++ = ' '; } @@ -269,7 +269,7 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[2]].b = p; /* Third field is optional and cannot contain CTL except TAB */ - for (; !vct_iscrlf(p); p++) { + for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { if (vct_isctl(*p) && !vct_issp(*p)) { hp->hd[hf[2]].b = NULL; return (400); @@ -278,7 +278,9 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[2]].e = p; /* Skip CRLF */ - i = vct_skipcrlf(p); + i = vct_iscrlf(p, htc->rxbuf_e); + if (!i) + return (400); *p = '\0'; p += i; diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index b8b9de4a7..67d07c312 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -428,20 +428,20 @@ http_splitheader(struct http *hp, int req) hh[n++] = p; while (!vct_islws(*p)) p++; - AZ(vct_iscrlf(p)); + AZ(vct_iscrlf(p, hp->rx_e)); *p++ = '\0'; /* URL/STATUS */ while (vct_issp(*p)) /* XXX: H space only */ p++; - AZ(vct_iscrlf(p)); + AZ(vct_iscrlf(p, hp->rx_e)); hh[n++] = p; while (!vct_islws(*p)) p++; - if (vct_iscrlf(p)) { + if (vct_iscrlf(p, hp->rx_e)) { hh[n++] = NULL; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); *q = '\0'; } else { *p++ = '\0'; @@ -449,30 +449,29 @@ http_splitheader(struct http *hp, int req) while (vct_issp(*p)) /* XXX: H space only */ p++; hh[n++] = p; - while (!vct_iscrlf(p)) + while (!vct_iscrlf(p, hp->rx_e)) p++; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); *q = '\0'; } assert(n == 3); while (*p != '\0') { assert(n < MAX_HDR); - if (vct_iscrlf(p)) + if (vct_iscrlf(p, hp->rx_e)) break; hh[n++] = p++; - while (*p != '\0' && !vct_iscrlf(p)) + while (*p != '\0' && !vct_iscrlf(p, hp->rx_e)) p++; if (*p == '\0') { break; } q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); *q = '\0'; } - if (*p != '\0') - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); assert(*p == '\0'); for (n = 0; n < 3 || hh[n] != NULL; n++) { @@ -568,7 +567,7 @@ http_rxchunk(struct http *hp) old = hp->rx_p; if (http_rxchar(hp, 2, 0) < 0) return (-1); - if (!vct_iscrlf(old)) { + if (!vct_iscrlf(old, hp->rx_e)) { vtc_log(hp->vl, hp->fatal, "Chunklen without CRLF"); return (-1); } diff --git a/include/vct.h b/include/vct.h index e9cf9be86..40425296a 100644 --- a/include/vct.h +++ b/include/vct.h @@ -30,6 +30,8 @@ /* from libvarnish/vct.c */ +#include "vas.h" + #define VCT_SP (1<<0) #define VCT_CRLF (1<<1) #define VCT_LWS (VCT_CRLF | VCT_SP) @@ -78,7 +80,22 @@ vct_is(int x, uint16_t y) #define vct_isxmlname(x) vct_is(x, VCT_XMLNAMESTART | VCT_XMLNAME) #define vct_istchar(x) vct_is(x, VCT_ALPHA | VCT_DIGIT | VCT_TCHAR) -#define vct_iscrlf(p) (((p)[0] == 0x0d && (p)[1] == 0x0a) || (p)[0] == 0x0a) +static inline int +vct_iscrlf(const char* p, const char* end) +{ + assert(p <= end); + if (p == end) + return (0); + if ((p[0] == 0x0d && (p+1 < end) && p[1] == 0x0a)) // CR LF + return (2); + if (p[0] == 0x0a) // LF + return (1); + return (0); +} /* NB: VCT always operate in ASCII, don't replace 0x0d with \r etc. */ -#define vct_skipcrlf(p) ((p)[0] == 0x0d && (p)[1] == 0x0a ? 2 : 1) +static inline char* +vct_skipcrlf(char* p, const char* end) +{ + return (p + vct_iscrlf(p, end)); +} diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c index 13bad74d1..7533158ac 100644 --- a/lib/libvarnish/vnum.c +++ b/lib/libvarnish/vnum.c @@ -38,9 +38,9 @@ #include "vdef.h" -#include "vct.h" #include "vnum.h" #include "vas.h" +#include "vct.h" static const char err_miss_num[] = "Missing number"; static const char err_invalid_num[] = "Invalid number"; From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] 5b1606ac0 Do not set the proto txt.b value when third field is missing Message-ID: <20190903100405.824C6AC114@lists.varnish-cache.org> commit 5b1606ac0eff9526c911c060f9b54e385b99f362 Author: Martin Blix Grydeland Date: Thu Aug 15 11:16:22 2019 +0200 Do not set the proto txt.b value when third field is missing In http1_splitline, if the third field is missing, we would still set the txt.b value to where the field would have been, with a NULL txt.e entry. This would cause http_Proto to attempt to parse the values there. Fix this by only setting the .b and .e if the third field was present. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 0531d7462..53d542196 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -266,7 +266,6 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, if (vct_isctl(*p)) return (400); } - hp->hd[hf[2]].b = p; if (q < p) *q = '\0'; /* Nul guard for the 2nd field. If q == p * (the third optional field is not @@ -274,13 +273,15 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, * cover this field. */ /* Third field is optional and cannot contain CTL except TAB */ + q = p; for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { - if (vct_isctl(*p) && !vct_issp(*p)) { - hp->hd[hf[2]].b = NULL; + if (vct_isctl(*p) && !vct_issp(*p)) return (400); - } } - hp->hd[hf[2]].e = p; + if (p > q) { + hp->hd[hf[2]].b = q; + hp->hd[hf[2]].e = p; + } /* Skip CRLF */ i = vct_iscrlf(p, htc->rxbuf_e); From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] 1a820aafb Fix http1_splitline parsing of 2 field HTTP proto lines using NLNL Message-ID: <20190903100405.5A7D0AC10F@lists.varnish-cache.org> commit 1a820aafb6a340ef44014d6a5a3e43d5ff3e6e93 Author: Martin Blix Grydeland Date: Thu Aug 15 10:56:58 2019 +0200 Fix http1_splitline parsing of 2 field HTTP proto lines using NLNL When parsing a request like this, "GET /\n\n", the first NL would be overwritten by nul guard inserted after the 2nd field, and the second NL would be overwritten by the nul guard after the missing 3rd field. This would cause http1_dissect_hdrs to attempt to decode the body as headers. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index c64a56853..0531d7462 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -218,7 +218,7 @@ static uint16_t http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, unsigned maxhdr) { - char *p; + char *p, *q; int i; assert(hf == HTTP1_Req || hf == HTTP1_Resp); @@ -259,14 +259,19 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[1]].e = p; if (!Tlen(hp->hd[hf[1]])) return (400); - *p++ = '\0'; /* Skip SP */ + q = p; for (; vct_issp(*p); p++) { if (vct_isctl(*p)) return (400); } hp->hd[hf[2]].b = p; + if (q < p) + *q = '\0'; /* Nul guard for the 2nd field. If q == p + * (the third optional field is not + * present), the last nul guard will + * cover this field. */ /* Third field is optional and cannot contain CTL except TAB */ for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] c3cb85760 Be stricter on final [CR]LF parsing in http1_dissect_hdrs Message-ID: <20190903100405.A20DAAC119@lists.varnish-cache.org> commit c3cb857602d96bc9d4e4a6058df6adafe29d802f Author: Martin Blix Grydeland Date: Thu Aug 15 11:19:41 2019 +0200 Be stricter on final [CR]LF parsing in http1_dissect_hdrs The end of http1_dissect_hdrs ends with skipping over the final [CR]LF that marks then end of the headers. Currently that skip is optional, that is, it is skipped if it was present. This patch adds an assert if the final [CR]LF is not found when finishing the parsing. HTTP1_Complete guarantees that it is there, if not we would not have started parsing the request or response in the first place, and if it is missing, there must be an error in the parsing leading up to it. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 53d542196..7f34e19be 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -111,6 +111,7 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, unsigned maxhdr) { char *q, *r, *s; + int i; assert(p > htc->rxbuf_b); assert(p <= htc->rxbuf_e); @@ -200,11 +201,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, return (400); } } - /* We cannot use vct_skipcrlf() we have to respect rxbuf_e */ - if (p+2 <= htc->rxbuf_e && p[0] == '\r' && p[1] == '\n') - p += 2; - else if (p+1 <= htc->rxbuf_e && p[0] == '\n') - p += 1; + i = vct_iscrlf(p, htc->rxbuf_e); + assert(i > 0); /* HTTP1_Complete guarantees this */ + p += i; HTC_RxPipeline(htc, p); htc->rxbuf_e = p; return (0); From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] ccfea8ba2 Fix HTTP header line continuation in http1_dissect_hdrs Message-ID: <20190903100405.BF8D0AC11E@lists.varnish-cache.org> commit ccfea8ba2917b9066c5f57d3072d11570e224dbf Author: Martin Blix Grydeland Date: Thu Aug 15 12:54:50 2019 +0200 Fix HTTP header line continuation in http1_dissect_hdrs When clearing the [CR]LF in a line continuation, we would continue replacing any [CR|LF|HT|SP] characters up until the end of the buffer, possibly overwriting later [CR]LFs. Fix this by only unconditionally overwrite one [CR]LF, and then only replace [HT|SP] with SP to keep with previous behaviour. Update r00494.vtc to include multiple line continuations to make sure they are parsed. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 7f34e19be..61563b8ea 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -145,7 +145,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, break; /* Clear line continuation LWS to spaces */ - while (q < htc->rxbuf_e && vct_islws(*q)) + while (q < r) + *q++ = ' '; + while (q < htc->rxbuf_e && vct_issp(*q)) *q++ = ' '; } diff --git a/bin/varnishtest/tests/r00494.vtc b/bin/varnishtest/tests/r00494.vtc index cb0bbe8d7..e0db8a4bf 100644 --- a/bin/varnishtest/tests/r00494.vtc +++ b/bin/varnishtest/tests/r00494.vtc @@ -6,6 +6,11 @@ server s1 { rxreq txresp -hdr {Foo: bar, barf: fail} -body "xxx" + + rxreq + txresp -hdr {Foo: bar, + + barf: fail} -body "xxx" } -start varnish v1 -vcl+backend { @@ -21,4 +26,10 @@ client c1 { expect resp.http.bar == "bar, barf: fail" expect resp.http.barf == expect resp.http.foo == + + txreq -url /2 + rxresp + expect resp.http.bar == "bar, barf: fail" + expect resp.http.barf == + expect resp.http.foo == } -run From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] 3fbb04308 Add a test case covering some HTTP/1 parsing corner cases Message-ID: <20190903100405.DA9DFAC122@lists.varnish-cache.org> commit 3fbb04308ac65bd06231fdbbb6918bf68912d1dd Author: Martin Blix Grydeland Date: Thu Aug 15 14:06:00 2019 +0200 Add a test case covering some HTTP/1 parsing corner cases diff --git a/bin/varnishtest/tests/b00069.vtc b/bin/varnishtest/tests/b00069.vtc new file mode 100644 index 000000000..2167c9483 --- /dev/null +++ b/bin/varnishtest/tests/b00069.vtc @@ -0,0 +1,29 @@ +varnishtest "HTTP/1 parsing checks" + +# Some tricky requests that have been known to cause parsing errors in the past. + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { +} -start + +# This test checks a bug that was dependent on the contents of the buffer left behind +# by the previous request +client c1 { + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nFoo: baar\r\n\r\n\r\n\r\n\r\n" + rxresp + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj\r" + rxresp + expect resp.status == 200 +} -run + +# This tests that the line continuation handling doesn't clear out the end of headers +# [CR]LF +client c1 { + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj" + rxresp + expect resp.status == 200 +} -run From martin at varnish-software.com Tue Sep 3 10:04:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:04:05 +0000 (UTC) Subject: [master] 406b583fe Avoid some code duplication Message-ID: <20190903100406.01933AC126@lists.varnish-cache.org> commit 406b583fe54634afd029e7a41e35b3cf9ccac28a Author: Martin Blix Grydeland Date: Fri Aug 23 13:53:42 2019 +0200 Avoid some code duplication Apply some adjustments to recent patches based off of review by Nils Goroll at UPLEX (@nigoroll) diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 61563b8ea..31c75ed88 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -128,15 +128,16 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, r++; continue; } - if (!vct_iscrlf(r, htc->rxbuf_e)) { + i = vct_iscrlf(r, htc->rxbuf_e); + if (i == 0) { VSLb(hp->vsl, SLT_BogoHeader, "Header has ctrl char 0x%02x", *r); return (400); } q = r; - assert(r < htc->rxbuf_e); - r = vct_skipcrlf(r, htc->rxbuf_e); - if (r >= htc->rxbuf_e) + r += i; + assert(r <= htc->rxbuf_e); + if (r == htc->rxbuf_e) break; if (vct_iscrlf(r, htc->rxbuf_e)) break; From martin at varnish-software.com Tue Sep 3 10:05:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:05 +0000 (UTC) Subject: [6.0] b4af2d116 Update changes.rst Message-ID: <20190903100505.DB89FAC9EF@lists.varnish-cache.org> commit b4af2d1164972d12e917ad2e12ae6cacba1f8ead Author: Martin Blix Grydeland Date: Tue Aug 27 11:14:07 2019 +0200 Update changes.rst diff --git a/doc/changes.rst b/doc/changes.rst index 08ff9b41e..226e2756f 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -26,6 +26,53 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. +================================ +Varnish Cache 6.0.4 (2019-08-27) +================================ + +* Now ``std.ip()`` can optionally take a port number or service name + argument. This is documented in the ``vmod_std(3)`` manual. (2993_) + +* Permit subsequent conditional requests on 304. (2871_) + +* Improved error messages from the VCL compiler on VMOD call argument + missmatch. (2874_) + +* Updated the builtin.vcl to use case-insensitive matching on + Surrogate-Control and Cache-Control backend response headers. + +* Ignore invalid Cache-Control time values containing trailing non-numeric + characters. + +* `varnishstat` now responds to the Home and End keys in interactive mode. + +* Fix a compile issue when using newer builds of gcc. (2879_) + +* Fix a VCL compilation assert when using very long VMOD object + names. (2880_) + +* Improved documentation on boolean types in VCL. (2846_) + +* New VRT functions for handling STRANDS (split strings) in + VMODs. `vmod_blob` now uses strands internally. + +* New log tag `VCL_use` will show which VCL is in use during request + handling. + +* Fail VCL loading if a VMOD objects are left uninitialized. (2839_) + +* Ensure that backend probes are executed in a timely manner. (2976_) + + +.. _2993: https://github.com/varnishcache/varnish-cache/pull/2993 +.. _2871: https://github.com/varnishcache/varnish-cache/issues/2871 +.. _2874: https://github.com/varnishcache/varnish-cache/issues/2874 +.. _2879: https://github.com/varnishcache/varnish-cache/issues/2879 +.. _2880: https://github.com/varnishcache/varnish-cache/issues/2880 +.. _2846: https://github.com/varnishcache/varnish-cache/issues/2846 +.. _2839: https://github.com/varnishcache/varnish-cache/issues/2839 +.. _2976: https://github.com/varnishcache/varnish-cache/issues/2976 + ================================ Varnish Cache 6.0.3 (2019-02-19) ================================ From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] 177e17c8f Add bounds-checking to vct_iscrlf and vct_skipcrlf Message-ID: <20190903100506.0F549AC9F3@lists.varnish-cache.org> commit 177e17c8f129c58daeeb98055761ee65ab5c3dfc Author: Alf-Andr? Walla Date: Tue Aug 13 12:52:39 2019 +0200 Add bounds-checking to vct_iscrlf and vct_skipcrlf The macros vct_iscrlf() and vct_skipcrlf() may look at one or two bytes after its pointer value, causing OOB reads. This would allow http1_dissect_hdrs to wrongly see a CRLF when one wasn't there (the last LF left over in the bufer from the previous request). Change the macros to inline functions, and harden them by always sending the end pointer so that they can't overflow. vct_iscrlf() will return an int value of 0 for no [CR]LF, 1 for LF and 2 for CRLF. vct_skipcrlf() will return the pointer having been skipped 0, 1 or 2 bytes. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index dd81863d3..5d99da47a 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -121,31 +121,31 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, /* Find end of next header */ q = r = p; - if (vct_iscrlf(p)) + if (vct_iscrlf(p, htc->rxbuf_e)) break; while (r < htc->rxbuf_e) { if (!vct_isctl(*r) || vct_issp(*r)) { r++; continue; } - if (!vct_iscrlf(r)) { + if (!vct_iscrlf(r, htc->rxbuf_e)) { VSLb(hp->vsl, SLT_BogoHeader, "Header has ctrl char 0x%02x", *r); return (400); } q = r; assert(r < htc->rxbuf_e); - r += vct_skipcrlf(r); + r = vct_skipcrlf(r, htc->rxbuf_e); if (r >= htc->rxbuf_e) break; - if (vct_iscrlf(r)) + if (vct_iscrlf(r, htc->rxbuf_e)) break; /* If line does not continue: got it. */ if (!vct_issp(*r)) break; /* Clear line continuation LWS to spaces */ - while (vct_islws(*q)) + while (q < htc->rxbuf_e && vct_islws(*q)) *q++ = ' '; } @@ -275,7 +275,7 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[2]].b = p; /* Third field is optional and cannot contain CTL except TAB */ - for (; !vct_iscrlf(p); p++) { + for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { if (vct_isctl(*p) && !vct_issp(*p)) { hp->hd[hf[2]].b = NULL; return (400); @@ -284,7 +284,9 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[2]].e = p; /* Skip CRLF */ - i = vct_skipcrlf(p); + i = vct_iscrlf(p, htc->rxbuf_e); + if (!i) + return (400); *p = '\0'; p += i; diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 616cb459e..e17643f8e 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -409,6 +409,7 @@ http_splitheader(struct http *hp, int req) char *p, *q, **hh; int n; char buf[20]; + const char* rxbuf_e = &hp->rxbuf[hp->prxbuf]; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); if (req) { @@ -428,20 +429,20 @@ http_splitheader(struct http *hp, int req) hh[n++] = p; while (!vct_islws(*p)) p++; - AZ(vct_iscrlf(p)); + AZ(vct_iscrlf(p, rxbuf_e)); *p++ = '\0'; /* URL/STATUS */ while (vct_issp(*p)) /* XXX: H space only */ p++; - AZ(vct_iscrlf(p)); + AZ(vct_iscrlf(p, rxbuf_e)); hh[n++] = p; while (!vct_islws(*p)) p++; - if (vct_iscrlf(p)) { + if (vct_iscrlf(p, rxbuf_e)) { hh[n++] = NULL; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, rxbuf_e); *q = '\0'; } else { *p++ = '\0'; @@ -449,26 +450,26 @@ http_splitheader(struct http *hp, int req) while (vct_issp(*p)) /* XXX: H space only */ p++; hh[n++] = p; - while (!vct_iscrlf(p)) + while (!vct_iscrlf(p, rxbuf_e)) p++; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, rxbuf_e); *q = '\0'; } assert(n == 3); while (*p != '\0') { assert(n < MAX_HDR); - if (vct_iscrlf(p)) + if (vct_iscrlf(p, rxbuf_e)) break; hh[n++] = p++; - while (*p != '\0' && !vct_iscrlf(p)) + while (*p != '\0' && !vct_iscrlf(p, rxbuf_e)) p++; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, rxbuf_e); *q = '\0'; } - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, rxbuf_e); assert(*p == '\0'); for (n = 0; n < 3 || hh[n] != NULL; n++) { @@ -564,15 +565,16 @@ http_rxchunk(struct http *hp) vtc_dump(hp->vl, 4, "chunk", hp->rxbuf + l, i); } l = hp->prxbuf; + if (http_rxchar(hp, 2, 0) < 0) return (-1); - if (!vct_iscrlf(hp->rxbuf + l)) { + if (!vct_iscrlf(&hp->rxbuf[l], &hp->rxbuf[hp->prxbuf])) { vtc_log(hp->vl, hp->fatal, "Wrong chunk tail[0] = %02x", hp->rxbuf[l] & 0xff); return (-1); } - if (!vct_iscrlf(hp->rxbuf + l + 1)) { + if (!vct_iscrlf(&hp->rxbuf[l + 1], &hp->rxbuf[hp->prxbuf])) { vtc_log(hp->vl, hp->fatal, "Wrong chunk tail[1] = %02x", hp->rxbuf[l + 1] & 0xff); diff --git a/include/vct.h b/include/vct.h index 24143a332..1b7ffbd4f 100644 --- a/include/vct.h +++ b/include/vct.h @@ -76,7 +76,22 @@ vct_is(int x, uint16_t y) #define vct_isxmlname(x) vct_is(x, VCT_XMLNAMESTART | VCT_XMLNAME) #define vct_istchar(x) vct_is(x, VCT_ALPHA | VCT_DIGIT | VCT_TCHAR) -#define vct_iscrlf(p) (((p)[0] == 0x0d && (p)[1] == 0x0a) || (p)[0] == 0x0a) +static inline int +vct_iscrlf(const char* p, const char* end) +{ + assert(p <= end); + if (p == end) + return (0); + if ((p[0] == 0x0d && (p+1 < end) && p[1] == 0x0a)) // CR LF + return (2); + if (p[0] == 0x0a) // LF + return (1); + return (0); +} /* NB: VCT always operate in ASCII, don't replace 0x0d with \r etc. */ -#define vct_skipcrlf(p) ((p)[0] == 0x0d && (p)[1] == 0x0a ? 2 : 1) +static inline char* +vct_skipcrlf(char* p, const char* end) +{ + return (p + vct_iscrlf(p, end)); +} From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] f98c25030 Allow a NULL value in http_Proto Message-ID: <20190903100506.2D966AC9FF@lists.varnish-cache.org> commit f98c250300bd7303bb7b706384ec153101a3eab0 Author: Martin Blix Grydeland Date: Thu Aug 15 10:44:00 2019 +0200 Allow a NULL value in http_Proto The proto field is optional in HTTP, so it may not be set. Set the proto to 0 also for a NULL value instead of segfaulting if it were NULL. diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 23eaa0b18..070ead2e6 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -212,7 +212,8 @@ http_Proto(struct http *to) fm = to->hd[HTTP_HDR_PROTO].b; - if ((fm[0] == 'H' || fm[0] == 'h') && + if (fm != NULL && + (fm[0] == 'H' || fm[0] == 'h') && (fm[1] == 'T' || fm[1] == 't') && (fm[2] == 'T' || fm[2] == 't') && (fm[3] == 'P' || fm[3] == 'p') && From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] 3dc8c15ad Fix http1_splitline parsing of 2 field HTTP proto lines using NLNL Message-ID: <20190903100506.4A69AACA0A@lists.varnish-cache.org> commit 3dc8c15adc23456f494fd23455b2251efe275eda Author: Martin Blix Grydeland Date: Thu Aug 15 10:56:58 2019 +0200 Fix http1_splitline parsing of 2 field HTTP proto lines using NLNL When parsing a request like this, "GET /\n\n", the first NL would be overwritten by nul guard inserted after the 2nd field, and the second NL would be overwritten by the nul guard after the missing 3rd field. This would cause http1_dissect_hdrs to attempt to decode the body as headers. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 5d99da47a..af9ca3898 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -224,7 +224,7 @@ static uint16_t http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, unsigned maxhdr) { - char *p; + char *p, *q; int i; assert(hf == HTTP1_Req || hf == HTTP1_Resp); @@ -265,14 +265,19 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[1]].e = p; if (!Tlen(hp->hd[hf[1]])) return (400); - *p++ = '\0'; /* Skip SP */ + q = p; for (; vct_issp(*p); p++) { if (vct_isctl(*p)) return (400); } hp->hd[hf[2]].b = p; + if (q < p) + *q = '\0'; /* Nul guard for the 2nd field. If q == p + * (the third optional field is not + * present), the last nul guard will + * cover this field. */ /* Third field is optional and cannot contain CTL except TAB */ for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] 73befed1a Do not set the proto txt.b value when third field is missing Message-ID: <20190903100506.69095ACA15@lists.varnish-cache.org> commit 73befed1a6950f5312e3a422dde82a7bb5a8bbe3 Author: Martin Blix Grydeland Date: Thu Aug 15 11:16:22 2019 +0200 Do not set the proto txt.b value when third field is missing In http1_splitline, if the third field is missing, we would still set the txt.b value to where the field would have been, with a NULL txt.e entry. This would cause http_Proto to attempt to parse the values there. Fix this by only setting the .b and .e if the third field was present. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index af9ca3898..e55555bf1 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -272,7 +272,6 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, if (vct_isctl(*p)) return (400); } - hp->hd[hf[2]].b = p; if (q < p) *q = '\0'; /* Nul guard for the 2nd field. If q == p * (the third optional field is not @@ -280,13 +279,15 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, * cover this field. */ /* Third field is optional and cannot contain CTL except TAB */ + q = p; for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { - if (vct_isctl(*p) && !vct_issp(*p)) { - hp->hd[hf[2]].b = NULL; + if (vct_isctl(*p) && !vct_issp(*p)) return (400); - } } - hp->hd[hf[2]].e = p; + if (p > q) { + hp->hd[hf[2]].b = q; + hp->hd[hf[2]].e = p; + } /* Skip CRLF */ i = vct_iscrlf(p, htc->rxbuf_e); From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] 3eb7a0458 Be stricter on final [CR]LF parsing in http1_dissect_hdrs Message-ID: <20190903100506.85168ACA23@lists.varnish-cache.org> commit 3eb7a04587d235bec5a312d3eae652abd8a63a14 Author: Martin Blix Grydeland Date: Thu Aug 15 11:19:41 2019 +0200 Be stricter on final [CR]LF parsing in http1_dissect_hdrs The end of http1_dissect_hdrs ends with skipping over the final [CR]LF that marks then end of the headers. Currently that skip is optional, that is, it is skipped if it was present. This patch adds an assert if the final [CR]LF is not found when finishing the parsing. HTTP1_Complete guarantees that it is there, if not we would not have started parsing the request or response in the first place, and if it is missing, there must be an error in the parsing leading up to it. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index e55555bf1..e5203a94e 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -111,6 +111,7 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, unsigned maxhdr) { char *q, *r, *s; + int i; assert(p > htc->rxbuf_b); assert(p <= htc->rxbuf_e); @@ -206,11 +207,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, return (400); } } - /* We cannot use vct_skipcrlf() we have to respect rxbuf_e */ - if (p+2 <= htc->rxbuf_e && p[0] == '\r' && p[1] == '\n') - p += 2; - else if (p+1 <= htc->rxbuf_e && p[0] == '\n') - p += 1; + i = vct_iscrlf(p, htc->rxbuf_e); + assert(i > 0); /* HTTP1_Complete guarantees this */ + p += i; HTC_RxPipeline(htc, p); htc->rxbuf_e = p; return (0); From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] bf18bb21e Fix HTTP header line continuation in http1_dissect_hdrs Message-ID: <20190903100506.A3E74ACA27@lists.varnish-cache.org> commit bf18bb21ef9c269edadac549b7b7d43fdb87051c Author: Martin Blix Grydeland Date: Thu Aug 15 12:54:50 2019 +0200 Fix HTTP header line continuation in http1_dissect_hdrs When clearing the [CR]LF in a line continuation, we would continue replacing any [CR|LF|HT|SP] characters up until the end of the buffer, possibly overwriting later [CR]LFs. Fix this by only unconditionally overwrite one [CR]LF, and then only replace [HT|SP] with SP to keep with previous behaviour. Update r00494.vtc to include multiple line continuations to make sure they are parsed. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index e5203a94e..e373d7d5d 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -146,7 +146,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, break; /* Clear line continuation LWS to spaces */ - while (q < htc->rxbuf_e && vct_islws(*q)) + while (q < r) + *q++ = ' '; + while (q < htc->rxbuf_e && vct_issp(*q)) *q++ = ' '; } diff --git a/bin/varnishtest/tests/r00494.vtc b/bin/varnishtest/tests/r00494.vtc index cb0bbe8d7..e0db8a4bf 100644 --- a/bin/varnishtest/tests/r00494.vtc +++ b/bin/varnishtest/tests/r00494.vtc @@ -6,6 +6,11 @@ server s1 { rxreq txresp -hdr {Foo: bar, barf: fail} -body "xxx" + + rxreq + txresp -hdr {Foo: bar, + + barf: fail} -body "xxx" } -start varnish v1 -vcl+backend { @@ -21,4 +26,10 @@ client c1 { expect resp.http.bar == "bar, barf: fail" expect resp.http.barf == expect resp.http.foo == + + txreq -url /2 + rxresp + expect resp.http.bar == "bar, barf: fail" + expect resp.http.barf == + expect resp.http.foo == } -run From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] ea1d09b3b Add a test case covering some HTTP/1 parsing corner cases Message-ID: <20190903100506.C28CFACA35@lists.varnish-cache.org> commit ea1d09b3b8ee8ad667b9d680013ed9448e0727dc Author: Martin Blix Grydeland Date: Thu Aug 15 14:06:00 2019 +0200 Add a test case covering some HTTP/1 parsing corner cases diff --git a/bin/varnishtest/tests/b00067.vtc b/bin/varnishtest/tests/b00067.vtc new file mode 100644 index 000000000..2167c9483 --- /dev/null +++ b/bin/varnishtest/tests/b00067.vtc @@ -0,0 +1,29 @@ +varnishtest "HTTP/1 parsing checks" + +# Some tricky requests that have been known to cause parsing errors in the past. + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { +} -start + +# This test checks a bug that was dependent on the contents of the buffer left behind +# by the previous request +client c1 { + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nFoo: baar\r\n\r\n\r\n\r\n\r\n" + rxresp + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj\r" + rxresp + expect resp.status == 200 +} -run + +# This tests that the line continuation handling doesn't clear out the end of headers +# [CR]LF +client c1 { + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj" + rxresp + expect resp.status == 200 +} -run From martin at varnish-software.com Tue Sep 3 10:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:06 +0000 (UTC) Subject: [6.0] a794dc6fe Update changelog Message-ID: <20190903100506.E0B6DACA3A@lists.varnish-cache.org> commit a794dc6feba1b48e352df5086db3d1be30abde9d Author: Martin Blix Grydeland Date: Fri Aug 16 13:21:37 2019 +0200 Update changelog diff --git a/doc/changes.rst b/doc/changes.rst index 226e2756f..e4ddebf5d 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -63,6 +63,7 @@ Varnish Cache 6.0.4 (2019-08-27) * Ensure that backend probes are executed in a timely manner. (2976_) +* Fixed issues related to HTTP/1 request parsing (VSV00003_) .. _2993: https://github.com/varnishcache/varnish-cache/pull/2993 .. _2871: https://github.com/varnishcache/varnish-cache/issues/2871 @@ -72,6 +73,7 @@ Varnish Cache 6.0.4 (2019-08-27) .. _2846: https://github.com/varnishcache/varnish-cache/issues/2846 .. _2839: https://github.com/varnishcache/varnish-cache/issues/2839 .. _2976: https://github.com/varnishcache/varnish-cache/issues/2976 +.. _VSV00003: https://varnish-cache.org/security/VSV00003.html ================================ Varnish Cache 6.0.3 (2019-02-19) From martin at varnish-software.com Tue Sep 3 10:05:07 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:05:07 +0000 (UTC) Subject: [6.0] 14d4eee6f Prepare for 6.0.4 Message-ID: <20190903100507.126AFACA42@lists.varnish-cache.org> commit 14d4eee6f0afc3020a044341235f54f3bd1449f1 Author: Martin Blix Grydeland Date: Tue Aug 27 12:38:29 2019 +0200 Prepare for 6.0.4 diff --git a/configure.ac b/configure.ac index 58153c804..b444ed72d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2019 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [6.0.3], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [6.0.4], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index e4ddebf5d..8626f4284 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -27,7 +27,7 @@ individual releases. These documents are updated as part of the release process. ================================ -Varnish Cache 6.0.4 (2019-08-27) +Varnish Cache 6.0.4 (2019-09-03) ================================ * Now ``std.ip()`` can optionally take a port number or service name From martin at varnish-software.com Tue Sep 3 10:06:04 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:04 +0000 (UTC) Subject: [6.2] 1cb778f6f Add bounds-checking to vct_iscrlf and vct_skipcrlf Message-ID: <20190903100604.E4444AD28A@lists.varnish-cache.org> commit 1cb778f6f69737109e8c070a74b8e95b78f46d13 Author: Alf-Andr? Walla Date: Tue Aug 13 12:52:39 2019 +0200 Add bounds-checking to vct_iscrlf and vct_skipcrlf The macros vct_iscrlf() and vct_skipcrlf() may look at one or two bytes after its pointer value, causing OOB reads. This would allow http1_dissect_hdrs to wrongly see a CRLF when one wasn't there (the last LF left over in the bufer from the previous request). Change the macros to inline functions, and harden them by always sending the end pointer so that they can't overflow. vct_iscrlf() will return an int value of 0 for no [CR]LF, 1 for LF and 2 for CRLF. vct_skipcrlf() will return the pointer having been skipped 0, 1 or 2 bytes. diff --git a/bin/varnishd/cache/cache_vrt_filter.c b/bin/varnishd/cache/cache_vrt_filter.c index 5e83a89a7..271be6ccd 100644 --- a/bin/varnishd/cache/cache_vrt_filter.c +++ b/bin/varnishd/cache/cache_vrt_filter.c @@ -34,12 +34,12 @@ #include #include -#include "vct.h" - #include "cache_varnishd.h" #include "cache_vcl.h" #include "vrt_obj.h" +#include "vct.h" + #include "cache_filter.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 15090bdcf..c64a56853 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -120,31 +120,31 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, /* Find end of next header */ q = r = p; - if (vct_iscrlf(p)) + if (vct_iscrlf(p, htc->rxbuf_e)) break; while (r < htc->rxbuf_e) { if (!vct_isctl(*r) || vct_issp(*r)) { r++; continue; } - if (!vct_iscrlf(r)) { + if (!vct_iscrlf(r, htc->rxbuf_e)) { VSLb(hp->vsl, SLT_BogoHeader, "Header has ctrl char 0x%02x", *r); return (400); } q = r; assert(r < htc->rxbuf_e); - r += vct_skipcrlf(r); + r = vct_skipcrlf(r, htc->rxbuf_e); if (r >= htc->rxbuf_e) break; - if (vct_iscrlf(r)) + if (vct_iscrlf(r, htc->rxbuf_e)) break; /* If line does not continue: got it. */ if (!vct_issp(*r)) break; /* Clear line continuation LWS to spaces */ - while (vct_islws(*q)) + while (q < htc->rxbuf_e && vct_islws(*q)) *q++ = ' '; } @@ -269,7 +269,7 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[2]].b = p; /* Third field is optional and cannot contain CTL except TAB */ - for (; !vct_iscrlf(p); p++) { + for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { if (vct_isctl(*p) && !vct_issp(*p)) { hp->hd[hf[2]].b = NULL; return (400); @@ -278,7 +278,9 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[2]].e = p; /* Skip CRLF */ - i = vct_skipcrlf(p); + i = vct_iscrlf(p, htc->rxbuf_e); + if (!i) + return (400); *p = '\0'; p += i; diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 0c772f50d..36c8964c6 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -431,20 +431,20 @@ http_splitheader(struct http *hp, int req) hh[n++] = p; while (!vct_islws(*p)) p++; - AZ(vct_iscrlf(p)); + AZ(vct_iscrlf(p, hp->rx_e)); *p++ = '\0'; /* URL/STATUS */ while (vct_issp(*p)) /* XXX: H space only */ p++; - AZ(vct_iscrlf(p)); + AZ(vct_iscrlf(p, hp->rx_e)); hh[n++] = p; while (!vct_islws(*p)) p++; - if (vct_iscrlf(p)) { + if (vct_iscrlf(p, hp->rx_e)) { hh[n++] = NULL; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); *q = '\0'; } else { *p++ = '\0'; @@ -452,26 +452,26 @@ http_splitheader(struct http *hp, int req) while (vct_issp(*p)) /* XXX: H space only */ p++; hh[n++] = p; - while (!vct_iscrlf(p)) + while (!vct_iscrlf(p, hp->rx_e)) p++; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); *q = '\0'; } assert(n == 3); while (*p != '\0') { assert(n < MAX_HDR); - if (vct_iscrlf(p)) + if (vct_iscrlf(p, hp->rx_e)) break; hh[n++] = p++; - while (*p != '\0' && !vct_iscrlf(p)) + while (*p != '\0' && !vct_iscrlf(p, hp->rx_e)) p++; q = p; - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); *q = '\0'; } - p += vct_skipcrlf(p); + p = vct_skipcrlf(p, hp->rx_e); assert(*p == '\0'); for (n = 0; n < 3 || hh[n] != NULL; n++) { @@ -567,7 +567,7 @@ http_rxchunk(struct http *hp) old = hp->rx_p; if (http_rxchar(hp, 2, 0) < 0) return (-1); - if (!vct_iscrlf(old)) { + if (!vct_iscrlf(old, hp->rx_e)) { vtc_log(hp->vl, hp->fatal, "Chunklen without CRLF"); return (-1); } diff --git a/include/vct.h b/include/vct.h index 24143a332..5a09020a0 100644 --- a/include/vct.h +++ b/include/vct.h @@ -30,6 +30,8 @@ /* from libvarnish/vct.c */ +#include "vas.h" + #define VCT_SP (1<<0) #define VCT_CRLF (1<<1) #define VCT_LWS (VCT_CRLF | VCT_SP) @@ -76,7 +78,22 @@ vct_is(int x, uint16_t y) #define vct_isxmlname(x) vct_is(x, VCT_XMLNAMESTART | VCT_XMLNAME) #define vct_istchar(x) vct_is(x, VCT_ALPHA | VCT_DIGIT | VCT_TCHAR) -#define vct_iscrlf(p) (((p)[0] == 0x0d && (p)[1] == 0x0a) || (p)[0] == 0x0a) +static inline int +vct_iscrlf(const char* p, const char* end) +{ + assert(p <= end); + if (p == end) + return (0); + if ((p[0] == 0x0d && (p+1 < end) && p[1] == 0x0a)) // CR LF + return (2); + if (p[0] == 0x0a) // LF + return (1); + return (0); +} /* NB: VCT always operate in ASCII, don't replace 0x0d with \r etc. */ -#define vct_skipcrlf(p) ((p)[0] == 0x0d && (p)[1] == 0x0a ? 2 : 1) +static inline char* +vct_skipcrlf(char* p, const char* end) +{ + return (p + vct_iscrlf(p, end)); +} diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c index 13bad74d1..7533158ac 100644 --- a/lib/libvarnish/vnum.c +++ b/lib/libvarnish/vnum.c @@ -38,9 +38,9 @@ #include "vdef.h" -#include "vct.h" #include "vnum.h" #include "vas.h" +#include "vct.h" static const char err_miss_num[] = "Missing number"; static const char err_invalid_num[] = "Invalid number"; From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] 0f0e51e98 Allow a NULL value in http_Proto Message-ID: <20190903100605.15279AD28D@lists.varnish-cache.org> commit 0f0e51e9871ed1bd1236378f8b0dea0d33df4e9e Author: Martin Blix Grydeland Date: Thu Aug 15 10:44:00 2019 +0200 Allow a NULL value in http_Proto The proto field is optional in HTTP, so it may not be set. Set the proto to 0 also for a NULL value instead of segfaulting if it were NULL. diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 5e3c92cd0..63d25799b 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -232,7 +232,8 @@ http_Proto(struct http *to) fm = to->hd[HTTP_HDR_PROTO].b; - if ((fm[0] == 'H' || fm[0] == 'h') && + if (fm != NULL && + (fm[0] == 'H' || fm[0] == 'h') && (fm[1] == 'T' || fm[1] == 't') && (fm[2] == 'T' || fm[2] == 't') && (fm[3] == 'P' || fm[3] == 'p') && From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] 72df38fa8 Fix http1_splitline parsing of 2 field HTTP proto lines using NLNL Message-ID: <20190903100605.32D5DAD291@lists.varnish-cache.org> commit 72df38fa8bfc0f5ca4a75d3e32657e8e590d85ab Author: Martin Blix Grydeland Date: Thu Aug 15 10:56:58 2019 +0200 Fix http1_splitline parsing of 2 field HTTP proto lines using NLNL When parsing a request like this, "GET /\n\n", the first NL would be overwritten by nul guard inserted after the 2nd field, and the second NL would be overwritten by the nul guard after the missing 3rd field. This would cause http1_dissect_hdrs to attempt to decode the body as headers. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index c64a56853..0531d7462 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -218,7 +218,7 @@ static uint16_t http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, unsigned maxhdr) { - char *p; + char *p, *q; int i; assert(hf == HTTP1_Req || hf == HTTP1_Resp); @@ -259,14 +259,19 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, hp->hd[hf[1]].e = p; if (!Tlen(hp->hd[hf[1]])) return (400); - *p++ = '\0'; /* Skip SP */ + q = p; for (; vct_issp(*p); p++) { if (vct_isctl(*p)) return (400); } hp->hd[hf[2]].b = p; + if (q < p) + *q = '\0'; /* Nul guard for the 2nd field. If q == p + * (the third optional field is not + * present), the last nul guard will + * cover this field. */ /* Third field is optional and cannot contain CTL except TAB */ for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] dd47e658a Do not set the proto txt.b value when third field is missing Message-ID: <20190903100605.55D7EAD29E@lists.varnish-cache.org> commit dd47e658a0de9d12c433a4a01fb43ea4fe4d3a41 Author: Martin Blix Grydeland Date: Thu Aug 15 11:16:22 2019 +0200 Do not set the proto txt.b value when third field is missing In http1_splitline, if the third field is missing, we would still set the txt.b value to where the field would have been, with a NULL txt.e entry. This would cause http_Proto to attempt to parse the values there. Fix this by only setting the .b and .e if the third field was present. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 0531d7462..53d542196 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -266,7 +266,6 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, if (vct_isctl(*p)) return (400); } - hp->hd[hf[2]].b = p; if (q < p) *q = '\0'; /* Nul guard for the 2nd field. If q == p * (the third optional field is not @@ -274,13 +273,15 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf, * cover this field. */ /* Third field is optional and cannot contain CTL except TAB */ + q = p; for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) { - if (vct_isctl(*p) && !vct_issp(*p)) { - hp->hd[hf[2]].b = NULL; + if (vct_isctl(*p) && !vct_issp(*p)) return (400); - } } - hp->hd[hf[2]].e = p; + if (p > q) { + hp->hd[hf[2]].b = q; + hp->hd[hf[2]].e = p; + } /* Skip CRLF */ i = vct_iscrlf(p, htc->rxbuf_e); From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] 34717183b Be stricter on final [CR]LF parsing in http1_dissect_hdrs Message-ID: <20190903100605.728A2AD2A2@lists.varnish-cache.org> commit 34717183beda3803e3d54c9826a1a9f026ca2505 Author: Martin Blix Grydeland Date: Thu Aug 15 11:19:41 2019 +0200 Be stricter on final [CR]LF parsing in http1_dissect_hdrs The end of http1_dissect_hdrs ends with skipping over the final [CR]LF that marks then end of the headers. Currently that skip is optional, that is, it is skipped if it was present. This patch adds an assert if the final [CR]LF is not found when finishing the parsing. HTTP1_Complete guarantees that it is there, if not we would not have started parsing the request or response in the first place, and if it is missing, there must be an error in the parsing leading up to it. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 53d542196..7f34e19be 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -111,6 +111,7 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, unsigned maxhdr) { char *q, *r, *s; + int i; assert(p > htc->rxbuf_b); assert(p <= htc->rxbuf_e); @@ -200,11 +201,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, return (400); } } - /* We cannot use vct_skipcrlf() we have to respect rxbuf_e */ - if (p+2 <= htc->rxbuf_e && p[0] == '\r' && p[1] == '\n') - p += 2; - else if (p+1 <= htc->rxbuf_e && p[0] == '\n') - p += 1; + i = vct_iscrlf(p, htc->rxbuf_e); + assert(i > 0); /* HTTP1_Complete guarantees this */ + p += i; HTC_RxPipeline(htc, p); htc->rxbuf_e = p; return (0); From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] ec3997a59 Fix HTTP header line continuation in http1_dissect_hdrs Message-ID: <20190903100605.93966AD2B1@lists.varnish-cache.org> commit ec3997a59a93cbc13a3cba22dfe0b4c4710a8f65 Author: Martin Blix Grydeland Date: Thu Aug 15 12:54:50 2019 +0200 Fix HTTP header line continuation in http1_dissect_hdrs When clearing the [CR]LF in a line continuation, we would continue replacing any [CR|LF|HT|SP] characters up until the end of the buffer, possibly overwriting later [CR]LFs. Fix this by only unconditionally overwrite one [CR]LF, and then only replace [HT|SP] with SP to keep with previous behaviour. Update r00494.vtc to include multiple line continuations to make sure they are parsed. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 7f34e19be..61563b8ea 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -145,7 +145,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, break; /* Clear line continuation LWS to spaces */ - while (q < htc->rxbuf_e && vct_islws(*q)) + while (q < r) + *q++ = ' '; + while (q < htc->rxbuf_e && vct_issp(*q)) *q++ = ' '; } diff --git a/bin/varnishtest/tests/r00494.vtc b/bin/varnishtest/tests/r00494.vtc index cb0bbe8d7..e0db8a4bf 100644 --- a/bin/varnishtest/tests/r00494.vtc +++ b/bin/varnishtest/tests/r00494.vtc @@ -6,6 +6,11 @@ server s1 { rxreq txresp -hdr {Foo: bar, barf: fail} -body "xxx" + + rxreq + txresp -hdr {Foo: bar, + + barf: fail} -body "xxx" } -start varnish v1 -vcl+backend { @@ -21,4 +26,10 @@ client c1 { expect resp.http.bar == "bar, barf: fail" expect resp.http.barf == expect resp.http.foo == + + txreq -url /2 + rxresp + expect resp.http.bar == "bar, barf: fail" + expect resp.http.barf == + expect resp.http.foo == } -run From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] af13de03e Add a test case covering some HTTP/1 parsing corner cases Message-ID: <20190903100605.B3E37AD2B6@lists.varnish-cache.org> commit af13de03eaa3d04f60ada52ed3235d545b8d3973 Author: Martin Blix Grydeland Date: Thu Aug 15 14:06:00 2019 +0200 Add a test case covering some HTTP/1 parsing corner cases diff --git a/bin/varnishtest/tests/b00069.vtc b/bin/varnishtest/tests/b00069.vtc new file mode 100644 index 000000000..2167c9483 --- /dev/null +++ b/bin/varnishtest/tests/b00069.vtc @@ -0,0 +1,29 @@ +varnishtest "HTTP/1 parsing checks" + +# Some tricky requests that have been known to cause parsing errors in the past. + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { +} -start + +# This test checks a bug that was dependent on the contents of the buffer left behind +# by the previous request +client c1 { + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nFoo: baar\r\n\r\n\r\n\r\n\r\n" + rxresp + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj\r" + rxresp + expect resp.status == 200 +} -run + +# This tests that the line continuation handling doesn't clear out the end of headers +# [CR]LF +client c1 { + send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj" + rxresp + expect resp.status == 200 +} -run From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] 6da64a47b Avoid some code duplication Message-ID: <20190903100605.D1C62AD2BB@lists.varnish-cache.org> commit 6da64a47beff44ecdb45c82b033811f2d19819af Author: Martin Blix Grydeland Date: Fri Aug 23 13:53:42 2019 +0200 Avoid some code duplication Apply some adjustments to recent patches based off of review by Nils Goroll at UPLEX (@nigoroll) diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 61563b8ea..31c75ed88 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -128,15 +128,16 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, r++; continue; } - if (!vct_iscrlf(r, htc->rxbuf_e)) { + i = vct_iscrlf(r, htc->rxbuf_e); + if (i == 0) { VSLb(hp->vsl, SLT_BogoHeader, "Header has ctrl char 0x%02x", *r); return (400); } q = r; - assert(r < htc->rxbuf_e); - r = vct_skipcrlf(r, htc->rxbuf_e); - if (r >= htc->rxbuf_e) + r += i; + assert(r <= htc->rxbuf_e); + if (r == htc->rxbuf_e) break; if (vct_iscrlf(r, htc->rxbuf_e)) break; From martin at varnish-software.com Tue Sep 3 10:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 3 Sep 2019 10:06:05 +0000 (UTC) Subject: [6.2] 9f8588e4a Prepare for 6.2.1 Message-ID: <20190903100605.F3D15AD2C1@lists.varnish-cache.org> commit 9f8588e4ab785244e06c3446fe09bf9db5dd8753 Author: Martin Blix Grydeland Date: Fri Aug 23 14:59:08 2019 +0200 Prepare for 6.2.1 Release Varnish 6.2.1 diff --git a/configure.ac b/configure.ac index 5639023e9..e80c8f179 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2019 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [6.2.0], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [6.2.1], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index 66ccbcdcc..3c0e400db 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -24,6 +24,17 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. +================================ +Varnish Cache 6.2.1 (2019-09-03) +================================ + +Bugs fixed +---------- + +* Fixed issues related to HTTP/1 request parsing (VSV00003_) + +.. _VSV00003: https://varnish-cache.org/security/VSV00003.html + ================================ Varnish Cache 6.2.0 (2019-03-15) ================================ From phk at FreeBSD.org Tue Sep 3 10:38:03 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 3 Sep 2019 10:38:03 +0000 (UTC) Subject: [master] a58d59edf White-space nit Message-ID: <20190903103803.C3F5B612EE@lists.varnish-cache.org> commit a58d59edf98dfb86c706fd95db289d1130407966 Author: Poul-Henning Kamp Date: Mon Aug 26 07:40:48 2019 +0000 White-space nit diff --git a/bin/varnishtest/tests/v00005.vtc b/bin/varnishtest/tests/v00005.vtc index 3fb2e6645..cd70d39c8 100644 --- a/bin/varnishtest/tests/v00005.vtc +++ b/bin/varnishtest/tests/v00005.vtc @@ -59,10 +59,10 @@ varnish v1 -errvcl {Probe request redefinition at:} { } varnish v1 -errvcl {Expected CNUM got '"120s"'} { - backend default { - .host = "127.0.0.1"; - .probe = { - .timeout = "120s"; - } - } + backend default { + .host = "127.0.0.1"; + .probe = { + .timeout = "120s"; + } + } } From phk at FreeBSD.org Tue Sep 3 10:38:03 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 3 Sep 2019 10:38:03 +0000 (UTC) Subject: [master] 2ce3ea3cf My thoughts about vsv00003 Message-ID: <20190903103803.D7EA5612F2@lists.varnish-cache.org> commit 2ce3ea3cfedbeae1990c63859b2c0dac54af6221 Author: Poul-Henning Kamp Date: Tue Sep 3 10:37:00 2019 +0000 My thoughts about vsv00003 diff --git a/doc/sphinx/phk/VSV00003.rst b/doc/sphinx/phk/VSV00003.rst new file mode 100644 index 000000000..dcb64f19e --- /dev/null +++ b/doc/sphinx/phk/VSV00003.rst @@ -0,0 +1,162 @@ +.. _phk_vsv00003: + +Here we are again - VSV00003 in perspective +=========================================== + +So it probably helps if you first re-read what I wrote two years ago +about our first :ref:`first major security hole. ` + +Statistically, it is incredibly hard to derive any information from +a single binary datapoint. + +If some event happens after X years, and that is all you know, there +is no way to meaningfully tell if that was a once per millenium +event arriving embarrassingly early or a biannual event arriving +fashionably late. + +We now have two datapoints: `VSV00001 `_ +happened after 11 year and `VSV00003 `_ +after 13 years [#f1]_. + +That allows us to cabin the expectations for the discovery of major +security problems in Varnish Cache to "probably about 3 per decade" [#f2]_. + +Given that one of my goals with Varnish Cache was to see how well +systems-programming in C can be done in the FOSS world [#f3]_ and +even though we are doing a lot better than most of the FOSS world, +that is a bit of a disappointment [#f4]_. + +The nature of the beast +----------------------- + +VSV00003 is a buffer overflow, a kind of bug which could have +manifested itself in many different ways, but here it runs directly +into the maw of an `assert` statement before it can do any harm, +so it is "merely" a Denial-Of-Service vulnerability. + +A DoS is of course bad enough, but not nearly as bad as a +remote code execution or information disclosure vulnerability +would have been. + +That, again, validates our strategy of littering our source code +with asserts, about one in ten source lines contain an assert, and +even more so that we leaving the asserts in the production code. + +I really wish more FOSS projects would pick up this practice. + +How did we find it +------------------ + +This is a bit embarrasing for me. + +For ages I have been muttering about wanting to "fuzz"[#f5]_ Varnish, +to see what would happen, but between all the many other items +on the TODO list, it never really bubbled to the top. + +A new employee at Varnish-Software needed a way to get to know +the source code, so he did, and struck this nugget of gold far +too fast. + +Hat-tip to Alf-Andr? Walla. + +Dealing with it +--------------- + +Martin Grydeland from Varnish Software has been the Senior Wrangler +of this security issue, while I deliberatly have taken a hands-off +stance, a decision I have no reason to regret. + +Thanks a lot Martin! + +As I explained at length in context of VSV00001, we really like to +be able to offer a VCL-based mitigation, so that people who +for one reason or another cannot update right away, still can +protect themselves. + +Initially we did not think that would even be possible, but tell +that to a German Engineer... + +Nils Goroll from UPLEX didn't quite say *"Halten Sie Mein Bier?"*, +but he did produce a VCL workaround right away, once again using +the inline-C capability, to frob things which are normally +"No User Serviceable Parts Behind This Door". + +Bravo Nils! + +Are we barking up the wrong tree ? +---------------------------------- + +An event like this is a good chance to "recalculate the route" +so to speak, and the first question we need to answer is if we +are barking up the wrong tree? + +Does it matter in the real world, that Varnish does not spit +out a handful of CVE's per year ? + +Would the significant amount of time we spend on trying to +prevent that be better used to extend Varnish ? + +There is no doubt that part of Varnish Cache's success is that +it is largely "fire & forget". + +Every so often I get an email from "the new guy" who just found a +Varnish instance which has been running for years, unbeknownst to +everybody still in the company. + +There are still Varnish 2.x and 3.x out there, running serious +workloads without making a fuzz about it. + +But is that actually a good thing ? + +Dan Geer thinks not, he has argued that all software should +have a firm expiry date, to prevent cyberspace ending as a +"Cybersecurity SuperFund Site". + +So far our two big security issues have both been DoS vulnerabilities, +and Varnish recovers as soon as the attack ends, but what if the +next one is a data-disclosure issue ? + +When Varnish users are not used to patch their Varnish instance, +would they even notice the security advisory, or would they +obliviously keep running the vulnerable code for years on end ? + +Of course, updating a software package has never been easier, in a +well-run installation it should be a non-event which happens +automatically. + +And in a world where August 2019 saw a grand total of 2004 CVEs, +how much should we (still) cater to people who "fire & forget" ? + +And finally we must ask ourselves if all the effort we spend on +code quality is worth it, if we still face a major security issue +as often as every other year ? + +We will be discussing these and many other issues at our next VDD. + +User input would be very welcome. + +*phk* + +.. rubric:: Footnotes + +.. [#f1] I'm not counting `VSV00002 `_, + it only affected a very small fraction of our users. + +.. [#f2] Sandia has a really fascinating introduction to + this obscure corner of statistics: + `Sensitivity in Risk Analyses with Uncertain Numbers + `_ + +.. [#f3] As distinct from for instance Aerospace or Automotive + organizations who must set aside serious resources for + Quality Assurance, meet legal requirements. + +.. [#f4] A disappointment not in any way reduced by the fact that + this is a bug of my own creation. + +.. [#f5] "Fuzzing" is a testing method to where you send random + garbage into your program, to see what happens. In practice + it is a lot more involved like that if you want it to + be an efficient process. John Regehr writes a lot about + it on `his blog "Embedded in Academia" `_ + and I fully agree with most of what he writes. diff --git a/doc/sphinx/phk/index.rst b/doc/sphinx/phk/index.rst index 70a7edc16..1870d959f 100644 --- a/doc/sphinx/phk/index.rst +++ b/doc/sphinx/phk/index.rst @@ -8,6 +8,7 @@ You may or may not want to know what Poul-Henning thinks. .. toctree:: :maxdepth: 1 + VSV00003.rst patent.rst lucky.rst apispaces.rst From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] 06a9a0d4b Store VSC exposed state per segment Message-ID: <20190909082306.5BFE0A6AC1@lists.varnish-cache.org> commit 06a9a0d4b927beeffe1114901eae10d1aa7e6637 Author: Martin Blix Grydeland Date: Fri Aug 2 14:26:03 2019 +0200 Store VSC exposed state per segment This moves the exposed flag handling to the segment level, rather than the point level. This enables not having to iterate over each point when there is no change from the previous. diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c index 8725124a7..a59a861c8 100644 --- a/lib/libvarnishapi/vsc.c +++ b/lib/libvarnishapi/vsc.c @@ -62,7 +62,6 @@ VTAILQ_HEAD(vsc_sf_head, vsc_sf); struct vsc_pt { struct VSC_point point; char *name; - int exposed; }; struct vsc_seg { @@ -77,6 +76,7 @@ struct vsc_seg { unsigned npoints; struct vsc_pt *points; + int exposed; }; struct vsc { @@ -368,26 +368,31 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp) */ static void -vsc_expose(const struct vsc *vsc, const struct vsc_seg *sp, int del) +vsc_expose(const struct vsc *vsc, struct vsc_seg *sp, int del) { struct vsc_pt *pp; unsigned u; + int expose; + + if (vsc->fnew != NULL && !sp->exposed && + !del && sp->head->ready == 1) + expose = 1; + else if (vsc->fdestroy != NULL && sp->exposed && + (del || sp->head->ready == 2)) + expose = 0; + else + return; pp = sp->points; for (u = 0; u < sp->npoints; u++, pp++) { if (pp->name == NULL) continue; - if (vsc->fdestroy != NULL && pp->exposed && - (del || sp->head->ready == 2)) { - vsc->fdestroy(vsc->priv, &pp->point); - pp->exposed = 0; - } - if (vsc->fnew != NULL && !pp->exposed && - !del && sp->head->ready == 1) { + if (expose) pp->point.priv = vsc->fnew(vsc->priv, &pp->point); - pp->exposed = 1; - } + else + vsc->fdestroy(vsc->priv, &pp->point); } + sp->exposed = expose; } /*-------------------------------------------------------------------- From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] e9436f63b Ignore index lines without either a '+' or '-' Message-ID: <20190909082306.709CEA6AC4@lists.varnish-cache.org> commit e9436f63be963a6d4942c4070504e0e8419c15cb Author: Martin Blix Grydeland Date: Thu Aug 29 17:43:12 2019 +0200 Ignore index lines without either a '+' or '-' When upgrading from when a previous release that doesn't have the latest VSM index file changes, the utilities will assert when trying to parse the index file from the previous version. Fix that by ignoring lines not starting with either '#', '+' or '-'. diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 53ceb387b..ba9ed716d 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -569,7 +569,7 @@ vsm_vlu_func(void *priv, const char *line) { struct vsm *vd; struct vsm_set *vs; - int i = -1; + int i = 0; CAST_OBJ_NOTNULL(vs, priv, VSM_SET_MAGIC); vd = vs->vsm; From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] 1e7b50b9f Speed up vsm_findseg Message-ID: <20190909082306.8A8C0A6AC7@lists.varnish-cache.org> commit 1e7b50b9fbd865aafc19e344f90679d9255f8d15 Author: Martin Blix Grydeland Date: Fri Aug 30 11:18:12 2019 +0200 Speed up vsm_findseg This speeds up vsm_findseg by keeping a direct pointer to the struct vsm_seg it points to in the vsm_fantom. To prevent stale vsm_fantoms in an application from causing segfaults, the last serial number seen is also kept on the fantom. If this serial number does not match, the slow path of iterating all segs to find the right match is done, and the fantom is updated to make any subsequent calls on the same fantom take the fast path. With this patch the fantoms store 2 serial numbers and a direct pointer to the seg. To fit this in struct vsm_fantom without breaking the ABI, the unused chunk pointer value has been repurposed, giving us two uintptr_t priv variables to work with. The direct segment pointer occupies one, and the two serial numbers occupy one half each of the other. This limits the bits for each serial to only 16 bits on 32 bit systems. But only direct matches is done, and it is unlikely that a stale fantom should have the exact right value to be accepted as valid. diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h index cd7387032..a852e4c77 100644 --- a/include/vapi/vsm.h +++ b/include/vapi/vsm.h @@ -44,7 +44,7 @@ struct vsm; struct vsm_fantom { uintptr_t priv; /* VSM private */ - struct VSM_chunk *chunk; + uintptr_t priv2; /* VSM private */ void *b; /* first byte of payload */ void *e; /* first byte past payload */ char *class; diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index ba9ed716d..2bd93f449 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -72,6 +72,17 @@ const struct vsm_valid VSM_valid[1] = {{"valid"}}; static vlu_f vsm_vlu_func; +#define VSM_PRIV_SHIFT \ + (sizeof (uintptr_t) * 4) +#define VSM_PRIV_MASK \ + (~((uintptr_t)UINTPTR_MAX << VSM_PRIV_SHIFT)) +#define VSM_PRIV_LOW(u) \ + ((uintptr_t)(u) & VSM_PRIV_MASK) +#define VSM_PRIV_HIGH(u) \ + (((uintptr_t)(u) >> VSM_PRIV_SHIFT) & VSM_PRIV_MASK) +#define VSM_PRIV_MERGE(low, high) \ + (VSM_PRIV_LOW(low) | (VSM_PRIV_LOW(high) << VSM_PRIV_SHIFT)) + /*--------------------------------------------------------------------*/ struct vsm_set; @@ -518,7 +529,8 @@ vsm_vlu_plus(struct vsm *vd, struct vsm_set *vs, const char *line) vg->av = av; vg->set = vs; vg->flags = VSM_FLAG_MARKSCAN; - vg->serial = ++vd->serial; + vg->serial = vd->serial; + VTAILQ_INSERT_TAIL(&vs->segs, vg, list); if (ac == 4) { vg->flags |= VSM_FLAG_CLUSTER; @@ -576,6 +588,11 @@ vsm_vlu_func(void *priv, const char *line) CHECK_OBJ_NOTNULL(vd, VSM_MAGIC); AN(line); + /* Up the serial counter. This wraps at UINTPTR_MAX/2 + * because thats the highest value we can store in struct + * vsm_fantom. */ + vd->serial = VSM_PRIV_LOW(vd->serial + 1); + switch (line[0]) { case '#': i = vsm_vlu_hash(vd, vs, line); @@ -602,6 +619,7 @@ vsm_readlines(struct vsm_set *vs) int i; do { + assert(vs->fd >= 0); i = VLU_Fd(vs->vlu, vs->fd); } while (!i); assert(i == -2); @@ -771,22 +789,44 @@ vsm_findseg(const struct vsm *vd, const struct vsm_fantom *vf) struct vsm_seg *vg; uintptr_t x; - x = vf->priv; + x = VSM_PRIV_HIGH(vf->priv); + if (x == vd->serial) { + vg = (struct vsm_seg *)vf->priv2; + if (!VALID_OBJ(vg, VSM_SEG_MAGIC) || + vg->serial != VSM_PRIV_LOW(vf->priv)) + WRONG("Corrupt fantom"); + return (vg); + } + + x = VSM_PRIV_LOW(vf->priv); vs = vd->mgt; VTAILQ_FOREACH(vg, &vs->segs, list) if (vg->serial == x) - return (vg); - VTAILQ_FOREACH(vg, &vs->stale, list) - if (vg->serial == x) - return (vg); + break; + if (vg == NULL) { + VTAILQ_FOREACH(vg, &vs->stale, list) + if (vg->serial == x) + break; + } vs = vd->child; - VTAILQ_FOREACH(vg, &vs->segs, list) - if (vg->serial == x) - return (vg); - VTAILQ_FOREACH(vg, &vs->stale, list) - if (vg->serial == x) - return (vg); - return (NULL); + if (vg == NULL) { + VTAILQ_FOREACH(vg, &vs->segs, list) + if (vg->serial == x) + break; + } + if (vg == NULL) { + VTAILQ_FOREACH(vg, &vs->stale, list) + if (vg->serial == x) + break; + } + if (vg == NULL) + return (NULL); + + /* Update the fantom with the new priv so that lookups will be + * fast on the next call. Note that this casts away the const. */ + ((struct vsm_fantom *)TRUST_ME(vf))->priv = + VSM_PRIV_MERGE(vg->serial, vd->serial); + return (vg); } /*--------------------------------------------------------------------*/ @@ -831,7 +871,8 @@ VSM__itern(struct vsm *vd, struct vsm_fantom *vf) } } memset(vf, 0, sizeof *vf); - vf->priv = vg->serial; + vf->priv = VSM_PRIV_MERGE(vg->serial, vd->serial); + vf->priv2 = (uintptr_t)vg; vf->class = vg->av[4]; vf->ident = vg->av[5]; AN(vf->class); @@ -854,7 +895,7 @@ VSM_Map(struct vsm *vd, struct vsm_fantom *vf) if (vg == NULL) return (vsm_diag(vd, "VSM_Map: bad fantom")); - assert(vg->serial == vf->priv); + assert(vg->serial == VSM_PRIV_LOW(vf->priv)); assert(vg->av[4] == vf->class); assert(vg->av[5] == vf->ident); From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] 68a04aecd Don't remove VSM_FLAG_CLUSTER too early Message-ID: <20190909082306.A4801A6ACC@lists.varnish-cache.org> commit 68a04aecdee977f5fac153779b65945feb201d04 Author: Martin Blix Grydeland Date: Fri Aug 30 15:18:46 2019 +0200 Don't remove VSM_FLAG_CLUSTER too early If a segment will be marked stale, it should not have its cluster flag removed until its actually deleted. This problem was observed in varnishtest as an assert. What happened was that a VSM_Map() was executed on a stale segment inside a cluster, which caused an assert when the cluster segment it pointed to was no longer marked VSM_FLAG_CLUSTER. diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 2bd93f449..6454b06b1 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -253,11 +253,6 @@ vsm_delseg(struct vsm_seg *vg, int refsok) CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC); - if (vg->flags & VSM_FLAG_CLUSTER) { - vg->flags &= ~VSM_FLAG_CLUSTER; - VTAILQ_REMOVE(&vg->set->clusters, vg, clist); - } - if (refsok && vg->refs) { AZ(vg->flags & VSM_FLAG_STALE); vg->flags |= VSM_FLAG_STALE; @@ -269,6 +264,11 @@ vsm_delseg(struct vsm_seg *vg, int refsok) if (vg->s != NULL) vsm_unmapseg(vg); + if (vg->flags & VSM_FLAG_CLUSTER) { + vg->flags &= ~VSM_FLAG_CLUSTER; + VTAILQ_REMOVE(&vg->set->clusters, vg, clist); + } + if (vg->flags & VSM_FLAG_STALE) VTAILQ_REMOVE(&vg->set->stale, vg, list); else From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] 63dbc260a Remove stale cluster segments when their refcount goes to zero Message-ID: <20190909082306.BECEAA6AD4@lists.varnish-cache.org> commit 63dbc260a86aecb694a6483ddfb4a2818d884945 Author: Martin Blix Grydeland Date: Fri Aug 30 15:24:32 2019 +0200 Remove stale cluster segments when their refcount goes to zero When a cluster is marked stale, there is no mechanism to actually remove it once all its containing segments (which would also be marked stale) goes away. Fix this by executing vsm_delseg on the cluster in VSM_Unmap if it is marked stale. diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 6454b06b1..a1961de8d 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -975,8 +975,13 @@ VSM_Unmap(struct vsm *vd, struct vsm_fantom *vf) assert(vg->s == NULL); assert(vg->sz == 0); assert(vg->cluster->refs > 0); - if (--vg->cluster->refs == 0) + if (--vg->cluster->refs == 0) { vsm_unmapseg(vg->cluster); + if (vg->cluster->flags & VSM_FLAG_STALE) { + AN(vg->flags & VSM_FLAG_STALE); + vsm_delseg(vg->cluster, 0); + } + } vg->b = vg->e = NULL; } else { vsm_unmapseg(vg); From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] 374b94331 Sprinkle CHECK_OBJ_NOTNULL on struct vsm_seg Message-ID: <20190909082306.DA1CBA6AEC@lists.varnish-cache.org> commit 374b94331178266da5835c454a853e34ad084ef4 Author: Martin Blix Grydeland Date: Sat Aug 31 12:43:39 2019 +0200 Sprinkle CHECK_OBJ_NOTNULL on struct vsm_seg Several places in the code lacked checking that these were still valid objects (ie not free'd). diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index a1961de8d..29be668ef 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -537,7 +537,7 @@ vsm_vlu_plus(struct vsm *vd, struct vsm_set *vs, const char *line) VTAILQ_INSERT_TAIL(&vs->clusters, vg, clist); } else if (*vg->av[2] != '0') { vg->cluster = vsm_findcluster(vs, vg->av[1]); - AN(vg->cluster); + CHECK_OBJ_NOTNULL(vg->cluster, VSM_SEG_MAGIC); } } return (0); @@ -924,6 +924,7 @@ VSM_Map(struct vsm *vd, struct vsm_fantom *vf) return (0); } + CHECK_OBJ_NOTNULL(vgc, VSM_SEG_MAGIC); assert(vgc->flags & VSM_FLAG_CLUSTER); assert(vg->s == NULL); assert(vg->sz == 0); @@ -964,6 +965,7 @@ VSM_Unmap(struct vsm *vd, struct vsm_fantom *vf) vg = vsm_findseg(vd, vf); if (vg == NULL) return (vsm_diag(vd, "VSM_Unmap: bad fantom")); + CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC); assert(vg->refs > 0); vg->refs--; vf->b = NULL; @@ -972,6 +974,7 @@ VSM_Unmap(struct vsm *vd, struct vsm_fantom *vf) return (0); if (vg->cluster) { + CHECK_OBJ_NOTNULL(vg->cluster, VSM_SEG_MAGIC); assert(vg->s == NULL); assert(vg->sz == 0); assert(vg->cluster->refs > 0); From martin at varnish-software.com Mon Sep 9 08:23:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:06 +0000 (UTC) Subject: [master] e264e7ea8 Remove the st_mtime check in vsm_refresh_set Message-ID: <20190909082306.F24F1A6AF3@lists.varnish-cache.org> commit e264e7ea80c42b5ddb389bb6885cb36123c5a73c Author: Martin Blix Grydeland Date: Sat Aug 31 12:46:40 2019 +0200 Remove the st_mtime check in vsm_refresh_set Now that we incrementally read the file, the check if the mtime of the index file has checked has to go away. If not, the index file will always be marked as new, forcing a reread of the entire index. diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 29be668ef..d62089986 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -662,8 +662,7 @@ vsm_refresh_set(struct vsm *vd, struct vsm_set *vs) st.st_dev != vs->fst.st_dev || st.st_mode != vs->fst.st_mode || st.st_size < vs->fst.st_size || - st.st_nlink < 1 || - memcmp(&st.st_mtime, &vs->fst.st_mtime, sizeof st.st_mtime))) { + st.st_nlink < 1)) { closefd(&vs->fd); } From martin at varnish-software.com Mon Sep 9 08:23:07 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:07 +0000 (UTC) Subject: [master] ec19cc19e Do not advance the vs->vg pointer unless there was a match Message-ID: <20190909082307.1837BA6AF9@lists.varnish-cache.org> commit ec19cc19ec8eebd8b9816c7e8977995e6ff76778 Author: Martin Blix Grydeland Date: Sat Aug 31 13:22:23 2019 +0200 Do not advance the vs->vg pointer unless there was a match The vsm_set vg pointer points to the last matched segment insertion, and is used as an optimization when looking for existing entries in the list. varnishd guarantees that insertions are always ordered, so there is no need to search the preceeding entries on a successful match. When parsing an index containg elements that included entries that are added and then subsequently removed in a later entry, this pointer would be advanced to the very end, failing to match the entries in between when parsing the rest of the file. Fix this mechanism by only updating the pointer on a successful match, and also advancing it one step it if the entry it is pointing to is removed. Note that these types of events are not supposed to be possible, because varnishd will when rewriting the index only include the active ones, removing any add-then-remove pairs. But if for whatever reason an attempt is made to reread a list, with this patch it should not cause problems. diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index d62089986..91540c8fd 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -253,6 +253,11 @@ vsm_delseg(struct vsm_seg *vg, int refsok) CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC); + if (vg->set->vg == vg) { + AZ(vg->flags & VSM_FLAG_STALE); + vg->set->vg = VTAILQ_NEXT(vg, list); + } + if (refsok && vg->refs) { AZ(vg->flags & VSM_FLAG_STALE); vg->flags |= VSM_FLAG_STALE; @@ -516,13 +521,18 @@ vsm_vlu_plus(struct vsm *vd, struct vsm_set *vs, const char *line) return(-1); } - while (vs->vg != NULL && vsm_cmp_av(&vs->vg->av[1], &av[1])) - vs->vg = VTAILQ_NEXT(vs->vg, list); - if (vs->vg != NULL) { - VAV_Free(av); + vg = vs->vg; + CHECK_OBJ_ORNULL(vg, VSM_SEG_MAGIC); + if (vg != NULL) + AZ(vg->flags & VSM_FLAG_STALE); + while (vg != NULL && vsm_cmp_av(&vg->av[1], &av[1])) + vg = VTAILQ_NEXT(vg, list); + if (vg != NULL) { /* entry compared equal, so it survives */ - vs->vg->flags |= VSM_FLAG_MARKSCAN; - vs->vg = VTAILQ_NEXT(vs->vg, list); + CHECK_OBJ_NOTNULL(vg, VSM_SEG_MAGIC); + VAV_Free(av); + vg->flags |= VSM_FLAG_MARKSCAN; + vs->vg = VTAILQ_NEXT(vg, list); } else { ALLOC_OBJ(vg, VSM_SEG_MAGIC); AN(vg); From martin at varnish-software.com Mon Sep 9 08:23:07 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 9 Sep 2019 08:23:07 +0000 (UTC) Subject: [master] b1a1c8a62 Adjust the segment length for the cluster allocation offset Message-ID: <20190909082307.35588A6B03@lists.varnish-cache.org> commit b1a1c8a6217f9eb8da25ff1d408fc91859f2e57d Author: Martin Blix Grydeland Date: Wed Sep 4 17:54:54 2019 +0200 Adjust the segment length for the cluster allocation offset Clusters VSM allocations start at offset 16. Make sure that the published segment includes that adjustment. diff --git a/bin/varnishd/common/common_vsmw.c b/bin/varnishd/common/common_vsmw.c index ee69eea56..71ced508f 100644 --- a/bin/varnishd/common/common_vsmw.c +++ b/bin/varnishd/common/common_vsmw.c @@ -317,7 +317,7 @@ VSMW_NewCluster(struct vsmw *vsmw, size_t len, const char *pfx) ALLOC_OBJ(seg, VSMWSEG_MAGIC); AN(seg); vc->cseg = seg; - seg->len = len; + seg->len = vc->len; seg->cluster = vc; REPLACE(seg->class, ""); REPLACE(seg->id, ""); From phk at FreeBSD.org Mon Sep 9 12:08:05 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 9 Sep 2019 12:08:05 +0000 (UTC) Subject: [master] 8e40d2548 Thinking about QUIC and OSI protocols Message-ID: <20190909120805.253BDADD37@lists.varnish-cache.org> commit 8e40d254802b6e668c52f64991d6471398381e87 Author: Poul-Henning Kamp Date: Mon Sep 9 12:07:30 2019 +0000 Thinking about QUIC and OSI protocols diff --git a/doc/sphinx/phk/index.rst b/doc/sphinx/phk/index.rst index 1870d959f..a65cad041 100644 --- a/doc/sphinx/phk/index.rst +++ b/doc/sphinx/phk/index.rst @@ -8,6 +8,7 @@ You may or may not want to know what Poul-Henning thinks. .. toctree:: :maxdepth: 1 + quic.rst VSV00003.rst patent.rst lucky.rst diff --git a/doc/sphinx/phk/quic.rst b/doc/sphinx/phk/quic.rst new file mode 100644 index 000000000..a92eeeb6a --- /dev/null +++ b/doc/sphinx/phk/quic.rst @@ -0,0 +1,176 @@ +QUIC visions of OSI +------------------- + +New York Times Style Magazine had an article last week +`about the Italian town Ivrea +`_, +which you have probably never heard about. + +Neither had I, 30+ years ago, when I got sent there as part of a project +to migrate the European Parliament from OSI protocols to TCP/IP. + +What ? You thought OSI protocols were only a theory ? + +Nothing could be further from the truth. + +One of the major reasons we are being bothered by Indian "Microsoft +Support" all the time is that the global telephone network runs on +Signalling System Number 7 ("SS7") which is very much an OSI +protocol. + +Your electricity meter very likely talks DLMS(/COSEM), which is also +an OSI protocol. + +In both cases, it cost serious money to just get to read the relevant +standards, which is why they could persist in this madness +undisturbed for decades. + +ITU-T finally saw the light a few years back, so now you can actually +Read `Q.700 `_ +if you do not belive me. + +Anyway, back in Luxembourg in the tail end of the 1980'ies, the European +parliament ran OSI protocols, and it sucked, and the more I dug into "The +Red/Yellow/Blue Book"[#f1]_, there more obvious it was that these +protocols were totally unsuitable for use on a local area network. + +We proposed to migrate the European Parliament to use TCP/IP, and +we did, which gave me a memorable year in Ivrea, but we could only +do so on the explicit condition, imposed by the European Commission, +that the parliament would migrate back, "?once the issues with the +OSI protocols were sorted out." + +They never sorted them out, because the OSI protocols were designed +and built by people who only considered communication between different +buildings, cities, countries and continents, but not what happened +inside each individual building [#f2]_. + +Having seen the title of this rant, you can probably already see where +I'm going with this, and you will be mostly right. + +The good news is that IETF learned their lesson, so QUIC is not +being rammed through and rubber-stamped the way HTTP/2 was, +in fact, one could argue that IETF got their revenge by handing +QUIC over to their arc-nemesis: +`The Transport Area `_. + +I think that was a good thing, because pretty much all of my +predictions about H2 came true, from the lack of benefits to the +DoS exposure designed into it. + +All those aliments came by because the people who pushed "H2 the +protocol previously known as SPDY" only considered the world from +the perspective of a huge company with geo-diverse datacenters for +whom packet loss is something that happens to other people and +congestion is solved by sending an email to Bandwidth Procurement. + +But those concerns are precisely what the "dinosaurs" in the Transport +Area care about and have studied and worked on for decades, so there +is every reason to expect that QUIC will emerge from the Transport +Area much better than it went in. + +While I was pretty certain that H2 would be a fizzle, I have a much +harder time seeing where QUIC will go. + +On the positive side, QUIC is a much better protocol, and it looks +like the kind of protocol we need in an increasingly mobile InterNet +where IP numbers are an ephemeral property. This is the carrot, and +it is a big and juicy one. + +In the neutral area QUIC is not a simple protocol, it is a full +transport protocol, which means loss detection, retransmission, +congestion control and all that, but you do not get better than TCP +without solving the problems TCP solved, and those are real and +hard problems. + +On the negative side, QUIC goes a long way to break through barriers +of authority, both by putting it on top of UDP to get it through +firewalls, but also by the very strong marriage to TLS1.3 which +dials privacy up to 11: Everything but the first byte of a QUIC +packet is encrypted. + +Authorities are not going to like that, and I can easily see more +autoritarian countries outright ban QUIC, and to make that ban +stick, they may even transition from "allowed if not banned" to +"banned if not allowed" firewalling. + +Of couse QUIC would still be a thing if you are big enough to +negotiate with G7-sized governments, and I would not be surprised +if QUIC ends up being a feasible protocol only for companies which +can point at the "job creation" their data-centers provide. + +The rest of us will have to wait and see where that leaves us. + +QUIC and Varnish +---------------- + +I can say with certainty that writing a QUIC implementation +from scratch, including TLS 1.3 is out of the question, that +is simply not happening. + +That leaves basically three options: + +1) Pick up a TLS library, write our own QUIC + +2) Pick up a QUIC library and the TLS library it uses. + +3) Stick with "That belongs in a separate process in front of Varnish." + +The precondition for linking an TLS library to Varnishd, is that +the private keys/certificates are still isolated in a different +address space, these days known as "KeyLess TLS". + +The good news is that QUIC is designed to do precisely that [#f3]_ . +The bad news is that as far as I can tell, none of the available +QUIC implementations do it, at least not yet. + +The actual selection of QUIC implementations we could adopt is very +short, and since I am not very inclined to make Go or Rust a +dependency for Varnish, it rapidly becomes even shorter. + +Presently, The H2O projects `quicly `_ +would probably be the most obvious candidate for us, but even that +would be a lot of work, and there is a some room between where +they have set their code quality bar, and where we have put ours. + +However, opting to write our own QUIC instead of adopting one +is a lot of work, not in the least for the necessary testing, +so all else being equal, adopting sounds more feasible. + +With number three we abdicate the ability to be "first line" if +QUIC/H3 does become the new black, and it would be incumbent on us +to make sure we work as well as possible with those "front burner" +boxes using a richer PROXY protocol or maybe a "naked" QUIC, +to maintain functionality. + +One argument for staying out of the fray is that our "No TLS in +Varnish" policy looks like it was the right decision. + +While it is inconvenient for small sites to have to run two +processes, as soon as sites grow, the feedback changes to +appreciation for the decoupling for TLS from policy/caching, +and once sites get even bigger, or more GDPR exposed, the +ability to use diverse TLS offloaders is seen as a big benefit. + +Finally, there is the little detail of testing: Varnishtest, +which has its own `VTest project `_ +now, will need to learn about HTTP3, QUIC and possibly TLS also. + +And of course, when we ask the Varnish users, they say *"Ohhh... +they all sound delicious, can we have the buffet ?"* :-) + +*phk* + + +.. rubric:: Footnotes + +.. [#f1] The ITU-U's standards were meant to come out in updated + printed volumes every four years, each "period" a different + color. + +.. [#f2] Not, and I want to stress this, because they were stupid + or ignorant, but it simply was not their job. Many + of them, like AT&T in USA, were legally banned from + the "computing" market. + +.. [#f3] See around figure 2 in `the QUIC/TLS draft `_. From phk at FreeBSD.org Mon Sep 9 12:26:05 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 9 Sep 2019 12:26:05 +0000 (UTC) Subject: [master] 26e4fed06 Fix header levels Message-ID: <20190909122605.671F2AE488@lists.varnish-cache.org> commit 26e4fed06880bd466ac86ee56f626f0e7bb7b6f5 Author: Poul-Henning Kamp Date: Mon Sep 9 12:25:19 2019 +0000 Fix header levels diff --git a/doc/sphinx/phk/quic.rst b/doc/sphinx/phk/quic.rst index a92eeeb6a..e874a5660 100644 --- a/doc/sphinx/phk/quic.rst +++ b/doc/sphinx/phk/quic.rst @@ -1,5 +1,5 @@ QUIC visions of OSI -------------------- +=================== New York Times Style Magazine had an article last week `about the Italian town Ivrea From phk at FreeBSD.org Mon Sep 9 14:15:06 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 9 Sep 2019 14:15:06 +0000 (UTC) Subject: [master] 98dc17709 Only fail on workspace exhaustion if we actually need it. Message-ID: <20190909141506.544DCB06FE@lists.varnish-cache.org> commit 98dc17709df79b91b964c79472af3b09779f481f Author: Poul-Henning Kamp Date: Mon Sep 9 14:13:25 2019 +0000 Only fail on workspace exhaustion if we actually need it. diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index d943fe205..e25866be1 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -513,20 +513,24 @@ VRT_UpperLowerStrands(VRT_CTX, VCL_STRANDS s, int up) (!up && vct_isupper(*p))) { *b++ = *p ^ 0x20; copy = 1; - } else { + } else if (b < e) { *b++ = *p; } - if (b == e) { - WS_Release(ctx->ws, 0); - VRT_fail(ctx, "Workspace overflow"); - return (NULL); - } + if (copy && b == e) + break; + } + if (copy && b == e) { + WS_Release(ctx->ws, 0); + VRT_fail(ctx, "Workspace overflow"); + return (NULL); } } + assert(b <= e); if (!copy) { WS_Release(ctx->ws, 0); return (q); } + assert(b < e); *b++ = '\0'; assert(b <= e); WS_ReleaseP(ctx->ws, b); From phk at FreeBSD.org Mon Sep 9 14:15:06 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 9 Sep 2019 14:15:06 +0000 (UTC) Subject: [master] 06ffea873 Fold req.htt.host to lowercase by default. Message-ID: <20190909141506.68985B0701@lists.varnish-cache.org> commit 06ffea8738b07b24de8ed0cd369f9229783b04ab Author: Poul-Henning Kamp Date: Mon Sep 9 14:13:54 2019 +0000 Fold req.htt.host to lowercase by default. diff --git a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl index ce4a5c445..a7e23f49a 100644 --- a/bin/varnishd/builtin.vcl +++ b/bin/varnishd/builtin.vcl @@ -35,6 +35,9 @@ vcl 4.0; # Client side sub vcl_recv { + if (req.http.host) { + set req.http.host = req.http.host.lower(); + } if (req.method == "PRI") { /* This will never happen in properly formed traffic (see: RFC7540) */ return (synth(405)); diff --git a/bin/varnishtest/tests/u00010.vtc b/bin/varnishtest/tests/u00010.vtc index dd37a15d0..9b92f0774 100644 --- a/bin/varnishtest/tests/u00010.vtc +++ b/bin/varnishtest/tests/u00010.vtc @@ -20,7 +20,7 @@ client c1 { varnish v1 -vsl_catchup -process p1 -expect-text 1 1 {list length 64} +process p1 -expect-text 1 1 {list length 6} process p1 -writehex 0c From phk at FreeBSD.org Mon Sep 9 19:50:09 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 9 Sep 2019 19:50:09 +0000 (UTC) Subject: [master] 904ceabf0 name vmod function / constructor / method RST xref like VCL Message-ID: <20190909195009.5587761DEF@lists.varnish-cache.org> commit 904ceabf07c294983efcebfe1d614c2d2fd5cdda Author: Nils Goroll Date: Mon Sep 9 12:52:52 2019 +0200 name vmod function / constructor / method RST xref like VCL as @slimhazard pointed out when reviewing a suggestion I made to some vmod documentation, the vmodtool generated link target names are confusing to users: vmod_foo.func is nothing you can use as VCL, while foo.func() is. diff --git a/doc/sphinx/reference/directors.rst b/doc/sphinx/reference/directors.rst index ace8b69d3..5d24e8fb9 100644 --- a/doc/sphinx/reference/directors.rst +++ b/doc/sphinx/reference/directors.rst @@ -162,7 +162,7 @@ Health Probes ============= It is possible in a VCL program to query the health of a director (see -:ref:`vmod_std.healthy`). A director can report its health if it implements the +:ref:`std.healthy()`). A director can report its health if it implements the ``healthy`` function, it is otherwise always considered healthy. Unless you are making a dynamic backend, you need to take care of the diff --git a/doc/sphinx/whats-new/changes-6.2.rst b/doc/sphinx/whats-new/changes-6.2.rst index 2fea0f335..afebe2de5 100644 --- a/doc/sphinx/whats-new/changes-6.2.rst +++ b/doc/sphinx/whats-new/changes-6.2.rst @@ -117,7 +117,7 @@ to make them more flexible and easier to use. The ``std.``\ *x2y* conversion functions are now deprecated. See :ref:`whatsnew_upgrading_std_conversion_2019_03`. -The function :ref:`vmod_directors.lookup` has been added to +The function :ref:`directors.lookup()` has been added to :ref:`vmod_directors(3)`, only for use in ``vcl_init`` or ``vcl_fini``. diff --git a/doc/sphinx/whats-new/upgrading-5.1.rst b/doc/sphinx/whats-new/upgrading-5.1.rst index 62a1726c4..9caba7e46 100644 --- a/doc/sphinx/whats-new/upgrading-5.1.rst +++ b/doc/sphinx/whats-new/upgrading-5.1.rst @@ -197,7 +197,7 @@ vcl_recv * Added ``req.storage``, which tells Varnish which storage backend to use if you choose to save the request body (see - :ref:`vmod_std.cache_req_body`). + :ref:`std.cache_req_body()`). * ``return(vcl(LABEL))`` may not be called after a restart. It can only be called from the active VCL instance. @@ -232,9 +232,9 @@ nuke limit is used in all cases. vmod_std ~~~~~~~~ -* Added ``std.getenv()``, see :ref:`vmod_std.getenv`. +* Added :ref:`std.getenv()`. -* Added ``std.late_100_continue()``, see :ref:`vmod_std.late_100_continue`. +* Added :ref:`std.late_100_continue()`. Other changes ============= diff --git a/doc/sphinx/whats-new/upgrading-5.2.rst b/doc/sphinx/whats-new/upgrading-5.2.rst index 8edd71b6b..d617ae1f9 100644 --- a/doc/sphinx/whats-new/upgrading-5.2.rst +++ b/doc/sphinx/whats-new/upgrading-5.2.rst @@ -121,7 +121,7 @@ situation. vmod_std ~~~~~~~~ -Added :ref:`vmod_std.file_exists`. +Added :ref:`std.file_exists()`. New VMODs in the standard distribution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/sphinx/whats-new/upgrading-6.0.rst b/doc/sphinx/whats-new/upgrading-6.0.rst index 7a0227995..4f9e3015d 100644 --- a/doc/sphinx/whats-new/upgrading-6.0.rst +++ b/doc/sphinx/whats-new/upgrading-6.0.rst @@ -461,9 +461,9 @@ backend, or set a value for the Host header in VCL. VMOD std -------- -:ref:`std.port(IP) ` always returns 0 when applied to a +:ref:`std.port()` always returns 0 when applied to a ``*.ip`` variable whose value is set to ``0.0.0.0`` because the -listener is UDS. :ref:`std.set_ip_tos(INT) ` is +listener is UDS. :ref:`std.set_ip_tos()` is silently ignored when the listener is UDS. The ``shard`` director @@ -519,7 +519,7 @@ except for ``req.restarts`` and ``req.xid``, which change by design. If you need to reset the client request headers to their original state (before changes in VCL), call -:ref:`std.rollback(req) `. +:ref:`std.rollback()`. ``return(restart)`` can now be called from ``vcl_recv{}``. diff --git a/doc/sphinx/whats-new/upgrading-6.1.rst b/doc/sphinx/whats-new/upgrading-6.1.rst index 7a5499af4..a9d286536 100644 --- a/doc/sphinx/whats-new/upgrading-6.1.rst +++ b/doc/sphinx/whats-new/upgrading-6.1.rst @@ -138,7 +138,7 @@ Other changes to VCL VMODs ===== -Added the :ref:`vmod_std.fnmatch` function to :ref:`vmod_std(3)`, which +Added the :ref:`std.fnmatch()` function to :ref:`vmod_std(3)`, which you can use for shell-style wildcard matching. Wildcard patterns may be a good fit for matching URLs, to match against a pattern like ``/foo/*/bar/*``. The patterns can be built at runtime, if you need to diff --git a/doc/sphinx/whats-new/upgrading-6.2.rst b/doc/sphinx/whats-new/upgrading-6.2.rst index 3659a664a..12746c208 100644 --- a/doc/sphinx/whats-new/upgrading-6.2.rst +++ b/doc/sphinx/whats-new/upgrading-6.2.rst @@ -58,11 +58,11 @@ The existing type-conversion functions in :ref:`vmod_std(3)` have been reworked to make them more flexible and easier to use. These functions now also accept suitable numeral or quantitative arguments. -* :ref:`vmod_std.duration` -* :ref:`vmod_std.bytes` -* :ref:`vmod_std.integer` -* :ref:`vmod_std.real` -* :ref:`vmod_std.time` +* :ref:`std.duration()` +* :ref:`std.bytes()` +* :ref:`std.integer()` +* :ref:`std.real()` +* :ref:`std.time()` These type-conversion functions should be fully backwards compatible, but the following differences should be noted: @@ -76,15 +76,15 @@ but the following differences should be noted: * Conversion functions now only ever truncate if necessary (instead of rounding). -* :ref:`vmod_std.round` has been added for explicit rounding. +* :ref:`std.round()` has been added for explicit rounding. The following functions are deprecated and should be replaced by the new conversion functions: -* :ref:`vmod_std.real2integer` -* :ref:`vmod_std.real2time` -* :ref:`vmod_std.time2integer` -* :ref:`vmod_std.time2real` +* :ref:`std.real2integer()` +* :ref:`std.real2time()` +* :ref:`std.time2integer()` +* :ref:`std.time2real()` They will be removed in a future version of Varnish. diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index fea8a955f..6181e8ffa 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -715,7 +715,7 @@ class FunctionStanza(Stanza): def parse(self): self.proto = ProtoType(self) - self.rstlbl = 'vmod_%s.%s' % (self.vcc.modname, self.proto.name) + self.rstlbl = '%s.%s()' % (self.vcc.modname, self.proto.name) self.vcc.contents.append(self) def cstuff(self, fo, where): @@ -748,7 +748,7 @@ class ObjectStanza(Stanza): self.fini.argstruct = False self.fini.args = [] - self.rstlbl = 'vmod_%s.%s' % (self.vcc.modname, self.proto.name) + self.rstlbl = '%s.%s()' % (self.vcc.modname, self.proto.name) self.vcc.contents.append(self) self.methods = [] @@ -831,7 +831,7 @@ class MethodStanza(Stanza): err("$Method %s: Method names need to start with . (dot)" % self.proto.bname, warn=False) self.proto.obj = "x" + self.pfx - self.rstlbl = 'vmod_%s.%s' % ( self.vcc.modname, self.proto.name) + self.rstlbl = 'x%s()' % self.proto.name p.methods.append(self) def cstruct(self, fo, define): diff --git a/lib/libvmod_blob/vmod.vcc b/lib/libvmod_blob/vmod.vcc index 5e34381a4..b29570df6 100644 --- a/lib/libvmod_blob/vmod.vcc +++ b/lib/libvmod_blob/vmod.vcc @@ -240,7 +240,7 @@ the encoding of the resulting blob according to the scheme *encoding*. *case* determines the case of hex digits for the ``HEX`` and ``URL`` encodings, and is ignored for other encodings. -As with `vmod_blob.decode`_: If *length* > 0, only decode the first +As with `blob.decode()`_: If *length* > 0, only decode the first *length* characters of the encoded string, otherwise decode the entire string. The default value of *length* is 0. @@ -274,8 +274,8 @@ object, i.e. they specify exactly the same region of memory, or both are empty. If the BLOBs are both empty (length is 0 and/or the internal pointer -is ``NULL``), then `vmod_blob.same`_ returns ``true``. If any -non-empty BLOB is compared to an empty BLOB, then `vmod_blob.same`_ +is ``NULL``), then `blob.same()`_ returns ``true``. If any +non-empty BLOB is compared to an empty BLOB, then `blob.same()`_ returns ``false``. $Function BOOL equal(BLOB, BLOB) @@ -283,9 +283,9 @@ $Function BOOL equal(BLOB, BLOB) Returns true if and only if the two BLOB arguments have equal contents (possibly in different memory regions). -As with `vmod_blob.same`_: If the BLOBs are both empty, then `vmod_blob.equal`_ +As with `blob.same()`_: If the BLOBs are both empty, then `blob.equal()`_ returns ``true``. If any non-empty BLOB is compared to an empty BLOB, -then `vmod_blob.equal`_ returns ``false``. +then `blob.equal()`_ returns ``false``. $Function INT length(BLOB) @@ -297,7 +297,7 @@ Returns a new BLOB formed from *length* bytes of the BLOB argument starting at *offset* bytes from the start of its memory region. The default value of *offset* is ``0B``. -`vmod_blob.sub`_ fails and returns NULL if the BLOB argument is empty, or if +`blob.sub()`_ fails and returns NULL if the BLOB argument is empty, or if ``offset + length`` requires more bytes than are available in the BLOB. @@ -350,28 +350,28 @@ Example:: # blob as base64 set resp.http.The-Blob-b64 = theblob1.encode(BASE64); -For any `vmod_blob.blob`_ object, `encoding` and `case`, encodings via -the `vmod_blob.blob.encode`_ method and the `vmod_blob.encode`_ +For any `blob.blob()`_ object, `encoding` and `case`, encodings via +the `xblob.encode()`_ method and the `blob.encode()`_ function are equal:: # Always true: blob.encode(ENC, CASE, blob.get()) == blob.encode(ENC, CASE) -But the `vmod_blob.blob.encode`_ object method is more efficient -- +But the `xblob.encode()`_ object method is more efficient -- the encoding is computed once and cached (with allocation in heap memory), and the cached encoding is retrieved on every subsequent -call. The `vmod_blob.encode`_ function computes the encoding on every +call. The `blob.encode()`_ function computes the encoding on every call, allocating space for the string in Varnish workspaces. So if the data in a BLOB are fixed at VCL initialization time, so that its encodings will always be the same, it is better to create a -`vmod_blob.blob`_ object. The VMOD's functions should be used for data that are +`blob.blob()`_ object. The VMOD's functions should be used for data that are not known until runtime. ERRORS ====== -The encoders, decoders and `vmod_blob.sub`_ may fail if there is +The encoders, decoders and `blob.sub()`_ may fail if there is insufficient space to create the new blob or string. Decoders may also fail if the encoded string is an illegal format for the decoding scheme. Encoders will fail for the ``IDENTITY`` and ``BASE64*`` @@ -381,7 +381,7 @@ If any of the VMOD's methods, functions or constructor fail, then VCL failure is invoked, just as if ``return(fail)`` had been called in the VCL source. This means that: -* If the ``vmod_blob.blob`_ object constructor fails, or if any methods or +* If the ``blob.blob()`_ object constructor fails, or if any methods or functions fail during ``vcl_init{}``, then the VCL program will fail to load, and the VCC compiler will emit an error message. @@ -399,18 +399,18 @@ LIMITATIONS =========== The VMOD allocates memory in various ways for new blobs and -strings. The `vmod_blob.blob`_ object and its methods allocate memory +strings. The `blob.blob()`_ object and its methods allocate memory from the heap, and hence they are only limited by available virtual memory. -The `vmod_blob.encode`_, `vmod_blob.decode`_ and -`vmod_blob.transcode`_ functions allocate Varnish workspace, as does -`vmod_blob.sub`_ for the newly created BLOB. If these functions are +The `blob.encode()`_, `blob.decode()`_ and +`blob.transcode()`_ functions allocate Varnish workspace, as does +`blob.sub()`_ for the newly created BLOB. If these functions are failing, as indicated by "out of space" messages in the Varnish log (with the ``VCL_Error`` tag), then you will need to increase the varnishd parameters ``workspace_client`` and/or ``workspace_backend``. -The `vmod_blob.transcode`_ function also allocates space on the stack +The `blob.transcode()`_ function also allocates space on the stack for a temporary BLOB. If this function causes stack overflow, you may need to increase the varnishd parameter ``thread_pool_stack``. diff --git a/lib/libvmod_directors/vmod.vcc b/lib/libvmod_directors/vmod.vcc index bafab18d6..0f27f3c29 100644 --- a/lib/libvmod_directors/vmod.vcc +++ b/lib/libvmod_directors/vmod.vcc @@ -190,7 +190,7 @@ $Object hash() Create a hashing backend director. The director chooses the backend server by computing a hash/digest of -the string given to `vmod_directors.hash.backend`_. +the string given to `xhash.backend()`_. Commonly used with ``client.ip`` or a session cookie to get sticky sessions. @@ -232,8 +232,8 @@ $Object shard() Create a shard director. Note that the shard director needs to be configured using at least one -`vmod_directors.shard.add_backend`_ call(s) **followed by a** -`vmod_directors.shard.reconfigure`_ **call** before it can hand out +`xshard.add_backend()`_ call(s) **followed by a** +`xshard.reconfigure()`_ **call** before it can hand out backends. _Note_ that due to various restrictions (documented below), it is @@ -312,14 +312,14 @@ The drawbacks are: Method `````` -When `vmod_directors.shard.reconfigure`_ is called, a consistent +When `xshard.reconfigure()`_ is called, a consistent hashing circular data structure gets built from the last 32 bits of SHA256 hash values of **\ ** (default *ident* being the backend name) for each backend and for a running number *n* from 1 to *replicas*. Hashing creates the seemingly random order for placement of backends on the consistent hashing ring. -When `vmod_directors.shard.backend`_ is called, a load balancing key +When `xshard.backend()`_ is called, a load balancing key gets generated unless provided. The smallest hash value in the circle is looked up that is larger than the key (searching clockwise and wrapping around as necessary). The backend for this hash value is the @@ -349,26 +349,26 @@ when configuring the shard director, you are advised to check:: $Method VOID .set_warmup(REAL probability=0.0) Set the default warmup probability. See the *warmup* parameter of -`vmod_directors.shard.backend`_. If *probability* is 0.0 (default), +`xshard.backend()`_. If *probability* is 0.0 (default), warmup is disabled. $Method VOID .set_rampup(DURATION duration=0) Set the default rampup duration. See *rampup* parameter of -`vmod_directors.shard.backend`_. If *duration* is 0 (default), rampup +`xshard.backend()`_. If *duration* is 0 (default), rampup is disabled. $Method VOID .associate(BLOB param=0) -Associate a default `vmod_directors.shard_param`_ object or clear an +Associate a default `directors.shard_param()`_ object or clear an association. The value of the *param* argument must be a call to the -`vmod_directors.shard_param.use`_ method. No argument clears the +`xshard_param.use()`_ method. No argument clears the association. The association can be changed per backend request using the *param* -argument of `vmod_directors.shard.backend`_. +argument of `xshard.backend()`_. $Method BOOL .add_backend(PRIV_TASK, BACKEND backend, [STRING ident], [DURATION rampup]) @@ -376,7 +376,7 @@ $Method BOOL .add_backend(PRIV_TASK, BACKEND backend, Add a backend *backend* to the director. *ident*: Optionally specify an identification string for this backend, -which will be hashed by `vmod_directors.shard.reconfigure`_ to +which will be hashed by `xshard.reconfigure()`_ to construct the consistent hashing ring. The identification string defaults to the backend name. @@ -384,10 +384,10 @@ defaults to the backend name. *rampup*: Optionally specify a specific rampup time for this backend. Otherwise, the per-director rampup time is used (see -`vmod_directors.shard.set_rampup`_). +`xshard.set_rampup()`_). NOTE: Backend changes need to be finalized with -`vmod_directors.shard.reconfigure`_ and are only supported on one +`xshard.reconfigure()`_ and are only supported on one shard director at a time. $Method BOOL .remove_backend(PRIV_TASK, [BACKEND backend=0], [STRING ident=0]) @@ -397,7 +397,7 @@ be specified. *ident* removes a specific instance. If *backend* is given without *ident*, all instances of this backend are removed. NOTE: Backend changes need to be finalized with -`vmod_directors.shard.reconfigure`_ and are only supported on one +`xshard.reconfigure()`_ and are only supported on one shard director at a time. $Method BOOL .clear(PRIV_TASK) @@ -405,7 +405,7 @@ $Method BOOL .clear(PRIV_TASK) Remove all backends from the director. NOTE: Backend changes need to be finalized with -`vmod_directors.shard.reconfigure`_ and are only supported on one +`xshard.reconfigure()`_ and are only supported on one shard director at a time. $Method BOOL .reconfigure(PRIV_TASK, INT replicas=67) @@ -418,12 +418,12 @@ used. $Method INT .key(STRANDS) Convenience method to generate a sharding key for use with the *key* -argument to the `vmod_directors.shard.backend`_ method by hashing the +argument to the `xshard.backend()`_ method by hashing the given string with SHA256. To generate sharding keys using other hashes, use a custom vmod like `vmod blobdigest`_ with the *key_blob* argument of the -`vmod_directors.shard.backend`_ method. +`xshard.backend()`_ method. .. _vmod blobdigest: https://code.uplex.de/uplex-varnish/libvmod-blobdigest/blob/master/README.rst @@ -464,7 +464,7 @@ is _not_ the order given when backends are added. * *key* lookup key with ``by=KEY`` - the `vmod_directors.shard.key`_ method may come handy to generate a + the `xshard.key()`_ method may come handy to generate a sharding key from custom strings. * *key_blob* lookup key with ``by=BLOB`` @@ -491,8 +491,8 @@ is _not_ the order given when backends are added. backend, unless this is also in its rampup period. The default rampup interval can be set per shard director using the - `vmod_directors.shard.set_rampup`_ method or specifically per - backend with the `vmod_directors.shard.add_backend`_ method. + `xshard.set_rampup()`_ method or specifically per + backend with the `xshard.add_backend()`_ method. * *warmup* probabilistic alternative server selection @@ -552,14 +552,14 @@ is _not_ the order given when backends are added. * *param* Use or associate a parameter set. The value of the *param* argument - must be a call to the `vmod_directors.shard_param.use`_ method. + must be a call to the `xshard_param.use()`_ method. - default: as set by `vmod_directors.shard.associate`_ or unset. + default: as set by `xshard.associate()`_ or unset. * for ``resolve=NOW`` take parameter defaults from the - `vmod_directors.shard_param`_ parameter set + `directors.shard_param()`_ parameter set - * for ``resolve=LAZY`` associate the `vmod_directors.shard_param`_ + * for ``resolve=LAZY`` associate the `directors.shard_param()`_ parameter set for this backend request Implementation notes for use of parameter sets with @@ -574,7 +574,7 @@ is _not_ the order given when backends are added. *param* argument is subsequently changed within the same backend request. - * Each call to `vmod_directors.shard.backend`_ overrides any + * Each call to `xshard.backend()`_ overrides any previous call. $Method VOID .debug(INT) @@ -585,7 +585,7 @@ $Object shard_param() Create a shard parameter set. -A parameter set allows for re-use of `vmod_directors.shard.backend`_ +A parameter set allows for re-use of `xshard.backend()`_ arguments across many shard director instances and simplifies advanced use cases (e.g. shard director with custom parameters layered below other directors). @@ -636,7 +636,7 @@ implement retries on alternative backends:: $Method VOID .clear() Reset the parameter set to default values as documented for -`vmod_directors.shard.backend`_. +`xshard.backend()`_. * in ``vcl_init{}``, resets the parameter set default for this VCL * in backend context, resets the parameter set for this backend @@ -654,7 +654,7 @@ $Method VOID .set( [ ENUM {CHOSEN, IGNORE, ALL} healthy ]) Change the given parameters of a parameter set as documented for -`vmod_directors.shard.backend`_. +`xshard.backend()`_. * in ``vcl_init{}``, changes the parameter set default for this VCL @@ -668,39 +668,39 @@ $Method STRING .get_by() Get a string representation of the *by* enum argument which denotes how a shard director using this parameter object would derive the -shard key. See `vmod_directors.shard.backend`_. +shard key. See `xshard.backend()`_. $Method INT .get_key() Get the key which a shard director using this parameter object would -use. See `vmod_directors.shard.backend`_. +use. See `xshard.backend()`_. $Method INT .get_alt() Get the *alt* parameter which a shard director using this parameter -object would use. See `vmod_directors.shard.backend`_. +object would use. See `xshard.backend()`_. $Method REAL .get_warmup() Get the *warmup* parameter which a shard director using this parameter -object would use. See `vmod_directors.shard.backend`_. +object would use. See `xshard.backend()`_. $Method BOOL .get_rampup() Get the *rampup* parameter which a shard director using this parameter -object would use. See `vmod_directors.shard.backend`_. +object would use. See `xshard.backend()`_. $Method STRING .get_healthy() Get a string representation of the *healthy* enum argument which a shard director using this parameter object would use. See -`vmod_directors.shard.backend`_. +`xshard.backend()`_. $Method BLOB .use() This method may only be used in backend context. -For use with the *param* argument of `vmod_directors.shard.backend`_ +For use with the *param* argument of `xshard.backend()`_ to associate this shard parameter set with a shard director. $Function BACKEND lookup(STRING) diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index a30d7809b..1a12d9fc8 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -155,7 +155,7 @@ expression. A period is leading if it is the first character in immediately follows a ``/`` is also leading (as in ``/.``). By default, *period* is ``false``. -`vmod_std.fnmatch`_ invokes VCL failure and returns ``false`` if +`std.fnmatch()`_ invokes VCL failure and returns ``false`` if either of *pattern* or *subject* is ``NULL`` -- for example, if an unset header is specified. @@ -194,7 +194,7 @@ Example:: Consider that the entire contents of the file appear in the string that is returned, including newlines that may result in invalid -headers if `vmod_std.fileread`_ is used to form a header. In that +headers if `std.fileread()`_ is used to form a header. In that case, you may need to modify the string, for example with ``regsub()`` (see :ref:`vcl(7)`):: @@ -436,7 +436,7 @@ formed by ORing the facility and level values. See your system's Notice: Unlike VCL and other functions in the std vmod, this function will not fail VCL processing for workspace overflows: For an out of -workspace condition, the `vmod_std.syslog`_ function has no effect. +workspace condition, the `std.syslog()`_ function has no effect. Example:: @@ -551,8 +551,8 @@ DEPRECATED functions $Function INT real2integer(REAL r, INT fallback) **DEPRECATED**: This function will be removed in a future version of -varnish, use `vmod_std.integer`_ with a *real* argument and the -`vmod_std.round`_ function instead, for example:: +varnish, use `std.integer()`_ with a *real* argument and the +`std.round()`_ function instead, for example:: std.integer(real=std.round(...), fallback=...) @@ -569,13 +569,13 @@ Examples:: $Function TIME real2time(REAL r, TIME fallback) **DEPRECATED**: This function will be removed in a future version of -varnish, use `vmod_std.time`_ with a *real* argument and the -`vmod_std.round`_ function instead, for example:: +varnish, use `std.time()`_ with a *real* argument and the +`std.round()`_ function instead, for example:: std.time(real=std.round(...), fallback=...) Rounds the real *r* to the nearest integer (see -`vmod_std.real2integer`_) and returns the corresponding time when +`std.real2integer()`_) and returns the corresponding time when interpreted as a unix epoch. If conversion fails, *fallback* will be returned. @@ -586,7 +586,7 @@ Example:: $Function INT time2integer(TIME t, INT fallback) **DEPRECATED**: This function will be removed in a future version of -varnish, use `vmod_std.integer`_ with a *time* argument instead, for +varnish, use `std.integer()`_ with a *time* argument instead, for example:: std.integer(time=..., fallback=...) @@ -601,7 +601,7 @@ Example:: $Function REAL time2real(TIME t, REAL fallback) **DEPRECATED**: This function will be removed in a future version of -varnish, use `vmod_std.real`_ with a *time* argument instead, for +varnish, use `std.real()`_ with a *time* argument instead, for example:: std.real(time=..., fallback=...) diff --git a/lib/libvmod_unix/vmod.vcc b/lib/libvmod_unix/vmod.vcc index 0c1140872..c7f5bc167 100644 --- a/lib/libvmod_unix/vmod.vcc +++ b/lib/libvmod_unix/vmod.vcc @@ -98,9 +98,9 @@ All functions in this VMOD are subject to the following constraints: * If the current listener is not a Unix domain socket, or if the attempt to read credentials fails, then a ``VCL_Error`` message is - written to the log. The STRING functions (`vmod_unix.user`_ and - `vmod_unix.group`_) return ``NULL``, while the INT functions - (`vmod_unix.uid`_ and `vmod_unix.gid`_) return -1. + written to the log. The STRING functions (`unix.user()`_ and + `unix.group()`_) return ``NULL``, while the INT functions + (`unix.uid()`_ and `unix.gid()`_) return -1. SEE ALSO ======== From martin at varnish-software.com Tue Sep 10 16:05:06 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 10 Sep 2019 16:05:06 +0000 (UTC) Subject: [master] b845c2789 Retire the kill(SIGNULL) test in VSM Message-ID: <20190910160506.1FAA32687@lists.varnish-cache.org> commit b845c2789cae4f165e30a3d0f3af1bfbbeca98ee Author: Martin Blix Grydeland Date: Tue Sep 10 16:31:04 2019 +0200 Retire the kill(SIGNULL) test in VSM A bug was uncovered in the VSM code that checks if kill(SIGNULL) would work as a test of liveness of the master and worker processes. If the user running the utility has the required permissions to send signal to the worker process, but not the management process, the code would wrongly assume it could do kill on both. It would then end up in a connect loop never succeeding. Because kill() can not always be successfully run (a common scenario when the user running varnishlog is not the same UID as the cache processes), there is a fall back to using fstat to check for Varnish restarts. Since this fallback is active for most use cases anyways, it was decided to retire the kill() mechanism rather than to fix it. This way the behaviour does not change depending on what user the utility is run as. This change was OK'd by PHK after discussing it on IRC. diff --git a/bin/varnishtest/tests/u00008.vtc b/bin/varnishtest/tests/u00008.vtc index 0c35fb3fc..9953fccad 100644 --- a/bin/varnishtest/tests/u00008.vtc +++ b/bin/varnishtest/tests/u00008.vtc @@ -37,10 +37,6 @@ process p1 -expect-text 0 0 "VBE.vcl1.s1.req" process p1 -expect-text 0 0 "DIAG" process p1 -screen_dump -varnish v1 -stop -process p1 -expect-text 2 1 "Uptime child: Not Running" -process p1 -screen_dump - process p1 -write {dek} process p1 -expect-text 0 1 "Concurrent connections to backend:" process p1 -screen_dump diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 91540c8fd..31bc6f023 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -150,8 +150,6 @@ struct vsm { int attached; double patience; - - int couldkill; }; /*--------------------------------------------------------------------*/ @@ -357,8 +355,6 @@ VSM_New(void) vd->child->vsm = vd; vd->wdfd = -1; vd->patience = 5; - if (getenv("VSM_NOPID") != NULL) - vd->couldkill = -1; return (vd); } @@ -485,17 +481,13 @@ vsm_vlu_hash(struct vsm *vd, struct vsm_set *vs, const char *line) int i; uintmax_t id1, id2; + (void)vd; + i = sscanf(line, "# %ju %ju", &id1, &id2); if (i != 2) { vs->retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED; return (0); } - if (vd->couldkill >= 0 && !kill(id1, 0)) { - vd->couldkill = 1; - } else if (vd->couldkill > 0 && errno == ESRCH) { - vs->retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED; - return (0); - } vs->retval |= VSM_MGT_RUNNING; if (id1 != vs->id1 || id2 != vs->id2) { vs->retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED; @@ -694,8 +686,7 @@ vsm_refresh_set(struct vsm *vd, struct vsm_set *vs) vs->fst.st_size = lseek(vs->fd, 0L, SEEK_CUR); - if (vd->couldkill < 1 || !kill(vs->id1, 0)) - vs->retval |= vs->flag_running; + vs->retval |= vs->flag_running; return (vs->retval); } From martin at varnish-software.com Wed Sep 11 11:06:05 2019 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 11 Sep 2019 11:06:05 +0000 (UTC) Subject: [master] a3593245f Retire also the reference to VSM_NOPID in docs Message-ID: <20190911110605.CE1F1A2EBF@lists.varnish-cache.org> commit a3593245f5a9f149da4890dbc678dcf9142929dd Author: Martin Blix Grydeland Date: Wed Sep 11 13:04:13 2019 +0200 Retire also the reference to VSM_NOPID in docs Ref previous commit to remove the use of kill(signull) on the pids of the Varnish processes to test liveness. diff --git a/doc/sphinx/reference/vsm.rst b/doc/sphinx/reference/vsm.rst index 7771b0110..d9a689c55 100644 --- a/doc/sphinx/reference/vsm.rst +++ b/doc/sphinx/reference/vsm.rst @@ -97,22 +97,3 @@ a chance to discover the deallocation. The include file provides the supported API for accessing VSM files. - -VSM and Containers ------------------- - -The varnish way works great with single purpose containers. By sharing -the varnish working directory read-only, vsm readers can be run in -containers separate from those running varnishd instances on the same -host. - -When running varnishd and vsm readers in the same process namespace, -pid information can be used by vsm readers to determine if varnishd -processes are alive. - -But, when running varnishd and vsm readers in different containers, -the pid information has no relevance and may even be ambiguous across -name spaces. - -Thus, with such setups, the environment variable VSM_NOPID needs to be -set for vsm readers to disable use of pid information. From nils.goroll at uplex.de Fri Sep 13 10:23:06 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 13 Sep 2019 10:23:06 +0000 (UTC) Subject: [master] bdf0c9f56 changes.rst: name vmod function / constructor / method RST xref like VCL Message-ID: <20190913102306.3BAA062FEE@lists.varnish-cache.org> commit bdf0c9f563179e487fbdd0d185ff4d05c91e2e19 Author: Nils Goroll Date: Fri Sep 13 12:21:57 2019 +0200 changes.rst: name vmod function / constructor / method RST xref like VCL Ref 904ceabf07c294983efcebfe1d614c2d2fd5cdda diff --git a/doc/changes.rst b/doc/changes.rst index b3923dce8..5a12b171e 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -46,8 +46,8 @@ NEXT (2019-09-15) * Retired the ``BackendStart`` log tag - ``BackendOpen`` contains all the information from it -C APIs (for vmod and utility authors) -------------------------------------- +APIs / VMODs +------------ * ``WS_Reserve()`` is now deprecated and any use should trigger a compiler warning. It is to be replaced by @@ -66,6 +66,26 @@ C APIs (for vmod and utility authors) We provide a script to help automate this change in the ``tools/coccinelle`` subdirectory of the source tree. +* The RST references generated by ``vmodtool.py`` have been changed to + match better the VCL syntax to avoid overhead where references are + used. The new scheme for a vmod called *name* is: + + * ``$Function``: *name*\ .\ *function*\ () + * ``$Object`` constructor: *name*\ .\ *object*\ () + * ``$Method``: x\ *object*\ .\ *method*\ () + + To illustrate, the old references:: + + :ref:`vmod_name.function` + :ref:`vmod_name.obj` + :ref:`vmod_name.obj.method` + + now are renamed to:: + + :ref:`name.function()` + :ref:`name.obj()` + :ref:`xobj.method()` + ================================ Varnish Cache 6.2.0 (2019-03-15) ================================ From nils.goroll at uplex.de Fri Sep 13 12:27:05 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 13 Sep 2019 12:27:05 +0000 (UTC) Subject: [master] 5c56bd1a2 save vmod developer life time Message-ID: <20190913122705.F2F586EBA2@lists.varnish-cache.org> commit 5c56bd1a22b87ca794c149bd807bc2692c365606 Author: Nils Goroll Date: Fri Sep 13 13:55:40 2019 +0200 save vmod developer life time by providing a trivial tool to rename vmod RST references. To @Dridi and all other ladybug-lovers: I tried, but gave up after 5'. Maybe spatch on its own would have done the job, but sed is just so much simpler and, IMHO, totally appropriate for the job. diff --git a/doc/changes.rst b/doc/changes.rst index 5a12b171e..9f6208035 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -86,6 +86,8 @@ APIs / VMODs :ref:`name.obj()` :ref:`xobj.method()` + ``tools/vmod_ref_rename.sh`` is provided to automate this task + ================================ Varnish Cache 6.2.0 (2019-03-15) ================================ diff --git a/tools/vmod_ref_rename.sh b/tools/vmod_ref_rename.sh new file mode 100755 index 000000000..ecf0091ee --- /dev/null +++ b/tools/vmod_ref_rename.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# trivial sed-based tool to rename RST references in vmod .vcc files +# to the new scheme as of commit +# 904ceabf07c294983efcebfe1d614c2d2fd5cdda +# +# only tested with GNU sed +# +# to be called from a vmod git repository +# +# Author: Nils Goroll +# +# This file is in the public domain + +typeset -ra files=($(git ls-files | grep -E '\.vcc$')) + +if [[ ${#files[@]} -eq 0 ]] ; then + echo >&2 'No vcc files found' + exit 0 +fi + +if [[ -n $(git status -s) ]] ; then + echo >&2 'clean up your tree first' + git status + exit 1 +fi + +set -eu + +sed -e 's#`vmod_\([^.]*\)\.\([^.`]*\)`_#`\1.\2()`_#g' \ + -e 's#`vmod_\([^.]*\)\.\([^.`]*\).\([^.`]*\)`_#`x\2.\3()`_#g' \ + -i "${files[@]}" + +if [[ -z $(git status -s) ]] ; then + echo >&2 'no change' + exit 0 +fi + +git commit -m 'rename vmod RST references (vmod_ref_rename.sh)' \ + "${files[@]}" + +echo DONE - review and test the previous commit From phk at FreeBSD.org Mon Sep 16 07:18:07 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 16 Sep 2019 07:18:07 +0000 (UTC) Subject: [master] 53b4d2f58 Mention Host:.lower() and vsm improvements. Message-ID: <20190916071807.5D09A9582B@lists.varnish-cache.org> commit 53b4d2f582026d8e8c13eb8709b1967369911bb5 Author: Poul-Henning Kamp Date: Mon Sep 16 07:09:38 2019 +0000 Mention Host:.lower() and vsm improvements. diff --git a/doc/changes.rst b/doc/changes.rst index 9f6208035..9c8d160af 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -27,9 +27,19 @@ individual releases. These documents are updated as part of the release process. ================================ -NEXT (2019-09-15) +NEXT (2020-03-15) ================================ +(nothing yet) + +================================ +Varnish Cache 6.3.0 (2019-09-15) +================================ + +* The Host: header is folded to lower-case in the builtin_vcl. + +* Improved performance of shared memory statistics counters. + * Synthetic objects created from ``vcl_backend_error {}`` now replace existing stale objects as ordinary backend fetches would, unless: From phk at FreeBSD.org Mon Sep 16 07:18:07 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 16 Sep 2019 07:18:07 +0000 (UTC) Subject: [master] a8defc075 Use back-slash escapes. Message-ID: <20190916071807.66DAD9582D@lists.varnish-cache.org> commit a8defc075a4f9c925dea0390f1a69d78ba416a21 Author: Poul-Henning Kamp Date: Mon Sep 16 07:17:02 2019 +0000 Use back-slash escapes. diff --git a/bin/varnishtest/tests/r00494.vtc b/bin/varnishtest/tests/r00494.vtc index e0db8a4bf..e46587c1d 100644 --- a/bin/varnishtest/tests/r00494.vtc +++ b/bin/varnishtest/tests/r00494.vtc @@ -1,16 +1,11 @@ varnishtest "HTTP continuation lines" -#NB: careful about spaces and tabs in this test. - server s1 { rxreq - txresp -hdr {Foo: bar, - barf: fail} -body "xxx" + txresp -hdr "Foo: bar,\n\tbarf: fail" -body "xxx" rxreq - txresp -hdr {Foo: bar, - - barf: fail} -body "xxx" + txresp -hdr "Foo: bar,\n \t\n\tbarf: fail" -body "xxx" } -start varnish v1 -vcl+backend { From phk at FreeBSD.org Mon Sep 16 07:40:05 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 16 Sep 2019 07:40:05 +0000 (UTC) Subject: [master] d58905aa7 Bump VRT_VERSION for release Message-ID: <20190916074005.4F7789763A@lists.varnish-cache.org> commit d58905aa7bf38db1959b8b19c9d02b4d9dd3c2f2 Author: Poul-Henning Kamp Date: Mon Sep 16 07:38:42 2019 +0000 Bump VRT_VERSION for release diff --git a/include/vrt.h b/include/vrt.h index 2a741c125..adcca0302 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -51,7 +51,9 @@ * Whenever something is deleted or changed in a way which is not * binary/load-time compatible, increment MAJOR version * - * unreleased (planned for 2019-09-15) + * unreleased (planned for 2020-03-15) + * (nothing yet) + * 10.0 (2019-09-15) * VRT_UpperLowerStrands added. * VRT_synth_page now takes STRANDS argument * VRT_hashdata() now takes STRANDS argument @@ -143,7 +145,7 @@ * vrt_acl type added */ -#define VRT_MAJOR_VERSION 9U +#define VRT_MAJOR_VERSION 10U #define VRT_MINOR_VERSION 0U From hermunn at varnish-software.com Mon Sep 16 09:07:05 2019 From: hermunn at varnish-software.com (Pål Hermunn Johansen) Date: Mon, 16 Sep 2019 09:07:05 +0000 (UTC) Subject: [master] cba5490ae Add heading to 6.3 changelog, ready to fork to 6.3 branch Message-ID: <20190916090705.44DA79B679@lists.varnish-cache.org> commit cba5490ae0878672bfe3c6af8372e8facd82a89a Author: P?l Hermunn Johansen Date: Mon Sep 16 11:05:07 2019 +0200 Add heading to 6.3 changelog, ready to fork to 6.3 branch diff --git a/doc/changes.rst b/doc/changes.rst index 9c8d160af..ac1b47902 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -36,6 +36,9 @@ NEXT (2020-03-15) Varnish Cache 6.3.0 (2019-09-15) ================================ +In addition to a significant number of bug fixes, these are the most +important changes in 6.3: + * The Host: header is folded to lower-case in the builtin_vcl. * Improved performance of shared memory statistics counters. From hermunn at varnish-software.com Mon Sep 16 09:58:05 2019 From: hermunn at varnish-software.com (Pål Hermunn Johansen) Date: Mon, 16 Sep 2019 09:58:05 +0000 (UTC) Subject: [6.3] 0c9a93f1b Prepare for 6.3.0 Message-ID: <20190916095805.322809C947@lists.varnish-cache.org> commit 0c9a93f1b2c6de49b8c6ec8cefd9d2be50041d79 Author: P?l Hermunn Johansen Date: Mon Sep 16 11:34:05 2019 +0200 Prepare for 6.3.0 diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index d4b343b46..a8ee9c61b 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -148,7 +148,7 @@ cnt_deliver(struct worker *wrk, struct req *req) http_PrintfHeader(req->resp, "Age: %.0f", floor(fmax(0., req->t_prev - req->objcore->t_origin))); - http_SetHeader(req->resp, "Via: 1.1 varnish (Varnish/6.2)"); + http_SetHeader(req->resp, "Via: 1.1 varnish (Varnish/6.3)"); if (cache_param->http_gzip_support && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && diff --git a/configure.ac b/configure.ac index fbfea3e45..74d84aa26 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS -Copyright (c) 2006-2018 Varnish Software]) +Copyright (c) 2006-2019 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [trunk], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [6.3.0], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index ac1b47902..081ab68a8 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -26,12 +26,6 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. -================================ -NEXT (2020-03-15) -================================ - -(nothing yet) - ================================ Varnish Cache 6.3.0 (2019-09-15) ================================ diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 9a708b593..e86d038fe 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -37,7 +37,7 @@ Longer listings like example command output and VCL look like this:: $ /opt/varnish/sbin/varnishd -V varnishd (varnish-trunk revision 199de9b) Copyright (c) 2006 Verdens Gang AS - Copyright (c) 2006-2018 Varnish Software AS + Copyright (c) 2006-2019 Varnish Software AS .. For maintainers: From phk at FreeBSD.org Mon Sep 16 11:37:05 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 16 Sep 2019 11:37:05 +0000 (UTC) Subject: [master] dc4a889cb Implementing ZERO_OBJ macro proposal. Message-ID: <20190916113705.EA45E9EFD4@lists.varnish-cache.org> commit dc4a889cb300e9a22d6ba4970ab7079a572bf337 Author: David Carlier Date: Wed Sep 11 09:56:59 2019 +0100 Implementing ZERO_OBJ macro proposal. - According to #3051, this does not seem too obvious to be properly detected on Linux systems. - Some other OSes prefer to play in their own 'backyard', having similar feature but named differently (e.g. NetBSD) would need addition autotools check. - Thus proposing implementing the macro with the volatile pointer approach rather than memory fence's, sufficient to prevent compiler optimisations. diff --git a/include/miniobj.h b/include/miniobj.h index b714c70e1..8da6ef42e 100644 --- a/include/miniobj.h +++ b/include/miniobj.h @@ -5,11 +5,11 @@ * */ -#ifdef HAVE_EXPLICIT_BZERO -# define ZERO_OBJ(to, sz) explicit_bzero(to, sz) -#else -# define ZERO_OBJ(to, sz) (void)memset(to, 0, sz) -#endif +#define ZERO_OBJ(to, sz) \ + do { \ + void *(*volatile z_obj)(void *, int, size_t) = memset; \ + (void)z_obj(to, 0, sz); \ + } while (0) #define INIT_OBJ(to, type_magic) \ do { \ diff --git a/varnish.m4 b/varnish.m4 index 392c36c60..b9899f613 100644 --- a/varnish.m4 +++ b/varnish.m4 @@ -62,12 +62,6 @@ AC_DEFUN([_VARNISH_SEARCH_LIBS], [ LIBS="${save_LIBS}" ]) -# _VARNISH_CHECK_EXPLICIT_BZERO() -# ------------------------------- -AC_DEFUN([_VARNISH_CHECK_EXPLICIT_BZERO], [ - AC_CHECK_FUNCS([explicit_bzero]) -]) - # _VARNISH_PKG_CONFIG # -------------------- AC_DEFUN([_VARNISH_PKG_CONFIG], [ From hermunn at varnish-software.com Mon Sep 16 12:03:05 2019 From: hermunn at varnish-software.com (Pål Hermunn Johansen) Date: Mon, 16 Sep 2019 12:03:05 +0000 (UTC) Subject: [master] ca7a3809b Take relevant from the 6.3 release into trunc Message-ID: <20190916120305.D3278A0A6A@lists.varnish-cache.org> commit ca7a3809b5c71bc2feb59dfc58af91db876b0fcf Author: P?l Hermunn Johansen Date: Mon Sep 16 13:58:54 2019 +0200 Take relevant from the 6.3 release into trunc To be exact: Update Via header, copyright year. See 0c9a93f1b2c6de49b8c6ec8cefd9d2be50041d79. diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index d4b343b46..a8ee9c61b 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -148,7 +148,7 @@ cnt_deliver(struct worker *wrk, struct req *req) http_PrintfHeader(req->resp, "Age: %.0f", floor(fmax(0., req->t_prev - req->objcore->t_origin))); - http_SetHeader(req->resp, "Via: 1.1 varnish (Varnish/6.2)"); + http_SetHeader(req->resp, "Via: 1.1 varnish (Varnish/6.3)"); if (cache_param->http_gzip_support && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && diff --git a/configure.ac b/configure.ac index fbfea3e45..135d73673 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS -Copyright (c) 2006-2018 Varnish Software]) +Copyright (c) 2006-2019 Varnish Software]) AC_REVISION([$Id$]) AC_INIT([Varnish], [trunk], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 9a708b593..e86d038fe 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -37,7 +37,7 @@ Longer listings like example command output and VCL look like this:: $ /opt/varnish/sbin/varnishd -V varnishd (varnish-trunk revision 199de9b) Copyright (c) 2006 Verdens Gang AS - Copyright (c) 2006-2018 Varnish Software AS + Copyright (c) 2006-2019 Varnish Software AS .. For maintainers: From gquintard at users.noreply.github.com Tue Sep 17 16:49:05 2019 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Tue, 17 Sep 2019 16:49:05 +0000 (UTC) Subject: [master] 3c0fe7941 Clarify varnishtest automatic connect behavior Message-ID: <20190917164905.A2F55A5E4A@lists.varnish-cache.org> commit 3c0fe7941062b16d2b993a377ef8ef4e37defd4f Author: Jordan Christiansen Date: Tue Sep 17 05:53:35 2019 -0500 Clarify varnishtest automatic connect behavior diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 67d07c312..b062773e2 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -69,14 +69,15 @@ extern const struct cmds http_cmds[]; * SECTION: client-server.macros Macros and automatic behaviour * * To make things easier in the general case, clients will connect by default - * to the first Varnish server declared and the -vcl+backend switch of the - * ``varnish`` command will add all the declared servers as backends. - * - * Be careful though, servers will by default listen to the 127.0.0.1 IP and - * will pick a random port, and publish 3 macros: sNAME_addr, sNAME_port and - * sNAME_sock, but only once they are started. - * For 'varnish -vcl+backend' to create the vcl with the correct values, the - * server must be started first. + * to a Varnish server called v1. To connect to a different Varnish server, use + * '-connect ${vNAME_sock}'. + * + * The -vcl+backend switch of the ``varnish`` command will add all the declared + * servers as backends. Be careful though, servers will by default listen to + * the 127.0.0.1 IP and will pick a random port, and publish 3 macros: + * sNAME_addr, sNAME_port and sNAME_sock, but only once they are started. For + * 'varnish -vcl+backend' to create the vcl with the correct values, the server + * must be started first. * * SECTION: client-server.args Arguments * From phk at FreeBSD.org Mon Sep 23 06:36:07 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 23 Sep 2019 06:36:07 +0000 (UTC) Subject: [master] c570edae7 Following-up on explicit_bzero removal now in autotools perspective Message-ID: <20190923063607.53573B186E@lists.varnish-cache.org> commit c570edae7f1dda698dc45686a6a1e13689479cf7 Author: David Carlier Date: Mon Sep 16 20:09:52 2019 +0100 Following-up on explicit_bzero removal now in autotools perspective diff --git a/configure.ac b/configure.ac index 135d73673..6d52fbb5b 100644 --- a/configure.ac +++ b/configure.ac @@ -226,7 +226,6 @@ AC_CHECK_HEADERS([priv.h]) AC_CHECK_HEADERS([fnmatch.h], [], [AC_MSG_ERROR([fnmatch.h is required])]) # Checks for library functions. -_VARNISH_CHECK_EXPLICIT_BZERO AC_CHECK_FUNCS([nanosleep]) AC_CHECK_FUNCS([setppriv]) AC_CHECK_FUNCS([fallocate]) diff --git a/varnish.m4 b/varnish.m4 index b9899f613..6a8eb0609 100644 --- a/varnish.m4 +++ b/varnish.m4 @@ -109,7 +109,6 @@ AC_DEFUN([_VARNISH_PKG_CONFIG], [ AC_DEFUN([_VARNISH_CHECK_DEVEL], [ AC_REQUIRE([_VARNISH_PKG_CONFIG]) - AC_REQUIRE([_VARNISH_CHECK_EXPLICIT_BZERO]) [_orig_cppflags=$CPPFLAGS] [CPPFLAGS=$VARNISHAPI_CFLAGS] @@ -637,7 +636,6 @@ AC_DEFUN([VARNISH_UTILITIES], [ # AC_DEFUN([VARNISH_PREREQ], [ AC_REQUIRE([_VARNISH_PKG_CONFIG]) - AC_REQUIRE([_VARNISH_CHECK_EXPLICIT_BZERO]) AC_MSG_CHECKING([for Varnish]) AC_MSG_RESULT([$VARNISH_VERSION]) From phk at FreeBSD.org Mon Sep 23 07:29:05 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 23 Sep 2019 07:29:05 +0000 (UTC) Subject: [master] 2a84af91d Upset Flexelint less Message-ID: <20190923072905.496EAB2953@lists.varnish-cache.org> commit 2a84af91dd830e75571ea351807b6afaaedbc885 Author: Poul-Henning Kamp Date: Mon Sep 23 07:28:36 2019 +0000 Upset Flexelint less diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 31bc6f023..423211e56 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -75,7 +75,7 @@ static vlu_f vsm_vlu_func; #define VSM_PRIV_SHIFT \ (sizeof (uintptr_t) * 4) #define VSM_PRIV_MASK \ - (~((uintptr_t)UINTPTR_MAX << VSM_PRIV_SHIFT)) + ((1UL << VSM_PRIV_SHIFT) - 1) #define VSM_PRIV_LOW(u) \ ((uintptr_t)(u) & VSM_PRIV_MASK) #define VSM_PRIV_HIGH(u) \ From daghf at varnish-software.com Tue Sep 24 14:59:06 2019 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Tue, 24 Sep 2019 14:59:06 +0000 (UTC) Subject: [master] f3e9ca6ab Add missing error handling in h2_rx_data Message-ID: <20190924145906.133A06602@lists.varnish-cache.org> commit f3e9ca6abc4a03e48df4e9894323cad25472793f Author: Dag Haavi Finstad Date: Tue Sep 24 16:50:33 2019 +0200 Add missing error handling in h2_rx_data A failing write on a different stream will set h2->error, which would cause us to panic here on the following AZ(h2->mailcall). Fixes: #3040 diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 527fb8e61..902c1e08c 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -750,6 +750,8 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) Lck_Lock(&h2->sess->mtx); while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0) AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0)); + if (h2->error || r2->error) + return (h2->error ? h2->error : r2->error); AZ(h2->mailcall); h2->mailcall = r2; h2->req0->r_window -= h2->rxf_len; From phk at FreeBSD.org Wed Sep 25 12:40:06 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 25 Sep 2019 12:40:06 +0000 (UTC) Subject: [master] 09dd2b279 Allocate one byte more from the workspace, to make it also fail WS allocation on 32bit RH Message-ID: <20190925124006.3012AA880B@lists.varnish-cache.org> commit 09dd2b279e0f02cf0e405191fb87082ec2f12b7a Author: Poul-Henning Kamp Date: Wed Sep 25 12:38:38 2019 +0000 Allocate one byte more from the workspace, to make it also fail WS allocation on 32bit RH Fixes #3061 diff --git a/bin/varnishtest/tests/v00058.vtc b/bin/varnishtest/tests/v00058.vtc index 76fec5ec6..dda187f6d 100644 --- a/bin/varnishtest/tests/v00058.vtc +++ b/bin/varnishtest/tests/v00058.vtc @@ -138,7 +138,7 @@ varnish v1 -vcl+backend { set req.http.Baz = "baz"; set req.http.Quux = "quux"; - vtc.workspace_alloc(client, -12); + vtc.workspace_alloc(client, -11); if (req.url == "/1") { # VRT_StrandsWS() marks the WS as overflowed, From dridi.boukelmoune at gmail.com Fri Sep 27 10:23:06 2019 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 27 Sep 2019 10:23:06 +0000 (UTC) Subject: [master] 350e158d8 Retire the MAIN.sess_drop VSC Message-ID: <20190927102306.D21AF6294A@lists.varnish-cache.org> commit 350e158d86453356c4519ad67bf60e69e8fc9505 Author: Dridi Boukelmoune Date: Fri Sep 27 12:21:51 2019 +0200 Retire the MAIN.sess_drop VSC When de16dba24abf landed its documentation was mixed up with the other sess_dropped counter. When sess_dropped appeared in ac393c4b825a the sess_drop counter was still function, it died short after as a side effect of ac2e067b0dac. diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc index 0377f9659..ca5704267 100644 --- a/bin/varnishd/VSC_main.vsc +++ b/bin/varnishd/VSC_main.vsc @@ -27,12 +27,6 @@ Count of sessions successfully accepted -.. varnish_vsc:: sess_drop - :group: wrk - :oneliner: Sessions dropped - - Count of sessions silently dropped due to lack of worker thread. - .. varnish_vsc:: sess_fail :group: wrk :oneliner: Session accept failures diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 3336fd89f..68e61524e 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -373,19 +373,6 @@ vca_make_session(struct worker *wrk, void *arg) /* Turn accepted socket into a session */ AN(wrk->aws->r); sp = SES_New(wrk->pool); - if (sp == NULL) { - /* - * We consider this a DoS situation and silently close the - * connection with minimum effort and fuzz, rather than try - * to send an intelligent message back. - */ - vca_pace_bad(); - VTCP_nonblocking(wa->acceptsock); - closefd(&wa->acceptsock); - wrk->stats->sess_drop++; - WS_Release(wrk->aws, 0); - return; - } CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk->stats->s_sess++; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 875129f68..647b43665 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -365,7 +365,8 @@ SES_New(struct pool *pp) CHECK_OBJ_NOTNULL(pp, POOL_MAGIC); sp = MPL_Get(pp->mpl_sess, &sz); - sp->magic = SESS_MAGIC; + AN(sp); + INIT_OBJ(sp, SESS_MAGIC); sp->pool = pp; sp->refcnt = 1; memset(sp->sattr, 0xff, sizeof sp->sattr); diff --git a/bin/varnishtest/tests/t02011.vtc b/bin/varnishtest/tests/t02011.vtc index 9c2269e74..45ec730c6 100644 --- a/bin/varnishtest/tests/t02011.vtc +++ b/bin/varnishtest/tests/t02011.vtc @@ -72,7 +72,6 @@ client c1 { varnish v1 -cliok "param.set thread_pool_min 3" delay 1 varnish v1 -vsl_catchup -varnish v1 -expect sess_drop == 0 varnish v1 -expect sess_dropped == 0 varnish v1 -expect req_dropped == 1 varnish v1 -expect MEMPOOL.req0.live == 0 diff --git a/doc/changes.rst b/doc/changes.rst index ac1b47902..06ebc0630 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -30,7 +30,7 @@ release process. NEXT (2020-03-15) ================================ -(nothing yet) +* The ``MAIN.sess_drop`` counter is gone. ================================ Varnish Cache 6.3.0 (2019-09-15) From nils.goroll at uplex.de Fri Sep 27 14:01:05 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 27 Sep 2019 14:01:05 +0000 (UTC) Subject: [master] ad731128b lost events in vrt history Message-ID: <20190927140105.9258C912D2@lists.varnish-cache.org> commit ad731128bc1df60c326a5a20e24b957136830849 Author: Nils Goroll Date: Fri Sep 27 15:05:26 2019 +0200 lost events in vrt history diff --git a/include/vrt.h b/include/vrt.h index adcca0302..f5128fda2 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -85,6 +85,9 @@ * VRT_LookupDirector() added * VRT_SetChanged() added * VRT_SetHealth() removed + * // in cache_filter.h: + * VRT_AddVDP() added + * VRT_RemoveVDP() added * 8.0 (2018-09-15) * VRT_Strands() added * VRT_StrandsWS() added @@ -101,6 +104,9 @@ * VRT_SetHealth() added * VRT_DisableDirector() added * VRT_DelDirector() added + * // in cache_filter.h: + * VRT_AddVFP() added + * VRT_RemoveVFP() added * 7.0 (2018-03-15) * lots of stuff moved from cache.h to cache_varnishd.h * (ie: from "$Abi vrt" to "$Abi strict") From gquintard at users.noreply.github.com Fri Sep 27 20:41:06 2019 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Fri, 27 Sep 2019 20:41:06 +0000 (UTC) Subject: [master] 8db414a50 Offer a configure --with-unwind switch Message-ID: <20190927204106.78A909BF22@lists.varnish-cache.org> commit 8db414a5020f3a5974ff461eeba5fb669a3eaf7c Author: Guillaume Quintard Date: Wed Sep 4 11:02:12 2019 +0900 Offer a configure --with-unwind switch diff --git a/.travis.yml b/.travis.yml index 5de9b6b3b..b68503157 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,9 +18,10 @@ jobs: - nghttp2 - python3-docutils - python3-sphinx + - libunwind-dev before_script: - ./autogen.sh - - ./configure + - ./configure --with-unwind script: &script-common - | if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then @@ -51,7 +52,7 @@ jobs: export UBSAN_OPTIONS=halt_on_error=1,print_stacktrace=1,use_sigaltstack=0,suppressions=$(pwd)/tools/ubsan.suppr export CC=clang-8 - ./autogen.sh - - ./configure --enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage --enable-asan --enable-ubsan + - ./configure --with-unwind --enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage --enable-asan --enable-ubsan - stage: test os: osx osx_image: xcode10.2 @@ -80,7 +81,7 @@ jobs: - export PATH=$PATH:$(echo $(pwd)/cov-analysis-*/bin) script: - ./autogen.sh - - ./configure + - ./configure --with-unwind - cov-build --dir cov-int make - tar cfz varnish.tgz cov-int - curl --form token="$COVTOKEN" diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 41fffd334..2a66a4e44 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -177,6 +177,11 @@ varnishd_LDADD = \ @PCRE_LIBS@ \ ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} +if WITH_UNWIND +varnishd_CFLAGS += -DUNW_LOCAL_ONLY +varnishd_LDADD += ${LIBUNWIND_LIBS} +endif + noinst_PROGRAMS = vhp_gen_hufdec vhp_gen_hufdec_SOURCES = hpack/vhp_gen_hufdec.c vhp_gen_hufdec_CFLAGS = @SAN_CFLAGS@ \ diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index c45dfc4c0..cd4cfc482 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -29,7 +29,11 @@ #include "config.h" +#ifdef WITH_UNWIND +#include +#else #include +#endif #include #include #include @@ -609,6 +613,47 @@ pan_sess(struct vsb *vsb, const struct sess *sp) /*--------------------------------------------------------------------*/ +#ifdef WITH_UNWIND + +static void +pan_backtrace(struct vsb *vsb) +{ + unw_cursor_t cursor; unw_context_t uc; + unw_word_t ip, sp; + unw_word_t offp; + char fname[1024]; + int ret; + + VSB_printf(vsb, "Backtrace:\n"); + VSB_indent(vsb, 2); + + ret = unw_getcontext(&uc); + if (ret != 0) { + VSB_printf(vsb, "Backtrace not available " + "(unw_getcontext returned %d)\n", ret); + return; + } + unw_init_local(&cursor, &uc); + if (ret != 0) { + VSB_printf(vsb, "Backtrace not available " + "(unw_init_local returned %d)\n", ret); + return; + } + while (unw_step(&cursor) > 0) { + fname[0] = '\0'; + ip = sp = 0; + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + unw_get_proc_name(&cursor, fname, sizeof(fname), &offp); + VSB_printf(vsb, "ip=0x%lx, sp=0x%lx <%s+0x%lx>\n", (long) ip, + (long) sp, fname[0] ? fname : "???", offp); + } + + VSB_indent(vsb, -2); +} + +#else /* WITH_UNWIND */ + #define BACKTRACE_LEVELS 10 static void @@ -651,6 +696,8 @@ pan_backtrace(struct vsb *vsb) VSB_indent(vsb, -2); } +#endif /* WITH_UNWIND */ + #ifdef HAVE_PTHREAD_GETATTR_NP static void pan_threadattr(struct vsb *vsb) diff --git a/configure.ac b/configure.ac index 6d52fbb5b..c5b5930cc 100644 --- a/configure.ac +++ b/configure.ac @@ -342,9 +342,25 @@ esac AC_SUBST(JEMALLOC_LDADD) AC_CHECK_FUNCS([setproctitle]) -AC_SEARCH_LIBS(backtrace, [execinfo], [], [ - AC_MSG_ERROR([Could not find backtrace() support]) -]) + +# if the default libexecinfo on alpine causes issues, you can use libunwind +AC_ARG_WITH([unwind], + [AS_HELP_STRING([--with-unwind], + [use libunwind to print stacktraces (use libexecinfo otherwise). Recommended on alpine linux. Defaults to no.])]) + +if test "$with_unwind" = yes; then + PKG_CHECK_MODULES([LIBUNWIND], [libunwind]) + AC_DEFINE([WITH_UNWIND], [1], + [Define to 1 to use libunwind instead of libexecinfo]) +else + AC_SEARCH_LIBS(backtrace, [execinfo], [], [ + AC_MSG_ERROR([Could not find backtrace() support]) + ]) +fi + +AM_CONDITIONAL([WITH_UNWIND], + [test "$with_unwind" = yes]) + # white lie - we don't actually test it AC_MSG_CHECKING([whether daemon() works]) case $target in diff --git a/doc/changes.rst b/doc/changes.rst index 06ebc0630..20b06c751 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -32,6 +32,11 @@ NEXT (2020-03-15) * The ``MAIN.sess_drop`` counter is gone. +* New configure switch: --with-unwind. Alpine linux appears to offer a + `libexecinfo` implementation that crashes when called by Varnish, this + offers the alternative of using `libunwind` instead. + + ================================ Varnish Cache 6.3.0 (2019-09-15) ================================ From gquintard at users.noreply.github.com Sat Sep 28 03:10:07 2019 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Sat, 28 Sep 2019 03:10:07 +0000 (UTC) Subject: [master] 5cd36cd5a Introduce circleci instructions Message-ID: <20190928031007.86E71A73C5@lists.varnish-cache.org> commit 5cd36cd5ac02889a22b94d6a5cc221ab4bd35d4a Author: Guillaume Quintard Date: Sun Sep 15 18:40:04 2019 +0200 Introduce circleci instructions diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..cc14d265b --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,393 @@ +version: 2.1 +commands: + debian_install_build_deps: + description: Install build dependencies + steps: + - run: + name: Install build dependencies + command: | + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + apt-get update + apt-get install -y \ + autoconf \ + automake \ + build-essential \ + ca-certificates \ + git \ + graphviz \ + libconfig-dev \ + libedit-dev \ + libjemalloc-dev \ + libncurses-dev \ + libpcre3-dev \ + libtool \ + libunwind-dev \ + make \ + pkg-config \ + python3-sphinx \ + rst2pdf \ + sudo + centos_install_build_deps: + description: Install build dependencies + steps: + - run: + name: Install build dependencies + command: | + yum install -y epel-release + yum install -y \ + automake \ + jemalloc-devel \ + git \ + libconfig-devel \ + libcurl-devel \ + libedit-devel \ + libtool \ + libunwind-devel \ + make \ + openssh-clients \ + pcre-devel \ + python-docutils \ + python3-sphinx \ + rst2pdf \ + ssh \ + sudo + alpine_install_build_deps: + description: Install build dependencies + steps: + - run: + name: Install build dependencies + command: | + apk update + apk add -q \ + autoconf \ + automake \ + build-base \ + ca-certificates \ + gzip \ + libconfig-dev \ + libedit-dev \ + libtool \ + libunwind-dev \ + linux-headers \ + pcre-dev \ + py-docutils \ + py-sphinx \ + tar \ + sudo +jobs: + build_debs: + parameters: + release: + description: the release name (stretch|buster|xenial|bionic) + default: "" + type: string + dist: + description: the Linux distribution (debian|ubuntu) + default: "" + type: string + description: Build << parameters.release >> debs + docker: + - image: << parameters.dist >>:<< parameters.release >> + steps: + - run: + name: Install packaging tools + command: | + apt-get update + apt-get install -y dpkg-dev ca-certificates debhelper devscripts equivs + - attach_workspace: + at: ~/project + - run: + name: Untar debian + command: tar xavf debian.tar.gz + - run: + name: Untar orig + command: tar xavf varnish*.tar.gz --strip 1 + - run: + name: Update changelog version + command: | + VERSION=$(./configure --version | awk 'NR == 1 {print $NF}') + + # VERSION looks like 5.2.1 or 5.2.0-rc1 + MAJOR=${VERSION%.*} # 5.2 + MINOR=${VERSION##*.} # 1 or 0-rc1 + MINOR=${MINOR%%-*} # 1 or 0 + RELEASE=${VERSION#*-} # 5.2.1 or rc1 + RELEASE=${RELEASE#$VERSION} # '' or rc1 + + # Take version override set on Jenkins builds into account. + if [ "$VERSION" = "trunk" ]; then + DEBVERSION=`date "+%Y%m%d"`-weekly~<< parameters.release >> + else + DEBVERSION="$MAJOR.$MINOR"-1~<< parameters.release >> + fi + + sed -i -e "s|@SECTION@|varnish-$MAJOR|" "debian/control" + sed -i -e "s|@VERSION@|$DEBVERSION|" "debian/changelog" + - run: + name: Install Build-Depends packages + command: | + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + yes | mk-build-deps --install debian/control || true + - run: + name: Build the packages + command: | + dpkg-buildpackage -us -uc -j16 + - run: + name: Import the packages into the workspace + command: | + mkdir debs + mv ../*.deb debs/ + - persist_to_workspace: + root: . + paths: + - debs/varnish*.deb + dist_ubuntu: + docker: + - image: ubuntu:bionic + steps: + - run: + command: | + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + apt-get update + apt-get install -y python3-sphinx autoconf automake libedit-dev make libtool pkg-config git libconfig-dev libpcre3-dev + - run: + name: Create the dist tarball + command: | + mkdir -p ~/.ssh + ssh-keyscan -H github.com >> ~/.ssh/known_hosts + git clone --branch=${CIRCLE_BRANCH} ${CIRCLE_REPOSITORY_URL} . + git checkout ${CIRCLE_SHA1} + ./autogen.des --quiet + make dist -j 16 + - persist_to_workspace: + root: . + paths: + - varnish*.tar.gz + tar_pkg_tools: + docker: + - image: centos:7 + steps: + - add_ssh_keys: + fingerprints: + - "11:ed:57:75:32:81:9d:d0:a4:5e:af:15:4b:d8:74:27" + - run: + name: Grab the pkg repo + command: | + yum install -y git + mkdir -p ~/.ssh + ssh-keyscan -H github.com >> ~/.ssh/known_hosts + echo ${CIRCLE_REPOSITORY_URL} + git clone --branch=weekly git at github.com:varnishcache/pkg-varnish-cache.git . + tar cvzf debian.tar.gz debian --dereference + tar cvzf redhat.tar.gz redhat --dereference + - persist_to_workspace: + root: . + paths: + - debian.tar.gz + - redhat.tar.gz + distcheck: + parameters: + release: + description: the release name (stretch|buster|xenial|bionic) + default: "" + type: string + dist: + description: the Linux distribution (debian|ubuntu) + default: "" + type: string + extra_conf: + description: platform-specific configure arguments + default: "" + type: string + docker: + - image: << parameters.dist >>:<< parameters.release >> + working_directory: /workspace + steps: + - << parameters.dist >>_install_build_deps + - attach_workspace: + at: /workspace + - run: + name: Extract and distcheck + command: | + tar xavf *.tar.gz --strip 1 + if [ << parameters.dist >> = centos ]; then + adduser varnish + else + adduser --disabled-password --gecos "" varnish + fi + chown -R varnish:varnish /workspace + sudo -u varnish ./configure \ + --quiet \ + --with-unwind \ + --enable-developer-warnings \ + --enable-debugging-symbols \ + --disable-stack-protector \ + --with-persistent-storage \ + << parameters.extra_conf >> + sudo -u varnish make distcheck -j 12 -k + push_packages: + docker: + - image: centos:7 + steps: + - attach_workspace: + at: ~/project + - run: + name: Tar the packages + command: | + rm rpms/varnish*.src.rpm + mv rpms/*/*.rpm rpms/ + tar cvzf packages.tar.gz rpms/*.rpm debs/*.deb + - store_artifacts: + destination: packages.tar.gz + path: packages.tar.gz + build_centos_7: + docker: + - image: centos:7 + environment: + DIST_DIR: build + DIST: el7 + steps: + - run: + name: Install packaging tools + command: | + yum install -y rpm-build yum-utils epel-release + # XXX: we should NOT have to do that here, they should be in the + # spec as BuildRequires + yum install -y make gcc + - attach_workspace: + at: ~/project + - run: + name: Create build dir + command: mkdir $DIST_DIR + - run: + name: Untar redhat + command: | + tar xavf redhat.tar.gz -C build + - run: + name: Untar orig + command: | + tar xavf varnish*.tar.gz -C build --strip 1 + - run: + name: Build Packages + command: | + set -e + set -u + + # use python3 + sed -i '1 i\%global __python %{__python3}' "$DIST_DIR"/redhat/varnish.spec + [ -n "$DIST" ] + VERSION=$("$DIST_DIR"/configure --version | awk 'NR == 1 {print $NF}') + + # VERSION looks like 5.2.1 or 5.2.0-rc1 + MAJOR=${VERSION%.*} # 5.2 + MINOR=${VERSION##*.} # 1 or 0-rc1 + MINOR=${MINOR%%-*} # 1 or 0 + RELEASE=${VERSION#*-} # 5.2.1 or rc1 + RELEASE=${RELEASE#$VERSION} # '' or rc1 + + cp -r -L "$DIST_DIR"/redhat/* "$DIST_DIR"/ + tar zcf "$DIST_DIR.tgz" --exclude "$DIST_DIR/redhat" "$DIST_DIR"/ + + if [ "$VERSION" = "trunk" ]; then + RPMVERSION=`date "+%Y%m%d"` + else + RPMVERSION="$MAJOR.$MINOR" + fi + + RESULT_DIR="rpms" + CUR_DIR="$(pwd)" + + rpmbuild() { + if [ -n "$RELEASE" ] + then + set -- --define "v_rc $RELEASE" "$@" + fi + command rpmbuild \ + --define "_smp_mflags -j10" \ + --define "dist $DIST" \ + --define "_topdir $HOME/rpmbuild" \ + --define "_sourcedir $CUR_DIR" \ + --define "_srcrpmdir $CUR_DIR/${RESULT_DIR}" \ + --define "_rpmdir $CUR_DIR/${RESULT_DIR}" \ + --define "versiontag ${RPMVERSION}" \ + --define "releasetag 0.0." \ + --define "srcname $DIST_DIR" \ + --define "nocheck 1" \ + "$@" + } + yum-builddep -y "$DIST_DIR"/redhat/varnish.spec + rpmbuild -bs "$DIST_DIR"/redhat/varnish.spec + rpmbuild --rebuild "$RESULT_DIR"/varnish-*.src.rpm + - persist_to_workspace: + root: . + paths: + - rpms/*.rpm + - rpms/*/*.rpm + +pkg_req: &pkg_req + requires: + - dist_ubuntu + - tar_pkg_tools + +workflows: + version: 2 + build: + jobs: + - dist_ubuntu + - tar_pkg_tools + - build_debs: + name: build_debian_stretch + dist: debian + release: stretch + <<: *pkg_req + - build_debs: + name: build_debian_buster + dist: debian + release: buster + <<: *pkg_req + - build_debs: + name: build_ubuntu_xenial + dist: ubuntu + release: xenial + <<: *pkg_req + - build_debs: + name: build_ubuntu_bionic + dist: ubuntu + release: bionic + <<: *pkg_req + - build_centos_7: + <<: *pkg_req + - hold: + type: approval + requires: + - build_debian_stretch + - build_debian_buster + - build_ubuntu_xenial + - build_ubuntu_bionic + - build_centos_7 + - push_packages: + requires: + - hold + - distcheck: + name: distcheck_centos_7 + dist: centos + release: "7" + requires: + - dist_ubuntu + - distcheck: + name: distcheck_debian_buster + dist: debian + release: buster + extra_conf: --enable-asan --enable-ubsan + requires: + - dist_ubuntu + - distcheck: + name: distcheck_alpine_3.10 + dist: alpine + release: "latest" + #extra_conf: --without-jemalloc + requires: + - dist_ubuntu From dridi.boukelmoune at gmail.com Sun Sep 29 12:02:06 2019 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Sun, 29 Sep 2019 12:02:06 +0000 (UTC) Subject: [master] 7ff657171 Add missing libunwind error handling Message-ID: <20190929120206.DE120A948A@lists.varnish-cache.org> commit 7ff657171e0c7cec53f1eb09c2c34aca20f9178a Author: Dridi Boukelmoune Date: Sun Sep 29 13:59:04 2019 +0200 Add missing libunwind error handling Spotted-By: Coverity Scan diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index cd4cfc482..aa9d914b7 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -30,10 +30,11 @@ #include "config.h" #ifdef WITH_UNWIND -#include +# include #else -#include +# include #endif + #include #include #include @@ -633,7 +634,7 @@ pan_backtrace(struct vsb *vsb) "(unw_getcontext returned %d)\n", ret); return; } - unw_init_local(&cursor, &uc); + ret = unw_init_local(&cursor, &uc); if (ret != 0) { VSB_printf(vsb, "Backtrace not available " "(unw_init_local returned %d)\n", ret); From gquintard at users.noreply.github.com Mon Sep 30 01:22:05 2019 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Mon, 30 Sep 2019 01:22:05 +0000 (UTC) Subject: [master] 08df05544 [cci] tell the sanitizers about the suppr files Message-ID: <20190930012205.D48E164287@lists.varnish-cache.org> commit 08df05544963e869a3984de428f6a8075fce6be7 Author: Guillaume Quintard Date: Sun Sep 29 17:31:18 2019 -0700 [cci] tell the sanitizers about the suppr files diff --git a/.circleci/config.yml b/.circleci/config.yml index cc14d265b..e1e9b7c7a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -166,6 +166,7 @@ jobs: root: . paths: - varnish*.tar.gz + - tools/*.suppr tar_pkg_tools: docker: - image: centos:7 @@ -219,6 +220,12 @@ jobs: adduser --disabled-password --gecos "" varnish fi chown -R varnish:varnish /workspace + + export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0,disable_coredump=0 + export LSAN_OPTIONS=abort_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/lsan.suppr + export TSAN_OPTIONS=abort_on_error=1,halt_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/tsan.suppr + export UBSAN_OPTIONS=halt_on_error=1,print_stacktrace=1,use_sigaltstack=0,suppressions=$(pwd)/tools/ubsan.suppr + sudo -u varnish ./configure \ --quiet \ --with-unwind \ @@ -227,7 +234,9 @@ jobs: --disable-stack-protector \ --with-persistent-storage \ << parameters.extra_conf >> - sudo -u varnish make distcheck -j 12 -k + sudo -u varnish \ + --preserve-env=ASAN_OPTIONS,LSAN_OPTIONS,TSAN_OPTIONS,UBSAN_OPTIONS \ + make distcheck -j 12 -k push_packages: docker: - image: centos:7 From phk at FreeBSD.org Mon Sep 30 08:34:06 2019 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 30 Sep 2019 08:34:06 +0000 (UTC) Subject: [master] 7c5b58cba VDD19Q3 public summary Message-ID: <20190930083406.0D43D96562@lists.varnish-cache.org> commit 7c5b58cbacfb8412cb155e4b63e5825b871fdb0c Author: Poul-Henning Kamp Date: Mon Sep 30 08:33:15 2019 +0000 VDD19Q3 public summary diff --git a/doc/sphinx/phk/index.rst b/doc/sphinx/phk/index.rst index a65cad041..043ede143 100644 --- a/doc/sphinx/phk/index.rst +++ b/doc/sphinx/phk/index.rst @@ -8,6 +8,7 @@ You may or may not want to know what Poul-Henning thinks. .. toctree:: :maxdepth: 1 + vdd19q3.rst quic.rst VSV00003.rst patent.rst diff --git a/doc/sphinx/phk/quic.rst b/doc/sphinx/phk/quic.rst index e874a5660..c512af7a7 100644 --- a/doc/sphinx/phk/quic.rst +++ b/doc/sphinx/phk/quic.rst @@ -1,3 +1,5 @@ +.. _phk_quick_osi: + QUIC visions of OSI =================== diff --git a/doc/sphinx/phk/vdd19q3.rst b/doc/sphinx/phk/vdd19q3.rst new file mode 100644 index 000000000..a5d2b8598 --- /dev/null +++ b/doc/sphinx/phk/vdd19q3.rst @@ -0,0 +1,118 @@ +.. _vdd19q3: + +Varnish Developer Day 2019Q3 +============================ + +We try to bring the core Varnish People into the same room a +couple of times a year for "Varnish Developer Day" meetings, +and last week we did that at Varnish Software's Oslo offices. + +Tuesday was a "Hackathon", where we lounged around and worked +concrete issues and ideas, Wednesday was the "formal" day where +we sat around a table and negotiated and made decisions. + +The main issues this time were HTTP3, backends and project +organization, and here I will try to give a quick summary. + +HTTP3 and QUIC +-------------- + +Everybody seemed to agree that we want H3 support, and after +Dag's quick overview of the protocol, the challenge of doing +that were evident. + +We also agreed that having certificates and secret keys inside +the varnish worker process is still a no-go, so some variant +of "key-less" is called for. Fortunately H3 is designed with +this in mind for performance reasons. + +Getting from A-B is the hard part, and we may introduce a A' +pit-stop where we implement key-less TLS1.3 on HTTP1+2, and +possibly also a A'' pitstop to get TLS on backends. + +Dag and PHK will try to plot a course for this. + +Backends +-------- + +There are a lot of annoying details about backends we want to +do something about, from probes being near-magical to H1 to +getting a proper handle on the lifetime of dynamic backends. + +Some concrete improvements came up during the hackathon and we will +be persuing those right away. + +Fixing probing is probably a V7 thing, and we need to think +and prototype how we expose probing in VCL. + +Bugwash +------- + +We are getting more people involved on the other side of the Atlantic, +and we are moving the Monday afternoon bugwash from 13:00-14:00 EU +time to 15:00-15:30 EU time, so they do not have to get out of bed +so early. + +We will also try to make the bugwash more producive, by having PHK +publish an "agenda" some hours beforehand, so people can prepare, +and instead shorten the bugwash to 30 minutes to keep the time +commitment the same. + +Everybody is welcome to attend our bugwashs, on the IRC channel +#varnish-hacking on irc.linpro.no. + +Project organization +-------------------- + +There has been some friction in the project this summer and we +have talked a lot about how to counter that. + +A significant part of the problem is that too much of the project +business goes through me: I am always the one nagging and no'ing +peoples pull requests and that makes both them and me unhappy. + +We have drawn up a set of "rules of engagement" which will distribute +the workload more evenly, essentially assuring that somebody from +another organization will have looked at patches and pull requests +before me, both to move some of the "no-ing" away from me and also +to get people to pay more attention to each others work. + +For this to work, everybdoy will have to spend a bit more time on +"project work", but everybody agreed to do that, so we think it can +fly. + +These discussions also brought up another thing: + +Retirement Notice +----------------- + +One interesting feature of the IT industry, is that there are no +retirement parties, because the industry more or less got born in +the 1990'ies. + +There was an IT industry before then, I was part of it for most of +a decade, and it did have retirement parties, because people had been +going at it since the 50ies. + +One almost invariable part of the proceedings were the "Handling +Over Of The Listing", where the retiree ceremoniously handed over +a four inch thick Z-fold listing of "The XYZ Program" to the younger +person now assuming responsibility for its care, feeding & maintenance, +until his - or the program's - retirement. + +If you do the math, you will find that I am now also getting into +my 50ies, and the prospect of retirement is migrating from "theoretical +event in distant future" to "I need to think about this." + +On Tuesday the 20th of January 2026 I will be 60 years old, the +Varnish Cache project will be 20 years old, and I will be retired +from active project management in the Varnish Cache Project. + +That is six? years in the future, a full half the current age of +the project, and a long time in IT, but I want to reserve the date, +so that the project has plenty of time to figure out what they want +to do about it. + +The VDD appointed Martin and Nils to own that issue. + +*phk* From nils.goroll at uplex.de Mon Sep 30 13:17:06 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 30 Sep 2019 13:17:06 +0000 (UTC) Subject: [master] ecef48518 Added the syntax 'backend name none;' Message-ID: <20190930131706.85E37A1A08@lists.varnish-cache.org> commit ecef48518f3b3f4bbf28256e090bdbb5cd2b163c Author: Andrew Wiik Date: Tue Sep 24 19:30:09 2019 -0400 Added the syntax 'backend name none;' diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index a8ee9c61b..c04eb9bf7 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -792,7 +792,6 @@ cnt_recv_prep(struct req *req, const char *ci) /* By default we use the first backend */ req->director_hint = VCL_DefaultDirector(req->vcl); - AN(req->director_hint); req->d_ttl = -1; req->d_grace = -1; diff --git a/bin/varnishtest/tests/v00060.vtc b/bin/varnishtest/tests/v00060.vtc new file mode 100644 index 000000000..3ce39e569 --- /dev/null +++ b/bin/varnishtest/tests/v00060.vtc @@ -0,0 +1,45 @@ +varnishtest "NULL backend allowed" + +server s1 { + rxreq + txresp + +} -start + +varnish v1 -vcl { + backend default none; +} -start + +client c1 { + txreq + rxresp + expect resp.status == 503 +} -run + +# Test NULL none default backend + +varnish v1 -vcl+backend { + backend null_backend none; + backend null_backend_uppercase None; + sub vcl_recv { + if (req.url ~ "/no_backend_lowercase") { + set req.backend_hint = null_backend; + } else if (req.url ~ "no_backend_uppercase") { + set req.backend_hint = null_backend_uppercase; + } + } +} + +client c1 { + txreq + rxresp + expect resp.status == 200 + + txreq -url "/no_backend_lowercase" + rxresp + expect resp.status == 503 + + txreq -url "/no_backend_uppercase" + rxresp + expect resp.status == 503 +} -run diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index 3200b1f84..f4f4f760b 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -321,6 +321,16 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) "?proxy_header", NULL); + if (tl->t->tok == ID && (vcc_IdIs(tl->t, "none") || vcc_IdIs(tl->t, "None"))) { + vsb = VSB_new_auto(); + AN(vsb); + tl->fb = vsb; + Fb(tl, 0, "\n\t%s = (NULL);\n", vgcname); + vcc_NextToken(tl); + SkipToken(tl, ';'); + return; + } + SkipToken(tl, '{'); vsb = VSB_new_auto(); From nils.goroll at uplex.de Mon Sep 30 13:30:07 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 30 Sep 2019 13:30:07 +0000 (UTC) Subject: [master] 5c7f839ee whitespace ocd Message-ID: <20190930133007.37832A1FB1@lists.varnish-cache.org> commit 5c7f839eeaa5f75e6a8a1f1e5a947905bb5d9e7f Author: Nils Goroll Date: Mon Sep 30 15:21:48 2019 +0200 whitespace ocd Ref #3067 diff --git a/bin/varnishtest/tests/v00060.vtc b/bin/varnishtest/tests/v00060.vtc index 3ce39e569..b1540dd5a 100644 --- a/bin/varnishtest/tests/v00060.vtc +++ b/bin/varnishtest/tests/v00060.vtc @@ -20,18 +20,18 @@ client c1 { varnish v1 -vcl+backend { backend null_backend none; - backend null_backend_uppercase None; - sub vcl_recv { - if (req.url ~ "/no_backend_lowercase") { - set req.backend_hint = null_backend; - } else if (req.url ~ "no_backend_uppercase") { - set req.backend_hint = null_backend_uppercase; - } - } + backend null_backend_uppercase None; + sub vcl_recv { + if (req.url ~ "/no_backend_lowercase") { + set req.backend_hint = null_backend; + } else if (req.url ~ "no_backend_uppercase") { + set req.backend_hint = null_backend_uppercase; + } + } } client c1 { - txreq + txreq rxresp expect resp.status == 200 @@ -39,7 +39,7 @@ client c1 { rxresp expect resp.status == 503 - txreq -url "/no_backend_uppercase" + txreq -url "/no_backend_uppercase" rxresp expect resp.status == 503 } -run From nils.goroll at uplex.de Mon Sep 30 13:30:07 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 30 Sep 2019 13:30:07 +0000 (UTC) Subject: [master] e0bbedd73 avoid 3 duplicated lines (very minor) Message-ID: <20190930133007.50884A1FB4@lists.varnish-cache.org> commit e0bbedd731537e4c3b067e3593a5edb5664c0f79 Author: Nils Goroll Date: Mon Sep 30 15:22:17 2019 +0200 avoid 3 duplicated lines (very minor) Ref #3067 diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index f4f4f760b..b943cf5fd 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -321,10 +321,12 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) "?proxy_header", NULL); - if (tl->t->tok == ID && (vcc_IdIs(tl->t, "none") || vcc_IdIs(tl->t, "None"))) { - vsb = VSB_new_auto(); - AN(vsb); - tl->fb = vsb; + vsb = VSB_new_auto(); + AN(vsb); + tl->fb = vsb; + + if (tl->t->tok == ID && + (vcc_IdIs(tl->t, "none") || vcc_IdIs(tl->t, "None"))) { Fb(tl, 0, "\n\t%s = (NULL);\n", vgcname); vcc_NextToken(tl); SkipToken(tl, ';'); @@ -333,10 +335,6 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) SkipToken(tl, '{'); - vsb = VSB_new_auto(); - AN(vsb); - tl->fb = vsb; - Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n", vgcname); From nils.goroll at uplex.de Mon Sep 30 13:30:07 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 30 Sep 2019 13:30:07 +0000 (UTC) Subject: [master] b1b2b6115 changelog tlc Message-ID: <20190930133007.734B4A1FBB@lists.varnish-cache.org> commit b1b2b6115daabb059e0d7aebe902f58cbbe33acc Author: Nils Goroll Date: Mon Sep 30 15:27:20 2019 +0200 changelog tlc Ref #3067 @andrewwiik would you please look after the user documentation? diff --git a/doc/changes.rst b/doc/changes.rst index 20b06c751..e55a4857c 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -36,6 +36,7 @@ NEXT (2020-03-15) `libexecinfo` implementation that crashes when called by Varnish, this offers the alternative of using `libunwind` instead. +* backend ``none`` was added for "no backend" ================================ Varnish Cache 6.3.0 (2019-09-15) From dridi.boukelmoune at gmail.com Mon Sep 30 14:36:06 2019 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 30 Sep 2019 14:36:06 +0000 (UTC) Subject: [master] f537a5b69 VSL manual polish Message-ID: <20190930143606.5FCB0A3AC9@lists.varnish-cache.org> commit f537a5b6902a3fd630febeae2c991680dc175055 Author: Dridi Boukelmoune Date: Mon Sep 30 16:24:21 2019 +0200 VSL manual polish We should avoid the word "received" in the context of response fields, since we don't "receive" resp.* fields, only beresp. This also fixes another inconsistency in the manual: RespReason - Client response response The HTTP response string received. diff --git a/include/tbl/vsl_tags_http.h b/include/tbl/vsl_tags_http.h index e0d180213..5e38ef2da 100644 --- a/include/tbl/vsl_tags_http.h +++ b/include/tbl/vsl_tags_http.h @@ -58,11 +58,11 @@ SLTH(Protocol, HTTP_HDR_PROTO, 1, 1, "protocol", ) SLTH(Status, HTTP_HDR_STATUS, 0, 1, "status", - "The HTTP status code received.\n\n" + "The HTTP response status code.\n\n" ) -SLTH(Reason, HTTP_HDR_REASON, 0, 1, "response", - "The HTTP response string received.\n\n" +SLTH(Reason, HTTP_HDR_REASON, 0, 1, "reason", + "The HTTP response reason string.\n\n" ) SLTH(Header, HTTP_HDR_FIRST, 1, 1, "header", From nils.goroll at uplex.de Mon Sep 30 18:53:07 2019 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 30 Sep 2019 18:53:07 +0000 (UTC) Subject: [master] cf05817f1 add vtc to check for a ttl = 0s object not replacing a grace object Message-ID: <20190930185307.E091EA9171@lists.varnish-cache.org> commit cf05817f1f1b3961e7b055632f07d543a54168aa Author: Nils Goroll Date: Mon Sep 30 20:43:48 2019 +0200 add vtc to check for a ttl = 0s object not replacing a grace object ... to avoid future regressions of a very useful feature. Using a gap in the test numbers. diff --git a/bin/varnishtest/tests/b00035.vtc b/bin/varnishtest/tests/b00035.vtc new file mode 100644 index 000000000..aacb40e62 --- /dev/null +++ b/bin/varnishtest/tests/b00035.vtc @@ -0,0 +1,44 @@ +varnishtest "Test grace object not replaced by ttl = 0s" + +server s1 { + rxreq + txresp -bodylen 3 + rxreq + txresp -bodylen 6 + # bgfetch fails +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.http.X-Force-Miss) { + set req.hash_always_miss = true; + } + } + sub vcl_backend_response { + if (beresp.status != 200 || bereq.http.X-Force-Miss) { + set beresp.ttl = 0s; + } else { + set beresp.ttl = 0.001s; + } + set beresp.grace = 10s; + return (deliver); + } +} -start + + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 3 + + txreq -hdr "X-Force-Miss: 1" + rxresp + expect resp.status == 200 + expect resp.bodylen == 6 + + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 3 +} -run