From dridi.boukelmoune at gmail.com Wed Feb 1 06:33:07 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 1 Feb 2023 06:33:07 +0000 (UTC) Subject: [master] c607e9b1a vtc: Drive-by redesign of c55 Message-ID: <20230201063307.EEAD41129FE@lists.varnish-cache.org> commit c607e9b1a443a03481fe23ed6fa78941a01801a3 Author: Dridi Boukelmoune Date: Wed Feb 1 07:11:26 2023 +0100 vtc: Drive-by redesign of c55 There's no point checking that a resp header is unset when we don't rxresp in the first place... There were other things that could be simplified. diff --git a/bin/varnishtest/tests/c00055.vtc b/bin/varnishtest/tests/c00055.vtc index 6e97e1d40..e5609f35d 100644 --- a/bin/varnishtest/tests/c00055.vtc +++ b/bin/varnishtest/tests/c00055.vtc @@ -4,7 +4,10 @@ server s1 { rxreq expect req.bodylen == 3 txresp -hdr "Connection: close" -hdr "Foo: BAR" -body "1234" + + expect_close accept + rxreq expect req.bodylen == 3 txresp -hdr "Foo: Foo" -body "56" @@ -14,22 +17,19 @@ varnish v1 -vcl+backend { import std; sub vcl_recv { - if (req.url == "/wrong-sub") { - return (pass); - } - if (std.cache_req_body(1KB)) { - set req.http.stored = true; - } else { - set req.http.stored = false; + if (req.url != "/wrong-sub") { + set req.http.stored = std.cache_req_body(1KB); } return (pass); } + sub vcl_deliver { if (resp.http.foo == "BAR") { return (restart); } set resp.http.stored = req.http.stored; } + sub vcl_backend_fetch { if (bereq.url == "/wrong-sub") { if (std.cache_req_body(1KB)) { @@ -41,12 +41,6 @@ varnish v1 -vcl+backend { } } -start -# check log for the aborted POST -logexpect l1 -v v1 { - expect * 1006 Begin - expect * = FetchError "^straight insufficient bytes" -} -start - varnish v1 -cliok "param.set debug +syncvsl" client c1 { @@ -57,38 +51,46 @@ client c1 { expect resp.http.stored == true } -run -delay .1 +# check log for the aborted POST +logexpect l1 -v v1 { + expect * 1006 Begin + expect * = FetchError "^straight insufficient bytes" +} -start -client c1 { - txreq -req POST -nolen -hdr "Content-Length: 52" - delay .3 - expect resp.http.stored == +client c2 { + txreq -req POST -hdr "Content-Length: 52" +} -run + +logexpect l1 -wait + +# wrong calling context +client c3 { + txreq -url "/wrong-sub" + rxresp + expect resp.status == 503 } -run delay .1 +varnish v1 -expect MGT.child_died == 0 + +# no req body server s1 { rxreq txresp } -start -client c1 { - txreq -url "/wrong-sub" - rxresp - expect resp.status == 503 -} -run - -client c1 { - txreq -url "/is_varnish_still_running" +client c4 { + txreq rxresp expect resp.status == 200 expect resp.http.stored == true } -run -client c2 { - txreq -req POST -nolen -hdr "Content-Length: 1025" - expect_close - expect resp.http.stored == +# req body overflow +client c5 { + txreq -req POST -hdr "Content-Length: 1025" + expect_close } -run varnish v1 -errvcl {req.body can only be cached in vcl_recv} { @@ -100,6 +102,3 @@ varnish v1 -errvcl {req.body can only be cached in vcl_recv} { } } } - -varnish v1 -stop -logexpect l1 -wait From phk at FreeBSD.org Wed Feb 1 07:07:06 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 1 Feb 2023 07:07:06 +0000 (UTC) Subject: [master] 1cbf48730 Give the ESI doc a wash Message-ID: <20230201070706.294CA113AD3@lists.varnish-cache.org> commit 1cbf4873013ae8c36bcfd294426daea69223d4ed Author: Poul-Henning Kamp Date: Wed Feb 1 07:05:52 2023 +0000 Give the ESI doc a wash diff --git a/doc/sphinx/users-guide/esi.rst b/doc/sphinx/users-guide/esi.rst index 890b583d6..92fe5082d 100644 --- a/doc/sphinx/users-guide/esi.rst +++ b/doc/sphinx/users-guide/esi.rst @@ -27,9 +27,7 @@ with VCL:: esi:remove -Content substitution based on variables and cookies is not implemented -but is on the roadmap. At least if you look at the roadmap from a -certain angle. During a full moon. +Content substitution based on variables and cookies is not implemented. Varnish will not process ESI instructions in HTML comments. @@ -66,6 +64,10 @@ For ESI to work you need to activate ESI processing in VCL, like this:: } } +Note that ``set beresp.do_esi = true;`` is not required, and should +be avoided, for the included fragments, unless they also contains +```` instructions. + Example: esi:remove and ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The `` and `` constructs can be used to present @@ -87,8 +89,39 @@ For example:: --> -Footnotes about ESI -------------------- +What happens when it fails ? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, the fragments must have ``resp.status`` 200 or 206 or +their inclusion will cause the parent request to abort. + +Likewise, if the fragment is a streaming fetch, and that fetch +fails, the parent request aborts. + +If you include synthetic fragments, that is fragments created in +``vcl_backend_error{}`` or ``vcl_synth{}``, you must set +``(be)resp.status`` to 200 before ``return(deliver);`` + +We say "abort" rather than "fail", because by the time Varnish +starts inserting the fragments, the HTTP response header has long +since been sent, and it is no longer possible to change the parent +requests's ``resp.status`` to a 5xx, so the only way to signal that +something is amiss, is to close the connection. + +However, it is possible to allow individual `` + +Can an ESI fragment also use ESI-includes ? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Yes, but the depth is limited by the ``max_esi_depth`` +parameter in order to prevent infinite recursion. Doing ESI on JSON and other non-XML'ish content ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -120,23 +153,23 @@ ESI includes with HTTPS protocol ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If ESI:include tags specify HTTPS protocol, it will be ignored -by default, because Varnish has no way to fetch it encryption -enabled. If you want to treat HTTPS in ESI:include tags as if -it were HTTP, set:: +by default, because Varnish has no way to fetch it with encryption. +If you want Varnish to fetch them like it does anything else, set:: param.set feature +esi_ignore_https ESI on partial responses (206) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Varnish can ``pass`` range requests but it is ESI processing a partial -response makes no sense, so the fetch fails if you do ask for that. -If you really know what you are doing, you can use this workaround:: +Varnish supports range requests, but in general partial responses +make no sense in an ESI context. + +If you really know what you are doing, change the 206 to a 200:: sub vcl_backend_response { if (beresp.status == 206 && beresp.http.secret == "swordfish") { set beresp.do_esi = True; - set beresp.status = 1206; + set beresp.status = 200; } } @@ -147,3 +180,26 @@ If the original client request switched to a different VCL using ``return(vcl(...))`` in ``vcl_recv``, any esi:include-requests will still start out in the same VCL as the original did, *not* in the one it switched to. + +ESI and gzip compression +~~~~~~~~~~~~~~~~~~~~~~~~ + +Varnish's ESI implementation handles gzip compression automatically, +no matter how it is mixed: The parent request can be compressed +or uncompressed and the fragments can be compressed or uncompressed, +it all works out. + +Varnish does this compressing all parts of ESI responses +separately, and stitching them together on the fly during +delivery, which has a negative impact on compression ratio. + +When you ``set beresp.do_esi = True;`` on a gzip'ed response, it +will be uncompressed and recompressed part-wise during the fetch. + +The part-wise compression reduces the opportunities for +removing redundancy, because back-references in the gzip +data stream cannot point outside it's own part. + +The other case where compression ratio is impacted, is if an +uncompressed fragment is inserted into a compressed +response. From dridi.boukelmoune at gmail.com Wed Feb 1 17:12:07 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 1 Feb 2023 17:12:07 +0000 (UTC) Subject: [master] 706330867 fetch: Backends are in charge of printing headers Message-ID: <20230201171207.71E5E64F1E@lists.varnish-cache.org> commit 7063308676415010da5f7b70f571a22a62c66c4b Author: Guillaume Quintard Date: Sat Dec 24 23:13:35 2022 -0800 fetch: Backends are in charge of printing headers The current backend implementation reads the headers all at once, as a big buffer, then manually chops them up, and later on, in the startfetch step, Varnish loops through all the headers and prints them. This is inconvenient for custom backends that are most likely going to use http_SetH() (directly or via http_SetHeader(), http_PrinfHeader() or others), which also prints the headers being added. As a result, those implementations end up logging the header twice. To work around the issue we can push the burden of logging the beresp headers onto the backend implementation. It does change one test, as now the Timestamp:Beresp log record appears after the headers instead of before. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 7ac117cc4..4802c05fc 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -273,6 +273,7 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); bo = ctx->bo; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(bo->bereq, HTTP_MAGIC); if (bo->htc != NULL) CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC); wrk = ctx->bo->wrk; @@ -317,6 +318,7 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) i = V1F_FetchRespHdr(bo); if (i == 0) { AN(bo->htc->priv); + http_VSL_log(bo->beresp); return (0); } } diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 343a28102..0af5c0d54 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -442,8 +442,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) return (F_STP_ERROR); } - http_VSL_log(bo->beresp); - if (bo->htc != NULL && bo->htc->body_status == BS_ERROR) { bo->htc->doclose = SC_RX_BODY; vbf_cleanup(bo); diff --git a/bin/varnishtest/tests/c00036.vtc b/bin/varnishtest/tests/c00036.vtc index adec31ab0..514fe08a9 100644 --- a/bin/varnishtest/tests/c00036.vtc +++ b/bin/varnishtest/tests/c00036.vtc @@ -33,11 +33,11 @@ logexpect l1 -v v1 -q "vxid == 1004" { expect 0 1004 BackendOpen {^\d+ s1} expect 0 1004 Timestamp {^Bereq:} - expect 0 1004 Timestamp {^Beresp:} expect 0 1004 BerespProtocol {^HTTP/1.1} expect 0 1004 BerespStatus {^200} expect 0 1004 BerespReason {^OK} expect 0 1004 BerespHeader {^Content-Length: 6} + expect 0 1004 Timestamp {^Beresp:} } -start client c1 { diff --git a/doc/changes.rst b/doc/changes.rst index 979857f08..4d0012a5d 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -75,6 +75,8 @@ Varnish Cache NEXT (2023-03-15) * The ``debug.xid`` CLI command now sets the next XID to be used, rather than "one less than the next XID to be used" +* Backend implementations are in charge of logging their headers. + ================================ Varnish Cache 7.2.0 (2022-09-15) ================================ diff --git a/doc/sphinx/reference/directors.rst b/doc/sphinx/reference/directors.rst index 66c0f406c..450515df7 100644 --- a/doc/sphinx/reference/directors.rst +++ b/doc/sphinx/reference/directors.rst @@ -204,6 +204,11 @@ to implement the whole probing infrastructure from scratch. You may also consider making your custom backend compliant with regards to the VCL state (see :ref:`ref-vmod-event-functions`). +If you are implementing the `gethdrs` method of your backend (i.e. your +backend is able to generate a backend response to be manipulated in +`vcl_backend_response`), you will want to log the response code, protocol and +the various headers it'll create for easier debugging. For this, you can look +at the `VSL*` family of functions, listed in `cache/cache.h`. Data structure considerations ----------------------------- From nils.goroll at uplex.de Tue Feb 7 09:12:07 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 7 Feb 2023 09:12:07 +0000 (UTC) Subject: [master] 0c1aef58e On linux, use close_range() if available and prefer it over closefrom() Message-ID: <20230207091207.9A3A7111F8A@lists.varnish-cache.org> commit 0c1aef58e57a5935116bf55176cbf48aad3d3a08 Author: Nils Goroll Date: Tue Feb 7 10:06:30 2023 +0100 On linux, use close_range() if available and prefer it over closefrom() which might come from libbsd piggy-bagged on libedit. diff --git a/configure.ac b/configure.ac index dc0153c50..e5b4a188a 100644 --- a/configure.ac +++ b/configure.ac @@ -227,6 +227,7 @@ AC_CHECK_HEADERS([sys/vfs.h]) AC_CHECK_HEADERS([endian.h]) AC_CHECK_HEADERS([pthread_np.h], [], [], [#include ]) AC_CHECK_HEADERS([priv.h]) +AC_CHECK_HEADERS([linux/close_range.h]) AC_CHECK_HEADERS([fnmatch.h], [], [AC_MSG_ERROR([fnmatch.h is required])]) # Checks for library functions. diff --git a/lib/libvarnish/vsub.c b/lib/libvarnish/vsub.c index b528c12c4..0cdac7364 100644 --- a/lib/libvarnish/vsub.c +++ b/lib/libvarnish/vsub.c @@ -38,7 +38,9 @@ #include // Solaris closefrom(3c) #include #include -#ifndef HAVE_CLOSEFROM +#ifdef HAVE_LINUX_CLOSE_RANGE_H +# include +#elif HAVE_CLOSEFROM # include #endif @@ -65,7 +67,10 @@ VSUB_closefrom(int fd) assert(fd >= 0); -#ifdef HAVE_CLOSEFROM +#ifdef HAVE_LINUX_CLOSE_RANGE_H + AZ(close_range(fd, ~0U, 0)); + return; +#elif HAVE_CLOSEFROM closefrom(fd); return; #else From dridi.boukelmoune at gmail.com Tue Feb 7 12:11:06 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 7 Feb 2023 12:11:06 +0000 (UTC) Subject: [master] 908c9b811 vtc: Add BLOB literal coverage for synth bodies Message-ID: <20230207121106.909FB117432@lists.varnish-cache.org> commit 908c9b81132a93d3dd8880c10d5541ea009f94c3 Author: Dridi Boukelmoune Date: Tue Feb 7 13:05:37 2023 +0100 vtc: Add BLOB literal coverage for synth bodies diff --git a/bin/varnishtest/tests/r03079.vtc b/bin/varnishtest/tests/r03079.vtc index 22da633ac..100df5af6 100644 --- a/bin/varnishtest/tests/r03079.vtc +++ b/bin/varnishtest/tests/r03079.vtc @@ -50,7 +50,9 @@ varnish v1 -vcl { set resp.body += "world"; } } - if (req.url ~ "blob") { + if (req.url ~ "blob/literal") { + set resp.body = :aGVsbG93b3JsZA==:; + } elif (req.url ~ "blob") { set resp.body = blob.decode(HEX, encoded="1100"); if (req.url ~ "reset") { set resp.body = blob.decode(HEX, encoded="221100"); @@ -95,4 +97,8 @@ client c2 { txreq -url "/blob/add" rxresp expect resp.bodylen == 5 + + txreq -url "/blob/literal" + rxresp + expect resp.body == helloworld } -run From dridi.boukelmoune at gmail.com Wed Feb 8 13:40:09 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 13:40:09 +0000 (UTC) Subject: [master] 380e3a4c6 vcc_utils: New vcc_BoolVal() for boolean literals Message-ID: <20230208134009.ED4324C05@lists.varnish-cache.org> commit 380e3a4c667d72e6e1130caef0698cd5d8238983 Author: Walid Boudebouda Date: Fri Jan 13 12:08:19 2023 +0100 vcc_utils: New vcc_BoolVal() for boolean literals diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index a3e5d51e0..b99e40fdf 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -448,6 +448,7 @@ double vcc_DurationUnit(struct vcc *); void vcc_ByteVal(struct vcc *, VCL_INT *); void vcc_Duration(struct vcc *tl, double *); uint64_t vcc_UintVal(struct vcc *tl); +uint8_t vcc_BoolVal(struct vcc *tl); int vcc_IsFlag(struct vcc *tl); int vcc_IsFlagRaw(struct vcc *, const struct token *, const struct token *); char *vcc_Dup_be(const char *b, const char *e); diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 50abffe75..b5103c040 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -285,6 +285,29 @@ Resolve_Sockaddr(struct vcc *tl, ZERO_OBJ(rss, sizeof rss); } +/*-------------------------------------------------------------------- +* Recognize boolean const "true" or "false" +*/ + +uint8_t +vcc_BoolVal(struct vcc *tl) +{ + struct symbol* sym; + + if (tl->t->tok != ID) { + VSB_cat(tl->sb, "Expected \"true\" or \"false\"\n"); + vcc_ErrWhere(tl, tl->t); + return (0); + } + sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_NOERR, XREF_NONE); + if (sym == NULL || sym->type != BOOL) { + VSB_cat(tl->sb, "Expected \"true\" or \"false\"\n"); + vcc_ErrWhere(tl, tl->t); + return (0); + } + return (sym->eval_priv != NULL); +} + /*-------------------------------------------------------------------- * Recognize and convert units of duration, return seconds. */ From dridi.boukelmoune at gmail.com Wed Feb 8 13:40:10 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 13:40:10 +0000 (UTC) Subject: [master] 7078d783f vcc_backend: Add an expect_close attribute to probes Message-ID: <20230208134010.12BA94C08@lists.varnish-cache.org> commit 7078d783f1e138a1b1d507b9b3c965fc0b79890a Author: Walid Boudebouda Date: Fri Jan 13 12:15:09 2023 +0100 vcc_backend: Add an expect_close attribute to probes Despite adding a `Connection: close` header by default to probe requests, Varnish does not actively close the connection as it should. This new attribute will allow to tolerate backends that equally don't honor this header, and it is true by default to match the current behavior. diff --git a/bin/varnishtest/tests/c00113.vtc b/bin/varnishtest/tests/c00113.vtc new file mode 100644 index 000000000..190d271e5 --- /dev/null +++ b/bin/varnishtest/tests/c00113.vtc @@ -0,0 +1,29 @@ +varnishtest "probe expect close" + +server s0 { + rxreq + txresp + expect_close +} -dispatch + +varnish v1 -vcl+backend { + probe default { + .window = 1; + .threshold = 1; + .timeout = 1s; + .interval = 0.1s; + .expect_close = true; + } +} -start + +varnish v2 -vcl+backend { + probe default { + .window = 1; + .threshold = 1; + .timeout = 1s; + .interval = 0.1s; + .expect_close = false; + } +} -start + +# expect_close has no effect yet diff --git a/bin/varnishtest/tests/v00005.vtc b/bin/varnishtest/tests/v00005.vtc index 4e28d5388..9c5a6f447 100644 --- a/bin/varnishtest/tests/v00005.vtc +++ b/bin/varnishtest/tests/v00005.vtc @@ -32,6 +32,27 @@ varnish v1 -vcl { } } +# Check expect_close definition +varnish v1 -errvcl {Expected "true" or "false"} { + backend b1 { + .host = "${localhost}"; + .probe = { + .url = "/"; + .expect_close = faux; + } + } +} + +varnish v1 -errvcl {Expected "true" or "false"} { + backend b1 { + .host = "${localhost}"; + .probe = { + .url = "/"; + .expect_close = 1; + } + } +} + # Check redefinition varnish v1 -errvcl {Probe request redefinition at:} { backend b1 { diff --git a/doc/sphinx/reference/vcl-probe.rst b/doc/sphinx/reference/vcl-probe.rst index 25eeb5aa1..bb92be1bd 100644 --- a/doc/sphinx/reference/vcl-probe.rst +++ b/doc/sphinx/reference/vcl-probe.rst @@ -95,6 +95,15 @@ The expected HTTP status, defaults to ``200``:: .expected_response = 418; +Attribute ``.expect_close`` +--------------------------- + +Whether or not to expect the backend to close the underlying connection. + +Accepts ``true`` or ``false``, defaults to ``true``:: + + .expect_close = false; + Attribute ``.timeout`` ---------------------- diff --git a/include/vrt.h b/include/vrt.h index e9ca4f087..8242c63ef 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -60,6 +60,7 @@ * NEXT (2023-03-15) * VXID is 64 bit * [cache.h] http_GetRange() changed + * exp_close added to struct vrt_backend_probe * 16.0 (2022-09-15) * VMOD C-prototypes moved into JSON * VRT_AddVDP() deprecated @@ -589,7 +590,8 @@ struct vrt_backend { unsigned exp_status; \ unsigned window; \ unsigned threshold; \ - unsigned initial; + unsigned initial; \ + unsigned exp_close; #define VRT_BACKEND_PROBE_HANDLE() \ do { \ @@ -599,6 +601,7 @@ struct vrt_backend { DN(window); \ DN(threshold); \ DN(initial); \ + DN(exp_close); \ } while (0) struct vrt_backend_probe { diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index e4ccde185..f9d31ce8c 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -183,7 +183,7 @@ vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep) const struct token *t_field; const struct token *t_did = NULL, *t_window = NULL, *t_threshold = NULL; struct token *t_initial = NULL; - unsigned window, threshold, initial, status; + unsigned window, threshold, initial, status, exp_close; char buf[32]; const char *name; double t; @@ -197,6 +197,7 @@ vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep) "?window", "?threshold", "?initial", + "?expect_close", NULL); SkipToken(tl, '{'); @@ -216,6 +217,7 @@ vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep) threshold = 0; initial = 0; status = 0; + exp_close = 1; while (tl->t->tok != '}') { vcc_IsField(tl, &t_field, fs); @@ -273,6 +275,9 @@ vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep) t_threshold = tl->t; threshold = vcc_UintVal(tl); ERRCHK(tl); + } else if (vcc_IdIs(t_field, "expect_close")) { + exp_close = vcc_BoolVal(tl); + ERRCHK(tl); } else { vcc_ErrToken(tl, t_field); vcc_ErrWhere(tl, t_field); @@ -321,6 +326,7 @@ vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep) Fh(tl, 0, "\t.initial = ~0U,\n"); if (status > 0) Fh(tl, 0, "\t.exp_status = %u,\n", status); + Fh(tl, 0, "\t.exp_close = %u,\n", exp_close); Fh(tl, 0, "}};\n"); SkipToken(tl, '}'); } From dridi.boukelmoune at gmail.com Wed Feb 8 13:40:10 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 13:40:10 +0000 (UTC) Subject: [master] 3ffb28c8b backend_probe: Honor the expect_close attribute Message-ID: <20230208134010.455614C0E@lists.varnish-cache.org> commit 3ffb28c8b8b7eea6dcf6a6050e211fd64ee1d20e Author: Walid Boudebouda Date: Mon Jan 16 17:01:13 2023 +0100 backend_probe: Honor the expect_close attribute Considering that both Varnish and the backend should normally react to the `Connection: close` header added by default, and considering how the probe code is structured, the least intrusive approach is to tolerate a timeout when we don't expect the backend to actively close the connection. diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index d38a51b72..e4589dd37 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -357,8 +357,11 @@ vbp_poke(struct vbp_target *vt) } i = poll(pfd, 1, tmo); if (i <= 0) { - if (!i) + if (!i) { + if (!vt->exp_close) + break; errno = ETIMEDOUT; + } bprintf(vt->resp_buf, "Poll error %d (%s)", errno, VAS_errtxt(errno)); i = -1; diff --git a/bin/varnishtest/tests/c00113.vtc b/bin/varnishtest/tests/c00113.vtc index 190d271e5..978eb8a88 100644 --- a/bin/varnishtest/tests/c00113.vtc +++ b/bin/varnishtest/tests/c00113.vtc @@ -10,7 +10,7 @@ varnish v1 -vcl+backend { probe default { .window = 1; .threshold = 1; - .timeout = 1s; + .timeout = 0.1s; .interval = 0.1s; .expect_close = true; } @@ -20,10 +20,13 @@ varnish v2 -vcl+backend { probe default { .window = 1; .threshold = 1; - .timeout = 1s; + .timeout = 0.1s; .interval = 0.1s; .expect_close = false; } } -start -# expect_close has no effect yet +delay 0.5 + +varnish v1 -cliexpect sick backend.list +varnish v2 -cliexpect healthy backend.list diff --git a/doc/sphinx/reference/vcl-probe.rst b/doc/sphinx/reference/vcl-probe.rst index bb92be1bd..d53d2e265 100644 --- a/doc/sphinx/reference/vcl-probe.rst +++ b/doc/sphinx/reference/vcl-probe.rst @@ -104,6 +104,10 @@ Accepts ``true`` or ``false``, defaults to ``true``:: .expect_close = false; +Warning: when the backend does not close the connection, +setting ``expect_close`` to ``false`` makes probe tasks wait until +they time out before inspecting the response. + Attribute ``.timeout`` ---------------------- From dridi.boukelmoune at gmail.com Wed Feb 8 13:54:05 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 13:54:05 +0000 (UTC) Subject: [master] 6f50b7c8f vtc: Fix c113 Message-ID: <20230208135405.6E98E58BA@lists.varnish-cache.org> commit 6f50b7c8f2cd1f18b29e407664fe8648032f09ae Author: Dridi Boukelmoune Date: Wed Feb 8 14:52:30 2023 +0100 vtc: Fix c113 I changed Walid's test to make it run faster and created an unfortunate race condition as a result. diff --git a/bin/varnishtest/tests/c00113.vtc b/bin/varnishtest/tests/c00113.vtc index 978eb8a88..4a02cf8f1 100644 --- a/bin/varnishtest/tests/c00113.vtc +++ b/bin/varnishtest/tests/c00113.vtc @@ -14,7 +14,7 @@ varnish v1 -vcl+backend { .interval = 0.1s; .expect_close = true; } -} -start +} varnish v2 -vcl+backend { probe default { @@ -24,7 +24,10 @@ varnish v2 -vcl+backend { .interval = 0.1s; .expect_close = false; } -} -start +} + +varnish v1 -start +varnish v2 -start delay 0.5 From dridi.boukelmoune at gmail.com Wed Feb 8 14:14:05 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 14:14:05 +0000 (UTC) Subject: [master] 31baed29c Revert "On linux, use close_range() if available and prefer it over closefrom()" Message-ID: <20230208141405.D055D652B@lists.varnish-cache.org> commit 31baed29c5e77bafe8850d935240acefdb33cd4c Author: Dridi Boukelmoune Date: Wed Feb 8 15:02:06 2023 +0100 Revert "On linux, use close_range() if available and prefer it over closefrom()" This reverts commit 0c1aef58e57a5935116bf55176cbf48aad3d3a08. The close_range(2) system call is too recent and not recognized by the host system on CircleCI, so the fedora-latest container detects it but is denied execution (EPERM) from the host's libseccomp. Also, on platforms with neither close_range(2) nor closefrom(2) we ended up not including and failing virtually everywhere in our CI. The ifdef dance could have looked like this: #ifdef HAVE_LINUX_CLOSE_RANGE_H # include #elif HAVE_CLOSEFROM #else # include #endif Note the extra #else missing from the original patch. This is reverted for now because we need to check that close_range(2) works at configure time to circumvent the host mismatch problem. diff --git a/configure.ac b/configure.ac index e5b4a188a..dc0153c50 100644 --- a/configure.ac +++ b/configure.ac @@ -227,7 +227,6 @@ AC_CHECK_HEADERS([sys/vfs.h]) AC_CHECK_HEADERS([endian.h]) AC_CHECK_HEADERS([pthread_np.h], [], [], [#include ]) AC_CHECK_HEADERS([priv.h]) -AC_CHECK_HEADERS([linux/close_range.h]) AC_CHECK_HEADERS([fnmatch.h], [], [AC_MSG_ERROR([fnmatch.h is required])]) # Checks for library functions. diff --git a/lib/libvarnish/vsub.c b/lib/libvarnish/vsub.c index 0cdac7364..b528c12c4 100644 --- a/lib/libvarnish/vsub.c +++ b/lib/libvarnish/vsub.c @@ -38,9 +38,7 @@ #include // Solaris closefrom(3c) #include #include -#ifdef HAVE_LINUX_CLOSE_RANGE_H -# include -#elif HAVE_CLOSEFROM +#ifndef HAVE_CLOSEFROM # include #endif @@ -67,10 +65,7 @@ VSUB_closefrom(int fd) assert(fd >= 0); -#ifdef HAVE_LINUX_CLOSE_RANGE_H - AZ(close_range(fd, ~0U, 0)); - return; -#elif HAVE_CLOSEFROM +#ifdef HAVE_CLOSEFROM closefrom(fd); return; #else From dridi.boukelmoune at gmail.com Wed Feb 8 14:28:05 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 14:28:05 +0000 (UTC) Subject: [master] 1608518bf vtc_server: Make the dispatch check reliable Message-ID: <20230208142805.1AF306DF2@lists.varnish-cache.org> commit 1608518bf0e624e958e08bddd2e049c31ed9b886 Author: Dridi Boukelmoune Date: Wed Feb 8 15:23:30 2023 +0100 vtc_server: Make the dispatch check reliable If a dispatch server instance is already done by the time we list servers with varnish -vcl+backend we end up with the condition failing on the fd field being negative, since the session was already closed. Adding an explicit flag will prevet that from happening. diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 3942ae92d..b5eccf632 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -59,6 +59,7 @@ struct server { int depth; int sock; int fd; + unsigned is_dispatch; char listen[256]; char aaddr[VTCP_ADDRBUFSIZE]; char aport[VTCP_PORTBUFSIZE]; @@ -361,6 +362,7 @@ server_dispatch_thread(void *priv) bprintf(snbuf, "s%d", sn++); vtc_log(vl, 3, "dispatch fd %d -> %s", fd, snbuf); s2 = server_new(snbuf, vl); + s2->is_dispatch = 1; s2->spec = s->spec; bstrcpy(s2->listen, s->listen); s2->fd = fd; @@ -430,7 +432,7 @@ cmd_server_gen_vcl(struct vsb *vsb) AZ(pthread_mutex_lock(&server_mtx)); VTAILQ_FOREACH(s, &servers, list) { - if (s->sock < 0 && s->fd >= 0) /* dispatch instance */ + if (s->is_dispatch) continue; if (VUS_is(s->listen)) From dridi.boukelmoune at gmail.com Wed Feb 8 14:28:05 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 14:28:05 +0000 (UTC) Subject: [master] a4165c56c Revert "vtc: Fix c113" Message-ID: <20230208142805.32E646DF5@lists.varnish-cache.org> commit a4165c56c06fa46c21e00fc44bd26f291ab2834c Author: Dridi Boukelmoune Date: Wed Feb 8 15:17:00 2023 +0100 Revert "vtc: Fix c113" This reverts commit 6f50b7c8f2cd1f18b29e407664fe8648032f09ae. The test case was correct but too fast for the dispatch instance check. diff --git a/bin/varnishtest/tests/c00113.vtc b/bin/varnishtest/tests/c00113.vtc index 4a02cf8f1..978eb8a88 100644 --- a/bin/varnishtest/tests/c00113.vtc +++ b/bin/varnishtest/tests/c00113.vtc @@ -14,7 +14,7 @@ varnish v1 -vcl+backend { .interval = 0.1s; .expect_close = true; } -} +} -start varnish v2 -vcl+backend { probe default { @@ -24,10 +24,7 @@ varnish v2 -vcl+backend { .interval = 0.1s; .expect_close = false; } -} - -varnish v1 -start -varnish v2 -start +} -start delay 0.5 From dridi.boukelmoune at gmail.com Wed Feb 8 14:36:04 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Feb 2023 14:36:04 +0000 (UTC) Subject: [master] 51d010e45 vtc_server: Whitespace OCD Message-ID: <20230208143605.0CE9975C6@lists.varnish-cache.org> commit 51d010e45bb4a2edb18482689541795f53d0b8c1 Author: Dridi Boukelmoune Date: Wed Feb 8 15:32:54 2023 +0100 vtc_server: Whitespace OCD diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index b5eccf632..a4a306df5 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -437,13 +437,12 @@ cmd_server_gen_vcl(struct vsb *vsb) if (VUS_is(s->listen)) VSB_printf(vsb, - "backend %s { .path = \"%s\"; }\n", - s->name, s->listen); + "backend %s { .path = \"%s\"; }\n", + s->name, s->listen); else VSB_printf(vsb, - "backend %s { .host = \"%s\"; " - ".port = \"%s\"; }\n", - s->name, s->aaddr, s->aport); + "backend %s { .host = \"%s\"; .port = \"%s\"; }\n", + s->name, s->aaddr, s->aport); } AZ(pthread_mutex_unlock(&server_mtx)); } From nils.goroll at uplex.de Wed Feb 8 14:46:05 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 8 Feb 2023 14:46:05 +0000 (UTC) Subject: [master] f74c5ed72 Minor polish of the CHERI saga while catching up with it Message-ID: <20230208144605.9204F7C44@lists.varnish-cache.org> commit f74c5ed7245a837f49935caed6c11233897e96d0 Author: Nils Goroll Date: Wed Feb 8 15:15:01 2023 +0100 Minor polish of the CHERI saga while catching up with it phk, if any of this does not match your intentions, please just change it back. waving from the boat... diff --git a/doc/sphinx/phk/cheri1.rst b/doc/sphinx/phk/cheri1.rst index 03545e568..1f519f9eb 100644 --- a/doc/sphinx/phk/cheri1.rst +++ b/doc/sphinx/phk/cheri1.rst @@ -72,7 +72,7 @@ For those of you not familiar with Varnish, you will need to know: I still hate Autocrap tools --------------------------- -Autocrap is a hack on a hack on hack which really ruins software +Autocrap is a hack on a hack on a hack which really ruins software portability, but it is the "industry standard" so we use it also for Varnish, no matter how much I hate it. @@ -133,7 +133,7 @@ so:: The two typedefs ``uintptr_t`` and ``intptr_t`` are big enough to hold a pointer so that you can write "portable" code which -does the kind the kind of integer-pointer-mis-math which +does the kind of integer-pointer-mis-math which CHERI prevents you from doing. In theory we should not have any ``[u]intptr_t`` in Varnish, diff --git a/doc/sphinx/phk/cheri6.rst b/doc/sphinx/phk/cheri6.rst index 02e2f9401..6c52b9621 100644 --- a/doc/sphinx/phk/cheri6.rst +++ b/doc/sphinx/phk/cheri6.rst @@ -119,10 +119,10 @@ The only "proper" solution is to build some kind of datastructure: List, tree, hash, DB2 database, pick any poison you prefer, and search out the metadata pointer using the impotent pointer as key. Given that CHERI pointers are huge, it may be a better idea to embed -a numeric index in the object and use that the key, +a numeric index in the object and use that as the key. An important benefit of this ?additional work? is that if your -free-function get passed a pointer to something else, you will +free-function gets passed a pointer to something else, you will find out, because it is not in your data-structure. It would be a good idea if CHERI came with a quality implementation From nils.goroll at uplex.de Wed Feb 8 16:24:05 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 8 Feb 2023 16:24:05 +0000 (UTC) Subject: [master] 033990ac3 Polish -jsolaris docs Message-ID: <20230208162405.8410D6518E@lists.varnish-cache.org> commit 033990ac3d35cd1ba003b3f04c086d39d38b0f1a Author: Nils Goroll Date: Wed Feb 8 17:11:52 2023 +0100 Polish -jsolaris docs diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 12bd0425f..007dbf803 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -443,15 +443,15 @@ specific options. Available jails are: -j - Reduce `privileges(5)` for `varnishd` and sub-process to the + Reduce `privileges(5)` for `varnishd` and sub-processes to the minimally required set. Only available on platforms which have the `setppriv(2)` call. The optional `worker` argument can be used to pass a privilege-specification (see `ppriv(1)`) by which to extend the effective set of the varnish worker process. While extended - privileges may be required by custom vmods, it is always the more - secure to *not* use the `worker` option. + privileges may be required by custom vmods, *not* using the `worker` + option is always more secure. Example to grant basic privileges to the worker process:: From nils.goroll at uplex.de Wed Feb 8 15:17:23 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 8 Feb 2023 16:17:23 +0100 Subject: [master] 02636039d heritage: Remove unset params::[gu]id fields In-Reply-To: <20230130165506.5079A118B46@lists.varnish-cache.org> References: <20230130165506.5079A118B46@lists.varnish-cache.org> Message-ID: <126aff6c-9d16-a181-5454-72a6d8c13e8d@uplex.de> On 30.01.23 17:55, Dridi Boukelmoune wrote: > > commit 02636039d4da9fbbe25362a7a17a9375873d11f4 > Author: Dridi Boukelmoune > Date: Tue Jan 24 11:32:09 2023 +0100 > > heritage: Remove unset params::[gu]id fields FTR: General went away with 38c4a7d66ef6d6d4bfeca7cc75f82d8df6f5f7f0 and it seems I did not remove their use in the Solaris jail when I should have. I will look at the Solaris jail now. Nils -- ** * * UPLEX - Nils Goroll Systemoptimierung Scheffelstra?e 32 22301 Hamburg tel +49 40 28805731 mob +49 170 2723133 fax +49 40 42949753 xmpp://slink at jabber.int.uplex.de/ http://uplex.de/ From nils.goroll at uplex.de Fri Feb 10 08:54:07 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 10 Feb 2023 08:54:07 +0000 (UTC) Subject: [master] 4995d793c Improve the Unix jail documentation Message-ID: <20230210085407.C023667C3@lists.varnish-cache.org> commit 4995d793ca34f400cea719baade6335ce6b42dad Author: Nils Goroll Date: Fri Feb 10 09:50:24 2023 +0100 Improve the Unix jail documentation Document that the daemon and worker user have to share their primary group. Provide an exmaple of how to set up a system for the default users. Note: I am well aware of the commands in pkg-varnish-cache, but they use Linux specific useradd syntax. The commands given hopefully are portable - I tested them on Solaris and Linux. diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 007dbf803..126ef802b 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -475,6 +475,18 @@ specific options. Available jails are: The optional `workuser` argument specifies an alternative user to use for the worker process. It defaults to ``vcache``. + The users given for the `user` and `workuser` arguments need to have + the same primary ("login") group. + + To set up a system for the default users with a group name + ``varnish``, shell commands similar to these may be used:: + + groupadd varnish + useradd -g varnish -d /nonexistent -s /bin/false \ + -c "Varnish-Cache Daemon User" varnish + useradd -g varnish -d /nonexistent -s /bin/false \ + -c "Varnish-Cache Worker User" vcache + -j none last resort jail choice: With jail mechanism ``none``, varnish will From dridi.boukelmoune at gmail.com Mon Feb 13 19:07:07 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 13 Feb 2023 19:07:07 +0000 (UTC) Subject: [master] f088fc4d9 vnum: Work around uninitialized variable in test code Message-ID: <20230213190707.9CFCA11E5DC@lists.varnish-cache.org> commit f088fc4d943224b5d781a8c4bb3f7e4f82af3b25 Author: William Wilson Date: Tue Jan 31 14:25:06 2023 -0500 vnum: Work around uninitialized variable in test code The value should always be set, because we already assign zero on error, but it might escape (pun intended) the vigilance of the compiler. Instead of always making `VNUM_2bytes()` assign its second parameter, it was decided that fixing the test case would be enough since we already require error handling. diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c index 8b90b97c8..021aa7baf 100644 --- a/lib/libvarnish/vnum.c +++ b/lib/libvarnish/vnum.c @@ -575,7 +575,7 @@ main(int argc, char *argv[]) { int ec = 0; struct test_case *tc; - uintmax_t val; + uintmax_t val = 0; const char **p; const char *e; double d1, d2; From dridi.boukelmoune at gmail.com Mon Feb 20 07:17:10 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 20 Feb 2023 07:17:10 +0000 (UTC) Subject: [master] 7cca67cd3 doc: Typo Message-ID: <20230220071710.B0AE6106947@lists.varnish-cache.org> commit 7cca67cd399177232c9949c66e7716efd3e84428 Author: Dridi Boukelmoune Date: Mon Feb 20 08:01:56 2023 +0100 doc: Typo diff --git a/doc/sphinx/whats-new/upgrading-7.1.rst b/doc/sphinx/whats-new/upgrading-7.1.rst index a09a6e649..5d458c582 100644 --- a/doc/sphinx/whats-new/upgrading-7.1.rst +++ b/doc/sphinx/whats-new/upgrading-7.1.rst @@ -119,7 +119,7 @@ In the VMOD descriptor, it is possible to add the following stanza:: or - $Alias .deprecated_method objec.original_method + $Alias .deprecated_method object.original_method This is a good occasion to revisit unfortunate name choices in existing VMODs. From dridi.boukelmoune at gmail.com Mon Feb 20 07:17:10 2023 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 20 Feb 2023 07:17:10 +0000 (UTC) Subject: [master] 0e8180c12 doc: Document the $Alias stanza Message-ID: <20230220071710.D1AFA106981@lists.varnish-cache.org> commit 0e8180c12670c64da5344ce52af768c546199000 Author: Dridi Boukelmoune Date: Mon Feb 20 08:10:46 2023 +0100 doc: Document the $Alias stanza diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index 10460cd7b..a4437396d 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -264,6 +264,29 @@ managing instances, in particular their memory management. As the lifetime of object instances is the vcl, they will usually be allocated from the heap. +Deprecated Aliases +------------------ + +The ``$Alias`` stanza offers a mechanism to rename a function or an +object's method without removing the previous name. This allows name +changes to maintain compatibility until the alias is dropped. + +The syntax for a function is:: + + $Alias deprecated_function original_function + + [description] + +The syntax for a method is:: + + $Alias .deprecated_method object.original_method + + [description] + +The ``$Alias`` stanza can appear anywhere, this allows grouping them +in a dedicated "deprecated" section of their manual. The optional +description can be used to explain why a function was renamed. + .. _ref-vmod-vcl-c-types: VCL and C data types From nils.goroll at uplex.de Mon Feb 20 15:38:06 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 20 Feb 2023 15:38:06 +0000 (UTC) Subject: [master] 6e22b8158 Basic "via" backends support Message-ID: <20230220153806.2EE60119386@lists.varnish-cache.org> commit 6e22b8158347cd3f8bd24a65d447038959fa6686 Author: Nils Goroll Date: Fri Mar 22 15:50:07 2019 +0100 Basic "via" backends support In varnish-cache, the deliberate decision has been made to not support TLS from the same address space as varnish itself, see doc/sphinx/phk/ssl_again.rst So the obvious way to connect to TLS backends is to use a TLS "onloader" (a term coined by @slimhazard as in the opposite of "offloader"), which turns a clear connection into a TLS connection. Before this change, this required additional configuration in two places: An address/port or UDS path needs to be uniquely allocated for each destination address, the specific onloader configuration has to be put in place and a varnish backend pointing to the onloader needs to be added. All of this for each individual backend. Also, this requirement prevents any use of dynamic backends with a TLS onloader. haproxy, however, offers a convenient and elegant way to avoid this configuration overhead: The PROXY protocol can also be used to transport the destination address which haproxy is to connect to if a server's address is unspecified (IN_ADDR_ANY / 0.0.0.0). The configuration template for this use case looks like this (huge thank you to @wtarreau for pointing out this great option in haproxy): listen clear-to-ssl bind /my/path/to/ssl_onloader accept-proxy balance roundrobin stick-table type ip size 100 stick on dst server s0 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt server s1 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt server s2 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt # .. approximately as many servers as expected peers # for improved tls session caching With this setup, by connecting to /my/path/to/ssl_onloader and sending the address to make a TLS connection to in a PROXY header (as the server address / port), we can reduce the configuration overhead outside varnish substantially. In particular, we do not require a path / port per destination dynamic TLS backends become possible This patch implements the basis for simple means of configuring such an ssl onloader: backends can be created with an additional "via" director, which has to resolve to a simple backend. The connection is then made to that address and the actual endpoint address is sent in an additional PROXY header. Notice that sending yet another proxy header to the actual backend is unaffected. Despite using the same format, the two proxy headers are semantically different: The first, here coined the "preamble", is the address to make the connection to while the (optional) second proxy header continues to contain the addresses of the connection to varnish. Future improvements on the roadmap: * resolution of the "via" backend at the time the connection is made: This will allow for fault tolerance and load balancing of via backends * Cascade the health check: If the "via" backend is probed / set down, any backends using it could be set unhealthy also. * Timeouts: The "via" backend's timeouts could define maximum values for any connections made through it Tivia: To future Varnish-Cache historians, this patch originates from #2850 and went through three more iterations, making it a likely candidate for the PR with the longest turnaround time of 1543 days. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 4802c05fc..f4722729e 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -37,16 +37,19 @@ #include #include "cache_varnishd.h" +#include "cache_director.h" #include "vsa.h" #include "vtcp.h" #include "vtim.h" +#include "vsa.h" #include "cache_backend.h" #include "cache_conn_pool.h" #include "cache_transport.h" #include "cache_vcl.h" #include "http1/cache_http1.h" +#include "proxy/cache_proxy.h" #include "VSC_vbe.h" @@ -560,17 +563,87 @@ VRT_backend_vsm_need(VRT_CTX) return (VRT_VSC_Overhead(VSC_vbe_size)); } +/* + * The new_backend via parameter is a VCL_BACKEND, but we need a (struct + * backend) + * + * For now, we resolve it when creating the backend, which imples no redundancy + * / load balancing across the via director if it is more than a simple backend. + */ + +static const struct backend * +via_resolve(VRT_CTX, const struct vrt_endpoint *vep, VCL_BACKEND via) +{ + const struct backend *viabe = NULL; + + AN(vep); + AN(via); + + if (vep->uds_path) { + VRT_fail(ctx, "Via is only supported for IP addresses"); + return (NULL); + } + + via = VRT_DirectorResolve(ctx, via); + + if (via != NULL && + (via->vdir->methods == vbe_methods || + via->vdir->methods == vbe_methods_noprobe)) + CAST_OBJ_NOTNULL(viabe, via->priv, BACKEND_MAGIC); + + if (viabe == NULL) + VRT_fail(ctx, "Via does not resolve to a backend"); + + return (viabe); +} + +/* + * construct a new endpoint identical to vep with sa in a proxy header + */ +static struct vrt_endpoint * +via_endpoint(const struct vrt_endpoint *vep, const struct suckaddr *sa) +{ + struct vsb *preamble; + struct vrt_blob blob[1]; + struct vrt_endpoint *nvep, *ret; + const struct suckaddr *client_bogo; + + AN(vep); + AN(sa); + + nvep = VRT_Endpoint_Clone(vep); + AN(nvep); + + if (VSA_Get_Proto(sa) == AF_INET6) + client_bogo = bogo_ip6; + else + client_bogo = bogo_ip; + + preamble = VSB_new_auto(); + AN(preamble); + VPX_Format_Proxy(preamble, 2, client_bogo, sa, NULL); + blob->blob = VSB_data(preamble); + blob->len = VSB_len(preamble); + nvep->preamble = blob; + ret = VRT_Endpoint_Clone(nvep); + VSB_destroy(&preamble); + free(nvep); + + return (ret); +} + VCL_BACKEND VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, - const struct vrt_backend *vrt) + const struct vrt_backend *vrt, VCL_BACKEND via) { struct backend *be; struct vcl *vcl; const struct vrt_backend_probe *vbp; const struct vrt_endpoint *vep; const struct vdi_methods *m; - const struct suckaddr *sa; + const struct suckaddr *sa = NULL; char abuf[VTCP_ADDRBUFSIZE]; + const struct backend *viabe = NULL; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC); @@ -585,6 +658,12 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, assert(vep->ipv4== NULL && vep->ipv6== NULL); } + if (via) { + viabe = via_resolve(ctx, vep, via); + if (viabe == NULL) + return (NULL); + } + vcl = ctx->vcl; AN(vcl); AN(vrt->vcl_name); @@ -594,14 +673,13 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, if (be == NULL) return (NULL); - vep = be->endpoint = VRT_Endpoint_Clone(vep); #define DA(x) do { if (vrt->x != NULL) REPLACE((be->x), (vrt->x)); } while (0) #define DN(x) do { be->x = vrt->x; } while (0) VRT_BACKEND_HANDLE(); #undef DA #undef DN - if (be->hosthdr == NULL) { + if (viabe || be->hosthdr == NULL) { if (vrt->endpoint->uds_path != NULL) sa = bogo_ip; else if (cache_param->prefer_ipv6 && vep->ipv6 != NULL) @@ -610,8 +688,10 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, sa = vep->ipv4; else sa = vep->ipv6; - VTCP_name(sa, abuf, sizeof abuf, NULL, 0); - REPLACE(be->hosthdr, abuf); + if (be->hosthdr == NULL) { + VTCP_name(sa, abuf, sizeof abuf, NULL, 0); + REPLACE(be->hosthdr, abuf); + } } be->vsc = VSC_vbe_New(vc, &be->vsc_seg, @@ -620,6 +700,12 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, if (! vcl->temp->is_warm) VRT_VSC_Hide(be->vsc_seg); + if (viabe) + vep = be->endpoint = via_endpoint(viabe->endpoint, sa); + else + vep = be->endpoint = VRT_Endpoint_Clone(vep); + + AN(vep); be->conn_pool = VCP_Ref(vep, vbe_proto_ident); AN(be->conn_pool); @@ -652,12 +738,12 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, } VCL_BACKEND -VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt) +VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt, VCL_BACKEND via) { CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC); CHECK_OBJ_NOTNULL(vrt->endpoint, VRT_ENDPOINT_MAGIC); - return (VRT_new_backend_clustered(ctx, NULL, vrt)); + return (VRT_new_backend_clustered(ctx, NULL, vrt, via)); } /*-------------------------------------------------------------------- diff --git a/bin/varnishtest/tests/d00007.vtc b/bin/varnishtest/tests/d00007.vtc index 2c05693dc..4198e3fb3 100644 --- a/bin/varnishtest/tests/d00007.vtc +++ b/bin/varnishtest/tests/d00007.vtc @@ -7,32 +7,84 @@ server s1 { accept rxreq txresp + close + accept + rxreq + txresp + close + accept + rxreq + txresp +} -start + +# the use case for via-proxy is to have a(n ha)proxy make a(n ssl) +# connection on our behalf. For the purpose of testing, we use another +# varnish in place - but we are behaving realistically in that we do +# not use any prior information for the actual backend connection - +# just the information from the proxy protocol + +varnish v2 -proto PROXY -vcl { + import debug; + import std; + + backend dummy { .host = "${bad_backend}"; } + + sub vcl_init { + new s1 = debug.dyn("0.0.0.0", "0"); + } + + sub vcl_recv { + s1.refresh(server.ip, std.port(server.ip)); + set req.backend_hint = s1.backend(); + return (pass); + } } -start +# +# we vtc.sleep to make sure that the health check is done and server +# s1 has accepted again. We would rather want to use barriers, but +# there is a (yet not understood) bug in varnishtest which prevents +# the bX_sock marcros from being available in the second varnish +# instance + varnish v1 -vcl { import debug; + import vtc; backend dummy { .host = "${bad_backend}"; } probe pr { .threshold = 8; .initial = 8; + .interval = 1m; } + backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } + sub vcl_init { new s1 = debug.dyn("0.0.0.0", "0"); } sub vcl_recv { - s1.refresh("${s1_addr}", "${s1_port}", pr); + if (req.url == "/1") { + s1.refresh("${s1_addr}", "${s1_port}", pr); + vtc.sleep(1s); + } else if (req.url == "/2") { + s1.refresh("${s1_addr}", "${s1_port}", pr, + via=v2); + vtc.sleep(1s); + } set req.backend_hint = s1.backend(); } } -start -varnish v1 -expect MAIN.n_backend == 2 +varnish v1 -expect MAIN.n_backend == 3 client c1 { - txreq + txreq -url /1 + rxresp + expect resp.status == 200 + txreq -url /2 rxresp expect resp.status == 200 } -run diff --git a/include/vrt.h b/include/vrt.h index 8242c63ef..4f524e4a5 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -61,6 +61,8 @@ * VXID is 64 bit * [cache.h] http_GetRange() changed * exp_close added to struct vrt_backend_probe + * VRT_new_backend() signature changed + * VRT_new_backend_clustered() signature changed * 16.0 (2022-09-15) * VMOD C-prototypes moved into JSON * VRT_AddVDP() deprecated @@ -613,9 +615,9 @@ struct vrt_backend_probe { }; /* Backend related */ -VCL_BACKEND VRT_new_backend(VRT_CTX, const struct vrt_backend *); +VCL_BACKEND VRT_new_backend(VRT_CTX, const struct vrt_backend *, VCL_BACKEND); VCL_BACKEND VRT_new_backend_clustered(VRT_CTX, - struct vsmw_cluster *, const struct vrt_backend *); + struct vsmw_cluster *, const struct vrt_backend *, VCL_BACKEND); size_t VRT_backend_vsm_need(VRT_CTX); void VRT_delete_backend(VRT_CTX, VCL_BACKEND *); struct vrt_endpoint *VRT_Endpoint_Clone(const struct vrt_endpoint *vep); diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index f9d31ce8c..ad694f11d 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -606,7 +606,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\t%s =\n\t VRT_new_backend_clustered(ctx, vsc_cluster,\n" - "\t\t&vgc_dir_priv_%s);\n", + "\t\t&vgc_dir_priv_%s, NULL);\n", vgcname, vgcname); VSB_printf(ifp->ini, "\tif (%s)\n\t\tVRT_StaticDirector(%s);", vgcname, vgcname); diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index a94ae3ab3..8d400256e 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -577,7 +577,7 @@ create_cold_backend(VRT_CTX) INIT_OBJ(be, VRT_BACKEND_MAGIC); be->endpoint = vep; be->vcl_name = "doomed"; - return (VRT_new_backend(ctx, be)); + return (VRT_new_backend(ctx, be, NULL)); } static int diff --git a/vmod/vmod_debug.vcc b/vmod/vmod_debug.vcc index ced0725e9..fbeebd214 100644 --- a/vmod/vmod_debug.vcc +++ b/vmod/vmod_debug.vcc @@ -152,7 +152,7 @@ $Function BOOL fail2() Function to fail vcl code. Always returns true. -$Object dyn(STRING addr, STRING port, PROBE probe=0) +$Object dyn(STRING addr, STRING port, PROBE probe=0, BACKEND via=0) Dynamically create a single-backend director, addr and port must not be empty. @@ -160,7 +160,7 @@ $Method BACKEND .backend() Return the dynamic backend. -$Method VOID .refresh(STRING addr, STRING port, PROBE probe=0) +$Method VOID .refresh(STRING addr, STRING port, PROBE probe=0, BACKEND via=0) Dynamically refresh & (always!) replace the backend by a new one. diff --git a/vmod/vmod_debug_dyn.c b/vmod/vmod_debug_dyn.c index 2f1a1d180..24685cc83 100644 --- a/vmod/vmod_debug_dyn.c +++ b/vmod/vmod_debug_dyn.c @@ -62,7 +62,7 @@ struct xyzzy_debug_dyn_uds { static void dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, - VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) + VCL_STRING addr, VCL_STRING port, VCL_PROBE probe, VCL_BACKEND via) { const struct suckaddr *sa; VCL_BACKEND dir, dir2; @@ -72,6 +72,7 @@ dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, CHECK_OBJ_NOTNULL(dyn, VMOD_DEBUG_DYN_MAGIC); XXXAN(addr); XXXAN(port); + CHECK_OBJ_ORNULL(via, DIRECTOR_MAGIC); INIT_OBJ(&vep, VRT_ENDPOINT_MAGIC); INIT_OBJ(&vrt, VRT_BACKEND_MAGIC); @@ -89,7 +90,7 @@ dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, else WRONG("Wrong proto family"); - dir = VRT_new_backend(ctx, &vrt); + dir = VRT_new_backend(ctx, &vrt, via); AN(dir); /* @@ -110,7 +111,8 @@ dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, VCL_VOID xyzzy_dyn__init(VRT_CTX, struct xyzzy_debug_dyn **dynp, - const char *vcl_name, VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) + const char *vcl_name, VCL_STRING addr, VCL_STRING port, VCL_PROBE probe, + VCL_BACKEND via) { struct xyzzy_debug_dyn *dyn; @@ -132,7 +134,7 @@ xyzzy_dyn__init(VRT_CTX, struct xyzzy_debug_dyn **dynp, AZ(pthread_mutex_init(&dyn->mtx, NULL)); - dyn_dir_init(ctx, dyn, addr, port, probe); + dyn_dir_init(ctx, dyn, addr, port, probe, via); XXXAN(dyn->dir); *dynp = dyn; } @@ -160,11 +162,11 @@ xyzzy_dyn_backend(VRT_CTX, struct xyzzy_debug_dyn *dyn) VCL_VOID xyzzy_dyn_refresh(VRT_CTX, struct xyzzy_debug_dyn *dyn, - VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) + VCL_STRING addr, VCL_STRING port, VCL_PROBE probe, VCL_BACKEND via) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(dyn, VMOD_DEBUG_DYN_MAGIC); - dyn_dir_init(ctx, dyn, addr, port, probe); + dyn_dir_init(ctx, dyn, addr, port, probe, via); } static int @@ -207,7 +209,8 @@ dyn_uds_init(VRT_CTX, struct xyzzy_debug_dyn_uds *uds, VCL_STRING path) vep.ipv4 = NULL; vep.ipv6 = NULL; - if ((dir = VRT_new_backend(ctx, &vrt)) == NULL) + // we support via: uds -> ip, but not via: ip -> uds + if ((dir = VRT_new_backend(ctx, &vrt, NULL)) == NULL) return (-1); AZ(pthread_mutex_lock(&uds->mtx)); From nils.goroll at uplex.de Mon Feb 20 15:38:06 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 20 Feb 2023 15:38:06 +0000 (UTC) Subject: [master] da539902c via backends in VCL Message-ID: <20230220153806.4DDA0119389@lists.varnish-cache.org> commit da539902c2c8842305a944b56dff105e9ba4a6c8 Author: Nils Goroll Date: Fri Mar 22 17:32:36 2019 +0100 via backends in VCL Due to the intialization order, only native vcl backends can be used from vcl as via backends. As directors are defined in vcl_init which gets to run only after the native backends have been initialized, directors can not be refered to from a backend. diff --git a/bin/varnishtest/tests/c00042.vtc b/bin/varnishtest/tests/c00042.vtc new file mode 100644 index 000000000..9bd29ccfd --- /dev/null +++ b/bin/varnishtest/tests/c00042.vtc @@ -0,0 +1,63 @@ +varnishtest "Test vcl defined via backends" + +server s1 { + rxreq + txresp + rxreq + txresp +} -start + +# the use case for via-proxy is to have a(n ha)proxy make a(n ssl) +# connection on our behalf. For the purpose of testing, we use another +# varnish in place - but we are behaving realistically in that we do +# not use any prior information for the actual backend connection - +# just the information from the proxy protocol + +varnish v2 -proto PROXY -vcl { + import debug; + import std; + + backend dummy { .host = "${bad_backend}"; } + + sub vcl_init { + new s1 = debug.dyn("0.0.0.0", "0"); + } + + sub vcl_recv { + s1.refresh(server.ip, std.port(server.ip)); + set req.backend_hint = s1.backend(); + return (pass); + } +} -start + +varnish v1 -vcl { + import debug; + import vtc; + + backend dummy { .host = "${bad_backend}"; } + + backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } + backend s1 { .via = v2; .host = "${s1_addr}"; .port = "${s1_port}"; } + + sub vcl_recv { + set req.backend_hint = s1; + } +} -start + +client c1 { + txreq -url /1 + rxresp + expect resp.status == 200 + txreq -url /2 + rxresp + expect resp.status == 200 +} -run + +varnish v1 -errvcl "Cannot set both .via and .path" { + backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } + + backend s1 { + .via = v2; + .path = "/path/to/uds"; + } +} diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index ad694f11d..a062e1cb5 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -378,6 +378,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) struct fld_spec *fs; struct inifin *ifp; struct vsb *vsb1; + struct symbol *via = NULL; char *p; unsigned u; double t; @@ -418,6 +419,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) "?max_connections", "?proxy_header", "?preamble", + "?via", NULL); tl->fb = VSB_new_auto(); @@ -538,6 +540,13 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) t_preamble = tl->t; vcc_NextToken(tl); SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "via")) { + via = VCC_SymbolGet(tl, SYM_MAIN, SYM_BACKEND, + SYMTAB_EXISTING, XREF_REF); + ERRCHK(tl); + AN(via); + AN(via->rname); + SkipToken(tl, ';'); } else { ErrInternal(tl); VSB_destroy(&tl->fb); @@ -559,6 +568,12 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) return; } + if (via != NULL && t_path != NULL) { + VSB_printf(tl->sb, "Cannot set both .via and .path.\n"); + vcc_ErrWhere(tl, t_be); + return; + } + vsb1 = VSB_new_auto(); AN(vsb1); VSB_printf(vsb1, @@ -606,8 +621,8 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\t%s =\n\t VRT_new_backend_clustered(ctx, vsc_cluster,\n" - "\t\t&vgc_dir_priv_%s, NULL);\n", - vgcname, vgcname); + "\t\t&vgc_dir_priv_%s, %s);\n", + vgcname, vgcname, via ? via->rname : "NULL"); VSB_printf(ifp->ini, "\tif (%s)\n\t\tVRT_StaticDirector(%s);", vgcname, vgcname); VSB_printf(ifp->fin, "\t\tVRT_delete_backend(ctx, &%s);", vgcname); From nils.goroll at uplex.de Mon Feb 20 15:38:06 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 20 Feb 2023 15:38:06 +0000 (UTC) Subject: [master] 15a8e6c0d Add the .authority field to backend definitions. Message-ID: <20230220153806.6FB3C11938D@lists.varnish-cache.org> commit 15a8e6c0d832005a9dd0b3fd8145d1c261cee4b9 Author: Geoff Simmons Date: Wed Aug 21 14:33:45 2019 +0200 Add the .authority field to backend definitions. If the .via field is also set, then the value of .authority is set as the authority TLV in the PROXY header. This gives the "true" backend (usually the ssl-onloader) the opportunity to set the SNI (HostName field) from the TLV value, for the TLS handshake with the remote backend. This mandates that PROXYv2 is always used with a via backend (since only version 2 supports TLVs). If the value of .authority is the empty string, then the TLV is not sent. If .authority is not set for the backend, then fall back to .host_header, which itself may have been a fallback to .host. Note that if neither .authority nor .host_header is set, and .host is set to an IP address, then the IP address is forwarded as the SNI value, which is not permitted for HostName (RFC4366 ch 3.1). So users are advised to set either .authority or .host_header, or set .authority="", when .via is set. Usage note with haproxy: To enable sending SNI when haproxy is used as a TLS onloader, ``sni fc_pp_authority`` needs to be used with the backend configuration. Full usage example with haproxy 2.2: listen sslon mode tcp maxconn 1000 bind /shared/varnish_haproxy/haproxy_sslon accept-proxy mode 777 stick-table type ip size 100 stick on dst server s00 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt alpn http/1.1 sni fc_pp_authority server s01 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt alpn http/1.1 sni fc_pp_authority # ... A higher number of servers improves TLS session caching. diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index f4722729e..ba3b54c08 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -576,8 +576,8 @@ via_resolve(VRT_CTX, const struct vrt_endpoint *vep, VCL_BACKEND via) { const struct backend *viabe = NULL; - AN(vep); - AN(via); + CHECK_OBJ_NOTNULL(vep, VRT_ENDPOINT_MAGIC); + CHECK_OBJ_NOTNULL(via, DIRECTOR_MAGIC); if (vep->uds_path) { VRT_fail(ctx, "Via is only supported for IP addresses"); @@ -586,9 +586,16 @@ via_resolve(VRT_CTX, const struct vrt_endpoint *vep, VCL_BACKEND via) via = VRT_DirectorResolve(ctx, via); - if (via != NULL && - (via->vdir->methods == vbe_methods || - via->vdir->methods == vbe_methods_noprobe)) + if (via == NULL) { + VRT_fail(ctx, "Via resolution failed"); + return (NULL); + } + + CHECK_OBJ(via, DIRECTOR_MAGIC); + CHECK_OBJ_NOTNULL(via->vdir, VCLDIR_MAGIC); + + if (via->vdir->methods == vbe_methods || + via->vdir->methods == vbe_methods_noprobe) CAST_OBJ_NOTNULL(viabe, via->priv, BACKEND_MAGIC); if (viabe == NULL) @@ -601,18 +608,19 @@ via_resolve(VRT_CTX, const struct vrt_endpoint *vep, VCL_BACKEND via) * construct a new endpoint identical to vep with sa in a proxy header */ static struct vrt_endpoint * -via_endpoint(const struct vrt_endpoint *vep, const struct suckaddr *sa) +via_endpoint(const struct vrt_endpoint *vep, const struct suckaddr *sa, + const char *auth) { struct vsb *preamble; struct vrt_blob blob[1]; struct vrt_endpoint *nvep, *ret; const struct suckaddr *client_bogo; - AN(vep); + CHECK_OBJ_NOTNULL(vep, VRT_ENDPOINT_MAGIC); AN(sa); nvep = VRT_Endpoint_Clone(vep); - AN(nvep); + CHECK_OBJ_NOTNULL(nvep, VRT_ENDPOINT_MAGIC); if (VSA_Get_Proto(sa) == AF_INET6) client_bogo = bogo_ip6; @@ -621,11 +629,12 @@ via_endpoint(const struct vrt_endpoint *vep, const struct suckaddr *sa) preamble = VSB_new_auto(); AN(preamble); - VPX_Format_Proxy(preamble, 2, client_bogo, sa, NULL); + VPX_Format_Proxy(preamble, 2, client_bogo, sa, auth); blob->blob = VSB_data(preamble); blob->len = VSB_len(preamble); nvep->preamble = blob; ret = VRT_Endpoint_Clone(nvep); + CHECK_OBJ_NOTNULL(ret, VRT_ENDPOINT_MAGIC); VSB_destroy(&preamble); free(nvep); @@ -658,7 +667,7 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, assert(vep->ipv4== NULL && vep->ipv6== NULL); } - if (via) { + if (via != NULL) { viabe = via_resolve(ctx, vep, via); if (viabe == NULL) return (NULL); @@ -701,7 +710,8 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, VRT_VSC_Hide(be->vsc_seg); if (viabe) - vep = be->endpoint = via_endpoint(viabe->endpoint, sa); + vep = be->endpoint = via_endpoint(viabe->endpoint, sa, + be->authority); else vep = be->endpoint = VRT_Endpoint_Clone(vep); diff --git a/bin/varnishtest/tests/c00042.vtc b/bin/varnishtest/tests/c00042.vtc index 9bd29ccfd..894fc5c07 100644 --- a/bin/varnishtest/tests/c00042.vtc +++ b/bin/varnishtest/tests/c00042.vtc @@ -1,10 +1,10 @@ varnishtest "Test vcl defined via backends" server s1 { - rxreq - txresp - rxreq - txresp + loop 5 { + rxreq + txresp + } } -start # the use case for via-proxy is to have a(n ha)proxy make a(n ssl) @@ -16,6 +16,7 @@ server s1 { varnish v2 -proto PROXY -vcl { import debug; import std; + import proxy; backend dummy { .host = "${bad_backend}"; } @@ -28,14 +29,13 @@ varnish v2 -proto PROXY -vcl { set req.backend_hint = s1.backend(); return (pass); } + + sub vcl_deliver { + set resp.http.Authority = proxy.authority(); + } } -start varnish v1 -vcl { - import debug; - import vtc; - - backend dummy { .host = "${bad_backend}"; } - backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } backend s1 { .via = v2; .host = "${s1_addr}"; .port = "${s1_port}"; } @@ -48,9 +48,79 @@ client c1 { txreq -url /1 rxresp expect resp.status == 200 + expect resp.http.Authority == "127.0.0.1" txreq -url /2 rxresp expect resp.status == 200 + expect resp.http.Authority == "127.0.0.1" +} -run + +varnish v1 -vcl { + backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } + + backend s1 { + .via = v2; + .host = "${s1_addr}"; + .port = "${s1_port}"; + .authority = "authority.com"; + } + + sub vcl_recv { + set req.backend_hint = s1; + } +} + +client c1 { + txreq -url /3 + rxresp + expect resp.status == 200 + expect resp.http.Authority == "authority.com" +} -run + +varnish v1 -vcl { + backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } + + backend s1 { + .via = v2; + .host = "${s1_addr}"; + .port = "${s1_port}"; + .host_header = "host.com"; + } + + sub vcl_recv { + set req.backend_hint = s1; + } +} + +client c1 { + txreq -url /4 + rxresp + expect resp.status == 200 + expect resp.http.Authority == "host.com" +} -run + +# Setting .authority = "" disables sending the TLV. +varnish v1 -vcl { + backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } + + backend s1 { + .via = v2; + .host = "${s1_addr}"; + .port = "${s1_port}"; + .authority = ""; + } + + sub vcl_recv { + set req.backend_hint = s1; + } +} + +client c1 { + txreq -url /5 + rxresp + expect resp.status == 200 + # vmod_proxy returns the empty string if the TLV is absent. + expect resp.http.Authority == "" } -run varnish v1 -errvcl "Cannot set both .via and .path" { diff --git a/bin/varnishtest/tests/c00114.vtc b/bin/varnishtest/tests/c00114.vtc new file mode 100644 index 000000000..84e9aee69 --- /dev/null +++ b/bin/varnishtest/tests/c00114.vtc @@ -0,0 +1,59 @@ +varnishtest "TLV authority over via backends used as SNI for haproxy backend/1" + +# This test is skipped unless haproxy is available. It fails unless +# that binary implements the fc_pp_authority fetch, to return the TLV +# Authority value sent in a PROXYv2 header. + +# In this version of the test, we set port 0 in the server config of +# the "ssl-onloading" haproxy, and set the destination port in the +# backend config for Varnish. The onloader sets its destination port +# from the address forwarded via PROXY, which in turn is set from the +# Varnish backend config. See c00101.vtc for another config method. + +feature ignore_unknown_macro + +feature cmd {haproxy --version 2>&1 | grep -q 'HA-*Proxy version'} + +server s1 { + rxreq + txresp -hdr "Foo: bar" +} -start + +haproxy h1 -conf { + listen feh1 + mode http + bind "fd@${feh1}" ssl verify none crt ${testdir}/common.pem + server s1 ${s1_addr}:${s1_port} + http-response set-header X-SNI %[ssl_fc_sni] +} -start + +# Note the use of port 0 for server s0. +haproxy h2 -conf { + listen clear-to-ssl + bind unix@"${tmpdir}/h2.sock" accept-proxy + server s0 0.0.0.0:0 ssl verify none sni fc_pp_authority +} -start + +varnish v1 -vcl { + backend h2 { .path = "${tmpdir}/h2.sock"; } + + # The ssl-onloader uses the port number set here. + backend h1 { + .via = h2; + .host = "${h1_feh1_addr}"; + .port = "${h1_feh1_port}"; + .authority = "authority.com"; + } + + sub vcl_recv { + set req.backend_hint = h1; + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.Foo == "bar" + expect resp.http.X-SNI == "authority.com" +} -run diff --git a/bin/varnishtest/tests/common.pem b/bin/varnishtest/tests/common.pem new file mode 100644 index 000000000..ca8778e4f --- /dev/null +++ b/bin/varnishtest/tests/common.pem @@ -0,0 +1,65 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnb0BDF7FsqzslakNg7u/n/JQkq6nheuKwvyTqECfpc9y7uSB +e/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97N1/LZa6vecjjgGSP0Aag/gS/ocnM +RIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKttJP8xME7j3bTwIDElx/hNI0n7L+yS +kAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6VkIzdOEtH6TcghXmuGcuqvLNH9Buo +syngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+JHm0pkDzAZ2WluNsuXlrJToPirWyj +6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd3wIDAQABAoIBABojc8UE/2W4WgwC +04Z82ig7Ezb7Ui9S9M+S4zUCYHItijIkE4DkIfO3y7Hk4x6iJdyb191HK9UdC5p9 +32upS9XFPgM/izx3GZvxDhO+xXbSep7ovbyuQ3pPkHTx3TTavpm3GyvmcTKKoy4R +jP4dWhzDXPdQW1ol3ZS4EDau4rlyClY6oi1mq9aBEX3MqVjB/nO7s2AbdgclAgP2 +OZMhTzWYR1k5tYySHCXh3ggGMCikyvHU0+SsGyrstYzP1VYi/n3f0VgqW/5ZjG8x +6SHpe04unErPF3HuSun2ZMCFdBxaTFZ8FENb8evrSXe3nQOc9W21RQdRRrNNUbjl +JYI4veECgYEA0ATYKMS1VCUYRZoQ49b5GTg7avUYqfW4bEo4fSfBue8NrnKR3Wu8 +PPBiCTuIYq1vSF+60B7Vu+hW0A8OuQ2UuMxLpYcQ7lKfNad/+yAfoWWafIqCqNU9 +at0QMdbW6A69d6jZt7OrXtleBsphCnN58jTz4ch4PIa2Oyq46NUXCvUCgYEAwh8t +G6BOHOs3yRNI2s9Y9EEfwoil2uIKrZhqiL3AwdIpu5uNIMuPnbaEpXvRX6jv/qtL +321i8vZLc31aM7zfxQ6B4ReQFJfYC80FJsWvcLwT9hB9mTJpLS4sIu5tzQc87O6w +RtjFMom+5ns5hfPB4Eccy0EtbQWVY4nCzUeO6QMCgYBSvqqRRPXwG7VU8lznlHqP +upuABzChYrnScY+Y0TixUlL54l79Wb6N6vzEOWceAWkzu8iewrU4QspNhr/PgoR3 +IeSxWlG0yy7Dc/ZnmTabx8O06I/iwrfkizzG5nOj6UEamRLJjPGNEB/jyZriQl7u +pnugg1K4mMliLbNSAnlhBQKBgQCmYepbv260Qrex1KGhSg9Ia3k5V74weYYFfJnz +UhChD+1NK+ourcsOtp3C6PlwMHBjq5aAjlU9QfUxq8NgjQaO8/xGXdfUjsFSfAtq +TA4vZkUFpuTAJgEYBHc4CXx7OzTxLzRPxQRgaMgC7KNFOMR34vu/CsJQq3R7uFwL +bsYC2QKBgQCtEmg1uDZVdByX9zyUMuRxz5Tq/vDcp+A5lJj2mha1+bUMaKX2+lxQ +vPxY55Vaw/ukWkJirRrpGv6IytBn0dLAFSlKZworZGBaxsm8OGTFJ5Oe9+kZTjI9 +hvjpClOA1otbmj2F2uZAbuIjxQGDNUkLoifN5yDYCC8JPujHuHmULw== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIGeTCCBGGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJGUjEW +MBQGA1UECBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoT +B296b24uaW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYP +c3VwcG9ydEBvem9uLmlvMB4XDTE2MDExNzIzMDIzOFoXDTE4MDExNjIzMDIzOFow +gb4xCzAJBgNVBAYTAkZSMRYwFAYDVQQIEw1JbGUtZGUtRnJhbmNlMRowGAYDVQQH +ExFOZXVpbGx5LXN1ci1TZWluZTEYMBYGA1UEChMPVE9BRCBDb25zdWx0aW5nMRcw +FQYDVQQLEw5lUGFyYXBoZXIgVGVhbTEWMBQGA1UEAxMNd3d3LnRlc3QxLmNvbTEw +MC4GCSqGSIb3DQEJARYhYXJuYXVsdC5taWNoZWxAdG9hZC1jb25zdWx0aW5nLmZy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnb0BDF7FsqzslakNg7u/ +n/JQkq6nheuKwvyTqECfpc9y7uSBe/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97 +N1/LZa6vecjjgGSP0Aag/gS/ocnMRIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKtt +JP8xME7j3bTwIDElx/hNI0n7L+ySkAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6V +kIzdOEtH6TcghXmuGcuqvLNH9BuosyngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+J +Hm0pkDzAZ2WluNsuXlrJToPirWyj6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd +3wIDAQABo4IBvzCCAbswCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMB +MB0GA1UdDgQWBBTIihFNVNgOseQnsWEcAQxAbIKE4TCBsgYDVR0jBIGqMIGngBRv +G9At9gzk2MW5Z7JVey1LtPIZ8KGBg6SBgDB+MQswCQYDVQQGEwJGUjEWMBQGA1UE +CBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB296b24u +aW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYPc3VwcG9y +dEBvem9uLmlvggkA15FtIaGcrk8wDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg9j +b21tb25OYW1lOmNvcHkwCQYDVR0SBAIwADBIBgNVHR8EQTA/MD2gO6A5hjdodHRw +Oi8vb3BlbnNzbGNhLnRvYWQtY29uc3VsdGluZy5jb20vb3BlbnZwbi9MYXRlc3Qu +Y3JsMBEGCWCGSAGG+EIBAQQEAwIGQDAxBglghkgBhvhCAQ0EJBYiVE9BRC1Db25z +dWx0aW5nIHNlcnZlciBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAewDa +9BukGNJMex8gsXmmdaczTr8yh9Uvw4NJcZS38I+26o//2g+d6i7wxcQg8hIm62Hj +0TblGU3+RsJo4uzcWxxA5YUYlVszbHNBRpQengEE5pjwHvoXVMNES6Bt8xP04+Vj +0qVnA8gUaDMk9lN5anK7tF/mbHOIJwHJZYCa2t3y95dIOVEXFwOIzzbSbaprjkLN +w0BgR5paJz7NZWNqo4sZHUUz94uH2bPEd01SqHO0dJwEVxadgxuPnD05I9gqGpGX +Zf3Rn7EQylvUtX9mpPaulQPXc3emefewLUSSAdnZrVikZK2J/B4lSi9FpUwl4iQH +pZoE0QLQHtB1SBKacnOAddGSTLSdFvpzjErjjWSpMukF0vutmrP86GG3xtshWVhI +u+yLfDJVm/pXfaeDtWMXpxIT/U1i0avpk5MZtFMRC0MTaxEWBTnnJm+/yiaAXQYg +E1ZIP0mkZkiUojIawTR7JTjHGhIraP9UVPNceVy0DLfETHEou3vhwBn7PFOz7piJ +wjp3A47DStJD4fapaX6B1fqM+n34CMD9ZAiJFgQEIQfObAWC9hyr4m+pqkp1Qfuw +vsAP/ZoS1CBirJfm3i+Gshh+VeH+TAmO/NBBYCfzBdgkNz4tJCkOc7CUT/NQTR/L +N2OskR/Fkge149RJi7hHvE3gk/mtGtNmHJPuQ+s= +-----END CERTIFICATE----- + diff --git a/bin/varnishtest/tests/d00007.vtc b/bin/varnishtest/tests/d00007.vtc index 4198e3fb3..b119d9cc2 100644 --- a/bin/varnishtest/tests/d00007.vtc +++ b/bin/varnishtest/tests/d00007.vtc @@ -2,18 +2,30 @@ varnishtest "Test dynamic backends" server s1 { rxreq + expect req.url == "/" + expect req.http.Probe == "p1" + expect req.http.Authority == txresp close accept rxreq + expect req.url == "/1" + expect req.http.Probe == + expect req.http.Authority == txresp close accept rxreq + expect req.url == "/" + expect req.http.Probe == "p2" + expect req.http.Authority == "127.0.0.1" txresp close accept rxreq + expect req.url == "/2" + expect req.http.Probe == + expect req.http.Authority == "127.0.0.1" txresp } -start @@ -26,6 +38,7 @@ server s1 { varnish v2 -proto PROXY -vcl { import debug; import std; + import proxy; backend dummy { .host = "${bad_backend}"; } @@ -36,8 +49,13 @@ varnish v2 -proto PROXY -vcl { sub vcl_recv { s1.refresh(server.ip, std.port(server.ip)); set req.backend_hint = s1.backend(); + set req.http.Authority = proxy.authority(); return (pass); } + + sub vcl_deliver { + set resp.http.Authority = req.http.Authority; + } } -start # @@ -53,10 +71,26 @@ varnish v1 -vcl { backend dummy { .host = "${bad_backend}"; } - probe pr { + probe p1 { + .threshold = 8; + .initial = 8; + .interval = 1m; + .request = + "GET / HTTP/1.1" + "Host: ${s1_addr}" + "Probe: p1" + "Connection: close"; + } + + probe p2 { .threshold = 8; .initial = 8; .interval = 1m; + .request = + "GET / HTTP/1.1" + "Host: ${s1_addr}" + "Probe: p2" + "Connection: close"; } backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } @@ -67,10 +101,10 @@ varnish v1 -vcl { sub vcl_recv { if (req.url == "/1") { - s1.refresh("${s1_addr}", "${s1_port}", pr); + s1.refresh("${s1_addr}", "${s1_port}", p1); vtc.sleep(1s); } else if (req.url == "/2") { - s1.refresh("${s1_addr}", "${s1_port}", pr, + s1.refresh("${s1_addr}", "${s1_port}", p2, via=v2); vtc.sleep(1s); } @@ -84,7 +118,9 @@ client c1 { txreq -url /1 rxresp expect resp.status == 200 + expect resp.http.Authority == txreq -url /2 rxresp expect resp.status == 200 + expect resp.http.Authority == "127.0.0.1" } -run diff --git a/include/vrt.h b/include/vrt.h index 4f524e4a5..5d01f542d 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -63,6 +63,7 @@ * exp_close added to struct vrt_backend_probe * VRT_new_backend() signature changed * VRT_new_backend_clustered() signature changed + * authority field added to struct vrt_backend * 16.0 (2022-09-15) * VMOD C-prototypes moved into JSON * VRT_AddVDP() deprecated @@ -561,6 +562,7 @@ struct vrt_endpoint { #define VRT_BACKEND_FIELDS(rigid) \ rigid char *vcl_name; \ rigid char *hosthdr; \ + rigid char *authority; \ vtim_dur connect_timeout; \ vtim_dur first_byte_timeout; \ vtim_dur between_bytes_timeout; \ @@ -571,6 +573,7 @@ struct vrt_endpoint { do { \ DA(vcl_name); \ DA(hosthdr); \ + DA(authority); \ DN(connect_timeout); \ DN(first_byte_timeout); \ DN(between_bytes_timeout); \ diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index a062e1cb5..c86896623 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -372,6 +372,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) const struct token *t_port = NULL; const struct token *t_path = NULL; const struct token *t_hosthdr = NULL; + const struct token *t_authority = NULL; const struct token *t_did = NULL; const struct token *t_preamble = NULL; struct symbol *pb; @@ -420,6 +421,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) "?proxy_header", "?preamble", "?via", + "?authority", NULL); tl->fb = VSB_new_auto(); @@ -547,6 +549,12 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) AN(via); AN(via->rname); SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "authority")) { + ExpectErr(tl, CSTR); + assert(tl->t->dec != NULL); + t_authority = tl->t; + vcc_NextToken(tl); + SkipToken(tl, ';'); } else { ErrInternal(tl); VSB_destroy(&tl->fb); @@ -609,6 +617,28 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) Fb(tl, 0, "\"0.0.0.0\""); Fb(tl, 0, ",\n"); + /* + * Emit the authority field, falling back to hosthdr, then host. + * + * When authority is "", sending the TLV is disabled. + * + * Falling back to host may result in an IP address in authority, + * which is an illegal SNI HostName (RFC 4366 ch. 3.1). But we + * document the potential error, rather than try to find out + * whether or not Emit_Sockaddr() had to look up a name. + */ + if (via != NULL) { + AN(t_host); + Fb(tl, 0, "\t.authority = "); + if (t_authority != NULL) + EncToken(tl->fb, t_authority); + else if (t_hosthdr != NULL) + EncToken(tl->fb, t_hosthdr); + else + EncToken(tl->fb, t_host); + Fb(tl, 0, ",\n"); + } + /* Close the struct */ Fb(tl, 0, "};\n"); diff --git a/vmod/vmod_debug_dyn.c b/vmod/vmod_debug_dyn.c index 24685cc83..fa988fe4f 100644 --- a/vmod/vmod_debug_dyn.c +++ b/vmod/vmod_debug_dyn.c @@ -79,6 +79,7 @@ dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, vrt.endpoint = &vep; vrt.vcl_name = dyn->vcl_name; vrt.hosthdr = addr; + vrt.authority = addr; vrt.probe = probe; sa = VSS_ResolveOne(NULL, addr, port, AF_UNSPEC, SOCK_STREAM, 0); From nils.goroll at uplex.de Mon Feb 20 15:38:06 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 20 Feb 2023 15:38:06 +0000 (UTC) Subject: [master] 884ef9da0 Explicitly test connection pooling works properly Message-ID: <20230220153806.8E52B119395@lists.varnish-cache.org> commit 884ef9da03de1d586ec580dbf60e9b51be63eb2a Author: Nils Goroll Date: Mon Dec 6 17:05:35 2021 +0100 Explicitly test connection pooling works properly Connect to s1 and s2 via v2. Note on the v2 VCL: We use this varnish instance as a PROXY protocol aware forwarder, which takes the address to connect to from the incoming PROXY header (to mimic haproxy instead of requiring it). Previously, we used debug.dyn(), but that does not work with two different backends because it does not create different backend instances, so connection pooling fails on this level, unrelated to the actual test subject. We avoid this issue by an explicit VCL implementation. diff --git a/bin/varnishtest/tests/c00042.vtc b/bin/varnishtest/tests/c00042.vtc index 894fc5c07..698599d99 100644 --- a/bin/varnishtest/tests/c00042.vtc +++ b/bin/varnishtest/tests/c00042.vtc @@ -3,30 +3,38 @@ varnishtest "Test vcl defined via backends" server s1 { loop 5 { rxreq - txresp + txresp -hdr "Server: s1" } } -start +server s2 { + rxreq + txresp -hdr "Server: s2" +} -start + # the use case for via-proxy is to have a(n ha)proxy make a(n ssl) # connection on our behalf. For the purpose of testing, we use another # varnish in place - but we are behaving realistically in that we do # not use any prior information for the actual backend connection - # just the information from the proxy protocol -varnish v2 -proto PROXY -vcl { - import debug; +varnish v2 -proto PROXY -vcl+backend { import std; import proxy; - backend dummy { .host = "${bad_backend}"; } - - sub vcl_init { - new s1 = debug.dyn("0.0.0.0", "0"); - } - sub vcl_recv { - s1.refresh(server.ip, std.port(server.ip)); - set req.backend_hint = s1.backend(); + if (server.ip == "${s1_addr}" && + std.port(server.ip) == ${s1_port}) { + set req.backend_hint = s1; + } else + if (server.ip == "${s2_addr}" && + std.port(server.ip) == ${s2_port}) { + set req.backend_hint = s2; + } + else { + return (synth(404, "unknown backend")); + } + std.log("PROXY " + req.url + " -> " + req.backend_hint); return (pass); } @@ -35,24 +43,42 @@ varnish v2 -proto PROXY -vcl { } } -start +varnish v2 -cliok "param.set debug +syncvsl" + varnish v1 -vcl { backend v2 { .host = "${v2_addr}"; .port = "${v2_port}"; } backend s1 { .via = v2; .host = "${s1_addr}"; .port = "${s1_port}"; } + backend s2 { .via = v2; .host = "${s2_addr}"; .port = "${s2_port}"; } sub vcl_recv { - set req.backend_hint = s1; + if (req.url ~ "^/s1/") { + set req.backend_hint = s1; + } else if (req.url ~ "^/s2/") { + set req.backend_hint = s2; + } else { + return (synth(400)); + } } } -start client c1 { - txreq -url /1 + txreq -url /s1/1 + rxresp + expect resp.status == 200 + expect resp.http.Authority == "127.0.0.1" + expect resp.http.Server == "s1" + + txreq -url /s2/1 rxresp expect resp.status == 200 expect resp.http.Authority == "127.0.0.1" - txreq -url /2 + expect resp.http.Server == "s2" + + txreq -url /s1/2 rxresp expect resp.status == 200 expect resp.http.Authority == "127.0.0.1" + expect resp.http.Server == "s1" } -run varnish v1 -vcl { @@ -71,7 +97,7 @@ varnish v1 -vcl { } client c1 { - txreq -url /3 + txreq -url /s1/3 rxresp expect resp.status == 200 expect resp.http.Authority == "authority.com" @@ -93,7 +119,7 @@ varnish v1 -vcl { } client c1 { - txreq -url /4 + txreq -url /s1/4 rxresp expect resp.status == 200 expect resp.http.Authority == "host.com" @@ -116,7 +142,7 @@ varnish v1 -vcl { } client c1 { - txreq -url /5 + txreq -url /s1/5 rxresp expect resp.status == 200 # vmod_proxy returns the empty string if the TLV is absent. From nils.goroll at uplex.de Mon Feb 20 15:38:06 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 20 Feb 2023 15:38:06 +0000 (UTC) Subject: [master] 9db64085f Document .via and .authority VCL backend attributes Message-ID: <20230220153806.BA0D011939A@lists.varnish-cache.org> commit 9db64085f1fdc20dd95be86212c2d29d15156dbf Author: Nils Goroll Date: Tue May 24 12:19:39 2022 +0200 Document .via and .authority VCL backend attributes diff --git a/doc/changes.rst b/doc/changes.rst index 4d0012a5d..7d63ec4b1 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -77,6 +77,14 @@ Varnish Cache NEXT (2023-03-15) * Backend implementations are in charge of logging their headers. +* Support for backend connections through a proxy with a PROXY2 + preamble has been added: + + * VCL ``backend``\ s gained attributes ``.via`` and ``.authority`` + + * The ``VRT_new_backend_clustered()`` and ``VRT_new_backend()`` + signatures have been changed + ================================ Varnish Cache 7.2.0 (2022-09-15) ================================ diff --git a/doc/sphinx/reference/vcl-backend.rst b/doc/sphinx/reference/vcl-backend.rst index 048f25cdd..cd4307639 100644 --- a/doc/sphinx/reference/vcl-backend.rst +++ b/doc/sphinx/reference/vcl-backend.rst @@ -142,6 +142,59 @@ Send a BLOB on all newly opened connections to the backend:: .preamble = :SGVsbG8gV29ybGRcbgo=:; +.. _backend_definition_via: + +Attribute ``.via`` +------------------ + +.. _PROXY2: https://raw.githubusercontent.com/haproxy/haproxy/master/doc/proxy-protocol.txt + +Name of another *proxy* backend through which to make the connection +to the *destination* backend using the `PROXY2`_ protocol, for example:: + + backend proxy { + .path = "/path/to/proxy2_endpoint"; + } + backend destination { + .host = "1.2.3.4"; + .via = proxy; + } + +The *proxy* backend can also use a ``.host``\ /\ ``.port`` definition +rather than ``.path``. + +Use of the ``.path`` attribute for the *destination* backend is not +supported. + +The ``.via`` attribute is unrelated to ``.proxy_header``. If both are +used, a second header is sent as per ``.proxy_header`` specification. + +As of this release, the *proxy* backend used with ``.via`` can not be a +director and the protocol is fixed to `PROXY2`_. + +Implementation detail: + +If ``.via = `` is used, a `PROXY2`_ preamble is created with +the *destination* backend's address information as ``dst_addr``\ /\ +``dst_port`` and, optionally, other TLV attributes. The connection is +then made to the *proxy* backend's endpoint (``path`` or ``host``\ /\ +``port``). This is technically equivalent to specifying a ``backend +destination_via_proxy`` with a ``.preamble`` attribute containing the +appropriate `PROXY2`_ preamble for the *destination* backend. + +Attribute ``.authority`` +------------------------ + +The HTTP authority to use when connecting to this backend. If unset, +``.host_header`` or ``.host`` are used. + +``.authority = ""`` disables sending an authority. + +As of this release, the attribute is only used by ``.via`` connections +as a ``PP2_TYPE_AUTHORITY`` Type-Length-Value (TLV) in the `PROXY2`_ +preamble. + + Attribute ``.probe`` -------------------- diff --git a/doc/sphinx/users-guide/vcl-backends.rst b/doc/sphinx/users-guide/vcl-backends.rst index f6d7bcb09..76ef15e1c 100644 --- a/doc/sphinx/users-guide/vcl-backends.rst +++ b/doc/sphinx/users-guide/vcl-backends.rst @@ -150,6 +150,58 @@ more tight, maybe relying on the ``==`` operator in stead, like this:: } +Connecting Through a Proxy +-------------------------- + +.. _PROXY2: https://raw.githubusercontent.com/haproxy/haproxy/master/doc/proxy-protocol.txt +.. _haproxy: http://www.haproxy.org/ +.. _SNI: https://en.wikipedia.org/wiki/Server_Name_Indication + +As of this release, Varnish can connect to an actual *destination* +through a *proxy* using the `PROXY2`_ protocol. Other protocols may be +added. + +For now, a typical use case of this feature is to make TLS-encrypted +connections through a TLS *onloader*. The *onloader* needs to support +dynamic connections with the destination address information taken +from a `PROXY2`_ preamble. For example with `haproxy`_ Version 2.2 or +higher, this snippet can be used as a basis for configuring an +*onloader*:: + + # to review and adjust: + # - maxconn + # - bind ... mode ... + # - ca-file ... + # + listen sslon + mode tcp + maxconn 1000 + bind /path/to/sslon accept-proxy mode 777 + stick-table type ip size 100 + stick on dst + server s00 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt alpn http/1.1 sni fc_pp_authority + server s01 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt alpn http/1.1 sni fc_pp_authority + server s02 0.0.0.0:443 ssl ca-file /etc/ssl/certs/ca-bundle.crt alpn http/1.1 sni fc_pp_authority + # ... + # A higher number of servers improves TLS session caching + +Varnish running on the same server/namespace can then use the +*onloader* with the ``.via`` feature (see :ref:`backend_definition_via`):: + + backend sslon { + .path = "/path/to/sslon"; + } + + backend destination { + .host = "my.https.service"; + .port = "443"; + .via = sslon; + } + +The ``.authority`` attribute can be used to specify the `SNI`_ for the +connection if it differs from ``.host``. + + .. _users-guide-advanced_backend_servers-directors: From nils.goroll at uplex.de Mon Feb 20 15:38:06 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 20 Feb 2023 15:38:06 +0000 (UTC) Subject: [master] 8289ea013 Forbid .via backend stacking for now Message-ID: <20230220153807.020CC11939F@lists.varnish-cache.org> commit 8289ea01317c02fc201d8f32cc7210ff1136d552 Author: Nils Goroll Date: Tue Aug 30 14:43:29 2022 +0200 Forbid .via backend stacking for now suggested by Dridi diff --git a/bin/varnishtest/tests/c00042.vtc b/bin/varnishtest/tests/c00042.vtc index 698599d99..b2a99dc97 100644 --- a/bin/varnishtest/tests/c00042.vtc +++ b/bin/varnishtest/tests/c00042.vtc @@ -12,7 +12,7 @@ server s2 { txresp -hdr "Server: s2" } -start -# the use case for via-proxy is to have a(n ha)proxy make a(n ssl) +# the use case for via-proxy is to have a(n ha)proxy make a (TLS) # connection on our behalf. For the purpose of testing, we use another # varnish in place - but we are behaving realistically in that we do # not use any prior information for the actual backend connection - @@ -145,6 +145,7 @@ client c1 { txreq -url /s1/5 rxresp expect resp.status == 200 + # vmod_proxy returns the empty string if the TLV is absent. expect resp.http.Authority == "" } -run @@ -157,3 +158,21 @@ varnish v1 -errvcl "Cannot set both .via and .path" { .path = "/path/to/uds"; } } + +varnish v1 -errvcl "Can not stack .via backends" { + backend a { .host = "${v2_addr}"; .port = "${v2_port}"; } + + backend b { + .via = a; + .host = "127.0.0.1"; + } + + backend c { + .via = b; + .host = "127.0.0.2"; + } + + sub vcl_backend_fetch { + set bereq.backend = c; + } +} diff --git a/doc/sphinx/reference/vcl-backend.rst b/doc/sphinx/reference/vcl-backend.rst index cd4307639..ae1a994ec 100644 --- a/doc/sphinx/reference/vcl-backend.rst +++ b/doc/sphinx/reference/vcl-backend.rst @@ -169,8 +169,9 @@ supported. The ``.via`` attribute is unrelated to ``.proxy_header``. If both are used, a second header is sent as per ``.proxy_header`` specification. -As of this release, the *proxy* backend used with ``.via`` can not be a -director and the protocol is fixed to `PROXY2`_. +As of this release, the *proxy* backend used with ``.via`` can not be +a director, it can not itself use ``.via`` (error: *Can not stack .via +backends*) and the protocol is fixed to `PROXY2`_. Implementation detail: diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index c86896623..81f0da98a 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -364,7 +364,8 @@ vcc_ParseProbe(struct vcc *tl) */ static void -vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) +vcc_ParseHostDef(struct vcc *tl, struct symbol *sym, + const struct token *t_be, const char *vgcname) { const struct token *t_field; const struct token *t_val; @@ -548,6 +549,19 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) ERRCHK(tl); AN(via); AN(via->rname); + + if (via->extra != NULL) { + AZ(strcmp(via->extra, "via")); + VSB_cat(tl->sb, + "Can not stack .via backends at\n"); + vcc_ErrWhere(tl, tl->t); + VSB_destroy(&tl->fb); + return; + } + + AN(sym); + AZ(sym->extra); + sym->extra = "via"; SkipToken(tl, ';'); } else if (vcc_IdIs(t_field, "authority")) { ExpectErr(tl, CSTR); @@ -582,6 +596,9 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) return; } + if (via != NULL) + AZ(via->extra); + vsb1 = VSB_new_auto(); AN(vsb1); VSB_printf(vsb1, @@ -666,7 +683,7 @@ void vcc_ParseBackend(struct vcc *tl) { struct token *t_first, *t_be; - struct symbol *sym; + struct symbol *sym = NULL; const char *dn; tl->ndirector++; @@ -704,7 +721,7 @@ vcc_ParseBackend(struct vcc *tl) } } Fh(tl, 0, "\nstatic VCL_BACKEND %s;\n", dn); - vcc_ParseHostDef(tl, t_be, dn); + vcc_ParseHostDef(tl, sym, t_be, dn); if (tl->err) { VSB_printf(tl->sb, "\nIn %.*s specification starting at:\n", PF(t_first)); From nils.goroll at uplex.de Fri Feb 24 17:03:07 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 24 Feb 2023 17:03:07 +0000 (UTC) Subject: [master] 054215b51 Also test ESI onerror with max_esi_depth reached Message-ID: <20230224170307.1EF89116656@lists.varnish-cache.org> commit 054215b51ede8caefa856e27e8328fac0ddba737 Author: Nils Goroll Date: Fri Feb 24 18:00:08 2023 +0100 Also test ESI onerror with max_esi_depth reached With onerror=abort, the request is aborted as with a bad return code. With onerror=continue, the include remains empty This already behaved like I expected it to, this vtc merely adds an explicit test. diff --git a/bin/varnishtest/tests/r03865.vtc b/bin/varnishtest/tests/r03865.vtc index 98f706b5b..3bb1994e5 100644 --- a/bin/varnishtest/tests/r03865.vtc +++ b/bin/varnishtest/tests/r03865.vtc @@ -38,6 +38,20 @@ client c1 { expect resp.body == "before " } -run +varnish v1 -cliok "param.set max_esi_depth 0" + +client c1 { + txreq -url "/abort" + non_fatal + rxresphdrs + expect resp.status == 200 + rxchunk + expect_close + expect resp.body == "before " +} -run + +varnish v1 -cliok "param.set max_esi_depth 1" + varnish v1 -vsl_catchup server s1 -wait @@ -55,3 +69,12 @@ client c1 { rxresp expect resp.body == "before FOOBAR after" } -run + +varnish v1 -cliok "param.set max_esi_depth 0" + +client c1 { + fatal + txreq -url "/continue" + rxresp + expect resp.body == "before after" +} -run From phk at FreeBSD.org Mon Feb 27 08:42:09 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 08:42:09 +0000 (UTC) Subject: [master] 8a179e223 Fix c00042, jails do not have 127.0.0.1 as localhost. Message-ID: <20230227084210.15CB41148A8@lists.varnish-cache.org> commit 8a179e223e8e9506040476a7f4109e9714f46bd5 Author: Poul-Henning Kamp Date: Mon Feb 27 08:40:46 2023 +0000 Fix c00042, jails do not have 127.0.0.1 as localhost. diff --git a/bin/varnishtest/tests/c00042.vtc b/bin/varnishtest/tests/c00042.vtc index b2a99dc97..6c9208284 100644 --- a/bin/varnishtest/tests/c00042.vtc +++ b/bin/varnishtest/tests/c00042.vtc @@ -65,19 +65,19 @@ client c1 { txreq -url /s1/1 rxresp expect resp.status == 200 - expect resp.http.Authority == "127.0.0.1" + expect resp.http.Authority == "${s1_addr}" expect resp.http.Server == "s1" txreq -url /s2/1 rxresp expect resp.status == 200 - expect resp.http.Authority == "127.0.0.1" + expect resp.http.Authority == "${s2_addr}" expect resp.http.Server == "s2" txreq -url /s1/2 rxresp expect resp.status == 200 - expect resp.http.Authority == "127.0.0.1" + expect resp.http.Authority == "${s1_addr}" expect resp.http.Server == "s1" } -run From phk at FreeBSD.org Mon Feb 27 08:50:06 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 08:50:06 +0000 (UTC) Subject: [master] 096505549 Also fix "loopback" ip# in d00007, with a slight cheat. Message-ID: <20230227085006.5DFEE114D87@lists.varnish-cache.org> commit 0965055497beab488a1e6743131a7d7731d10e5a Author: Poul-Henning Kamp Date: Mon Feb 27 08:49:16 2023 +0000 Also fix "loopback" ip# in d00007, with a slight cheat. diff --git a/bin/varnishtest/tests/d00007.vtc b/bin/varnishtest/tests/d00007.vtc index b119d9cc2..9443010f9 100644 --- a/bin/varnishtest/tests/d00007.vtc +++ b/bin/varnishtest/tests/d00007.vtc @@ -1,34 +1,5 @@ varnishtest "Test dynamic backends" -server s1 { - rxreq - expect req.url == "/" - expect req.http.Probe == "p1" - expect req.http.Authority == - txresp - close - accept - rxreq - expect req.url == "/1" - expect req.http.Probe == - expect req.http.Authority == - txresp - close - accept - rxreq - expect req.url == "/" - expect req.http.Probe == "p2" - expect req.http.Authority == "127.0.0.1" - txresp - close - accept - rxreq - expect req.url == "/2" - expect req.http.Probe == - expect req.http.Authority == "127.0.0.1" - txresp -} -start - # the use case for via-proxy is to have a(n ha)proxy make a(n ssl) # connection on our behalf. For the purpose of testing, we use another # varnish in place - but we are behaving realistically in that we do @@ -58,6 +29,40 @@ varnish v2 -proto PROXY -vcl { } } -start + +# NB: ${v2_addr} in s1's work should really be ${s1_addr}, but it is not +# defined until after the (implicit) listen(2) call, so we cheat +# and use v2's address instead. + +server s1 { + rxreq + expect req.url == "/" + expect req.http.Probe == "p1" + expect req.http.Authority == + txresp + close + accept + rxreq + expect req.url == "/1" + expect req.http.Probe == + expect req.http.Authority == + txresp + close + accept + rxreq + expect req.url == "/" + expect req.http.Probe == "p2" + expect req.http.Authority == "${v2_addr}" + txresp + close + accept + rxreq + expect req.url == "/2" + expect req.http.Probe == + expect req.http.Authority == "${v2_addr}" + txresp +} -start + # # we vtc.sleep to make sure that the health check is done and server # s1 has accepted again. We would rather want to use barriers, but @@ -122,5 +127,5 @@ client c1 { txreq -url /2 rxresp expect resp.status == 200 - expect resp.http.Authority == "127.0.0.1" + expect resp.http.Authority == "${s1_addr}" } -run From phk at FreeBSD.org Mon Feb 27 09:16:05 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 09:16:05 +0000 (UTC) Subject: [master] c292f8d7d Set permissive modes on h2's unix sockts in case v1 runs as user varnish Message-ID: <20230227091605.9EA0D11646B@lists.varnish-cache.org> commit c292f8d7df13e8712501ddc995f2ce168efeb346 Author: Poul-Henning Kamp Date: Mon Feb 27 09:15:06 2023 +0000 Set permissive modes on h2's unix sockts in case v1 runs as user varnish diff --git a/bin/varnishtest/tests/c00114.vtc b/bin/varnishtest/tests/c00114.vtc index 84e9aee69..28d691642 100644 --- a/bin/varnishtest/tests/c00114.vtc +++ b/bin/varnishtest/tests/c00114.vtc @@ -29,6 +29,7 @@ haproxy h1 -conf { # Note the use of port 0 for server s0. haproxy h2 -conf { + unix-bind mode 777 listen clear-to-ssl bind unix@"${tmpdir}/h2.sock" accept-proxy server s0 0.0.0.0:0 ssl verify none sni fc_pp_authority From phk at FreeBSD.org Mon Feb 27 11:04:05 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 11:04:05 +0000 (UTC) Subject: [master] 363ebd99a Add common.pem to EXTRA_DIST Message-ID: <20230227110405.C68031199FB@lists.varnish-cache.org> commit 363ebd99a017d6f1a3a6f070fdf9b7ee5565876e Author: Poul-Henning Kamp Date: Mon Feb 27 11:02:50 2023 +0000 Add common.pem to EXTRA_DIST diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 4937381d0..78d448a44 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -63,6 +63,7 @@ varnishtest_CFLAGS = \ -DTOP_BUILDDIR='"${top_builddir}"' EXTRA_DIST = $(top_srcdir)/bin/varnishtest/tests/*.vtc \ + $(top_srcdir)/bin/varnishtest/tests/common.pem \ $(top_srcdir)/bin/varnishtest/tests/README \ $(top_srcdir)/bin/varnishtest/gensequences \ $(top_srcdir)/bin/varnishtest/sequences \ From phk at FreeBSD.org Mon Feb 27 13:01:06 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 13:01:06 +0000 (UTC) Subject: [master] a953639dc Flexelinting Message-ID: <20230227130106.631FC11CFC2@lists.varnish-cache.org> commit a953639dc0a2b9a5897cdbf8024b25eb864b8ad8 Author: Poul-Henning Kamp Date: Mon Feb 27 13:00:47 2023 +0000 Flexelinting diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 4b79ebc1b..4c646d337 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -496,7 +496,7 @@ http_rxchar(struct http *hp, int n, int eof) pfd[0].fd = hp->sess->fd; pfd[0].events = POLLIN; pfd[0].revents = 0; - i = poll(pfd, 1, hp->timeout * 1000); + i = poll(pfd, 1, (int)(hp->timeout * 1000)); if (i < 0 && errno == EINTR) continue; if (i == 0) { @@ -1500,7 +1500,7 @@ cmd_http_expect_close(CMD_ARGS) fds[0].fd = hp->sess->fd; fds[0].events = POLLIN; fds[0].revents = 0; - i = poll(fds, 1, hp->timeout * 1000); + i = poll(fds, 1, (int)(hp->timeout * 1000)); if (i < 0 && errno == EINTR) continue; if (i == 0) diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c index b70944bda..42410e45f 100644 --- a/bin/varnishtest/vtc_http2.c +++ b/bin/varnishtest/vtc_http2.c @@ -181,7 +181,7 @@ get_bytes(const struct http *hp, char *buf, int n) pfd[0].fd = hp->sess->fd; pfd[0].events = POLLIN; pfd[0].revents = 0; - i = poll(pfd, 1, hp->timeout * 1000); + i = poll(pfd, 1, (int)(hp->timeout * 1000)); if (i < 0 && errno == EINTR) continue; if (i == 0) @@ -2450,7 +2450,7 @@ cmd_rxsettings(CMD_ARGS) CAST_OBJ_NOTNULL(f, s->frame, FRAME_MAGIC); CHKFRAME(f->type, TYPE_SETTINGS, 0, *av); if (! isnan(f->md.settings[SETTINGS_INITIAL_WINDOW_SIZE])) { - val = f->md.settings[SETTINGS_INITIAL_WINDOW_SIZE]; + val = (uint32_t)f->md.settings[SETTINGS_INITIAL_WINDOW_SIZE]; VTAILQ_FOREACH(s2, &hp->streams, list) s2->win_peer += (val - hp->h2_win_peer->init); hp->h2_win_peer->init = val; diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 12554b853..f763fcce7 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -472,7 +472,7 @@ varnish_launch(struct varnish *v) fd[1].events = POLLIN; fd[2].fd = v->fds[2]; fd[2].events = POLLIN; - i = poll(fd, 2, vtc_maxdur * 1000 / 3); + i = poll(fd, 2, (int)(vtc_maxdur * 1000 / 3)); vtc_log(v->vl, 4, "CLIPOLL %d 0x%x 0x%x 0x%x", i, fd[0].revents, fd[1].revents, fd[2].revents); if (i == 0) From phk at FreeBSD.org Mon Feb 27 13:33:06 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 13:33:06 +0000 (UTC) Subject: [master] 0cf4541ff Flexelint a signed/unsigned mix. Message-ID: <20230227133306.2F06411DEB2@lists.varnish-cache.org> commit 0cf4541ff31c8ddae4d58a8ca0d3a095c66166be Author: Poul-Henning Kamp Date: Mon Feb 27 13:32:17 2023 +0000 Flexelint a signed/unsigned mix. diff --git a/bin/varnishd/http2/cache_http2_hpack.c b/bin/varnishd/http2/cache_http2_hpack.c index f58788b12..51968317a 100644 --- a/bin/varnishd/http2/cache_http2_hpack.c +++ b/bin/varnishd/http2/cache_http2_hpack.c @@ -99,7 +99,7 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) int disallow_empty; unsigned n; char *p; - int i; + unsigned u; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); AN(b); @@ -125,7 +125,7 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) disallow_empty = 1; /* First field cannot contain SP or CTL */ - for (p = b, i = 0; i < len; p++, i++) { + for (p = b, u = 0; u < len; p++, u++) { if (vct_issp(*p) || vct_isctl(*p)) return (H2SE_PROTOCOL_ERROR); } @@ -136,7 +136,7 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) disallow_empty = 1; /* Second field cannot contain LWS or CTL */ - for (p = b, i = 0; i < len; p++, i++) { + for (p = b, u = 0; u < len; p++, u++) { if (vct_islws(*p) || vct_isctl(*p)) return (H2SE_PROTOCOL_ERROR); } @@ -148,13 +148,13 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) len-=1; n = hp->nhd; - for (p = b + namelen, i = 0; i < len-namelen; - p++, i++) { + for (p = b + namelen, u = 0; u < len-namelen; + p++, u++) { if (vct_issp(*p) || vct_isctl(*p)) return (H2SE_PROTOCOL_ERROR); } - if (!i) + if (!u) return (H2SE_PROTOCOL_ERROR); } else if (!strncmp(b, ":authority: ", namelen)) { b+=6; From phk at FreeBSD.org Mon Feb 27 14:04:06 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 14:04:06 +0000 (UTC) Subject: [master] 651cbd15e add vtc.c to doc generation Message-ID: <20230227140406.0D34211ED62@lists.varnish-cache.org> commit 651cbd15e6a76a04978e3d9e512c59a5fae31feb Author: Guillaume Quintard Date: Thu Feb 23 22:13:00 2023 -0800 add vtc.c to doc generation diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am index 56a3a9096..96fc5fc1a 100644 --- a/doc/sphinx/Makefile.am +++ b/doc/sphinx/Makefile.am @@ -158,6 +158,7 @@ include/vsl-tags.rst: $(top_builddir)/lib/libvarnishapi/vsl2rst BUILT_SOURCES += include/vsl-tags.rst VTCSYN_SRC = \ + $(top_srcdir)/bin/varnishtest/vtc.c \ $(top_srcdir)/bin/varnishtest/vtc_barrier.c \ $(top_srcdir)/bin/varnishtest/vtc_haproxy.c \ $(top_srcdir)/bin/varnishtest/vtc_http.c \ From phk at FreeBSD.org Mon Feb 27 14:44:05 2023 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 27 Feb 2023 14:44:05 +0000 (UTC) Subject: [master] 110e7c5d5 Purely cosmetic: VCL_Poll() should be called inside cli_mtx. Message-ID: <20230227144405.DBAA911FFAF@lists.varnish-cache.org> commit 110e7c5d5aafba1d72f73e35fd019959854a3a5c Author: Poul-Henning Kamp Date: Mon Feb 27 14:42:40 2023 +0000 Purely cosmetic: VCL_Poll() should be called inside cli_mtx. diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c index e5006f8de..2dd203597 100644 --- a/bin/varnishd/cache/cache_cli.c +++ b/bin/varnishd/cache/cache_cli.c @@ -76,8 +76,8 @@ cli_cb_before(const struct cli *cli) ASSERT_CLI(); VSL(SLT_CLI, NO_VXID, "Rd %s", VSB_data(cli->cmd)); - VCL_Poll(); Lck_Lock(&cli_mtx); + VCL_Poll(); } static void From nils.goroll at uplex.de Mon Feb 27 14:49:03 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 27 Feb 2023 14:49:03 +0000 (UTC) Subject: [master] c0a9d7319 Optimize VRE_sub() by avoiding VSB_putc() Message-ID: <20230227144903.527D94411@lists.varnish-cache.org> commit c0a9d7319793ff4d7ffe0756163cffbc09b93c37 Author: Nils Goroll Date: Wed Feb 22 16:13:16 2023 +0100 Optimize VRE_sub() by avoiding VSB_putc() We keep s as a pointer to the start of an unaltered section and move e to be able to call VSB_bcat() when a backslash is encountered or substitution is complete. diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c index 96b7ef677..c0f87c0c4 100644 --- a/lib/libvarnish/vre.c +++ b/lib/libvarnish/vre.c @@ -276,7 +276,7 @@ VRE_sub(const vre_t *code, const char *subject, const char *replacement, txt groups[10]; size_t count; int i, offset = 0; - const char *s; + const char *s, *e; unsigned x; CHECK_OBJ_NOTNULL(code, VRE_MAGIC); @@ -301,21 +301,21 @@ VRE_sub(const vre_t *code, const char *subject, const char *replacement, /* Copy prefix to match */ s = subject + offset; VSB_bcat(vsb, s, pdiff(s, groups[0].b)); - for (s = replacement; *s != '\0'; s++ ) { - if (*s != '\\' || s[1] == '\0') { - VSB_putc(vsb, *s); + for (s = e = replacement; *e != '\0'; e++ ) { + if (*e != '\\' || e[1] == '\0') continue; - } - s++; - if (isdigit(*s)) { - x = *s - '0'; + VSB_bcat(vsb, s, pdiff(s, e)); + s = ++e; + if (isdigit(*e)) { + s++; + x = *e - '0'; if (x >= count) continue; VSB_bcat(vsb, groups[x].b, Tlen(groups[x])); continue; } - VSB_putc(vsb, *s); } + VSB_bcat(vsb, s, pdiff(s, e)); offset = pdiff(subject, groups[0].e); if (!all) break; From nils.goroll at uplex.de Mon Feb 27 20:33:13 2023 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 27 Feb 2023 20:33:13 +0000 (UTC) Subject: [master] 7b6665337 cstyle Message-ID: <20230227203313.CE61910409E@lists.varnish-cache.org> commit 7b6665337dabc82f862ff986c9b5fb6ee8c70c19 Author: Nils Goroll Date: Mon Feb 27 21:32:01 2023 +0100 cstyle diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 56ad0340e..2ba29b0a0 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -260,7 +260,7 @@ retire_backend(VCL_BACKEND *bp) if (temp->is_warm) VDI_Event(d, VCL_EVENT_COLD); - if(vdir->methods->destroy != NULL) + if (vdir->methods->destroy != NULL) vdir->methods->destroy(d); assert (d == vdir->dir); vcldir_free(vdir);