From nils.goroll at uplex.de Mon Nov 1 10:49:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 1 Nov 2021 10:49:06 +0000 (UTC) Subject: [master] d10a8b25e Micro polish Message-ID: <20211101104906.E2988927C@lists.varnish-cache.org> commit d10a8b25e45bf292de837d53c17908ce407f7dea Author: Nils Goroll Date: Mon Nov 1 11:37:57 2021 +0100 Micro polish calling strlen() twice caused an itch diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 872f9388f..1991aea77 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -586,7 +586,7 @@ VCL_VOID VRT_SetHdr(VRT_CTX , VCL_HEADER hs, const char *pfx, VCL_STRANDS s) { VCL_HTTP hp; - unsigned u, l; + unsigned u, l, pl; char *p, *b; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); @@ -596,9 +596,8 @@ VRT_SetHdr(VRT_CTX , VCL_HEADER hs, const char *pfx, VCL_STRANDS s) CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); u = WS_ReserveAll(hp->ws); - l = hs->what[0] + 1; - if (pfx != NULL) - l += strlen(pfx); + pl = (pfx == NULL) ? 0 : strlen(pfx); + l = hs->what[0] + 1 + pl; if (u <= l) { WS_Release(hp->ws, 0); WS_MarkOverflow(hp->ws); @@ -621,11 +620,9 @@ VRT_SetHdr(VRT_CTX , VCL_HEADER hs, const char *pfx, VCL_STRANDS s) memcpy(p, hs->what + 1, hs->what[0]); p += hs->what[0]; *p++ = ' '; - if (pfx != NULL) { - l = strlen(pfx); - memcpy(p, pfx, l); - p += l; - } + if (pfx != NULL) + memcpy(p, pfx, pl); + p += pl; if (FEATURE(FEATURE_VALIDATE_HEADERS) && !validhdr(b)) { VRT_fail(ctx, "Bad header %s", b); WS_Release(hp->ws, 0); From nils.goroll at uplex.de Mon Nov 1 15:50:09 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 1 Nov 2021 15:50:09 +0000 (UTC) Subject: [master] 9f5044eb8 Macros for VCL_STRANDS creation Message-ID: <20211101155009.DF83093A06@lists.varnish-cache.org> commit 9f5044eb8d551bafeecdefc1d91529abfe8b9490 Author: Nils Goroll Date: Tue Oct 26 17:39:28 2021 +0200 Macros for VCL_STRANDS creation diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 1991aea77..31424c2ca 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -54,6 +54,7 @@ #include "common/vsmw.h" #include "proxy/cache_proxy.h" +// NOT using TOSTRANDS() to create a NULL pointer element despite n == 0 const struct strands *vrt_null_strands = &(struct strands){ .n = 0, .p = (const char *[1]){NULL} diff --git a/doc/changes.rst b/doc/changes.rst index c290a644c..77eba21c0 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -31,6 +31,20 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. +=============================== +Varnish Cache NEXT (2022-03-15) +=============================== + +* Added macros ``TOSTRAND(s)`` and ``TOSTRANDS(x, ...)`` to create a + ``struct strands *`` (intended to be used as a ``VCL_STANDS``) from + a single string ``s`` or ``x`` strings, respectively. + + Note that the macros create a local pointer value (on the stack), + which should only be used for local variables and parameters, but + never as a function return value (use ``VRT_AllocStrandsWS()`` for + that or just return a ``VCL_STRING`` result created with + ``VRT_StrandsWS()``). + ================================ Varnish Cache 7.0.0 (2021-09-15) ================================ diff --git a/include/vrt.h b/include/vrt.h index 005e485bb..a0d4f10ff 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -281,6 +281,12 @@ struct strands { */ extern const struct strands *vrt_null_strands; +/* + * Macros for VCL_STRANDS creation + */ +#define TOSTRAND(s)(&(struct strands){.n=1,.p=(const char *[1]){s}}) +#define TOSTRANDS(x, ...)(&(struct strands){.n=x,.p=(const char *[x]){__VA_ARGS__}}) + /*********************************************************************** * VCL_BLOB: * diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 1c601931c..cdd2bd498 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -180,9 +180,8 @@ vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1, VSB_cat(e->vsb, "\nVRT_STRANDS_string(ctx,\v+\n"); VSB_printf(e->vsb, - "&(struct strands){.n = %d, .p = " - "(const char *[%d]){\n%s\n}}", - e3->nstr, e3->nstr, VSB_data(e3->vsb)); + "TOSTRANDS(%d,%s)", + e3->nstr, VSB_data(e3->vsb)); VSB_cat(e->vsb, "\v-\n)\n"); } else { @@ -193,10 +192,8 @@ vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1, case 't': e3 = (*p == 'T' ? e1 : e2); AN(e3); - VSB_printf(e->vsb, - "&(struct strands){.n = %d, .p = " - "(const char *[%d]){\n%s\n}}", - e3->nstr, e3->nstr, VSB_data(e3->vsb)); + VSB_printf(e->vsb, "TOSTRANDS(%d,%s)", + e3->nstr, VSB_data(e3->vsb)); break; case '1': VSB_cat(e->vsb, VSB_data(e1->vsb)); diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index e467e4146..07f1039af 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -517,15 +517,9 @@ event_warm(VRT_CTX, const struct vmod_priv *priv) { struct priv_vcl *priv_vcl; char buf[32]; - const char *p[2]; - struct strands msg[1]; // Using VSLs for coverage - msg->n = 2; - msg->p = p; - p[0] = VCL_Name(ctx->vcl); - p[1] = ": VCL_EVENT_WARM"; - VSLs(SLT_Debug, 0, msg); + VSLs(SLT_Debug, 0, TOSTRANDS(2, VCL_Name(ctx->vcl), ": VCL_EVENT_WARM")); AN(ctx->msg); if (cache_param->max_esi_depth == 42) { diff --git a/vmod/vmod_directors_shard.c b/vmod/vmod_directors_shard.c index 19f48339b..744e3552b 100644 --- a/vmod/vmod_directors_shard.c +++ b/vmod/vmod_directors_shard.c @@ -373,8 +373,6 @@ static inline uint32_t shard_get_key(VRT_CTX, const struct vmod_directors_shard_param *p) { struct http *http; - struct strands s[1]; - const char *sp[1]; VCL_ENUM by = default_by(p->by); if (by == VENUM(KEY) || by == VENUM(BLOB)) @@ -390,10 +388,7 @@ shard_get_key(VRT_CTX, const struct vmod_directors_shard_param *p) AN(ctx->http_bereq); AN(http = ctx->http_bereq); } - sp[0] = http->hd[HTTP_HDR_URL].b; - s->n = 1; - s->p = sp; - return (VRT_HashStrands32(s)); + return (VRT_HashStrands32(TOSTRAND(http->hd[HTTP_HDR_URL].b))); } WRONG("by enum"); } diff --git a/vmod/vmod_directors_shard_cfg.c b/vmod/vmod_directors_shard_cfg.c index 6cd709df8..d76c61c6b 100644 --- a/vmod/vmod_directors_shard_cfg.c +++ b/vmod/vmod_directors_shard_cfg.c @@ -270,8 +270,6 @@ shardcfg_hashcircle(struct sharddir *shardd) const char *ident; const int len = 12; // log10(UINT32_MAX) + 2; char s[len]; - struct strands ss[1]; - const char *ssp[2]; CHECK_OBJ_NOTNULL(shardd, SHARDDIR_MAGIC); AZ(shardd->hashcircle); @@ -309,12 +307,9 @@ shardcfg_hashcircle(struct sharddir *shardd) for (j = 0; j < r; j++) { assert(snprintf(s, len, "%d", j) < len); - ss->n = 2; - ssp[0] = ident; - ssp[1] = s; - ss->p = ssp; assert (i < n_points); - shardd->hashcircle[i].point = VRT_HashStrands32(ss); + shardd->hashcircle[i].point = + VRT_HashStrands32(TOSTRANDS(2, ident, s)); shardd->hashcircle[i].host = h; i++; } From phk at FreeBSD.org Wed Nov 3 10:23:07 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 3 Nov 2021 10:23:07 +0000 (UTC) Subject: [master] 415ed78f5 FlexeLinting. Message-ID: <20211103102307.B73DA63A80@lists.varnish-cache.org> commit 415ed78f506465bf3d2801d82b7c50b57f736bfd Author: Poul-Henning Kamp Date: Wed Nov 3 10:21:18 2021 +0000 FlexeLinting. diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index 07f1039af..266d194f0 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -517,9 +517,10 @@ event_warm(VRT_CTX, const struct vmod_priv *priv) { struct priv_vcl *priv_vcl; char buf[32]; + const char *vcl_name = VCL_Name(ctx->vcl); // Using VSLs for coverage - VSLs(SLT_Debug, 0, TOSTRANDS(2, VCL_Name(ctx->vcl), ": VCL_EVENT_WARM")); + VSLs(SLT_Debug, 0, TOSTRANDS(2, vcl_name, ": VCL_EVENT_WARM")); AN(ctx->msg); if (cache_param->max_esi_depth == 42) { From nils.goroll at uplex.de Wed Nov 3 15:10:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 3 Nov 2021 15:10:08 +0000 (UTC) Subject: [master] 9a20cdfd3 Fix (struct vpi_ii).p type Message-ID: <20211103151008.4B47D96820@lists.varnish-cache.org> commit 9a20cdfd3fa6dac117b523082116c804fcca6332 Author: Nils Goroll Date: Wed Nov 3 16:05:33 2021 +0100 Fix (struct vpi_ii).p type It needs to be a generic pointer pointer, because it is initialized as a pointer to a pointer to an arbitrary struct, yet (void **) is can not be dereferenced. Right now, the instance info is not used, but this might change. diff --git a/include/vcc_interface.h b/include/vcc_interface.h index 8c81bddc0..c1a74fc37 100644 --- a/include/vcc_interface.h +++ b/include/vcc_interface.h @@ -75,7 +75,7 @@ void VPI_acl_log(VRT_CTX, const char *); /* vmod object instance info */ struct vpi_ii { - const void * p; + uintptr_t * p; const char * const name; }; From nils.goroll at uplex.de Thu Nov 4 10:16:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 4 Nov 2021 10:16:08 +0000 (UTC) Subject: [master] 87771b9bb Add missing cast Message-ID: <20211104101608.9F7876E0ED@lists.varnish-cache.org> commit 87771b9bbacfc58b10b6c1aff9e96710ac0c25cd Author: Nils Goroll Date: Thu Nov 4 11:12:37 2021 +0100 Add missing cast fixes regression from 9a20cdfd3fa6dac117b523082116c804fcca6332 diff --git a/lib/libvcc/vcc_xref.c b/lib/libvcc/vcc_xref.c index 3e5573eb6..035c42cfb 100644 --- a/lib/libvcc/vcc_xref.c +++ b/lib/libvcc/vcc_xref.c @@ -408,7 +408,7 @@ vcc_instance_info(struct vcc *tl, const struct symbol *sym) CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC); AN(sym->rname); - Fc(tl, 0, "\t{ .p = &%s, .name = \"", sym->rname); + Fc(tl, 0, "\t{ .p = (uintptr_t *)&%s, .name = \"", sym->rname); VCC_SymName(tl->fc, sym); Fc(tl, 0, "\" },\n"); } From nils.goroll at uplex.de Mon Nov 8 09:40:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 09:40:08 +0000 (UTC) Subject: [master] d2eb70177 vtc: defuse assertion while stopping Message-ID: <20211108094008.AB7A7978FC@lists.varnish-cache.org> commit d2eb70177c11ef801a04c9cc3e68f219dfb6ee5e Author: Nils Goroll Date: Mon Nov 8 10:31:39 2021 +0100 vtc: defuse assertion while stopping The disconnect function should not complain when the server is already closed by an explicit close. Saw this failure in vtest: * top TEST ../../../../bin/varnishtest/tests/r01918.vtc starting ... ** s1 === txresp -nolen -bodylen 10 **** s1 txresp|HTTP/1.1 200 OK\r **** s1 txresp|\r **** s1 txresp|!"#$%&'() ** s1 === close ... ** s1 Waiting for server (4/-1) **** s1 Closed *** s1 shutting fd -1 ---- s1 Shutdown failed: Bad file descriptor diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 77dcae8dc..23606a1ac 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -265,7 +265,7 @@ server_disc(void *priv, struct vtclog *vl, int *fdp) CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC); vtc_log(vl, 3, "shutting fd %d", *fdp); j = shutdown(*fdp, SHUT_WR); - if (!VTCP_Check(j)) + if (!vtc_stop && !VTCP_Check(j)) vtc_fatal(vl, "Shutdown failed: %s", strerror(errno)); VTCP_close(fdp); } From nils.goroll at uplex.de Mon Nov 8 10:09:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 10:09:06 +0000 (UTC) Subject: [master] 0b84355c0 VCL_REGEX: Support concatenation of constant strings Message-ID: <20211108100907.00EEF9B981@lists.varnish-cache.org> commit 0b84355c033f23ecca61787547b073fef0bd274b Author: Nils Goroll Date: Fri Oct 29 16:51:04 2021 +0200 VCL_REGEX: Support concatenation of constant strings For the REGEX type, we now peek ahead after the first CSTR token if a '+' operator follows and, if yes, create the pattern as a concatenation. Fixes #3726 diff --git a/bin/varnishtest/tests/b00028.vtc b/bin/varnishtest/tests/b00028.vtc index 074595956..4280e8e6c 100644 --- a/bin/varnishtest/tests/b00028.vtc +++ b/bin/varnishtest/tests/b00028.vtc @@ -8,7 +8,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_backend_response { - if (beresp.http.foo ~ "bar") { + if (beresp.http.foo ~ "b" + "ar") { set beresp.http.foo1 = "1"; } else { set beresp.status = 999; diff --git a/bin/varnishtest/tests/c00103.vtc b/bin/varnishtest/tests/c00103.vtc index 11da0f0b9..75dc18ed3 100644 --- a/bin/varnishtest/tests/c00103.vtc +++ b/bin/varnishtest/tests/c00103.vtc @@ -8,7 +8,8 @@ varnish v1 -vcl { # on purpose to ensure we don't treat REGEX expressions # differently. if (req.url ~ (debug.just_return_regex( - debug.just_return_regex("hello")))) { + debug.just_return_regex("he" + + "l" + "lo")))) { return (synth(200)); } return (synth(500)); diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index f1971efad..8404b2552 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -80,6 +80,27 @@ varnish v1 -errvcl {Regexp compilation error:} { } } +varnish v1 -errvcl {Regexp compilation error:} { + backend b none; + sub vcl_recv { + if (req.url ~ "[" + "a") {} + } +} + +varnish v1 -errvcl {Expected CSTR got 'req'} { + backend b none; + sub vcl_recv { + if (req.url ~ "a" + req.http.foo) {} + } +} + +varnish v1 -errvcl {Expected ')' got '-'} { + backend b none; + sub vcl_recv { + if (req.url ~ "a" - "b") {} + } +} + varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; backend b none; diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 04dca950d..5633f83f4 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -51,19 +51,38 @@ void vcc_regexp(struct vcc *tl, struct vsb *vgc_name) { + struct vsb *pattern; char buf[BUFSIZ]; vre_t *t; int error, erroroffset; + struct token *t1; struct inifin *ifp; + pattern = VSB_new_auto(); + AN(pattern); + assert(tl->t->tok == CSTR); + VSB_cat(pattern, tl->t->dec); + + t1 = vcc_PeekToken(tl); + AN(t1); + while (t1->tok == '+') { + vcc_NextToken(tl); + SkipToken(tl, '+'); + ExpectErr(tl, CSTR); + VSB_cat(pattern, tl->t->dec); + t1 = vcc_PeekToken(tl); + AN(t1); + } + AZ(VSB_finish(pattern)); - t = VRE_compile(tl->t->dec, 0, &error, &erroroffset, 0); + t = VRE_compile(VSB_data(pattern), 0, &error, &erroroffset, 0); if (t == NULL) { VSB_cat(tl->sb, "Regexp compilation error:\n\n"); AZ(VRE_error(tl->sb, error)); VSB_cat(tl->sb, "\n\n"); vcc_ErrWhere(tl, tl->t); + VSB_destroy(&pattern); return; } VRE_free(&t); @@ -74,9 +93,10 @@ vcc_regexp(struct vcc *tl, struct vsb *vgc_name) Fh(tl, 0, "static struct vre *%s;\n", buf); ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\tVPI_re_init(&%s, ",buf); - EncToken(ifp->ini, tl->t); + VSB_quote(ifp->ini, VSB_data(pattern), -1, VSB_QUOTE_CSTR); VSB_cat(ifp->ini, ");"); VSB_printf(ifp->fin, "\t\tVPI_re_fini(%s);", buf); + VSB_destroy(&pattern); } /* From nils.goroll at uplex.de Mon Nov 8 15:11:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 15:11:07 +0000 (UTC) Subject: [7.0] f5798fd1f vcc: do not overwrite SUB symbol properties when call'ing Message-ID: <20211108151107.7994EA8F58@lists.varnish-cache.org> commit f5798fd1f9362e2a56933c457ead9b85e9d97c79 Author: Nils Goroll Date: Mon Oct 25 18:46:14 2021 +0200 vcc: do not overwrite SUB symbol properties when call'ing vcc_act_call() implements use-before-define semantics. To do so, it needs to instantiate SUB symbols if they do not exist. However, it wrongly called VCC_GlobalSymbol() also for existing symbols, overwriting symbol properties. In the case of the built-in subs, the symbol's lname (historically) still is the unescaped literal name, while user defined subs have their name escaped via VCC_GlobalSymbol() -> VCC_PrintCName(). This made the wrong call to VCC_GlobalSymbol() apparent when a built-in sub was called with an explicit "call" action. Besides fixing the VCC_GlobalSymbol() call, we also need to set the lname and rname attributes for built-in SUB symbols initialized in VCC_New(). Alternatively, we could also have used VCC_GlobalSymbol() there, but that would have affected other places where we (still) rely on the known name scheme of built-in subs, e.h. EmitStruct(). While the name unifaction was nice in general, I found the necessary changes (look up SUB symbols) not worth the benefit. Fixes #3719 diff --git a/bin/varnishtest/tests/m00053.vtc b/bin/varnishtest/tests/m00053.vtc index d5c501ea4..97ed034ce 100644 --- a/bin/varnishtest/tests/m00053.vtc +++ b/bin/varnishtest/tests/m00053.vtc @@ -92,9 +92,12 @@ varnish v1 -vcl { sub vcl_backend_fetch { debug.call(priv_top); } + sub vcl_backend_response { + set beresp.status = 200; + } sub vcl_backend_error { # falling through to None backend would be success - set beresp.status = 200; + call vcl_backend_response; return (deliver); } } -start diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c index 7c7a57714..0ed675da6 100644 --- a/lib/libvcc/vcc_action.c +++ b/lib/libvcc/vcc_action.c @@ -52,16 +52,16 @@ vcc_act_call(struct vcc *tl, struct token *t, struct symbol *sym) t0 = tl->t; sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL_NOERR, XREF_REF); - if (sym == NULL) + if (sym == NULL) { sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_SUB, SYMTAB_CREATE, XREF_REF); - - if (sym == NULL) - return; + if (sym == NULL) + return; + VCC_GlobalSymbol(sym, SUB); + } if (sym->kind == SYM_SUB) { vcc_AddCall(tl, t0, sym); - VCC_GlobalSymbol(sym, SUB); Fb(tl, 1, "%s(ctx, VSUB_STATIC, NULL);\n", sym->lname); SkipToken(tl, ';'); diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index 60427d526..d954ea8b9 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -820,6 +820,7 @@ VCC_New(void) struct vcc *tl; struct symbol *sym; struct proc *p; + struct vsb *vsb; int i; ALLOC_OBJ(tl, VCC_MAGIC); @@ -849,7 +850,25 @@ VCC_New(void) SYM_MAIN, SYM_SUB, VCL_LOW, VCL_HIGH); p = vcc_NewProc(tl, sym); p->method = &method_tab[i]; - VSB_printf(p->cname, "VGC_function_%s", p->method->name); + + // see also VCC_GlobalSymbol() + vsb = VSB_new_auto(); + AN(vsb); + VSB_printf(vsb, "%s_%s", SUB->global_pfx, p->method->name); + AZ(VSB_finish(vsb)); + + AZ(VSB_bcat(p->cname, VSB_data(vsb), VSB_len(vsb))); + + sym->lname = strdup(VSB_data(vsb)); + AN(sym->lname); + + VSB_clear(vsb); + VSB_printf(vsb, "sub_%s", sym->lname); + AZ(VSB_finish(vsb)); + + sym->rname = strdup(VSB_data(vsb)); + AN(sym->rname); + VSB_destroy(&vsb); } tl->sb = VSB_new_auto(); AN(tl->sb); From nils.goroll at uplex.de Mon Nov 8 15:11:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 15:11:07 +0000 (UTC) Subject: [7.0] 2fd71469f vcc: Fix dynamic calls to built-in SUBs and properly check evaluation context Message-ID: <20211108151107.9BD2BA8F5B@lists.varnish-cache.org> commit 2fd71469f60e56683723b9fddb6ae34ed9b79997 Author: Nils Goroll Date: Tue Oct 26 13:33:23 2021 +0200 vcc: Fix dynamic calls to built-in SUBs and properly check evaluation context As a follow-up issue from #3719, it was noticed that dynamic calls to built-in SUBs did not work. This issue was caused by more (struct symbol) members missing initialization in VCC_New(). In turn, it became apparent that the evaluation context check in vcc_expr5() as tested in v00020.vtc only worked by accident, and only for built-in subs because (struct symbol).eval was NULL for built-in subs. We fix SUB type expression evaluation with a type specific evaluation function which allows expression evaluation from explicit SUB contexts only. Fixes #3720 diff --git a/bin/varnishtest/tests/m00053.vtc b/bin/varnishtest/tests/m00053.vtc index 97ed034ce..72e54ab89 100644 --- a/bin/varnishtest/tests/m00053.vtc +++ b/bin/varnishtest/tests/m00053.vtc @@ -98,6 +98,7 @@ varnish v1 -vcl { sub vcl_backend_error { # falling through to None backend would be success call vcl_backend_response; + debug.call(vcl_backend_response); return (deliver); } } -start @@ -205,6 +206,7 @@ varnish v1 -vcl { } sub vcl_init { + new vbr = debug.caller(vcl_backend_response); new c = debug.caller(foo); } diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index 603f3a251..a5b37eed3 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -31,12 +31,31 @@ varnish v1 -errvcl {Comparison of different types: INT '!=' STRING} { } } -varnish v1 -errvcl {Symbol 'vcl_recv' type (sub) can not be used in expression.} { +varnish v1 -errvcl {Symbol 'vcl_recv' can only be used as a SUB expression} { + backend proforma none; sub vcl_recv { set req.http.foo = vcl_recv; } } +varnish v1 -errvcl {Symbol 'vcl_recv' can only be used as a SUB expression} { + backend proforma none; + sub vcl_recv { + return (synth(200)); + } + sub vcl_synth { + set req.http.foo = vcl_recv; + } +} + +varnish v1 -errvcl {Symbol 'asub' can only be used as a SUB expression} { + backend proforma none; + sub asub {} + sub vcl_recv { + set req.http.foo = asub; + } +} + varnish v1 -errvcl {Symbol 'acl' type (reserved) can not be used in expression.} { import std; sub vcl_recv { call acl; } diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index d954ea8b9..d3acb0383 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -64,6 +64,7 @@ #include "libvcc.h" #include "vfil.h" +#include "vct.h" static const struct method method_tab[] = { { "none", 0U, 0}, @@ -869,6 +870,11 @@ VCC_New(void) sym->rname = strdup(VSB_data(vsb)); AN(sym->rname); VSB_destroy(&vsb); + + sym->type = SUB; + sym->kind = VCC_HandleKind(SUB); + AZ(VCT_invalid_name(sym->rname, NULL)); + sym->eval = vcc_Eval_Sub; } tl->sb = VSB_new_auto(); AN(tl->sb); diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 3f3ccc3c0..6ce150c4c 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -351,6 +351,7 @@ sym_act_f vcc_Act_Obj; void vcc_Expr_Init(struct vcc *tl); sym_expr_t vcc_Eval_Var; sym_expr_t vcc_Eval_Handle; +sym_expr_t vcc_Eval_Sub; sym_expr_t vcc_Eval_SymFunc; sym_expr_t vcc_Eval_TypeMethod; void vcc_Eval_Func(struct vcc *, const struct vjsn_val *, @@ -377,6 +378,7 @@ void vcc_lex_source(struct vcc *tl, struct source *sp, int eoi); void vcc_stevedore(struct vcc *vcc, const char *stv_name); /* vcc_symb.c */ +vcc_kind_t VCC_HandleKind(vcc_type_t fmt); void VCC_PrintCName(struct vsb *vsb, const char *b, const char *e); struct symbol *VCC_MkSym(struct vcc *tl, const char *b, vcc_ns_t, vcc_kind_t, int, int); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index c2e25c871..598a283b4 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -329,6 +329,29 @@ vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t, } } +void v_matchproto_(sym_expr_t) +vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t, + struct symbol *sym, vcc_type_t type) +{ + + (void)t; + (void)tl; + AN(sym->rname); + AZ(type->stringform); + + assert (sym->type == SUB); + + if (type == SUB) { + *e = vcc_mk_expr(sym->type, "%s", sym->rname); + (*e)->constant = EXPR_CONST; + return; + } + + VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n", + sym->name, sym->type->name); + vcc_ErrWhere(tl, tl->t); +} + /*-------------------------------------------------------------------- */ diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c index 5125cda3e..25d824b91 100644 --- a/lib/libvcc/vcc_symb.c +++ b/lib/libvcc/vcc_symb.c @@ -76,7 +76,7 @@ struct symtab { VTAILQ_HEAD(,symbol) symbols; }; -static vcc_kind_t +vcc_kind_t VCC_HandleKind(vcc_type_t fmt) { if (fmt == ACL) return (SYM_ACL); @@ -510,7 +510,10 @@ VCC_GlobalSymbol(struct symbol *sym, vcc_type_t type) sym->kind = VCC_HandleKind(sym->type); if (sym->kind != SYM_NONE) { AZ(VCT_invalid_name(sym->rname, NULL)); - sym->eval = vcc_Eval_Handle; + if (type == SUB) + sym->eval = vcc_Eval_Sub; + else + sym->eval = vcc_Eval_Handle; } else { WRONG("Wrong kind of global symbol"); } From nils.goroll at uplex.de Mon Nov 8 15:11:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 15:11:07 +0000 (UTC) Subject: [7.0] 464dad5eb Split out dns-dependent test Message-ID: <20211108151107.E2E30A8F63@lists.varnish-cache.org> commit 464dad5ebfb787d4723a20b6cbf51c0a5a7ce12b Author: Nils Goroll Date: Fri Oct 29 16:58:57 2021 +0200 Split out dns-dependent test Conflicts: bin/varnishtest/tests/v00022.vtc diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index f4421a166..8a8dc1cf3 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -1,7 +1,5 @@ varnishtest "Various VCL compiler coverage tests" -feature dns - shell "true > ${tmpdir}/_varnishtest_empty_file" varnish v1 -vcl { @@ -82,13 +80,6 @@ varnish v1 -errvcl {Regexp compilation error:} { } } -varnish v1 -errvcl {resolves to too many addresses} { - backend b { .host = "${localhost}"; } - sub vcl_recv { - if (remote.ip == "dns-canary-multi.varnish-cache.org") {} - } -} - varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; backend b { .host = "${localhost}"; } diff --git a/bin/varnishtest/tests/v00022.vtc b/bin/varnishtest/tests/v00022.vtc new file mode 100644 index 000000000..fcb8014da --- /dev/null +++ b/bin/varnishtest/tests/v00022.vtc @@ -0,0 +1,10 @@ +varnishtest "Various VCL compiler coverage tests - DNS dependent" + +feature dns + +varnish v1 -errvcl {resolves to too many addresses} { + backend b { .host = "${localhost}"; } + sub vcl_recv { + if (remote.ip == "dns-canary-multi.varnish-cache.org") {} + } +} From nils.goroll at uplex.de Mon Nov 8 15:11:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 15:11:08 +0000 (UTC) Subject: [7.0] 5e1589bf4 Use backend none more Message-ID: <20211108151108.1DFBCA8F6B@lists.varnish-cache.org> commit 5e1589bf469be312e9af6ee98053936d55cfb7ce Author: Nils Goroll Date: Fri Oct 29 17:00:05 2021 +0200 Use backend none more diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index 8a8dc1cf3..f1971efad 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -8,14 +8,14 @@ varnish v1 -vcl { } varnish v1 -errvcl {include not followed by semicolon.} { - backend b { .host = "${localhost}"; } + backend b none; include "${tmpdir}/_varnishtest_empty_file" | } shell "rm -f ${tmpdir}/_varnishtest_empty_file" varnish v1 -errvcl {include not followed by string constant.} { - backend b { .host = "${localhost}"; } + backend b none; include << } @@ -29,18 +29,18 @@ varnish v1 -errvcl {include not followed by string constant.} { } varnish v1 -errvcl {Unknown duration unit 'k'} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_backend_response { set beresp.ttl = 1. k; } } varnish v1 -errvcl {Operator > not possible on BACKEND} { - backend a { .host = "${localhost}"; } - backend b { .host = "${localhost}"; } + backend a none; + backend b none; sub vcl_recv { if (a > b) { } } } varnish v1 -errvcl {Unknown property 'foo' for type HTTP} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_hash { if (req.foo != "bar") { } } } @@ -51,21 +51,21 @@ varnish v1 -errvcl {Symbol not found: 'foo.bar'} { } varnish v1 -errvcl {Cannot be set in subroutine 'vcl_pipe'} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_pipe { set bereq.first_byte_timeout = 10s; } } varnish v1 -errvcl {Cannot be set in subroutine 'vcl_pipe'.} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_pipe { set bereq.between_bytes_timeout = 10s; } } varnish v1 -errvcl {Undefined backend c, first reference:} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_backend_response { if (beresp.backend == c) { set beresp.ttl = 1h; @@ -74,7 +74,7 @@ varnish v1 -errvcl {Undefined backend c, first reference:} { } varnish v1 -errvcl {Regexp compilation error:} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_recv { if (req.url ~ "[a") {} } @@ -82,7 +82,7 @@ varnish v1 -errvcl {Regexp compilation error:} { varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; - backend b { .host = "${localhost}"; } + backend b none; sub vcl_init { new foo = directors.shard(); @@ -96,7 +96,7 @@ varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { varnish v1 -syntax 4.0 -errvcl {Expression has type directors.shard, expected ACL} { import directors; - backend b { .host = "${localhost}"; } + backend b none; sub vcl_init { new foo = directors.shard(); @@ -121,7 +121,7 @@ varnish v1 -errvcl {Undefined sub foo} { varnish v1 -syntax 4.0 -errvcl {Symbol not found: 'directors.foo' At:} { import directors; - backend b { .host = "${localhost}"; } + backend b none; sub vcl_init { new foo = directors.foo(); @@ -130,7 +130,7 @@ At:} { # 'foo' overloaded varnish v1 -syntax 4.0 -errvcl {Symbol not found: 'foo'} { - backend b { .host = "${localhost}"; } + backend b none; acl foo -pedantic { "${localhost}"/32; diff --git a/bin/varnishtest/tests/v00022.vtc b/bin/varnishtest/tests/v00022.vtc index fcb8014da..953882fd8 100644 --- a/bin/varnishtest/tests/v00022.vtc +++ b/bin/varnishtest/tests/v00022.vtc @@ -3,7 +3,7 @@ varnishtest "Various VCL compiler coverage tests - DNS dependent" feature dns varnish v1 -errvcl {resolves to too many addresses} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_recv { if (remote.ip == "dns-canary-multi.varnish-cache.org") {} } From nils.goroll at uplex.de Mon Nov 8 15:11:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 15:11:08 +0000 (UTC) Subject: [7.0] 8a4a7cc61 VCL_REGEX: Support concatenation of constant strings Message-ID: <20211108151108.53097A8F73@lists.varnish-cache.org> commit 8a4a7cc612253267b5ff97d3d52130953618c3c2 Author: Nils Goroll Date: Fri Oct 29 16:51:04 2021 +0200 VCL_REGEX: Support concatenation of constant strings For the REGEX type, we now peek ahead after the first CSTR token if a '+' operator follows and, if yes, create the pattern as a concatenation. Fixes #3726 diff --git a/bin/varnishtest/tests/b00028.vtc b/bin/varnishtest/tests/b00028.vtc index 074595956..4280e8e6c 100644 --- a/bin/varnishtest/tests/b00028.vtc +++ b/bin/varnishtest/tests/b00028.vtc @@ -8,7 +8,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_backend_response { - if (beresp.http.foo ~ "bar") { + if (beresp.http.foo ~ "b" + "ar") { set beresp.http.foo1 = "1"; } else { set beresp.status = 999; diff --git a/bin/varnishtest/tests/c00103.vtc b/bin/varnishtest/tests/c00103.vtc index 11da0f0b9..75dc18ed3 100644 --- a/bin/varnishtest/tests/c00103.vtc +++ b/bin/varnishtest/tests/c00103.vtc @@ -8,7 +8,8 @@ varnish v1 -vcl { # on purpose to ensure we don't treat REGEX expressions # differently. if (req.url ~ (debug.just_return_regex( - debug.just_return_regex("hello")))) { + debug.just_return_regex("he" + + "l" + "lo")))) { return (synth(200)); } return (synth(500)); diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index f1971efad..8404b2552 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -80,6 +80,27 @@ varnish v1 -errvcl {Regexp compilation error:} { } } +varnish v1 -errvcl {Regexp compilation error:} { + backend b none; + sub vcl_recv { + if (req.url ~ "[" + "a") {} + } +} + +varnish v1 -errvcl {Expected CSTR got 'req'} { + backend b none; + sub vcl_recv { + if (req.url ~ "a" + req.http.foo) {} + } +} + +varnish v1 -errvcl {Expected ')' got '-'} { + backend b none; + sub vcl_recv { + if (req.url ~ "a" - "b") {} + } +} + varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; backend b none; diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 04dca950d..5633f83f4 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -51,19 +51,38 @@ void vcc_regexp(struct vcc *tl, struct vsb *vgc_name) { + struct vsb *pattern; char buf[BUFSIZ]; vre_t *t; int error, erroroffset; + struct token *t1; struct inifin *ifp; + pattern = VSB_new_auto(); + AN(pattern); + assert(tl->t->tok == CSTR); + VSB_cat(pattern, tl->t->dec); + + t1 = vcc_PeekToken(tl); + AN(t1); + while (t1->tok == '+') { + vcc_NextToken(tl); + SkipToken(tl, '+'); + ExpectErr(tl, CSTR); + VSB_cat(pattern, tl->t->dec); + t1 = vcc_PeekToken(tl); + AN(t1); + } + AZ(VSB_finish(pattern)); - t = VRE_compile(tl->t->dec, 0, &error, &erroroffset, 0); + t = VRE_compile(VSB_data(pattern), 0, &error, &erroroffset, 0); if (t == NULL) { VSB_cat(tl->sb, "Regexp compilation error:\n\n"); AZ(VRE_error(tl->sb, error)); VSB_cat(tl->sb, "\n\n"); vcc_ErrWhere(tl, tl->t); + VSB_destroy(&pattern); return; } VRE_free(&t); @@ -74,9 +93,10 @@ vcc_regexp(struct vcc *tl, struct vsb *vgc_name) Fh(tl, 0, "static struct vre *%s;\n", buf); ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\tVPI_re_init(&%s, ",buf); - EncToken(ifp->ini, tl->t); + VSB_quote(ifp->ini, VSB_data(pattern), -1, VSB_QUOTE_CSTR); VSB_cat(ifp->ini, ");"); VSB_printf(ifp->fin, "\t\tVPI_re_fini(%s);", buf); + VSB_destroy(&pattern); } /* From nils.goroll at uplex.de Mon Nov 8 16:14:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 16:14:05 +0000 (UTC) Subject: [master] 31dc27cef vdef: implement vmin[_t], vmax[_t] and vlimit[_t] Message-ID: <20211108161405.E0C04AB2B4@lists.varnish-cache.org> commit 31dc27cefcb595b016737d75d4b23e3fbffd01a4 Author: Asad Sajjad Ahmed Date: Tue Sep 28 14:18:50 2021 +0200 vdef: implement vmin[_t], vmax[_t] and vlimit[_t] This should make the code easier to read and stop us from being inconsistent. Signed-off-by: Asad Sajjad Ahmed diff --git a/include/vdef.h b/include/vdef.h index c4004611f..a810be196 100644 --- a/include/vdef.h +++ b/include/vdef.h @@ -164,6 +164,55 @@ int __llvm_gcov_flush(void); #define RDN2(x, y) ((x)&(~((uintptr_t)(y)-1UL))) /* PWR2(y) true */ #define RUP2(x, y) (((x)+((y)-1))&(~((uintptr_t)(y)-1UL))) /* PWR2(y) true */ +/********************************************************************** + * Find the minimum or maximum values. + * Only evaluate the expression once and perform type checking. + */ + +/* ref: https://stackoverflow.com/a/17624752 */ + +#define VINDIRECT(a, b, c) a ## b ## c +#define VCOMBINE(a, b, c) VINDIRECT(a, b, c) + +#if defined(__COUNTER__) +# define VUNIQ_NAME(base) VCOMBINE(base, __LINE__, __COUNTER__) +#else +# define VUNIQ_NAME(base) VCOMBINE(base, __LINE__, 0) +#endif + +/* ref: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html */ + +#define _vmin(a, b, _va, _vb) \ +({ \ + typeof (a) _va = (a); \ + typeof (b) _vb = (b); \ + (void)(&_va == &_vb); \ + _va < _vb ? _va : _vb; \ +}) + +#define _vmax(a, b, _va, _vb) \ +({ \ + typeof (a) _va = (a); \ + typeof (b) _vb = (b); \ + (void)(&_va == &_vb); \ + _va > _vb ? _va : _vb; \ +}) + +#define vmin(a, b) _vmin((a), (b), VUNIQ_NAME(_vmina), \ + VUNIQ_NAME(_vminb)) +#define vmax(a, b) _vmax((a), (b), VUNIQ_NAME(_vmaxa), \ + VUNIQ_NAME(_vmaxb)) + +#define vmin_t(type, a, b) vmin((type)(a), (type)(b)) +#define vmax_t(type, a, b) vmax((type)(a), (type)(b)) + +/********************************************************************** + * Clamp the value between two limits. + */ + +#define vlimit(a, l, u) vmax((l), vmin((a), (u))) +#define vlimit_t(type, a, l, u) vmax_t(type, (l), vmin_t(type, (a), (u))) + /********************************************************************** * FlexeLint and compiler shutuppery */ From nils.goroll at uplex.de Mon Nov 8 16:14:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 16:14:06 +0000 (UTC) Subject: [master] 519ead4a3 take in use vmin[_t] for existing code Message-ID: <20211108161406.2C2F4AB2B8@lists.varnish-cache.org> commit 519ead4a3a019e28c1e5b7c8eab87261760dd07c Author: Asad Sajjad Ahmed Date: Tue Sep 28 14:22:07 2021 +0200 take in use vmin[_t] for existing code Signed-off-by: Asad Sajjad Ahmed diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 8d50d64b2..97e652702 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -633,8 +633,7 @@ vbp_set_defaults(struct vbp_target *vt, const struct vrt_backend_probe *vp) if (vt->initial == ~0U) vt->initial = vt->threshold - 1; - if (vt->initial > vt->threshold) - vt->initial = vt->threshold; + vt->initial = vmin(vt->initial, vt->threshold); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index c6fc3b0b6..07af11e37 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -663,8 +663,7 @@ ved_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, /* The main body of the object */ dl = foo->last / 8 - foo->ll; if (dl > 0) { - if (dl > len) - dl = len; + dl = vmin(dl, len); if (ved_bytes(foo->ecx, act, pp, dl)) return (-1); foo->ll += dl; @@ -686,8 +685,7 @@ ved_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, /* Last block */ dl = foo->stop / 8 - foo->ll; if (dl > 0) { - if (dl > len) - dl = len; + dl = vmin(dl, len); if (ved_bytes(foo->ecx, act, pp, dl)) return (-1); foo->ll += dl; diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 0624fefe1..cee4eb57b 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -271,7 +271,6 @@ static enum vfp_status v_matchproto_(vfp_pull_f) vfp_esi_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { enum vfp_status vp; - ssize_t d; struct vef_priv *vef; CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); @@ -280,9 +279,7 @@ vfp_esi_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) AN(p); AN(lp); if (DO_DEBUG(DBG_ESI_CHOP)) { - d = (VRND_RandomTestable() & 3) + 1; - if (d < *lp) - *lp = d; + *lp = vmin(*lp, (VRND_RandomTestable() & 3) + 1); } vp = VFP_Suck(vc, p, lp); if (vp != VFP_ERROR && *lp > 0) diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index ea5553b3f..76a3a2422 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -110,8 +110,7 @@ vbf_allocobj(struct busyobj *bo, unsigned l) * on Transient storage. */ - if (oc->ttl > cache_param->shortlived) - oc->ttl = cache_param->shortlived; + oc->ttl = vmin_t(float, oc->ttl, cache_param->shortlived); oc->grace = 0.0; oc->keep = 0.0; return (STV_NewObject(bo->wrk, oc, stv_transient, l)); @@ -762,8 +761,7 @@ vbf_objiterator(void *priv, unsigned flush, const void *ptr, ssize_t len) l = len; if (VFP_GetStorage(bo->vfc, &l, &pd) != VFP_OK) return (1); - if (len < l) - l = len; + l = vmin(l, len); memcpy(pd, ps, l); VFP_Extend(bo->vfc, l, l == len ? VFP_END : VFP_OK); ps += l; @@ -966,8 +964,7 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo) l = ll; if (VFP_GetStorage(bo->vfc, &l, &ptr) != VFP_OK) break; - if (l > ll) - l = ll; + l = vmin(l, ll); memcpy(ptr, VSB_data(synth_body) + o, l); VFP_Extend(bo->vfc, l, l == ll ? VFP_END : VFP_OK); ll -= l; diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c index 402884e5f..e4ccbc7c6 100644 --- a/bin/varnishd/cache/cache_range.c +++ b/bin/varnishd/cache/cache_range.c @@ -85,9 +85,7 @@ vrg_range_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, p += l; len -= l; } - l = vrg_priv->range_high - vrg_priv->range_off; - if (l > len) - l = len; + l = vmin(vrg_priv->range_high - vrg_priv->range_off, len); vrg_priv->range_off += len; if (vrg_priv->range_off >= vrg_priv->range_high) act = VDP_END; diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index fbda72f0b..02ddbf922 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -80,9 +80,7 @@ strands_cat(char *buf, unsigned bufl, const struct strands *s) for (i = 0; i < s->n && bufl > 0; i++) { if (s->p[i] == NULL || *s->p[i] == '\0') continue; - ll = strlen(s->p[i]); - if (ll > bufl) - ll = bufl; + ll = vmin_t(unsigned, strlen(s->p[i]), bufl); memcpy(buf, s->p[i], ll); l += ll; buf += ll; @@ -271,9 +269,8 @@ VSLv(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, va_list ap) if (strchr(fmt, '%') == NULL) { vslr(tag, vxid, fmt, strlen(fmt) + 1); } else { - n = vsnprintf(buf, mlen, fmt, ap); - if (n > mlen - 1) - n = mlen - 1; + /* XXX: should probably check return value of vsnprintf */ + n = vmin_t(unsigned, vsnprintf(buf, mlen, fmt, ap), mlen - 1); buf[n++] = '\0'; /* NUL-terminated */ vslr(tag, vxid, buf, n); } @@ -381,9 +378,7 @@ VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s) mlen = cache_param->vsl_reclen; /* including NUL */ - l = strands_len(s) + 1; - if (l > mlen) - l = mlen; + l = vmin(strands_len(s) + 1, mlen); assert(vsl->wlp < vsl->wle); @@ -508,8 +503,7 @@ VSLb_bin(struct vsl_log *vsl, enum VSL_tag_e tag, ssize_t len, const void *ptr) mlen = cache_param->vsl_reclen; /* Truncate */ - if (len > mlen) - len = mlen; + len = vmin_t(ssize_t, len, mlen); assert(vsl->wlp < vsl->wle); diff --git a/bin/varnishd/cache/cache_ws_emu.c b/bin/varnishd/cache/cache_ws_emu.c index 43ee87f85..f3d74150e 100644 --- a/bin/varnishd/cache/cache_ws_emu.c +++ b/bin/varnishd/cache/cache_ws_emu.c @@ -540,9 +540,7 @@ WS_Dump(const struct ws *ws, char where, size_t off, void *buf, size_t len) break; if (wa->ptr == NULL) break; - l = wa->len; - if (l > len) - l = len; + l = vmin_t(size_t, wa->len, len); memcpy(b, wa->ptr, l); b += l; len -= l; diff --git a/bin/varnishd/hpack/vhp_decode.c b/bin/varnishd/hpack/vhp_decode.c index b7c712212..01965d833 100644 --- a/bin/varnishd/hpack/vhp_decode.c +++ b/bin/varnishd/hpack/vhp_decode.c @@ -270,9 +270,7 @@ vhd_lookup(struct vhd_ctx *ctx, unsigned first) assert(lu->l <= l); p += l - lu->l; - l = lu->l; - if (l > ctx->out_e - ctx->out) - l = ctx->out_e - ctx->out; + l = vmin_t(size_t, lu->l, ctx->out_e - ctx->out); memcpy(ctx->out, p, l); ctx->out += l; lu->l -= l; diff --git a/bin/varnishd/hpack/vhp_gen_hufdec.c b/bin/varnishd/hpack/vhp_gen_hufdec.c index ae2b812e4..cf18857cc 100644 --- a/bin/varnishd/hpack/vhp_gen_hufdec.c +++ b/bin/varnishd/hpack/vhp_gen_hufdec.c @@ -236,8 +236,7 @@ main(int argc, const char **argv) for (u = 0; u < HUF_LEN; u++) { if (maxlen < huf[u].blen) maxlen = huf[u].blen; - if (minlen > huf[u].blen) - minlen = huf[u].blen; + minlen = vmin(minlen, huf[u].blen); } top = tbl_new(8); diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c index 835db3599..06869a59a 100644 --- a/bin/varnishd/http1/cache_http1_vfp.c +++ b/bin/varnishd/http1/cache_http1_vfp.c @@ -65,8 +65,7 @@ v1f_read(const struct vfp_ctx *vc, struct http_conn *htc, void *d, ssize_t len) if (htc->pipeline_b) { l = htc->pipeline_e - htc->pipeline_b; assert(l > 0); - if (l > len) - l = len; + l = vmin(l, len); memcpy(p, htc->pipeline_b, l); p += l; len -= l; @@ -210,8 +209,7 @@ v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, if (vfe->priv2 == 0) // XXX: Optimize Content-Len: 0 out earlier return (VFP_END); - if (vfe->priv2 < l) - l = vfe->priv2; + l = vmin(l, vfe->priv2); lr = v1f_read(vc, htc, p, l); if (lr <= 0) return (VFP_Error(vc, "straight insufficient bytes")); diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index 84c6e2c93..172bb35b2 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -212,17 +212,13 @@ H2_Send_Frame(struct worker *wrk, struct h2_sess *h2, static int64_t h2_win_limit(const struct h2_req *r2, const struct h2_sess *h2) { - int64_t m; CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC); CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC); CHECK_OBJ_NOTNULL(h2->req0, H2_REQ_MAGIC); Lck_AssertHeld(&h2->sess->mtx); - m = r2->t_window; - if (m > h2->req0->t_window) - m = h2->req0->t_window; - return (m); + return (vmin(r2->t_window, h2->req0->t_window)); } static void @@ -276,9 +272,7 @@ h2_do_window(struct worker *wrk, struct h2_req *r2, (void)h2_cond_wait(h2->winupd_cond, h2, r2); if (h2_errcheck(r2, h2) == 0) { - w = h2_win_limit(r2, h2); - if (w > wanted) - w = wanted; + w = vmin(h2_win_limit(r2, h2), wanted); h2_win_charge(r2, h2, w); assert (w > 0); } diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index 6863d6278..0f9aa3652 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -177,8 +177,7 @@ update_position(void) current = 0; if (current > n_ptarray - 1) current = n_ptarray - 1; - if (current < page_start) - page_start = current; + page_start = vmin(page_start, current); if (current > page_start + (l_points - 1)) page_start = current - (l_points - 1); if (page_start < 0) diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 5eb5d6306..1cc4d8f24 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -1426,9 +1426,7 @@ cmd_http_chunkedlen(CMD_ARGS) VSB_printf(hp->vsb, "%x%s", len, nl); for (u = 0; u < len; u += v) { - v = len - u; - if (v > sizeof buf) - v = sizeof buf; + v = vmin_t(unsigned, len - u, sizeof buf); VSB_bcat(hp->vsb, buf, v); } VSB_printf(hp->vsb, "%s", nl); diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index d8e2b6183..b8d600877 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -222,9 +222,7 @@ update(unsigned p) tp2 = VRBT_NEXT(t_order, &h_order, tp); if (++l < LINES) { - len = tp->clen; - if (len > COLS - 20) - len = COLS - 20; + len = vmin(tp->clen, COLS - 20); AC(mvprintw(l, 0, "%9.2f %-*.*s %*.*s\n", tp->count, maxfieldlen, maxfieldlen, VSL_tags[tp->tag], diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c index d994f13fe..096a4ba79 100644 --- a/lib/libvarnish/vre.c +++ b/lib/libvarnish/vre.c @@ -218,9 +218,7 @@ vre_capture(const vre_t *code, const char *subject, size_t length, AN(count); AN(*count); ovector = pcre2_get_ovector_pointer(data); - nov = pcre2_get_ovector_count(data); - if (nov > *count) - nov = *count; + nov = vmin_t(size_t, pcre2_get_ovector_count(data), *count); for (g = 0; g < nov; g++) { b = ovector[2 * g]; e = ovector[2 * g + 1]; diff --git a/lib/libvarnish/vsb.c b/lib/libvarnish/vsb.c index f7e9e46c3..dd9210201 100644 --- a/lib/libvarnish/vsb.c +++ b/lib/libvarnish/vsb.c @@ -383,9 +383,7 @@ VSB_vprintf(struct vsb *s, const char *fmt, va_list ap) * vsnprintf() returns the amount that would have been copied, * given sufficient space, so don't over-increment s_len. */ - if (VSB_FREESPACE(s) < len) - len = VSB_FREESPACE(s); - s->s_len += len; + s->s_len += vmin_t(ssize_t, len, VSB_FREESPACE(s)); if (!VSB_HASROOM(s) && !VSB_CANEXTEND(s)) s->s_error = ENOMEM; diff --git a/lib/libvarnishapi/vsl_dispatch.c b/lib/libvarnishapi/vsl_dispatch.c index 4038273d0..5474d8ca9 100644 --- a/lib/libvarnishapi/vsl_dispatch.c +++ b/lib/libvarnishapi/vsl_dispatch.c @@ -933,8 +933,7 @@ vslq_ratelimit(struct VSLQ *vslq) now = VTIM_mono(); delta = now - vslq->last_use; vslq->credits += (delta / vslq->vsl->R_opt_p) * vslq->vsl->R_opt_l; - if (vslq->credits > vslq->vsl->R_opt_l) - vslq->credits = vslq->vsl->R_opt_l; + vslq->credits = vmin_t(double, vslq->credits, vslq->vsl->R_opt_l); vslq->last_use = now; if (vslq->credits < 1.0) diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c index 1982db96a..d78288db9 100644 --- a/lib/libvcc/vcc_acl.c +++ b/lib/libvcc/vcc_acl.c @@ -105,9 +105,7 @@ vcl_acl_cmp(const struct acl_e *ae1, const struct acl_e *ae2) p1 = ae1->data; p2 = ae2->data; - m = ae1->mask; - if (ae2->mask < m) - m = ae2->mask; + m = vmin(ae1->mask, ae2->mask); for (; m >= 8; m -= 8) { CMP(*p1, *p2); p1++; diff --git a/vmod/vmod_directors_shard_cfg.c b/vmod/vmod_directors_shard_cfg.c index d76c61c6b..4c10334ae 100644 --- a/vmod/vmod_directors_shard_cfg.c +++ b/vmod/vmod_directors_shard_cfg.c @@ -282,10 +282,7 @@ shardcfg_hashcircle(struct sharddir *shardd) rmax = (UINT32_MAX - 1) / shardd->n_backend; for (b = backends; b < backends + shardd->n_backend; b++) { CHECK_OBJ_NOTNULL(b->backend, DIRECTOR_MAGIC); - r = b->replicas; - if (r > rmax) - r = rmax; - n_points += r; + n_points += vmin(b->replicas, rmax); } assert(n_points < UINT32_MAX); @@ -301,9 +298,7 @@ shardcfg_hashcircle(struct sharddir *shardd) AN(ident); assert(ident[0] != '\0'); - r = b->replicas; - if (r > rmax) - r = rmax; + r = vmin(b->replicas, rmax); for (j = 0; j < r; j++) { assert(snprintf(s, len, "%d", j) < len); @@ -488,8 +483,7 @@ shardcfg_backend_del(struct backend_reconfig *re, re->shardd->n_backend--; if (i < re->shardd->n_backend + re->hole_n) { (re->hole_n)++; - if (i < re->hole_i) - re->hole_i = i; + re->hole_i = vmin(re->hole_i, i); } } } From nils.goroll at uplex.de Mon Nov 8 16:14:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 16:14:06 +0000 (UTC) Subject: [master] 393524d27 take in use vmax[_t] for existing code Message-ID: <20211108161406.6C64FAB2C0@lists.varnish-cache.org> commit 393524d273e618346550e1c069e56a5a6a265cb0 Author: Asad Sajjad Ahmed Date: Tue Sep 28 15:35:00 2021 +0200 take in use vmax[_t] for existing code Signed-off-by: Asad Sajjad Ahmed diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 645bfbd04..39b2dace5 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -319,9 +319,7 @@ child_sigmagic(size_t altstksz) memset(&sa, 0, sizeof sa); #ifdef HAVE_SIGALTSTACK - size_t sz = SIGSTKSZ + 4096; - if (sz < altstksz) - sz = altstksz; + size_t sz = vmax_t(size_t, SIGSTKSZ + 4096, altstksz); altstack.ss_sp = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c index f4eedc1f5..ee4159005 100644 --- a/bin/varnishd/cache/cache_req_body.c +++ b/bin/varnishd/cache/cache_req_body.c @@ -100,8 +100,7 @@ vrb_pull(struct req *req, ssize_t maxsize, objiterate_f *func, void *priv) req->want100cont = 0; (void)req->transport->minimal_response(req, 100); } - if (yet < 0) - yet = 0; + yet = vmax_t(ssize_t, yet, 0); do { AZ(vfc->failed); if (maxsize >= 0 && req_bodybytes > maxsize) { diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 2294e742c..c73c28385 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -1011,8 +1011,7 @@ VRT_l_sess_##x(VRT_CTX, VCL_DURATION d) \ { \ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC); \ - if (d < 0.0) \ - d = 0.0; \ + d = vmax(d, 0.0); \ setter; \ ctx->sp->x = d; \ } \ diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 3ef669de8..b44aa23bc 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -682,8 +682,9 @@ pool_herder(void *priv) VSC_C_main->threads_destroyed++; Lck_Unlock(&pool_mtx); delay = cache_param->wthread_destroy_delay; - } else if (delay < cache_param->wthread_destroy_delay) - delay = cache_param->wthread_destroy_delay; + } else + delay = vmax(delay, + cache_param->wthread_destroy_delay); } if (pp->die) { diff --git a/bin/varnishd/hpack/vhp_gen_hufdec.c b/bin/varnishd/hpack/vhp_gen_hufdec.c index cf18857cc..a69d1df83 100644 --- a/bin/varnishd/hpack/vhp_gen_hufdec.c +++ b/bin/varnishd/hpack/vhp_gen_hufdec.c @@ -234,8 +234,7 @@ main(int argc, const char **argv) (void)argv; for (u = 0; u < HUF_LEN; u++) { - if (maxlen < huf[u].blen) - maxlen = huf[u].blen; + maxlen = vmax(maxlen, huf[u].blen); minlen = vmin(minlen, huf[u].blen); } diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 6488c5b03..441a12166 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -130,8 +130,7 @@ MAC_reopen_sockets(void) VJ_master(JAIL_MASTER_LOW); if (err == 0) continue; - if (err > fail) - fail = err; + fail = vmax(fail, err); MGT_Complain(C_ERR, "Could not reopen listen socket %s: %s", ls->endpoint, VAS_errtxt(err)); diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index 5af419fed..a8181bd56 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -204,8 +204,7 @@ MCH_TrackHighFd(int fd) * in the master process. */ assert(fd > 0); - if (fd > mgt_max_fd) - mgt_max_fd = fd; + mgt_max_fd = vmax(mgt_max_fd, fd); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index d80033269..308015ced 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -574,8 +574,7 @@ MCF_AddParams(struct parspec *ps) exit(4); } mcf_addpar(pp); - if ((int)strlen(pp->name) + 1 > margin2) - margin2 = (int)strlen(pp->name) + 1; + margin2 = vmax_t(int, margin2, strlen(pp->name) + 1); } } diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index ac70b7aaf..427392873 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -157,8 +157,7 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) AZ(VFIL_fsinfo(fd, &bs, &fssize, NULL)); /* Increase granularity if it is lower than the filesystem block size */ - if (*granularity < bs) - *granularity = bs; + *granularity = vmax(*granularity, bs); if ((size == NULL || *size == '\0') && st.st_size != 0) { /* diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 9a4d58917..af36662cc 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -174,8 +174,7 @@ update(void) assert(l < n); bm[l] += bucket_miss[k]; bh[l] += bucket_hit[k]; - if (bm[l] + bh[l] > max) - max = bm[l] + bh[l]; + max = vmax(max, bm[l] + bh[l]); } /* scale,time */ @@ -210,7 +209,6 @@ update(void) inline static void upd_vsl_ts(const char *p) { - double t; if (timebend == 0) return; @@ -220,10 +218,7 @@ upd_vsl_ts(const char *p) if (p == NULL) return; - t = strtod(p + 1, NULL); - - if (t > vsl_ts) - vsl_ts = t; + vsl_ts = vmax(vsl_ts, strtod(p + 1, NULL)); } static int v_matchproto_ (VSLQ_dispatch_f) @@ -432,9 +427,7 @@ do_curses(void *arg) ms_delay = 1000U << (ch - '0'); break; case '+': - ms_delay /= 2; - if (ms_delay < 1) - ms_delay = 1; + ms_delay = vmax(ms_delay >> 1, 1); break; case '-': ms_delay *= 2; diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index 0f9aa3652..91306cec2 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -362,8 +362,7 @@ make_windows(void) l_points += l_info; l_info = 0; } - if (l_points < LINES_POINTS_MIN) - l_points = LINES_POINTS_MIN; + l_points = vmax(l_points, LINES_POINTS_MIN); y = 0; y_status = y; diff --git a/lib/libvarnish/vte.c b/lib/libvarnish/vte.c index 119dd9880..69056ab5a 100644 --- a/lib/libvarnish/vte.c +++ b/lib/libvarnish/vte.c @@ -82,12 +82,10 @@ VCLI_VTE(struct cli *cli, struct vsb **src, int width) wc = 0; } if (*p == '\n') { - if (cc > n_col) - n_col = cc; + n_col = vmax(n_col, cc); + w_ln = vmax(w_ln, wl); cc = 0; wc = 0; - if (wl > w_ln) - w_ln = wl; wl = 0; } else { wc++; diff --git a/vmod/vmod_directors_shard_cfg.c b/vmod/vmod_directors_shard_cfg.c index 4c10334ae..438609063 100644 --- a/vmod/vmod_directors_shard_cfg.c +++ b/vmod/vmod_directors_shard_cfg.c @@ -411,8 +411,7 @@ shardcfg_backend_expand(const struct backend_reconfig *re) CHECK_OBJ_NOTNULL(re->shardd, SHARDDIR_MAGIC); - if (min < 16) - min = 16; + min = vmax_t(unsigned, min, 16); if (re->shardd->l_backend < min) re->shardd->l_backend = min; diff --git a/vmod/vmod_std.c b/vmod/vmod_std.c index 719c5051a..8ce144eb9 100644 --- a/vmod/vmod_std.c +++ b/vmod/vmod_std.c @@ -242,8 +242,7 @@ VCL_BOOL v_matchproto_(td_std_cache_req_body) vmod_cache_req_body(VRT_CTX, VCL_BYTES size) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - if (size < 0) - size = 0; + size = vmax_t(VCL_BYTES, size, 0); if (VRT_CacheReqBody(ctx, (size_t)size) < 0) return (0); return (1); From nils.goroll at uplex.de Mon Nov 8 16:14:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 16:14:06 +0000 (UTC) Subject: [master] 1b2b231be take in use vlimit[_t] for existing code Message-ID: <20211108161406.848D9AB2CB@lists.varnish-cache.org> commit 1b2b231be8109a50d97c80f318d1afcea22935fe Author: Asad Sajjad Ahmed Date: Tue Sep 28 15:53:37 2021 +0200 take in use vlimit[_t] for existing code Signed-off-by: Asad Sajjad Ahmed diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index af36662cc..73a7b8717 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -300,12 +300,9 @@ accumulate(struct VSL_data *vsl, struct VSL_transaction * const pt[], continue; /* select bucket */ - i = lround(HIST_RES * log(value) / log_ten); - if (i < hist_low * HIST_RES) - i = hist_low * HIST_RES; - if (i >= hist_high * HIST_RES) - i = hist_high * HIST_RES - 1; - i -= hist_low * HIST_RES; + i = vlimit_t(int, lround(HIST_RES * log(value) / log_ten), + hist_low * HIST_RES, hist_high * HIST_RES - 1) - + hist_low * HIST_RES; assert(i >= 0); assert((unsigned)i < hist_buckets); diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index 91306cec2..46c937471 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -173,17 +173,11 @@ update_position(void) current = 0; page_start = 0; } else { - if (current < 0) - current = 0; - if (current > n_ptarray - 1) - current = n_ptarray - 1; + current = vlimit(current, 0, n_ptarray - 1); page_start = vmin(page_start, current); if (current > page_start + (l_points - 1)) page_start = current - (l_points - 1); - if (page_start < 0) - page_start = 0; - if (page_start > n_ptarray - 1) - page_start = n_ptarray - 1; + page_start = vlimit(page_start, 0, n_ptarray - 1); } if (current != old_current || page_start != old_page_start) @@ -1071,12 +1065,7 @@ handle_help_keypress(enum kb_e kb) WRONG("unhandled key binding"); } - if (help_line > bindings_help_len - l_points) - help_line = bindings_help_len - l_points; - - if (help_line < 0) - help_line = 0; - + help_line = vlimit(help_line, 0, bindings_help_len - l_points); redraw = (help_line != hl); } diff --git a/lib/libvarnish/vte.c b/lib/libvarnish/vte.c index 69056ab5a..816841f13 100644 --- a/lib/libvarnish/vte.c +++ b/lib/libvarnish/vte.c @@ -97,11 +97,7 @@ VCLI_VTE(struct cli *cli, struct vsb **src, int width) return; AN(n_col); - nsp = (width - (w_ln)) / n_col; - if (nsp > 3) - nsp = 3; - else if (nsp < 1) - nsp = 1; + nsp = vlimit((width - (w_ln)) / n_col, 1, 3); cc = 0; wc = 0; From nils.goroll at uplex.de Mon Nov 8 16:22:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 16:22:06 +0000 (UTC) Subject: [master] 0ee49a674 Polish after vmin_t() introduction Message-ID: <20211108162206.D1119ABBFD@lists.varnish-cache.org> commit 0ee49a674f4e0832239246abba41679b846e56c0 Author: Nils Goroll Date: Mon Nov 8 17:19:49 2021 +0100 Polish after vmin_t() introduction Minor rewrite for clarity. VSL lines are truncated, so the return value _is_ sufficiently checked. Ref 519ead4a3a019e28c1e5b7c8eab87261760dd07c diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 02ddbf922..7c0bbd49a 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -269,8 +269,8 @@ VSLv(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, va_list ap) if (strchr(fmt, '%') == NULL) { vslr(tag, vxid, fmt, strlen(fmt) + 1); } else { - /* XXX: should probably check return value of vsnprintf */ - n = vmin_t(unsigned, vsnprintf(buf, mlen, fmt, ap), mlen - 1); + n = vsnprintf(buf, mlen, fmt, ap); + n = vmin_t(unsigned, n, mlen - 1); buf[n++] = '\0'; /* NUL-terminated */ vslr(tag, vxid, buf, n); } From nils.goroll at uplex.de Mon Nov 8 16:38:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 16:38:06 +0000 (UTC) Subject: [master] ce331c3fc Polish vmin usage Message-ID: <20211108163806.D2125AC4AE@lists.varnish-cache.org> commit ce331c3fc6b6de1ba1a7c52fbaf51aa36abdde83 Author: Nils Goroll Date: Mon Nov 8 17:35:57 2021 +0100 Polish vmin usage Fixes warning on 32 bit: comparison of distinct pointer types ('typeof ((*lp)) *' (aka 'int *') and 'typeof (((VRND_RandomTestable() & 3) + 1)) *' (aka 'long *')) diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index cee4eb57b..0b2d46339 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -279,7 +279,7 @@ vfp_esi_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) AN(p); AN(lp); if (DO_DEBUG(DBG_ESI_CHOP)) { - *lp = vmin(*lp, (VRND_RandomTestable() & 3) + 1); + *lp = vmin_t(size_t, *lp, (VRND_RandomTestable() & 3) + 1); } vp = VFP_Suck(vc, p, lp); if (vp != VFP_ERROR && *lp > 0) From nils.goroll at uplex.de Mon Nov 8 17:03:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 8 Nov 2021 17:03:06 +0000 (UTC) Subject: [master] 64f7181b1 Polish min usage for SunCC Message-ID: <20211108170306.B2865AD202@lists.varnish-cache.org> commit 64f7181b1d337309e2bcae8a10be5f626f009e36 Author: Nils Goroll Date: Mon Nov 8 18:01:38 2021 +0100 Polish min usage for SunCC Fixes: left operand must be modifiable lvalue: op "=" diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index 172bb35b2..fcbe0153a 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -218,7 +218,7 @@ h2_win_limit(const struct h2_req *r2, const struct h2_sess *h2) CHECK_OBJ_NOTNULL(h2->req0, H2_REQ_MAGIC); Lck_AssertHeld(&h2->sess->mtx); - return (vmin(r2->t_window, h2->req0->t_window)); + return (vmin_t(int64_t, r2->t_window, h2->req0->t_window)); } static void diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c index d78288db9..4ee895157 100644 --- a/lib/libvcc/vcc_acl.c +++ b/lib/libvcc/vcc_acl.c @@ -105,7 +105,7 @@ vcl_acl_cmp(const struct acl_e *ae1, const struct acl_e *ae2) p1 = ae1->data; p2 = ae2->data; - m = vmin(ae1->mask, ae2->mask); + m = vmin_t(unsigned, ae1->mask, ae2->mask); for (; m >= 8; m -= 8) { CMP(*p1, *p2); p1++; diff --git a/vmod/vmod_directors_shard_cfg.c b/vmod/vmod_directors_shard_cfg.c index 438609063..3d3c6de11 100644 --- a/vmod/vmod_directors_shard_cfg.c +++ b/vmod/vmod_directors_shard_cfg.c @@ -282,7 +282,7 @@ shardcfg_hashcircle(struct sharddir *shardd) rmax = (UINT32_MAX - 1) / shardd->n_backend; for (b = backends; b < backends + shardd->n_backend; b++) { CHECK_OBJ_NOTNULL(b->backend, DIRECTOR_MAGIC); - n_points += vmin(b->replicas, rmax); + n_points += vmin_t(uint32_t, b->replicas, rmax); } assert(n_points < UINT32_MAX); @@ -298,7 +298,7 @@ shardcfg_hashcircle(struct sharddir *shardd) AN(ident); assert(ident[0] != '\0'); - r = vmin(b->replicas, rmax); + r = vmin_t(uint32_t, b->replicas, rmax); for (j = 0; j < r; j++) { assert(snprintf(s, len, "%d", j) < len); From phk at FreeBSD.org Tue Nov 9 07:53:07 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 9 Nov 2021 07:53:07 +0000 (UTC) Subject: [master] 5ea133b18 Add a missing ERRCHK() Message-ID: <20211109075307.3BA981057C1@lists.varnish-cache.org> commit 5ea133b18f4fe9f8c454c3931f5a3ba2e2025c64 Author: Poul-Henning Kamp Date: Tue Nov 9 07:47:55 2021 +0000 Add a missing ERRCHK() diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index cdd2bd498..dcc0c07c9 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -777,6 +777,7 @@ vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt) AN(sym); VCC_GlobalSymbol(sym, fmt); } + ERRCHK(tl); if (sym == NULL) AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL, XREF_REF)); From martin at varnish-software.com Tue Nov 9 15:41:05 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 9 Nov 2021 15:41:05 +0000 (UTC) Subject: [6.0] a9d3d695a Clear vut->sighup even if sighup_f is not defined Message-ID: <20211109154106.032C8113B0D@lists.varnish-cache.org> commit a9d3d695a019176cf30cbd7e4457fad46a6aa24c Author: Emanuele Rocca Date: Wed Oct 14 15:14:31 2020 +0200 Clear vut->sighup even if sighup_f is not defined Fixes #3437 diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index b02644a81..60c36d349 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -364,12 +364,15 @@ VUT_Main(struct VUT *vut) AN(vut->vslq); while (!vut->sigint) { - if (vut->sighup && vut->sighup_f) { - /* sighup callback */ + if (vut->sighup) { vut->sighup = 0; - i = vut->sighup_f(vut); - if (i) - break; + + if (vut->sighup_f) { + /* sighup callback */ + i = vut->sighup_f(vut); + if (i) + break; + } } if (vut->sigusr1) { From hermunn at varnish-software.com Tue Nov 9 15:49:05 2021 From: hermunn at varnish-software.com (PÃ¥l Hermunn Johansen) Date: Tue, 9 Nov 2021 15:49:05 +0000 (UTC) Subject: [6.0] 204c5b73e Increase default stack space Message-ID: <20211109154905.B40F2113F7D@lists.varnish-cache.org> commit 204c5b73e3ecb6b9b1533bad437dc9086c0269aa Author: P?l Hermunn Johansen Date: Thu May 20 14:10:15 2021 +0200 Increase default stack space A default stack space of 48k will cause a stack overflow in some of the test cases on some Linux distributions. The increase to 64k seems to be enough to solve this. diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index c87c891a6..0b0408776 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -646,9 +646,9 @@ MCF_InitParams(struct cli *cli) MCF_ParamConf(MCF_MINIMUM, "thread_pool_stack", "%jdb", (intmax_t)low); #if defined(__SANITIZER) || __has_feature(address_sanitizer) - def = 92 * 1024; + def = 128 * 1024; #else - def = 48 * 1024; + def = 64 * 1024; #endif if (def < low) def = low; diff --git a/doc/changes.rst b/doc/changes.rst index de40d44ff..fa6cf41c9 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -26,6 +26,14 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. +================================ +Varnish Cache 6.0.9 (unreleased) +================================ + +* Increase the default stack size to 64k. (3617_) + +.. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 + ================================ Varnish Cache 6.0.8 (2021-07-13) ================================ diff --git a/include/tbl/params.h b/include/tbl/params.h index deecd2051..5fe1e2dd6 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -1329,7 +1329,7 @@ PARAM( /* typ */ bytes, /* min */ "2k", /* max */ NULL, - /* default */ "48k", + /* default */ "64k", /* units */ "bytes", /* flags */ EXPERIMENTAL, /* s-text */ From martin at varnish-software.com Tue Nov 9 16:31:06 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 9 Nov 2021 16:31:06 +0000 (UTC) Subject: [6.0] 52f14431e Add #3437 to the changelog Message-ID: <20211109163106.500551151E1@lists.varnish-cache.org> commit 52f14431e5c5e75c18125166125ed0ba2420d2c0 Author: Martin Blix Grydeland Date: Tue Nov 9 17:29:59 2021 +0100 Add #3437 to the changelog diff --git a/doc/changes.rst b/doc/changes.rst index fa6cf41c9..21d3223a1 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -32,7 +32,11 @@ Varnish Cache 6.0.9 (unreleased) * Increase the default stack size to 64k. (3617_) +* Correctly reset the received SIGHUP flag in libvarnishapi when no + handling function for this signal is registered. (3437_) + .. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 +.. _3437: https://github.com/varnishcache/varnish-cache/issues/3437' ================================ Varnish Cache 6.0.8 (2021-07-13) From phk at FreeBSD.org Wed Nov 10 09:38:09 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 10 Nov 2021 09:38:09 +0000 (UTC) Subject: [master] 6865fc372 Polish to track original in FreeBSD Message-ID: <20211110093809.6984C10AA41@lists.varnish-cache.org> commit 6865fc37276b9407548785e9e2198a2182413984 Author: Poul-Henning Kamp Date: Wed Nov 10 09:21:43 2021 +0000 Polish to track original in FreeBSD diff --git a/include/vtree.h b/include/vtree.h index 6fb2fdaae..16122b62c 100644 --- a/include/vtree.h +++ b/include/vtree.h @@ -182,7 +182,7 @@ name##_VSPLAY_INSERT(struct name *head, struct type *elm) \ int __comp; \ name##_VSPLAY(head, elm); \ __comp = (cmp)(elm, (head)->sph_root); \ - if(__comp < 0) { \ + if (__comp < 0) { \ VSPLAY_LEFT(elm, field) = VSPLAY_LEFT((head)->sph_root, field);\ VSPLAY_RIGHT(elm, field) = (head)->sph_root; \ VSPLAY_LEFT((head)->sph_root, field) = NULL; \ @@ -370,16 +370,7 @@ struct { \ * from the bottom up to the root, to update augmented node data. */ #ifndef VRBT_AUGMENT -#define VRBT_AUGMENT(x) do {} while (0) -#define VRBT_AUGMENT_UP(x) do {} while (0) -#else -#define VRBT_AUGMENT_UP(x) \ - do { \ - while((x) != NULL) { \ - VRBT_AUGMENT(x); \ - x = VRBT_PARENT(x, field); \ - } \ - } while (0) +#define VRBT_AUGMENT(x) break #endif #define VRBT_SWAP_CHILD(head, out, in, field) do { \ @@ -495,7 +486,7 @@ name##_VRBT_INSERT_COLOR(struct name *head, struct type *elm) \ VRBT_FLIP_RIGHT(elm, field); \ else if (VRBT_RED_RIGHT(child, field)) \ VRBT_FLIP_LEFT(parent, field); \ - AN(parent); \ + AN(parent); \ elm = child; \ } \ VRBT_ROTATE_RIGHT(head, parent, elm, field); \ @@ -640,7 +631,10 @@ name##_VRBT_REMOVE(struct name *head, struct type *elm) \ VRBT_SET_PARENT(child, parent, field); \ if (parent != NULL) \ name##_VRBT_REMOVE_COLOR(head, parent, child); \ - VRBT_AUGMENT_UP(parent); \ + while (parent != NULL) { \ + VRBT_AUGMENT(parent); \ + parent = VRBT_PARENT(parent, field); \ + } \ return (old); \ } @@ -671,7 +665,10 @@ name##_VRBT_INSERT(struct name *head, struct type *elm) \ else \ VRBT_RIGHT(parent, field) = elm; \ name##_VRBT_INSERT_COLOR(head, elm); \ - VRBT_AUGMENT_UP(elm); \ + while (elm != NULL) { \ + VRBT_AUGMENT(elm); \ + elm = VRBT_PARENT(elm, field); \ + } \ return (NULL); \ } @@ -836,4 +833,5 @@ name##_VRBT_REINSERT(struct name *head, struct type *elm) \ for ((x) = VRBT_MAX(name, head); \ ((x) != NULL) && ((y) = name##_VRBT_PREV(x), (x) != NULL); \ (x) = (y)) + #endif /* _VTREE_H_ */ From nils.goroll at uplex.de Wed Nov 10 10:19:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 10 Nov 2021 10:19:07 +0000 (UTC) Subject: [master] 7e5213f9f vmin/vmax: Avoid typeof() where we can Message-ID: <20211110101907.2E93F10DD1F@lists.varnish-cache.org> commit 7e5213f9f7a35c664bf7486e6310794f74d9e6ea Author: Nils Goroll Date: Wed Nov 10 10:53:46 2021 +0100 vmin/vmax: Avoid typeof() where we can Reviewing flexelint output for the recently added vmin/vmax macros made apparent that vmin_t/vmax_t basically used typeof((cast)var), which makes for an unnecessary de-tour via typeof. We change the min/max macros to explicitly pass the type for the temporary variables such that typeof() is only needed for vmin/vmax. Being at it, we also reduce the min/max case to just one take macro ("take the min/max of ...") as they only differed in a single character, the operator. diff --git a/include/vdef.h b/include/vdef.h index a810be196..9b1043669 100644 --- a/include/vdef.h +++ b/include/vdef.h @@ -182,29 +182,24 @@ int __llvm_gcov_flush(void); /* ref: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html */ -#define _vmin(a, b, _va, _vb) \ -({ \ - typeof (a) _va = (a); \ - typeof (b) _vb = (b); \ +#define _vtake(op, ta, tb, a, b, _va, _vb) \ + ({ \ + ta _va = (a); \ + tb _vb = (b); \ (void)(&_va == &_vb); \ - _va < _vb ? _va : _vb; \ + _va op _vb ? _va : _vb; \ }) -#define _vmax(a, b, _va, _vb) \ -({ \ - typeof (a) _va = (a); \ - typeof (b) _vb = (b); \ - (void)(&_va == &_vb); \ - _va > _vb ? _va : _vb; \ -}) +#define opmin < +#define opmax > +#define vtake(n, ta, tb, a, b) _vtake(op ## n, ta, tb, a, b, \ + VUNIQ_NAME(_v ## n ## A), VUNIQ_NAME(_v ## n ## B)) -#define vmin(a, b) _vmin((a), (b), VUNIQ_NAME(_vmina), \ - VUNIQ_NAME(_vminb)) -#define vmax(a, b) _vmax((a), (b), VUNIQ_NAME(_vmaxa), \ - VUNIQ_NAME(_vmaxb)) +#define vmin(a, b) vtake(min, typeof(a), typeof(b), a, b) +#define vmax(a, b) vtake(max, typeof(a), typeof(b), a, b) -#define vmin_t(type, a, b) vmin((type)(a), (type)(b)) -#define vmax_t(type, a, b) vmax((type)(a), (type)(b)) +#define vmin_t(type, a, b) vtake(min, type, type, a, b) +#define vmax_t(type, a, b) vtake(max, type, type, a, b) /********************************************************************** * Clamp the value between two limits. From nils.goroll at uplex.de Wed Nov 10 10:19:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 10 Nov 2021 10:19:07 +0000 (UTC) Subject: [master] 493415482 vmin/vmax vs. flexelint Message-ID: <20211110101907.3FD9910DD21@lists.varnish-cache.org> commit 493415482be82f02543ce7719bae066a1e674db2 Author: Nils Goroll Date: Wed Nov 10 11:07:05 2021 +0100 vmin/vmax vs. flexelint diff --git a/flint.lnt b/flint.lnt index 53126a529..d20948346 100644 --- a/flint.lnt +++ b/flint.lnt @@ -241,6 +241,8 @@ /////////////////////////////////////////////////////////////////////// // -emacro(527, NEEDLESS) // unreachable code +-emacro(160, _vtake) // The sequence '( {' is non standard ++rw( __typeof__ ) /////////////////////////////////////////////////////////////////////// // diff --git a/include/vdef.h b/include/vdef.h index 9b1043669..faa4877c4 100644 --- a/include/vdef.h +++ b/include/vdef.h @@ -180,6 +180,10 @@ int __llvm_gcov_flush(void); # define VUNIQ_NAME(base) VCOMBINE(base, __LINE__, 0) #endif +#ifdef _lint +#define typeof(x) __typeof__(x) +#endif + /* ref: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html */ #define _vtake(op, ta, tb, a, b, _va, _vb) \ From martin at varnish-software.com Wed Nov 10 10:22:07 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 10 Nov 2021 10:22:07 +0000 (UTC) Subject: [6.0] 771c2f5c5 Add 3564 to the changelog Message-ID: <20211110102207.F2A2D10E11E@lists.varnish-cache.org> commit 771c2f5c5fcd1e6f1a9260264ab28db2075cdb9e Author: Martin Blix Grydeland Date: Wed Nov 10 10:44:10 2021 +0100 Add 3564 to the changelog diff --git a/doc/changes.rst b/doc/changes.rst index 21d3223a1..1df4563bb 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -35,8 +35,12 @@ Varnish Cache 6.0.9 (unreleased) * Correctly reset the received SIGHUP flag in libvarnishapi when no handling function for this signal is registered. (3437_) +* Make it possible to set the `sess.timeout_idle` VCL variable also when + using `VCL` syntax version `4.0`. (3564_) + .. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 .. _3437: https://github.com/varnishcache/varnish-cache/issues/3437' +.. _3564: https://github.com/varnishcache/varnish-cache/issues/3564' ================================ Varnish Cache 6.0.8 (2021-07-13) From martin at varnish-software.com Wed Nov 10 10:22:08 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 10 Nov 2021 10:22:08 +0000 (UTC) Subject: [6.0] 91b22de5d Add MAIN.esi_req counter to changelog Message-ID: <20211110102208.1475210E121@lists.varnish-cache.org> commit 91b22de5d70f18bf1c41b189f5a30d3276991ff2 Author: Martin Blix Grydeland Date: Wed Nov 10 10:46:02 2021 +0100 Add MAIN.esi_req counter to changelog diff --git a/doc/changes.rst b/doc/changes.rst index 1df4563bb..cf188ce97 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -38,6 +38,9 @@ Varnish Cache 6.0.9 (unreleased) * Make it possible to set the `sess.timeout_idle` VCL variable also when using `VCL` syntax version `4.0`. (3564_) +* New `varnishstat` counter `MAIN.esi_req`. This increments for each ESI + subrequest that is made. + .. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 .. _3437: https://github.com/varnishcache/varnish-cache/issues/3437' .. _3564: https://github.com/varnishcache/varnish-cache/issues/3564' From martin at varnish-software.com Wed Nov 10 10:22:08 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 10 Nov 2021 10:22:08 +0000 (UTC) Subject: [6.0] 90cdbe9b0 Add vcl.show changes to changelog Message-ID: <20211110102208.37CB310E125@lists.varnish-cache.org> commit 90cdbe9b0c64c802f0abe6de1ac33678978bbd28 Author: Martin Blix Grydeland Date: Wed Nov 10 11:16:45 2021 +0100 Add vcl.show changes to changelog diff --git a/doc/changes.rst b/doc/changes.rst index cf188ce97..a816cb293 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -41,6 +41,9 @@ Varnish Cache 6.0.9 (unreleased) * New `varnishstat` counter `MAIN.esi_req`. This increments for each ESI subrequest that is made. +* The CLI command `vcl.show -v` now outputs the `builtin` VCL source last, + after any included VCL sources files. + .. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 .. _3437: https://github.com/varnishcache/varnish-cache/issues/3437' .. _3564: https://github.com/varnishcache/varnish-cache/issues/3564' From nils.goroll at uplex.de Wed Nov 10 11:49:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 10 Nov 2021 11:49:06 +0000 (UTC) Subject: [master] 9fd79a7cb Flexelint vmin/vmax/vlimit Message-ID: <20211110114906.163A9110A0C@lists.varnish-cache.org> commit 9fd79a7cb69aad1597101aca6608d8bf8c03952d Author: Nils Goroll Date: Wed Nov 10 12:10:10 2021 +0100 Flexelint vmin/vmax/vlimit avoid warning 666 ("Expression with side effects passed to repeated parameter"): The non-type macros still trigger an warning due to the expression passed a second time in typeof(). Use the typed macros for these cases. avoid error 1058 ("Initializing a non-const reference"): Our type check (void)(&_va == &_vb) trips for dereferences. diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 7c0bbd49a..b301c5a2f 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -378,7 +378,7 @@ VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s) mlen = cache_param->vsl_reclen; /* including NUL */ - l = vmin(strands_len(s) + 1, mlen); + l = vmin_t(unsigned, strands_len(s) + 1, mlen); assert(vsl->wlp < vsl->wle); diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index fcbe0153a..2b66615ca 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -272,7 +272,7 @@ h2_do_window(struct worker *wrk, struct h2_req *r2, (void)h2_cond_wait(h2->winupd_cond, h2, r2); if (h2_errcheck(r2, h2) == 0) { - w = vmin(h2_win_limit(r2, h2), wanted); + w = vmin_t(int64_t, h2_win_limit(r2, h2), wanted); h2_win_charge(r2, h2, w); assert (w > 0); } diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index 427392873..4d8abe18a 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -157,7 +157,7 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) AZ(VFIL_fsinfo(fd, &bs, &fssize, NULL)); /* Increase granularity if it is lower than the filesystem block size */ - *granularity = vmax(*granularity, bs); + *granularity = vmax_t(unsigned, *granularity, bs); if ((size == NULL || *size == '\0') && st.st_size != 0) { /* diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 73a7b8717..0757276ed 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -218,7 +218,7 @@ upd_vsl_ts(const char *p) if (p == NULL) return; - vsl_ts = vmax(vsl_ts, strtod(p + 1, NULL)); + vsl_ts = vmax_t(double, vsl_ts, strtod(p + 1, NULL)); } static int v_matchproto_ (VSLQ_dispatch_f) diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index 46c937471..c9d7117b3 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -173,11 +173,11 @@ update_position(void) current = 0; page_start = 0; } else { - current = vlimit(current, 0, n_ptarray - 1); + current = vlimit_t(int, current, 0, n_ptarray - 1); page_start = vmin(page_start, current); if (current > page_start + (l_points - 1)) page_start = current - (l_points - 1); - page_start = vlimit(page_start, 0, n_ptarray - 1); + page_start = vlimit_t(int, page_start, 0, n_ptarray - 1); } if (current != old_current || page_start != old_page_start) @@ -1065,7 +1065,7 @@ handle_help_keypress(enum kb_e kb) WRONG("unhandled key binding"); } - help_line = vlimit(help_line, 0, bindings_help_len - l_points); + help_line = vlimit_t(int, help_line, 0, bindings_help_len - l_points); redraw = (help_line != hl); } diff --git a/lib/libvarnish/vte.c b/lib/libvarnish/vte.c index 816841f13..953975333 100644 --- a/lib/libvarnish/vte.c +++ b/lib/libvarnish/vte.c @@ -97,7 +97,7 @@ VCLI_VTE(struct cli *cli, struct vsb **src, int width) return; AN(n_col); - nsp = vlimit((width - (w_ln)) / n_col, 1, 3); + nsp = vlimit_t(int, (width - (w_ln)) / n_col, 1, 3); cc = 0; wc = 0; From nils.goroll at uplex.de Wed Nov 10 11:49:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 10 Nov 2021 11:49:06 +0000 (UTC) Subject: [master] 1fbe32e28 Fix signedness issue spotted by flexelint Message-ID: <20211110114906.2BD48110A0F@lists.varnish-cache.org> commit 1fbe32e2842f80372736971eaf9f7a4240b9ca0e Author: Nils Goroll Date: Wed Nov 10 12:43:15 2021 +0100 Fix signedness issue spotted by flexelint bitshift of signed diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 0757276ed..428a2e66f 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -75,7 +75,7 @@ static unsigned hist_buckets; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static int end_of_file = 0; -static int ms_delay = 1000; +static unsigned ms_delay = 1000; static unsigned rr_hist[HIST_N]; static unsigned nhist; static unsigned next_hist; @@ -424,7 +424,7 @@ do_curses(void *arg) ms_delay = 1000U << (ch - '0'); break; case '+': - ms_delay = vmax(ms_delay >> 1, 1); + ms_delay = vmax(ms_delay >> 1, 1U); break; case '-': ms_delay *= 2; @@ -487,7 +487,7 @@ main(int argc, char **argv) VUT_Usage(vut, &vopt_spec, 0); case 'p': ms_delay = lround(1e3 * strtod(optarg, NULL)); - if (ms_delay <= 0) + if (ms_delay == 0) VUT_Error(vut, 1, "-p: invalid '%s'", optarg); break; case 'P': From nils.goroll at uplex.de Wed Nov 10 12:36:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 10 Nov 2021 12:36:07 +0000 (UTC) Subject: [master] b474c9cce Neuter the VRBT_AUGMENT facility if not used. Message-ID: <20211110123607.62737111F9B@lists.varnish-cache.org> commit b474c9ccee2b119e6b9556179dcaf2c0808b15af Author: Poul-Henning Kamp Date: Tue Mar 23 11:43:34 2021 +0000 Neuter the VRBT_AUGMENT facility if not used. diff --git a/include/vtree.h b/include/vtree.h index 16122b62c..b4913c8ea 100644 --- a/include/vtree.h +++ b/include/vtree.h @@ -370,7 +370,16 @@ struct { \ * from the bottom up to the root, to update augmented node data. */ #ifndef VRBT_AUGMENT -#define VRBT_AUGMENT(x) break +#define VRBT_AUGMENT(x) do {} while (0) +#define VRBT_AUGMENT_UP(x) do {} while (0) +#else +#define VRBT_AUGMENT_UP(x) \ + do { \ + while((x) != NULL) { \ + VRBT_AUGMENT(x); \ + x = VRBT_PARENT(x, field); \ + } \ + } while (0) #endif #define VRBT_SWAP_CHILD(head, out, in, field) do { \ @@ -631,10 +640,7 @@ name##_VRBT_REMOVE(struct name *head, struct type *elm) \ VRBT_SET_PARENT(child, parent, field); \ if (parent != NULL) \ name##_VRBT_REMOVE_COLOR(head, parent, child); \ - while (parent != NULL) { \ - VRBT_AUGMENT(parent); \ - parent = VRBT_PARENT(parent, field); \ - } \ + VRBT_AUGMENT_UP(parent); \ return (old); \ } @@ -665,10 +671,7 @@ name##_VRBT_INSERT(struct name *head, struct type *elm) \ else \ VRBT_RIGHT(parent, field) = elm; \ name##_VRBT_INSERT_COLOR(head, elm); \ - while (elm != NULL) { \ - VRBT_AUGMENT(elm); \ - elm = VRBT_PARENT(elm, field); \ - } \ + VRBT_AUGMENT_UP(elm); \ return (NULL); \ } From nils.goroll at uplex.de Wed Nov 10 13:09:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 10 Nov 2021 13:09:05 +0000 (UTC) Subject: [master] bb401ab31 vtree.h: remove red/black tree augmentation entirely Message-ID: <20211110130905.4F391112E9F@lists.varnish-cache.org> commit bb401ab31d82f4332b38fbfc7beaf4d7143ef9ff Author: Nils Goroll Date: Wed Nov 10 14:07:32 2021 +0100 vtree.h: remove red/black tree augmentation entirely As agreed with phk diff --git a/include/vtree.h b/include/vtree.h index b4913c8ea..325a2cb1f 100644 --- a/include/vtree.h +++ b/include/vtree.h @@ -365,23 +365,6 @@ struct { \ VRBT_RED_LEFT(VRBT_PARENT(elm, field), field) : \ VRBT_RED_RIGHT(VRBT_PARENT(elm, field), field)) -/* - * Something to be invoked in a loop at the root of every modified subtree, - * from the bottom up to the root, to update augmented node data. - */ -#ifndef VRBT_AUGMENT -#define VRBT_AUGMENT(x) do {} while (0) -#define VRBT_AUGMENT_UP(x) do {} while (0) -#else -#define VRBT_AUGMENT_UP(x) \ - do { \ - while((x) != NULL) { \ - VRBT_AUGMENT(x); \ - x = VRBT_PARENT(x, field); \ - } \ - } while (0) -#endif - #define VRBT_SWAP_CHILD(head, out, in, field) do { \ if (VRBT_PARENT(out, field) == NULL) \ VRBT_ROOT(head) = (in); \ @@ -400,7 +383,6 @@ struct { \ VRBT_SWAP_CHILD(head, elm, tmp, field); \ VRBT_LEFT(tmp, field) = (elm); \ VRBT_SET_PARENT(elm, tmp, field); \ - VRBT_AUGMENT(elm); \ } while (/*CONSTCOND*/ 0) #define VRBT_ROTATE_RIGHT(head, elm, tmp, field) do { \ @@ -412,7 +394,6 @@ struct { \ VRBT_SWAP_CHILD(head, elm, tmp, field); \ VRBT_RIGHT(tmp, field) = (elm); \ VRBT_SET_PARENT(elm, tmp, field); \ - VRBT_AUGMENT(elm); \ } while (/*CONSTCOND*/ 0) /* Generates prototypes and inline functions */ @@ -640,7 +621,6 @@ name##_VRBT_REMOVE(struct name *head, struct type *elm) \ VRBT_SET_PARENT(child, parent, field); \ if (parent != NULL) \ name##_VRBT_REMOVE_COLOR(head, parent, child); \ - VRBT_AUGMENT_UP(parent); \ return (old); \ } @@ -671,7 +651,6 @@ name##_VRBT_INSERT(struct name *head, struct type *elm) \ else \ VRBT_RIGHT(parent, field) = elm; \ name##_VRBT_INSERT_COLOR(head, elm); \ - VRBT_AUGMENT_UP(elm); \ return (NULL); \ } From martin at varnish-software.com Fri Nov 12 12:30:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 12 Nov 2021 12:30:11 +0000 (UTC) Subject: [6.0] b1db3bf45 vsl: Give up when it's too late to buffer records Message-ID: <20211112123011.262BD114A99@lists.varnish-cache.org> commit b1db3bf45bef2594cf923a811918b4fe60805775 Author: Dridi Boukelmoune Date: Wed Oct 28 15:38:42 2020 +0100 vsl: Give up when it's too late to buffer records When a VUT is slow enough, it might very well be overrun while it is scanning logs. For our built-in VUTs like varnishncsa or varnishlog this can happen if writing the output can block waiting for IO ops or when the output is piped to a slow consumer. diff --git a/lib/libvarnishapi/vsl_dispatch.c b/lib/libvarnishapi/vsl_dispatch.c index ebc45123a..2b4336b2a 100644 --- a/lib/libvarnishapi/vsl_dispatch.c +++ b/lib/libvarnishapi/vsl_dispatch.c @@ -427,7 +427,7 @@ chunk_shm_to_buf(struct VSLQ *vslq, struct chunk *chunk) } /* Append a set of records to a vtx structure */ -static void +static enum vsl_status vtx_append(struct VSLQ *vslq, struct vtx *vtx, const struct VSLC_ptr *start, size_t len) { @@ -439,6 +439,9 @@ vtx_append(struct VSLQ *vslq, struct vtx *vtx, const struct VSLC_ptr *start, AN(start); i = VSL_Check(vslq->c, start); + if (i == vsl_check_e_inval) + return (vsl_e_overrun); + if (i == vsl_check_valid && !VTAILQ_EMPTY(&vtx->shmchunks_free)) { /* Shmref it */ chunk = VTAILQ_FIRST(&vtx->shmchunks_free); @@ -453,7 +456,6 @@ vtx_append(struct VSLQ *vslq, struct vtx *vtx, const struct VSLC_ptr *start, /* Append to shmref list */ VTAILQ_INSERT_TAIL(&vslq->shmrefs, chunk, shm.shmref); } else { - assert(i != vsl_check_e_inval); /* Buffer it */ chunk = VTAILQ_LAST(&vtx->chunks, chunkhead); CHECK_OBJ_ORNULL(chunk, CHUNK_MAGIC); @@ -468,6 +470,7 @@ vtx_append(struct VSLQ *vslq, struct vtx *vtx, const struct VSLC_ptr *start, } } vtx->len += len; + return (vsl_more); } /* Allocate a new vtx structure */ @@ -1310,8 +1313,9 @@ vslq_next(struct VSLQ *vslq) AN(vtx); } if (vtx != NULL) { - vtx_append(vslq, vtx, &c->rec, len); - vtx_scan(vslq, vtx); + r = vtx_append(vslq, vtx, &c->rec, len); + if (r == vsl_more) + vtx_scan(vslq, vtx); } return (r); From martin at varnish-software.com Fri Nov 12 12:30:10 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 12 Nov 2021 12:30:10 +0000 (UTC) Subject: [6.0] 8c902af1e vsl: Kill dead check Message-ID: <20211112123011.0A69E114A97@lists.varnish-cache.org> commit 8c902af1e38f664fa42d35be845a4129d9589817 Author: Dridi Boukelmoune Date: Wed Oct 28 15:31:33 2020 +0100 vsl: Kill dead check There's only one call site for vtx_dispatch() and it guarantees that len is greater than zero. diff --git a/lib/libvarnishapi/vsl_dispatch.c b/lib/libvarnishapi/vsl_dispatch.c index 0075e2322..ebc45123a 100644 --- a/lib/libvarnishapi/vsl_dispatch.c +++ b/lib/libvarnishapi/vsl_dispatch.c @@ -435,8 +435,7 @@ vtx_append(struct VSLQ *vslq, struct vtx *vtx, const struct VSLC_ptr *start, enum vsl_check i; AN(vtx); - if (len == 0) - return; + AN(len); AN(start); i = VSL_Check(vslq->c, start); From martin at varnish-software.com Fri Nov 12 12:32:07 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 12 Nov 2021 12:32:07 +0000 (UTC) Subject: [6.0] 0f92dccf3 Offer a configure --with-unwind switch Message-ID: <20211112123207.BB82F114EAB@lists.varnish-cache.org> commit 0f92dccf3d557addb1e34ceb1bac9a69cf6a6dca Author: Guillaume Quintard Date: Wed Sep 4 11:02:12 2019 +0900 Offer a configure --with-unwind switch Conflicts: .travis.yml bin/varnishd/cache/cache_panic.c diff --git a/.travis.yml b/.travis.yml index 8d31d9e04..02f080c04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ before_install: if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH="/usr/local/opt/sphinx-doc/bin:$PATH" elif [[ -n "$SAN_FLAGS" ]]; then - export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage ${SAN_FLAGS}" + export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage --with-unwind ${SAN_FLAGS}" export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0,disable_coredump=0 export LSAN_OPTIONS=abort_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/lsan.suppr export TSAN_OPTIONS=abort_on_error=1,halt_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/tsan.suppr diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index e6e0537e4..bd7bce594 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -173,6 +173,11 @@ varnishd_LDADD = \ @PCRE_LIBS@ \ ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} +if WITH_UNWIND +varnishd_CFLAGS += -DUNW_LOCAL_ONLY +varnishd_LDADD += ${LIBUNWIND_LIBS} +endif + noinst_PROGRAMS = vhp_gen_hufdec vhp_gen_hufdec_SOURCES = hpack/vhp_gen_hufdec.c vhp_gen_hufdec_CFLAGS = @SAN_CFLAGS@ \ diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index ef6234374..3a37ea65b 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -29,7 +29,11 @@ #include "config.h" +#ifdef WITH_UNWIND +#include +#else #include +#endif #include #include #include @@ -575,6 +579,47 @@ pan_sess(struct vsb *vsb, const struct sess *sp) /*--------------------------------------------------------------------*/ +#ifdef WITH_UNWIND + +static void +pan_backtrace(struct vsb *vsb) +{ + unw_cursor_t cursor; unw_context_t uc; + unw_word_t ip, sp; + unw_word_t offp; + char fname[1024]; + int ret; + + VSB_printf(vsb, "Backtrace:\n"); + VSB_indent(vsb, 2); + + ret = unw_getcontext(&uc); + if (ret != 0) { + VSB_printf(vsb, "Backtrace not available " + "(unw_getcontext returned %d)\n", ret); + return; + } + unw_init_local(&cursor, &uc); + if (ret != 0) { + VSB_printf(vsb, "Backtrace not available " + "(unw_init_local returned %d)\n", ret); + return; + } + while (unw_step(&cursor) > 0) { + fname[0] = '\0'; + ip = sp = 0; + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + unw_get_proc_name(&cursor, fname, sizeof(fname), &offp); + VSB_printf(vsb, "ip=0x%lx, sp=0x%lx <%s+0x%lx>\n", (long) ip, + (long) sp, fname[0] ? fname : "???", offp); + } + + VSB_indent(vsb, -2); +} + +#else /* WITH_UNWIND */ + #define BACKTRACE_LEVELS 10 static void @@ -616,6 +661,8 @@ pan_backtrace(struct vsb *vsb) VSB_indent(vsb, -2); } +#endif /* WITH_UNWIND */ + /*--------------------------------------------------------------------*/ static void __attribute__((__noreturn__)) diff --git a/configure.ac b/configure.ac index bbcbad126..4d4618ec4 100644 --- a/configure.ac +++ b/configure.ac @@ -336,9 +336,25 @@ esac AC_SUBST(JEMALLOC_LDADD) AC_CHECK_FUNCS([setproctitle]) -AC_SEARCH_LIBS(backtrace, [execinfo], [], [ - AC_MSG_ERROR([Could not find backtrace() support]) -]) + +# if the default libexecinfo on alpine causes issues, you can use libunwind +AC_ARG_WITH([unwind], + [AS_HELP_STRING([--with-unwind], + [use libunwind to print stacktraces (use libexecinfo otherwise). Recommended on alpine linux. Defaults to no.])]) + +if test "$with_unwind" = yes; then + PKG_CHECK_MODULES([LIBUNWIND], [libunwind]) + AC_DEFINE([WITH_UNWIND], [1], + [Define to 1 to use libunwind instead of libexecinfo]) +else + AC_SEARCH_LIBS(backtrace, [execinfo], [], [ + AC_MSG_ERROR([Could not find backtrace() support]) + ]) +fi + +AM_CONDITIONAL([WITH_UNWIND], + [test "$with_unwind" = yes]) + # white lie - we don't actually test it AC_MSG_CHECKING([whether daemon() works]) case $target in From martin at varnish-software.com Fri Nov 12 12:38:05 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 12 Nov 2021 12:38:05 +0000 (UTC) Subject: [6.0] 723aa0f0a Add 2 changelog entries Message-ID: <20211112123805.BA3E411528F@lists.varnish-cache.org> commit 723aa0f0a332f54d1b1c8800ade1a900bb4b180d Author: Martin Blix Grydeland Date: Fri Nov 12 13:37:19 2021 +0100 Add 2 changelog entries diff --git a/doc/changes.rst b/doc/changes.rst index a816cb293..cf9e6bb75 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -44,9 +44,16 @@ Varnish Cache 6.0.9 (unreleased) * The CLI command `vcl.show -v` now outputs the `builtin` VCL source last, after any included VCL sources files. +* Improve the ability of log utilities to detect log overruns. (3716_) + +* Add an option to `configure` to use `libunwind` for the stack backtrace + in the panic output. (3717_) + .. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 .. _3437: https://github.com/varnishcache/varnish-cache/issues/3437' .. _3564: https://github.com/varnishcache/varnish-cache/issues/3564' +.. _3716: https://github.com/varnishcache/varnish-cache/pull/3716' +.. _3717: https://github.com/varnishcache/varnish-cache/pull/3717' ================================ Varnish Cache 6.0.8 (2021-07-13) From dridi.boukelmoune at gmail.com Mon Nov 15 11:46:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 15 Nov 2021 11:46:06 +0000 (UTC) Subject: [master] 97d6342c2 mac: Polish Message-ID: <20211115114607.12BEE1190EF@lists.varnish-cache.org> commit 97d6342c2abcbecd5b6567dddb6f47c3bf3b860f Author: Dridi Boukelmoune Date: Mon Nov 15 12:44:19 2021 +0100 mac: Polish diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 441a12166..5204d259c 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -151,8 +151,7 @@ mk_listen_sock(const struct listen_arg *la, const struct suckaddr *sa) ls->sock = -1; ls->addr = VSA_Clone(sa); AN(ls->addr); - ls->endpoint = strdup(la->endpoint); - AN(ls->endpoint); + REPLACE(ls->endpoint, la->endpoint); ls->name = la->name; ls->transport = la->transport; ls->perms = la->perms; From dridi.boukelmoune at gmail.com Mon Nov 15 11:46:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 15 Nov 2021 11:46:07 +0000 (UTC) Subject: [master] 4bec43af4 mac: Add brackets around IPv6 endpoints Message-ID: <20211115114607.2A42C1190F1@lists.varnish-cache.org> commit 4bec43af4e59ec71ef59538e08235f11f0bc9e3a Author: Dridi Boukelmoune Date: Mon Nov 15 12:44:59 2021 +0100 mac: Add brackets around IPv6 endpoints diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 5204d259c..612198672 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -201,7 +201,10 @@ mac_tcp(void *priv, const struct suckaddr *sa) ls->addr = VTCP_my_suckaddr(ls->sock); VTCP_myname(ls->sock, abuf, sizeof abuf, pbuf, sizeof pbuf); - bprintf(nbuf, "%s:%s", abuf, pbuf); + if (VSA_Get_Proto(sa) == AF_INET6) + bprintf(nbuf, "[%s]:%s", abuf, pbuf); + else + bprintf(nbuf, "%s:%s", abuf, pbuf); REPLACE(ls->endpoint, nbuf); } VTAILQ_INSERT_TAIL(&la->socks, ls, arglist); From nils.goroll at uplex.de Mon Nov 15 14:14:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 15 Nov 2021 14:14:05 +0000 (UTC) Subject: [master] 686c65b34 Use correct list var name in mgt_vcl_discard_depcheck Message-ID: <20211115141405.C2FB66715@lists.varnish-cache.org> commit 686c65b34d36fa5c0dbc25a1811f60910c52e034 Author: Martin Blix Grydeland Date: Fri Nov 12 11:39:11 2021 +0100 Use correct list var name in mgt_vcl_discard_depcheck Using the wrong list variable would cause the dependency check to consider VCLs that were not attempted discarded. Fixes: #3734 diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index df77dd0c8..000b6b11e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -754,7 +754,7 @@ mgt_vcl_discard_depcheck(struct cli *cli) struct vclprog *vp; struct vcldep *vd; - VTAILQ_FOREACH(vp, &discardhead, list) { + VTAILQ_FOREACH(vp, &discardhead, discard_list) { VTAILQ_FOREACH(vd, &vp->dto, lto) if (!vd->from->discard) { mgt_vcl_discard_depfail(cli, vp); diff --git a/bin/varnishtest/tests/r03734.vtc b/bin/varnishtest/tests/r03734.vtc new file mode 100644 index 000000000..a34ebefd0 --- /dev/null +++ b/bin/varnishtest/tests/r03734.vtc @@ -0,0 +1,44 @@ +varnishtest "Issue 3734 - Discard dependency check and labels" + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + return (synth(200, "vcl1")); + } +} -start + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + return (synth(200, "vcl2")); + } +} + +varnish v1 -cliok { vcl.label lbl_vcl2 vcl2 } + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + if (req.url == "/label") { + return (vcl(lbl_vcl2)); + } + return (synth(200, "vcl3")); + } +} + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.reason == vcl3 + + txreq -url /label + rxresp + expect resp.status == 200 + expect resp.reason == vcl2 +} -run + +varnish v1 -cliok { vcl.discard vcl1 } From dridi.boukelmoune at gmail.com Mon Nov 15 14:44:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 15 Nov 2021 14:44:05 +0000 (UTC) Subject: [7.0] f5077e639 Use correct list var name in mgt_vcl_discard_depcheck Message-ID: <20211115144405.596137820@lists.varnish-cache.org> commit f5077e6399a359548beca2c3e5c827dccb5231fb Author: Martin Blix Grydeland Date: Fri Nov 12 11:39:11 2021 +0100 Use correct list var name in mgt_vcl_discard_depcheck Using the wrong list variable would cause the dependency check to consider VCLs that were not attempted discarded. Fixes: #3734 diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index df77dd0c8..000b6b11e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -754,7 +754,7 @@ mgt_vcl_discard_depcheck(struct cli *cli) struct vclprog *vp; struct vcldep *vd; - VTAILQ_FOREACH(vp, &discardhead, list) { + VTAILQ_FOREACH(vp, &discardhead, discard_list) { VTAILQ_FOREACH(vd, &vp->dto, lto) if (!vd->from->discard) { mgt_vcl_discard_depfail(cli, vp); diff --git a/bin/varnishtest/tests/r03734.vtc b/bin/varnishtest/tests/r03734.vtc new file mode 100644 index 000000000..a34ebefd0 --- /dev/null +++ b/bin/varnishtest/tests/r03734.vtc @@ -0,0 +1,44 @@ +varnishtest "Issue 3734 - Discard dependency check and labels" + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + return (synth(200, "vcl1")); + } +} -start + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + return (synth(200, "vcl2")); + } +} + +varnish v1 -cliok { vcl.label lbl_vcl2 vcl2 } + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + if (req.url == "/label") { + return (vcl(lbl_vcl2)); + } + return (synth(200, "vcl3")); + } +} + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.reason == vcl3 + + txreq -url /label + rxresp + expect resp.status == 200 + expect resp.reason == vcl2 +} -run + +varnish v1 -cliok { vcl.discard vcl1 } From dridi.boukelmoune at gmail.com Mon Nov 15 14:57:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 15 Nov 2021 14:57:07 +0000 (UTC) Subject: [master] 94bd48863 cli: New debug.shutdown.delay command Message-ID: <20211115145707.199F27F68@lists.varnish-cache.org> commit 94bd48863b035ce300187ed7739ded53bd891388 Author: Dridi Boukelmoune Date: Fri Oct 22 16:00:25 2021 +0200 cli: New debug.shutdown.delay command For the purpose of simulating a workload where the cache process takes significant time to shut down. diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 39b2dace5..095279dc3 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -48,6 +48,8 @@ #include "common/heritage.h" #include "vcli_serve.h" +#include "vnum.h" +#include "vtim.h" #include "vrnd.h" #include "hash/hash_slinger.h" @@ -56,6 +58,7 @@ int cache_shutdown = 0; volatile struct params *cache_param; static pthread_mutex_t cache_vrnd_mtx; +static vtim_dur shutdown_delay = 0; pthread_mutexattr_t mtxattr_errorcheck; @@ -224,6 +227,18 @@ cli_debug_xid(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "XID is %u", vxid_base); } +/* + * Artificially slow down the process shutdown. + */ +static void v_matchproto_(cli_func_t) +cli_debug_shutdown_delay(struct cli *cli, const char * const *av, void *priv) +{ + + (void)cli; + (void)priv; + shutdown_delay = VNUM_duration(av[2]); +} + /* * Default to seed=1, this is the only seed value POSIXl guarantees will * result in a reproducible random number sequence. @@ -241,8 +256,9 @@ cli_debug_srandom(struct cli *cli, const char * const *av, void *priv) } static struct cli_proto debug_cmds[] = { - { CLICMD_DEBUG_XID, "d", cli_debug_xid }, - { CLICMD_DEBUG_SRANDOM, "d", cli_debug_srandom }, + { CLICMD_DEBUG_XID, "d", cli_debug_xid }, + { CLICMD_DEBUG_SHUTDOWN_DELAY, "d", cli_debug_shutdown_delay }, + { CLICMD_DEBUG_SRANDOM, "d", cli_debug_srandom }, { NULL } }; @@ -434,6 +450,10 @@ child_main(int sigmagic, size_t altstksz) CLI_Run(); cache_shutdown = 1; + + if (shutdown_delay > 0) + VTIM_sleep(shutdown_delay); + VCA_Shutdown(); BAN_Shutdown(); EXP_Shutdown(); diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h index 9537833f6..7134c0c20 100644 --- a/include/tbl/cli_cmds.h +++ b/include/tbl/cli_cmds.h @@ -359,6 +359,15 @@ CLI_CMD(DEBUG_REQPOOLFAIL, "allocations will fail.", 1, 1 ) + +CLI_CMD(DEBUG_SHUTDOWN_DELAY, + "debug.shutdown.delay", + "debug.shutdown.delay", + "Add a delay to the child process shutdown.", + "", + 1, 1 +) + CLI_CMD(DEBUG_XID, "debug.xid", "debug.xid", From dridi.boukelmoune at gmail.com Mon Nov 15 16:36:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 15 Nov 2021 16:36:05 +0000 (UTC) Subject: [master] b9ad91e25 build: Use libunwind if available at configure time Message-ID: <20211115163605.D4C7F63131@lists.varnish-cache.org> commit b9ad91e258fca26fab04ae26237c7e19fb99dcfd Author: Dridi Boukelmoune Date: Fri Nov 12 17:10:28 2021 +0100 build: Use libunwind if available at configure time One can still use the --without-unwind configure flag. Refs #3717 diff --git a/configure.ac b/configure.ac index e5df08ab3..e61cc2730 100644 --- a/configure.ac +++ b/configure.ac @@ -369,17 +369,26 @@ AC_CHECK_FUNCS([setproctitle]) # if the default libexecinfo on alpine causes issues, you can use libunwind AC_ARG_WITH([unwind], [AS_HELP_STRING([--with-unwind], - [use libunwind to print stacktraces (use libexecinfo otherwise). Recommended on alpine linux. Defaults to no.])]) + [use libunwind to print stacktraces (use libexecinfo otherwise). Recommended on alpine linux. Defaults to auto.])]) -if test "$with_unwind" = yes; then +if test "$with_unwind" != no; then case $target in *-*-darwin*) # Always present but .pc is not installed + have_unwind=yes ;; *) - PKG_CHECK_MODULES([LIBUNWIND], [libunwind]) + PKG_CHECK_MODULES([LIBUNWIND], [libunwind], [have_unwind=yes], + [have_unwind=no]) ;; esac +fi + +if test "$with_unwind" = yes && test "$have_unwind" != yes; then + AC_MSG_ERROR([Could not find libunwind]) +fi + +if test "$have_unwind" = yes; then AC_DEFINE([WITH_UNWIND], [1], [Define to 1 to use libunwind instead of libexecinfo]) else @@ -388,8 +397,7 @@ else ]) fi -AM_CONDITIONAL([WITH_UNWIND], - [test "$with_unwind" = yes]) +AM_CONDITIONAL([WITH_UNWIND], [test "$have_unwind" = yes]) # white lie - we don't actually test it AC_MSG_CHECKING([whether daemon() works]) From dridi.boukelmoune at gmail.com Mon Nov 15 17:52:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 15 Nov 2021 17:52:05 +0000 (UTC) Subject: [master] cce142056 vtc: Account for [braces] on IPv6-only systems Message-ID: <20211115175205.C792B65653@lists.varnish-cache.org> commit cce142056e88d431ca34487dd5d95c206b3b5f0c Author: Dridi Boukelmoune Date: Mon Nov 15 18:39:53 2021 +0100 vtc: Account for [braces] on IPv6-only systems diff --git a/bin/varnishtest/tests/v00025.vtc b/bin/varnishtest/tests/v00025.vtc index 790f24873..c6cdadd8f 100644 --- a/bin/varnishtest/tests/v00025.vtc +++ b/bin/varnishtest/tests/v00025.vtc @@ -174,8 +174,8 @@ client c1 { expect resp.http.C-Sess-XID ~ "^[0-9]+$" expect resp.http.B-Sess-XID ~ "^[0-9]+$" expect resp.http.C-Sess-XID == resp.http.B-Sess-XID - expect resp.http.C-Endpoint == "${v1_addr}:${v1_port}" - expect resp.http.B-Endpoint == "${v1_addr}:${v1_port}" + expect resp.http.C-Endpoint ~ ".?${v1_addr}.?:${v1_port}" + expect resp.http.B-Endpoint ~ ".?${v1_addr}.?:${v1_port}" expect resp.http.C-Socket == "a0" expect resp.http.B-Socket == "a0" } -run From nils.goroll at uplex.de Tue Nov 16 11:41:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:07 +0000 (UTC) Subject: [master] cd5537209 Do not select active VCL automatically in the child process Message-ID: <20211116114107.2F36950D2@lists.varnish-cache.org> commit cd553720970e7da7109039c0583b506b4e3f7cc3 Author: AlveElde Date: Wed Aug 25 17:38:47 2021 +0200 Do not select active VCL automatically in the child process Do not select the first VCL present as the active VCL in the child process. Instead it should always use what the mgt process tells it through the explicit 'vcl.use' commands it will send. Previously, the child could select a cold VCL as the active VCL if that happened to be the first one present to it during restarts. This could lead to asserts as that is not an allowed state. diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 0efded131..ac72ede22 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -707,10 +707,6 @@ vcl_load(struct cli *cli, VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name); VTAILQ_INSERT_TAIL(&vcl_head, vcl, list); - Lck_Lock(&vcl_mtx); - if (vcl_active == NULL) - vcl_active = vcl; - Lck_Unlock(&vcl_mtx); VSC_C_main->n_vcl++; VSC_C_main->n_vcl_avail++; } From nils.goroll at uplex.de Tue Nov 16 11:41:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:07 +0000 (UTC) Subject: [master] 5bce732b6 Enforce invariant on vcl_active in the child process Message-ID: <20211116114107.429B450D4@lists.varnish-cache.org> commit 5bce732b681f24781d7a193d06eb9f30a6cc898f Author: Martin Blix Grydeland Date: Tue Oct 19 11:46:09 2021 +0200 Enforce invariant on vcl_active in the child process Add a ASSERT_VCL_ACTIVE() macro that asserts that vcl_active either is NULL or points to a VCL that is warm. Sprinkle this macro in the various calls throughout the child process that are involved in VCL handling. Patch by: @alveelde diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index ac72ede22..c69e1e5c7 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -213,6 +213,7 @@ vcl_send_event(struct vcl *vcl, enum vcl_event_e ev, struct vsb **msg) struct vrt_ctx *ctx; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); @@ -337,6 +338,7 @@ VCL_Update(struct vcl **vcc, struct vcl *vcl) *vcc = NULL; CHECK_OBJ_ORNULL(old, VCL_MAGIC); + ASSERT_VCL_ACTIVE(); Lck_Lock(&vcl_mtx); if (old != NULL) { @@ -393,6 +395,7 @@ VCL_IterDirector(struct cli *cli, const char *pat, struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vsb = VSB_new_auto(); AN(vsb); if (pat == NULL || *pat == '\0' || !strcmp(pat, "*")) { @@ -665,6 +668,7 @@ vcl_load(struct cli *cli, struct vsb *msg; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vcl = vcl_find(name); AZ(vcl); @@ -720,6 +724,7 @@ VCL_Poll(void) struct vcl *vcl, *vcl2; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); VTAILQ_FOREACH_SAFE(vcl, &vcl_head, list, vcl2) { if (vcl->temp == VCL_TEMP_BUSY || vcl->temp == VCL_TEMP_COOLING) @@ -755,6 +760,7 @@ vcl_cli_list(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vsb = VSB_new_auto(); AN(vsb); VTAILQ_FOREACH(vcl, &vcl_head, list) { @@ -787,6 +793,7 @@ vcl_cli_list_json(struct cli *cli, const char * const *av, void *priv) (void)priv; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); VCLI_JSON_begin(cli, 2, av); VCLI_Out(cli, ",\n"); VTAILQ_FOREACH(vcl, &vcl_head, list) { @@ -844,6 +851,7 @@ vcl_cli_state(struct cli *cli, const char * const *av, void *priv) AZ(priv); ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AN(av[2]); AN(av[3]); @@ -869,6 +877,7 @@ vcl_cli_discard(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); (void)cli; AZ(priv); vcl = vcl_find(av[2]); @@ -902,6 +911,7 @@ vcl_cli_label(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); (void)cli; (void)priv; vcl = vcl_find(av[3]); @@ -927,6 +937,7 @@ vcl_cli_use(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AN(cli); AZ(priv); vcl = vcl_find(av[2]); @@ -945,6 +956,7 @@ vcl_cli_show(struct cli *cli, const char * const *av, void *priv) int i; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AZ(priv); if (!strcmp(av[2], "-v") && av[3] == NULL) { VCLI_Out(cli, "Too few parameters"); diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h index 0c72c22ec..355cccf59 100644 --- a/bin/varnishd/cache/cache_vcl.h +++ b/bin/varnishd/cache/cache_vcl.h @@ -88,3 +88,9 @@ extern const struct vcltemp VCL_TEMP_COLD[1]; extern const struct vcltemp VCL_TEMP_WARM[1]; extern const struct vcltemp VCL_TEMP_BUSY[1]; extern const struct vcltemp VCL_TEMP_COOLING[1]; + +#define ASSERT_VCL_ACTIVE() \ + do { \ + assert(vcl_active == NULL || \ + vcl_active->temp->is_warm); \ + } while (0) diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index f7bcf2017..3fd34e42e 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -84,6 +84,7 @@ VCL_Refresh(struct vcl **vcc) while (vcl_active == NULL) (void)usleep(100000); + ASSERT_VCL_ACTIVE(); if (*vcc == vcl_active) return; @@ -97,6 +98,7 @@ VCL_Recache(const struct worker *wrk, struct vcl **vclp) AN(wrk); AN(vclp); CHECK_OBJ_NOTNULL(*vclp, VCL_MAGIC); + ASSERT_VCL_ACTIVE(); if (*vclp != vcl_active || wrk->wpriv->vcl == vcl_active) { VCL_Rel(vclp); From nils.goroll at uplex.de Tue Nov 16 11:41:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:07 +0000 (UTC) Subject: [master] df206894e Rename active_vcl to mgt_vcl_active Message-ID: <20211116114107.5D90150DA@lists.varnish-cache.org> commit df206894e678d800f4c45492d7dee94195cb8b79 Author: Martin Blix Grydeland Date: Tue Oct 19 14:02:33 2021 +0200 Rename active_vcl to mgt_vcl_active It is very easy to confuse the child process' vcl_active and the management process' active_vcl variables. Rename mgt's active_vcl to mgt_vcl_active, following the naming scheme used elsewhere. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index 000b6b11e..b5507d3ff 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -63,7 +63,7 @@ static unsigned vcl_count; struct vclproghead vclhead = VTAILQ_HEAD_INITIALIZER(vclhead); static struct vclproghead discardhead = VTAILQ_HEAD_INITIALIZER(discardhead); struct vmodfilehead vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead); -static struct vclprog *active_vcl; +static struct vclprog *mgt_vcl_active; static struct vev *e_poker; static int mgt_vcl_setstate(struct cli *, struct vclprog *, @@ -300,7 +300,7 @@ mgt_vcl_set_cooldown(struct vclprog *vp, vtim_mono now) { CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC); - if (vp == active_vcl || + if (vp == mgt_vcl_active || vp->state != VCL_STATE_AUTO || vp->warm == 0 || !VTAILQ_EMPTY(&vp->dto) || @@ -401,7 +401,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) os = vp->state; vp->state = vs; - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { assert (vs == VCL_STATE_WARM || vs == VCL_STATE_AUTO); AN(vp->warm); warm = 1; @@ -458,8 +458,8 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, AZ(C_flag); vp->fname = lib; - if (active_vcl == NULL) - active_vcl = vp; + if (mgt_vcl_active == NULL) + mgt_vcl_active = vp; if ((cli->result == CLIS_OK || cli->result == CLIS_TRUNCATED) && vcl_count > mgt_param.max_vcl && @@ -501,7 +501,7 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - active_vcl = NULL; + mgt_vcl_active = NULL; (void)mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); } @@ -514,7 +514,7 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) struct vcldep *vd; int done; - AN(active_vcl); + AN(mgt_vcl_active); /* The VCL has not been loaded yet, it cannot fail */ (void)cli; @@ -554,8 +554,10 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) } } while (!done); - if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", active_vcl->name)) + if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", + mgt_vcl_active->name)) { return (1); + } free(*p); *p = NULL; return (0); @@ -617,7 +619,7 @@ mcf_vcl_state(struct cli *cli, const char * const *av, void *priv) VCLI_SetResult(cli, CLIS_CANT); return; } - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { VCLI_Out(cli, "Cannot set the active VCL cold."); VCLI_SetResult(cli, CLIS_CANT); return; @@ -639,7 +641,7 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv) vp = mcf_find_vcl(cli, av[2]); if (vp == NULL) return; - if (vp == active_vcl) + if (vp == mgt_vcl_active) return; if (mgt_vcl_requirewarm(cli, vp)) @@ -651,8 +653,8 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "%s", p); } else { VCLI_Out(cli, "VCL '%s' now active", av[2]); - vp2 = active_vcl; - active_vcl = vp; + vp2 = mgt_vcl_active; + mgt_vcl_active = vp; now = VTIM_mono(); mgt_vcl_set_cooldown(vp, now); if (vp2 != NULL) @@ -669,7 +671,7 @@ mgt_vcl_discard(struct cli *cli, struct vclprog *vp) AN(vp); AN(vp->discard); - assert(vp != active_vcl); + assert(vp != mgt_vcl_active); while (!VTAILQ_EMPTY(&vp->dto)) mgt_vcl_discard(cli, VTAILQ_FIRST(&vp->dto)->from); @@ -699,7 +701,7 @@ mgt_vcl_discard_mark(struct cli *cli, const char *glob) VTAILQ_FOREACH(vp, &vclhead, list) { if (fnmatch(glob, vp->name, 0)) continue; - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "Cannot discard active VCL program %s\n", vp->name); @@ -829,7 +831,7 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv) VTAILQ_FOREACH(vp, &vclhead, list) { VSB_printf(vsb, "%s", - vp == active_vcl ? "active" : "available"); + vp == mgt_vcl_active ? "active" : "available"); vs = vp->warm ? VCL_STATE_WARM : VCL_STATE_COLD; VSB_printf(vsb, "\t%s\t%s", vp->state->name, vs->name); VSB_printf(vsb, "\t%6s\t%s", "-", vp->name); @@ -875,7 +877,7 @@ mcf_vcl_list_json(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "{\n"); VSB_indent(cli->sb, 2); VCLI_Out(cli, "\"status\": \"%s\",\n", - vp == active_vcl ? "active" : "available"); + vp == mgt_vcl_active ? "active" : "available"); VCLI_Out(cli, "\"state\": \"%s\",\n", vp->state->name); vs = vp->warm ? VCL_STATE_WARM : VCL_STATE_COLD; VCLI_Out(cli, "\"temperature\": \"%s\",\n", vs->name); @@ -1097,7 +1099,7 @@ mgt_vcl_atexit(void) if (getpid() != heritage.mgt_pid) return; - active_vcl = NULL; + mgt_vcl_active = NULL; while (!VTAILQ_EMPTY(&vclhead)) VTAILQ_FOREACH_SAFE(vp, &vclhead, list, vp2) if (VTAILQ_EMPTY(&vp->dto)) From nils.goroll at uplex.de Tue Nov 16 11:41:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:07 +0000 (UTC) Subject: [master] 8d0f2b836 Make mgt_has_vcl() return an error string Message-ID: <20211116114107.8B2BA50E8@lists.varnish-cache.org> commit 8d0f2b83687dc8a60b3dc6f361985cf429529ad5 Author: Martin Blix Grydeland Date: Tue Oct 19 13:56:16 2021 +0200 Make mgt_has_vcl() return an error string mgt_has_vcl() now returns an error string describing why it doesn't have a valid VCL. This is taken from #3711 by @bsdphk diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h index c8db1954e..f2d2f0f7e 100644 --- a/bin/varnishd/mgt/mgt.h +++ b/bin/varnishd/mgt/mgt.h @@ -231,7 +231,7 @@ void mgt_vcl_init(void); void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin, const char *vclname, int Cflag); int mgt_push_vcls(struct cli *, unsigned *status, char **p); -int mgt_has_vcl(void); +const char *mgt_has_vcl(void); extern char *mgt_cc_cmd; extern const char *mgt_vcl_path; extern const char *mgt_vmod_path; diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index a8181bd56..5e7ed7cb1 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -706,15 +706,17 @@ mch_pid_json(struct cli *cli, const char * const *av, void *priv) static void v_matchproto_(cli_func_t) mch_cli_server_start(struct cli *cli, const char * const *av, void *priv) { + const char *err; (void)av; (void)priv; if (child_state == CH_STOPPED) { - if (mgt_has_vcl()) { + err = mgt_has_vcl(); + if (err == NULL) { mgt_launch_child(cli); } else { VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No VCL available"); + VCLI_Out(cli, "%s", err); } } else { VCLI_SetResult(cli, CLIS_CANT); diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index f5d2ede33..ecc09dc3f 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -483,6 +483,7 @@ main(int argc, char * const *argv) char *p; struct cli cli[1]; char **av; + const char *err; unsigned u; struct sigaction sac; struct vev *e; @@ -909,10 +910,11 @@ main(int argc, char * const *argv) } assert(I_fd == -1); - if (!d_flag && !mgt_has_vcl() && !novcl) - MGT_Complain(C_ERR, "No VCL loaded yet"); + err = mgt_has_vcl(); + if (!d_flag && err != NULL && !novcl) + MGT_Complain(C_ERR, "%s", err); - if (mgt_has_vcl() && ! d_flag) + if (err == NULL && !d_flag) u = MCH_Start_Child(); else u = 0; diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index b5507d3ff..d14c9d95c 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -281,11 +281,16 @@ mgt_vcl_del(struct vclprog *vp) FREE_OBJ(vp); } -int +const char * mgt_has_vcl(void) { - - return (!VTAILQ_EMPTY(&vclhead)); + if (VTAILQ_EMPTY(&vclhead)) + return ("No VCL loaded"); + if (mgt_vcl_active == NULL) + return ("No active VCL"); + CHECK_OBJ_NOTNULL(mgt_vcl_active, VCLPROG_MAGIC); + AN(mgt_vcl_active->warm); + return (NULL); } /* From nils.goroll at uplex.de Tue Nov 16 11:41:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:07 +0000 (UTC) Subject: [master] 56bd0ec88 Change mgt_new_vcl() to return the newly compiled vclprog Message-ID: <20211116114107.C1CB050EC@lists.varnish-cache.org> commit 56bd0ec8837c25b903aa493c7d8f43d3484800f1 Author: Martin Blix Grydeland Date: Thu Nov 11 14:19:18 2021 +0100 Change mgt_new_vcl() to return the newly compiled vclprog mgt_new_vcl() now returns a pointer to the newly compiled VCL program, or NULL on failure. This also fixes a wrong return value used previously which would cause a "VCL compiled.\n" to be output to CLI when the child is not running even when the VCL compilation step failed. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index d14c9d95c..a45645e5d 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -426,7 +426,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) /*--------------------------------------------------------------------*/ -static int +static struct vclprog * mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, const char *vclsrcfile, const char *state, int C_flag) { @@ -442,7 +442,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, VCLI_Out(cli, "Too many (%d) VCLs already loaded\n", vcl_count); VCLI_Out(cli, "(See max_vcl and max_vcl_handling parameters)"); VCLI_SetResult(cli, CLIS_CANT); - return (0); + return (NULL); } if (state == NULL) @@ -451,13 +451,13 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, vs = mcf_vcl_parse_state(cli, state); if (vs == NULL) - return (0); + return (NULL); vp = mgt_vcl_add(vclname, vs); lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfile, C_flag); if (lib == NULL) { mgt_vcl_del(vp); - return (0); + return (NULL); } AZ(C_flag); @@ -475,7 +475,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, } if (!MCH_Running()) - return (0); + return (vp); if (mgt_cli_askchild(&status, &p, "vcl.load %s %s %d%s\n", vp->name, vp->fname, vp->warm, vp->state->name)) { @@ -483,12 +483,12 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, VCLI_Out(cli, "%s", p); VCLI_SetResult(cli, status); free(p); - return (0); + return (NULL); } free(p); mgt_vcl_set_cooldown(vp, VTIM_mono()); - return (1); + return (vp); } /*--------------------------------------------------------------------*/ @@ -573,25 +573,29 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) static void v_matchproto_(cli_func_t) mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv) { + struct vclprog *vp; (void)priv; if (!mcf_find_no_vcl(cli, av[2])) return; - if (!mgt_new_vcl(cli, av[2], av[3], "", av[4], 0)) + vp = mgt_new_vcl(cli, av[2], av[3], "", av[4], 0); + if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } static void v_matchproto_(cli_func_t) mcf_vcl_load(struct cli *cli, const char * const *av, void *priv) { + struct vclprog *vp; (void)priv; if (!mcf_find_no_vcl(cli, av[2])) return; - if (!mgt_new_vcl(cli, av[2], NULL, av[3], av[4], 0)) + vp = mgt_new_vcl(cli, av[2], NULL, av[3], av[4], 0); + if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } From nils.goroll at uplex.de Tue Nov 16 11:41:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:07 +0000 (UTC) Subject: [master] 49d31c8d7 Limit automatic active VCL selection to startup VCLs Message-ID: <20211116114108.04C9150FC@lists.varnish-cache.org> commit 49d31c8d72cc4c23ecd67594912eba03392c1362 Author: Martin Blix Grydeland Date: Thu Nov 11 14:33:23 2021 +0100 Limit automatic active VCL selection to startup VCLs Limit the selection of the active VCL from MGT's view point to be the last startup VCL given. That would be the VCL from the very last -f argument given to varnishd, or the autogenerated VCL from the -b argument (-f and -b are mutually exclusive). Because all startup VCLs are always set to state AUTO, and AUTO VCLs are made warm when the child is not running (which it is not at the time the startup VCLs are compiled), this ensures that it is a warm VCL that is selected as the active VCL. With this patch, VCLs loaded through the use of an initial CLI command script (-I option) will not cause a VCL to automatically be selected as the active VCL. Rather, it is expected that the initial CLI command script should have an explicit 'vcl.use' statement to select the active VCL. When an active VCL is not set, attempts to start the child will fail, which again will fail the varnishd daemon startup (unless -d is given) with an error code. The behaviour prior to this patch when using -I, -f '' (empty field), -F or -d was not well defined. The first VCL loaded (either by -I startup CLI script or a CLI 'vcl.load' command) would become the active VCL, even if that VCL is loaded cold. That is an illegal state and would lead to asserts. It is also not very useful functionality, given the typical use case for -I is to set up VCL labels. Those require the tips of the VCL tree dependency graph to be loaded first, and then the VCLs that selects the label. This means that the active VCL will typically be the last VCL loaded, which then will require the use of a 'vcl.use' statement in the -I script anyways. This makes it an acceptable change of default behaviour that should not affect users. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index a45645e5d..69b35371e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -463,9 +463,6 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, AZ(C_flag); vp->fname = lib; - if (mgt_vcl_active == NULL) - mgt_vcl_active = vp; - if ((cli->result == CLIS_OK || cli->result == CLIS_TRUNCATED) && vcl_count > mgt_param.max_vcl && mgt_param.max_vcl_handling == 1) { @@ -499,6 +496,9 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, { char buf[20]; static int n = 0; + struct vclprog *vp; + + AZ(MCH_Running()); AN(vclsrc); AN(origin); @@ -506,8 +506,13 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - mgt_vcl_active = NULL; - (void)mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); + vp = mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); + if (vp != NULL) { + /* Last startup VCL becomes the automatically selected + * active VCL. */ + AN(vp->warm); + mgt_vcl_active = vp; + } } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishtest/tests/u00000.vtc b/bin/varnishtest/tests/u00000.vtc index dbed3ce58..5103f85b3 100644 --- a/bin/varnishtest/tests/u00000.vtc +++ b/bin/varnishtest/tests/u00000.vtc @@ -105,6 +105,10 @@ shell -expect {VCL compiled.} { varnishadm -n ${tmpdir}/v1 vcl.load vcl1 ${tmpdir}/vcl } +shell -expect {VCL 'vcl1' now active} { + varnishadm -n ${tmpdir}/v1 vcl.use vcl1 +} + shell -expect {active auto warm - vcl1} { varnishadm -n ${tmpdir}/v1 vcl.list } From nils.goroll at uplex.de Tue Nov 16 11:41:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:08 +0000 (UTC) Subject: [master] bc8537eda Test case for handling initially cold VCLs Message-ID: <20211116114108.1E8125102@lists.varnish-cache.org> commit bc8537eda7206120373e3e701d9c72b3e4ff5db0 Author: AlveElde Date: Wed Aug 25 17:38:47 2021 +0200 Test case for handling initially cold VCLs diff --git a/bin/varnishtest/tests/v00067.vtc b/bin/varnishtest/tests/v00067.vtc new file mode 100644 index 000000000..46c72c18a --- /dev/null +++ b/bin/varnishtest/tests/v00067.vtc @@ -0,0 +1,41 @@ +varnishtest "The active VCL must always be warm" + +shell { + cat >${tmpdir}/f1 <<-EOF + vcl 4.1; + backend default none; + EOF +} + +# Load a cold VCL. This should not become the active VCL. +varnish v1 -cliok "vcl.load vcl_cold ${tmpdir}/f1 cold" +varnish v1 -cliexpect "available *cold *cold *- *vcl_cold" "vcl.list" + +# The cache should not start without a warm VCL. +varnish v1 -clierr 300 "start" + +# Load a warm VCL and make it the active VCL. +varnish v1 -cliok "vcl.load vcl_warm ${tmpdir}/f1 warm" +varnish v1 -cliok "vcl.use vcl_warm" +varnish v1 -cliexpect "active *warm *warm *- *vcl_warm" "vcl.list" + +# The cache now starts. +varnish v1 -cliok "start" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_cold" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_warm" "vcl.list" + +# Load an automatically warming VCL, and set it as the active VCL. +varnish v1 -cliok "vcl.load vcl_auto ${tmpdir}/f1 warm" +varnish v1 -cliok "vcl.use vcl_auto" +varnish v1 -cliexpect "available *warm *warm *0 *vcl_warm" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_auto" "vcl.list" + +# Cool the previous active VCL. +varnish v1 -cliok "vcl.state vcl_warm cold" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_warm" "vcl.list" + +# Restart the cache. +varnish v1 -cliok "stop" -cliok "start" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_cold" "vcl.list" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_warm" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_auto" "vcl.list" From nils.goroll at uplex.de Tue Nov 16 11:41:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:41:08 +0000 (UTC) Subject: [master] aa2232ebd Amend the docs on the '-I' option Message-ID: <20211116114108.6A856512D@lists.varnish-cache.org> commit aa2232ebd619152f1dcd5ae430a5e4a511711c34 Author: Martin Blix Grydeland Date: Thu Nov 11 16:31:32 2021 +0100 Amend the docs on the '-I' option Make a note in the documentation of CLI Command File that it is necessary to include an explicit 'vcl.use' command in the script. diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 844487467..cdb08d40e 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -510,6 +510,10 @@ a newline or carriage return. If a command in the file is prefixed with '-', failure will not abort the startup. +Note that it is necessary to include an explicit `vcl.use` command to +select which VCL should be the active VCL when relying on CLI Command File +to load the configurations at startup. + .. _ref-varnishd-params: RUN TIME PARAMETERS From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] 4f9785ec5 Do not select active VCL automatically in the child process Message-ID: <20211116114806.26F6C6153@lists.varnish-cache.org> commit 4f9785ec56c187eb62cc6bffad433da7a74d9f97 Author: AlveElde Date: Wed Aug 25 17:38:47 2021 +0200 Do not select active VCL automatically in the child process Do not select the first VCL present as the active VCL in the child process. Instead it should always use what the mgt process tells it through the explicit 'vcl.use' commands it will send. Previously, the child could select a cold VCL as the active VCL if that happened to be the first one present to it during restarts. This could lead to asserts as that is not an allowed state. diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 0efded131..ac72ede22 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -707,10 +707,6 @@ vcl_load(struct cli *cli, VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name); VTAILQ_INSERT_TAIL(&vcl_head, vcl, list); - Lck_Lock(&vcl_mtx); - if (vcl_active == NULL) - vcl_active = vcl; - Lck_Unlock(&vcl_mtx); VSC_C_main->n_vcl++; VSC_C_main->n_vcl_avail++; } From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] d13663f5b Enforce invariant on vcl_active in the child process Message-ID: <20211116114806.3DE1A6157@lists.varnish-cache.org> commit d13663f5b774a0bd827390517b5b0d5fc90962e0 Author: Martin Blix Grydeland Date: Tue Oct 19 11:46:09 2021 +0200 Enforce invariant on vcl_active in the child process Add a ASSERT_VCL_ACTIVE() macro that asserts that vcl_active either is NULL or points to a VCL that is warm. Sprinkle this macro in the various calls throughout the child process that are involved in VCL handling. Patch by: @alveelde diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index ac72ede22..c69e1e5c7 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -213,6 +213,7 @@ vcl_send_event(struct vcl *vcl, enum vcl_event_e ev, struct vsb **msg) struct vrt_ctx *ctx; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); @@ -337,6 +338,7 @@ VCL_Update(struct vcl **vcc, struct vcl *vcl) *vcc = NULL; CHECK_OBJ_ORNULL(old, VCL_MAGIC); + ASSERT_VCL_ACTIVE(); Lck_Lock(&vcl_mtx); if (old != NULL) { @@ -393,6 +395,7 @@ VCL_IterDirector(struct cli *cli, const char *pat, struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vsb = VSB_new_auto(); AN(vsb); if (pat == NULL || *pat == '\0' || !strcmp(pat, "*")) { @@ -665,6 +668,7 @@ vcl_load(struct cli *cli, struct vsb *msg; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vcl = vcl_find(name); AZ(vcl); @@ -720,6 +724,7 @@ VCL_Poll(void) struct vcl *vcl, *vcl2; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); VTAILQ_FOREACH_SAFE(vcl, &vcl_head, list, vcl2) { if (vcl->temp == VCL_TEMP_BUSY || vcl->temp == VCL_TEMP_COOLING) @@ -755,6 +760,7 @@ vcl_cli_list(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vsb = VSB_new_auto(); AN(vsb); VTAILQ_FOREACH(vcl, &vcl_head, list) { @@ -787,6 +793,7 @@ vcl_cli_list_json(struct cli *cli, const char * const *av, void *priv) (void)priv; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); VCLI_JSON_begin(cli, 2, av); VCLI_Out(cli, ",\n"); VTAILQ_FOREACH(vcl, &vcl_head, list) { @@ -844,6 +851,7 @@ vcl_cli_state(struct cli *cli, const char * const *av, void *priv) AZ(priv); ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AN(av[2]); AN(av[3]); @@ -869,6 +877,7 @@ vcl_cli_discard(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); (void)cli; AZ(priv); vcl = vcl_find(av[2]); @@ -902,6 +911,7 @@ vcl_cli_label(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); (void)cli; (void)priv; vcl = vcl_find(av[3]); @@ -927,6 +937,7 @@ vcl_cli_use(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AN(cli); AZ(priv); vcl = vcl_find(av[2]); @@ -945,6 +956,7 @@ vcl_cli_show(struct cli *cli, const char * const *av, void *priv) int i; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AZ(priv); if (!strcmp(av[2], "-v") && av[3] == NULL) { VCLI_Out(cli, "Too few parameters"); diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h index 0c72c22ec..355cccf59 100644 --- a/bin/varnishd/cache/cache_vcl.h +++ b/bin/varnishd/cache/cache_vcl.h @@ -88,3 +88,9 @@ extern const struct vcltemp VCL_TEMP_COLD[1]; extern const struct vcltemp VCL_TEMP_WARM[1]; extern const struct vcltemp VCL_TEMP_BUSY[1]; extern const struct vcltemp VCL_TEMP_COOLING[1]; + +#define ASSERT_VCL_ACTIVE() \ + do { \ + assert(vcl_active == NULL || \ + vcl_active->temp->is_warm); \ + } while (0) diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index f7bcf2017..3fd34e42e 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -84,6 +84,7 @@ VCL_Refresh(struct vcl **vcc) while (vcl_active == NULL) (void)usleep(100000); + ASSERT_VCL_ACTIVE(); if (*vcc == vcl_active) return; @@ -97,6 +98,7 @@ VCL_Recache(const struct worker *wrk, struct vcl **vclp) AN(wrk); AN(vclp); CHECK_OBJ_NOTNULL(*vclp, VCL_MAGIC); + ASSERT_VCL_ACTIVE(); if (*vclp != vcl_active || wrk->wpriv->vcl == vcl_active) { VCL_Rel(vclp); From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] 9228395ea Rename active_vcl to mgt_vcl_active Message-ID: <20211116114806.5B7D3615B@lists.varnish-cache.org> commit 9228395ea5d13693fe5965b29abfeb4c0e34ee77 Author: Martin Blix Grydeland Date: Tue Oct 19 14:02:33 2021 +0200 Rename active_vcl to mgt_vcl_active It is very easy to confuse the child process' vcl_active and the management process' active_vcl variables. Rename mgt's active_vcl to mgt_vcl_active, following the naming scheme used elsewhere. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index 000b6b11e..b5507d3ff 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -63,7 +63,7 @@ static unsigned vcl_count; struct vclproghead vclhead = VTAILQ_HEAD_INITIALIZER(vclhead); static struct vclproghead discardhead = VTAILQ_HEAD_INITIALIZER(discardhead); struct vmodfilehead vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead); -static struct vclprog *active_vcl; +static struct vclprog *mgt_vcl_active; static struct vev *e_poker; static int mgt_vcl_setstate(struct cli *, struct vclprog *, @@ -300,7 +300,7 @@ mgt_vcl_set_cooldown(struct vclprog *vp, vtim_mono now) { CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC); - if (vp == active_vcl || + if (vp == mgt_vcl_active || vp->state != VCL_STATE_AUTO || vp->warm == 0 || !VTAILQ_EMPTY(&vp->dto) || @@ -401,7 +401,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) os = vp->state; vp->state = vs; - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { assert (vs == VCL_STATE_WARM || vs == VCL_STATE_AUTO); AN(vp->warm); warm = 1; @@ -458,8 +458,8 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, AZ(C_flag); vp->fname = lib; - if (active_vcl == NULL) - active_vcl = vp; + if (mgt_vcl_active == NULL) + mgt_vcl_active = vp; if ((cli->result == CLIS_OK || cli->result == CLIS_TRUNCATED) && vcl_count > mgt_param.max_vcl && @@ -501,7 +501,7 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - active_vcl = NULL; + mgt_vcl_active = NULL; (void)mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); } @@ -514,7 +514,7 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) struct vcldep *vd; int done; - AN(active_vcl); + AN(mgt_vcl_active); /* The VCL has not been loaded yet, it cannot fail */ (void)cli; @@ -554,8 +554,10 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) } } while (!done); - if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", active_vcl->name)) + if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", + mgt_vcl_active->name)) { return (1); + } free(*p); *p = NULL; return (0); @@ -617,7 +619,7 @@ mcf_vcl_state(struct cli *cli, const char * const *av, void *priv) VCLI_SetResult(cli, CLIS_CANT); return; } - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { VCLI_Out(cli, "Cannot set the active VCL cold."); VCLI_SetResult(cli, CLIS_CANT); return; @@ -639,7 +641,7 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv) vp = mcf_find_vcl(cli, av[2]); if (vp == NULL) return; - if (vp == active_vcl) + if (vp == mgt_vcl_active) return; if (mgt_vcl_requirewarm(cli, vp)) @@ -651,8 +653,8 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "%s", p); } else { VCLI_Out(cli, "VCL '%s' now active", av[2]); - vp2 = active_vcl; - active_vcl = vp; + vp2 = mgt_vcl_active; + mgt_vcl_active = vp; now = VTIM_mono(); mgt_vcl_set_cooldown(vp, now); if (vp2 != NULL) @@ -669,7 +671,7 @@ mgt_vcl_discard(struct cli *cli, struct vclprog *vp) AN(vp); AN(vp->discard); - assert(vp != active_vcl); + assert(vp != mgt_vcl_active); while (!VTAILQ_EMPTY(&vp->dto)) mgt_vcl_discard(cli, VTAILQ_FIRST(&vp->dto)->from); @@ -699,7 +701,7 @@ mgt_vcl_discard_mark(struct cli *cli, const char *glob) VTAILQ_FOREACH(vp, &vclhead, list) { if (fnmatch(glob, vp->name, 0)) continue; - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "Cannot discard active VCL program %s\n", vp->name); @@ -829,7 +831,7 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv) VTAILQ_FOREACH(vp, &vclhead, list) { VSB_printf(vsb, "%s", - vp == active_vcl ? "active" : "available"); + vp == mgt_vcl_active ? "active" : "available"); vs = vp->warm ? VCL_STATE_WARM : VCL_STATE_COLD; VSB_printf(vsb, "\t%s\t%s", vp->state->name, vs->name); VSB_printf(vsb, "\t%6s\t%s", "-", vp->name); @@ -875,7 +877,7 @@ mcf_vcl_list_json(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "{\n"); VSB_indent(cli->sb, 2); VCLI_Out(cli, "\"status\": \"%s\",\n", - vp == active_vcl ? "active" : "available"); + vp == mgt_vcl_active ? "active" : "available"); VCLI_Out(cli, "\"state\": \"%s\",\n", vp->state->name); vs = vp->warm ? VCL_STATE_WARM : VCL_STATE_COLD; VCLI_Out(cli, "\"temperature\": \"%s\",\n", vs->name); @@ -1097,7 +1099,7 @@ mgt_vcl_atexit(void) if (getpid() != heritage.mgt_pid) return; - active_vcl = NULL; + mgt_vcl_active = NULL; while (!VTAILQ_EMPTY(&vclhead)) VTAILQ_FOREACH_SAFE(vp, &vclhead, list, vp2) if (VTAILQ_EMPTY(&vp->dto)) From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] 506c452a0 Make mgt_has_vcl() return an error string Message-ID: <20211116114806.7DE01615F@lists.varnish-cache.org> commit 506c452a06d1d5e8efd9beea961d6b140996c18a Author: Martin Blix Grydeland Date: Tue Oct 19 13:56:16 2021 +0200 Make mgt_has_vcl() return an error string mgt_has_vcl() now returns an error string describing why it doesn't have a valid VCL. This is taken from #3711 by @bsdphk diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h index c8db1954e..f2d2f0f7e 100644 --- a/bin/varnishd/mgt/mgt.h +++ b/bin/varnishd/mgt/mgt.h @@ -231,7 +231,7 @@ void mgt_vcl_init(void); void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin, const char *vclname, int Cflag); int mgt_push_vcls(struct cli *, unsigned *status, char **p); -int mgt_has_vcl(void); +const char *mgt_has_vcl(void); extern char *mgt_cc_cmd; extern const char *mgt_vcl_path; extern const char *mgt_vmod_path; diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index 5af419fed..6248ca1d7 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -707,15 +707,17 @@ mch_pid_json(struct cli *cli, const char * const *av, void *priv) static void v_matchproto_(cli_func_t) mch_cli_server_start(struct cli *cli, const char * const *av, void *priv) { + const char *err; (void)av; (void)priv; if (child_state == CH_STOPPED) { - if (mgt_has_vcl()) { + err = mgt_has_vcl(); + if (err == NULL) { mgt_launch_child(cli); } else { VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No VCL available"); + VCLI_Out(cli, "%s", err); } } else { VCLI_SetResult(cli, CLIS_CANT); diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index f5d2ede33..ecc09dc3f 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -483,6 +483,7 @@ main(int argc, char * const *argv) char *p; struct cli cli[1]; char **av; + const char *err; unsigned u; struct sigaction sac; struct vev *e; @@ -909,10 +910,11 @@ main(int argc, char * const *argv) } assert(I_fd == -1); - if (!d_flag && !mgt_has_vcl() && !novcl) - MGT_Complain(C_ERR, "No VCL loaded yet"); + err = mgt_has_vcl(); + if (!d_flag && err != NULL && !novcl) + MGT_Complain(C_ERR, "%s", err); - if (mgt_has_vcl() && ! d_flag) + if (err == NULL && !d_flag) u = MCH_Start_Child(); else u = 0; diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index b5507d3ff..d14c9d95c 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -281,11 +281,16 @@ mgt_vcl_del(struct vclprog *vp) FREE_OBJ(vp); } -int +const char * mgt_has_vcl(void) { - - return (!VTAILQ_EMPTY(&vclhead)); + if (VTAILQ_EMPTY(&vclhead)) + return ("No VCL loaded"); + if (mgt_vcl_active == NULL) + return ("No active VCL"); + CHECK_OBJ_NOTNULL(mgt_vcl_active, VCLPROG_MAGIC); + AN(mgt_vcl_active->warm); + return (NULL); } /* From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] a2c70c5e9 Change mgt_new_vcl() to return the newly compiled vclprog Message-ID: <20211116114806.98A3A6163@lists.varnish-cache.org> commit a2c70c5e9ee20b7474bf982ee30a20e5985a5b9f Author: Martin Blix Grydeland Date: Thu Nov 11 14:19:18 2021 +0100 Change mgt_new_vcl() to return the newly compiled vclprog mgt_new_vcl() now returns a pointer to the newly compiled VCL program, or NULL on failure. This also fixes a wrong return value used previously which would cause a "VCL compiled.\n" to be output to CLI when the child is not running even when the VCL compilation step failed. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index d14c9d95c..a45645e5d 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -426,7 +426,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) /*--------------------------------------------------------------------*/ -static int +static struct vclprog * mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, const char *vclsrcfile, const char *state, int C_flag) { @@ -442,7 +442,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, VCLI_Out(cli, "Too many (%d) VCLs already loaded\n", vcl_count); VCLI_Out(cli, "(See max_vcl and max_vcl_handling parameters)"); VCLI_SetResult(cli, CLIS_CANT); - return (0); + return (NULL); } if (state == NULL) @@ -451,13 +451,13 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, vs = mcf_vcl_parse_state(cli, state); if (vs == NULL) - return (0); + return (NULL); vp = mgt_vcl_add(vclname, vs); lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfile, C_flag); if (lib == NULL) { mgt_vcl_del(vp); - return (0); + return (NULL); } AZ(C_flag); @@ -475,7 +475,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, } if (!MCH_Running()) - return (0); + return (vp); if (mgt_cli_askchild(&status, &p, "vcl.load %s %s %d%s\n", vp->name, vp->fname, vp->warm, vp->state->name)) { @@ -483,12 +483,12 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, VCLI_Out(cli, "%s", p); VCLI_SetResult(cli, status); free(p); - return (0); + return (NULL); } free(p); mgt_vcl_set_cooldown(vp, VTIM_mono()); - return (1); + return (vp); } /*--------------------------------------------------------------------*/ @@ -573,25 +573,29 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) static void v_matchproto_(cli_func_t) mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv) { + struct vclprog *vp; (void)priv; if (!mcf_find_no_vcl(cli, av[2])) return; - if (!mgt_new_vcl(cli, av[2], av[3], "", av[4], 0)) + vp = mgt_new_vcl(cli, av[2], av[3], "", av[4], 0); + if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } static void v_matchproto_(cli_func_t) mcf_vcl_load(struct cli *cli, const char * const *av, void *priv) { + struct vclprog *vp; (void)priv; if (!mcf_find_no_vcl(cli, av[2])) return; - if (!mgt_new_vcl(cli, av[2], NULL, av[3], av[4], 0)) + vp = mgt_new_vcl(cli, av[2], NULL, av[3], av[4], 0); + if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] dda20238b Limit automatic active VCL selection to startup VCLs Message-ID: <20211116114806.B57166167@lists.varnish-cache.org> commit dda20238b9dc27f4c907e50fe6e207501683fa9a Author: Martin Blix Grydeland Date: Thu Nov 11 14:33:23 2021 +0100 Limit automatic active VCL selection to startup VCLs Limit the selection of the active VCL from MGT's view point to be the last startup VCL given. That would be the VCL from the very last -f argument given to varnishd, or the autogenerated VCL from the -b argument (-f and -b are mutually exclusive). Because all startup VCLs are always set to state AUTO, and AUTO VCLs are made warm when the child is not running (which it is not at the time the startup VCLs are compiled), this ensures that it is a warm VCL that is selected as the active VCL. With this patch, VCLs loaded through the use of an initial CLI command script (-I option) will not cause a VCL to automatically be selected as the active VCL. Rather, it is expected that the initial CLI command script should have an explicit 'vcl.use' statement to select the active VCL. When an active VCL is not set, attempts to start the child will fail, which again will fail the varnishd daemon startup (unless -d is given) with an error code. The behaviour prior to this patch when using -I, -f '' (empty field), -F or -d was not well defined. The first VCL loaded (either by -I startup CLI script or a CLI 'vcl.load' command) would become the active VCL, even if that VCL is loaded cold. That is an illegal state and would lead to asserts. It is also not very useful functionality, given the typical use case for -I is to set up VCL labels. Those require the tips of the VCL tree dependency graph to be loaded first, and then the VCLs that selects the label. This means that the active VCL will typically be the last VCL loaded, which then will require the use of a 'vcl.use' statement in the -I script anyways. This makes it an acceptable change of default behaviour that should not affect users. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index a45645e5d..69b35371e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -463,9 +463,6 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, AZ(C_flag); vp->fname = lib; - if (mgt_vcl_active == NULL) - mgt_vcl_active = vp; - if ((cli->result == CLIS_OK || cli->result == CLIS_TRUNCATED) && vcl_count > mgt_param.max_vcl && mgt_param.max_vcl_handling == 1) { @@ -499,6 +496,9 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, { char buf[20]; static int n = 0; + struct vclprog *vp; + + AZ(MCH_Running()); AN(vclsrc); AN(origin); @@ -506,8 +506,13 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - mgt_vcl_active = NULL; - (void)mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); + vp = mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); + if (vp != NULL) { + /* Last startup VCL becomes the automatically selected + * active VCL. */ + AN(vp->warm); + mgt_vcl_active = vp; + } } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishtest/tests/u00000.vtc b/bin/varnishtest/tests/u00000.vtc index dbed3ce58..5103f85b3 100644 --- a/bin/varnishtest/tests/u00000.vtc +++ b/bin/varnishtest/tests/u00000.vtc @@ -105,6 +105,10 @@ shell -expect {VCL compiled.} { varnishadm -n ${tmpdir}/v1 vcl.load vcl1 ${tmpdir}/vcl } +shell -expect {VCL 'vcl1' now active} { + varnishadm -n ${tmpdir}/v1 vcl.use vcl1 +} + shell -expect {active auto warm - vcl1} { varnishadm -n ${tmpdir}/v1 vcl.list } From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] a72a28a2b Test case for handling initially cold VCLs Message-ID: <20211116114806.D280C6172@lists.varnish-cache.org> commit a72a28a2bec375e67ad5d5b1b10ff913e8d3c80c Author: AlveElde Date: Wed Aug 25 17:38:47 2021 +0200 Test case for handling initially cold VCLs diff --git a/bin/varnishtest/tests/v00067.vtc b/bin/varnishtest/tests/v00067.vtc new file mode 100644 index 000000000..46c72c18a --- /dev/null +++ b/bin/varnishtest/tests/v00067.vtc @@ -0,0 +1,41 @@ +varnishtest "The active VCL must always be warm" + +shell { + cat >${tmpdir}/f1 <<-EOF + vcl 4.1; + backend default none; + EOF +} + +# Load a cold VCL. This should not become the active VCL. +varnish v1 -cliok "vcl.load vcl_cold ${tmpdir}/f1 cold" +varnish v1 -cliexpect "available *cold *cold *- *vcl_cold" "vcl.list" + +# The cache should not start without a warm VCL. +varnish v1 -clierr 300 "start" + +# Load a warm VCL and make it the active VCL. +varnish v1 -cliok "vcl.load vcl_warm ${tmpdir}/f1 warm" +varnish v1 -cliok "vcl.use vcl_warm" +varnish v1 -cliexpect "active *warm *warm *- *vcl_warm" "vcl.list" + +# The cache now starts. +varnish v1 -cliok "start" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_cold" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_warm" "vcl.list" + +# Load an automatically warming VCL, and set it as the active VCL. +varnish v1 -cliok "vcl.load vcl_auto ${tmpdir}/f1 warm" +varnish v1 -cliok "vcl.use vcl_auto" +varnish v1 -cliexpect "available *warm *warm *0 *vcl_warm" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_auto" "vcl.list" + +# Cool the previous active VCL. +varnish v1 -cliok "vcl.state vcl_warm cold" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_warm" "vcl.list" + +# Restart the cache. +varnish v1 -cliok "stop" -cliok "start" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_cold" "vcl.list" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_warm" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_auto" "vcl.list" From nils.goroll at uplex.de Tue Nov 16 11:48:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 11:48:06 +0000 (UTC) Subject: [7.0] d084467a4 Amend the docs on the '-I' option Message-ID: <20211116114806.EF69E6184@lists.varnish-cache.org> commit d084467a4e478adbd09da1231229bb8db8d3ceee Author: Martin Blix Grydeland Date: Thu Nov 11 16:31:32 2021 +0100 Amend the docs on the '-I' option Make a note in the documentation of CLI Command File that it is necessary to include an explicit 'vcl.use' command in the script. diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 844487467..cdb08d40e 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -510,6 +510,10 @@ a newline or carriage return. If a command in the file is prefixed with '-', failure will not abort the startup. +Note that it is necessary to include an explicit `vcl.use` command to +select which VCL should be the active VCL when relying on CLI Command File +to load the configurations at startup. + .. _ref-varnishd-params: RUN TIME PARAMETERS From nils.goroll at uplex.de Tue Nov 16 12:00:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 16 Nov 2021 12:00:08 +0000 (UTC) Subject: [master] 6503249ca Remove VRE options masks Message-ID: <20211116120008.DE9AB741E@lists.varnish-cache.org> commit 6503249ca94bf6b0729e290c422f5169fe1a9ccc Author: Nils Goroll Date: Tue Nov 16 12:57:48 2021 +0100 Remove VRE options masks varnish core code should continue to use the VRE_* options, vmods may now pass PCRE2_* options. diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c index 096a4ba79..96b7ef677 100644 --- a/lib/libvarnish/vre.c +++ b/lib/libvarnish/vre.c @@ -65,14 +65,6 @@ const int VRE_ERROR_NOMATCH = PCRE2_ERROR_NOMATCH; const unsigned VRE_CASELESS = PCRE2_CASELESS; -/* - * Even though we only have one for each case so far, keep track of masks - * to differentiate between compile and match options and enfore the hard - * VRE linkage. - */ -#define VRE_MASK_COMPILE PCRE2_CASELESS -#define VRE_MASK_MATCH 0 - vre_t * VRE_compile(const char *pattern, unsigned options, int *errptr, int *erroffset, unsigned jit) @@ -81,7 +73,6 @@ VRE_compile(const char *pattern, unsigned options, vre_t *v; AN(pattern); - AZ(options & (~VRE_MASK_COMPILE)); AN(errptr); AN(erroffset); @@ -247,7 +238,6 @@ VRE_match(const vre_t *code, const char *subject, size_t length, CHECK_OBJ_NOTNULL(code, VRE_MAGIC); AN(subject); - AZ(options & (~VRE_MASK_MATCH)); if (length == 0) length = PCRE2_ZERO_TERMINATED; @@ -264,7 +254,6 @@ VRE_capture(const vre_t *code, const char *subject, size_t length, int options, CHECK_OBJ_NOTNULL(code, VRE_MAGIC); AN(subject); - AZ(options & (~VRE_MASK_MATCH)); AN(groups); AN(count); From nils.goroll at uplex.de Wed Nov 17 11:07:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:06 +0000 (UTC) Subject: [master] 2b78367cc vca: Remove the tcp_opt::iponly field Message-ID: <20211117110706.C009E613FC@lists.varnish-cache.org> commit 2b78367cc09951b6a93b70fdd015c2eaa14de42f Author: Dridi Boukelmoune Date: Mon Sep 27 07:18:29 2021 +0200 vca: Remove the tcp_opt::iponly field It is a 1:1 mapping with IPPROTO_TCP, so TCP_NODELAY was moved down to be with the other IPPROTO_TCP options. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index e9c174c0a..296737d49 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -87,20 +87,20 @@ static struct tcp_opt { socklen_t sz; void *ptr; int need; - int iponly; } tcp_opts[] = { -#define TCPO(lvl, nam, sz, ip) { lvl, nam, #nam, sizeof(sz), 0, 0, ip}, +#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, - TCPO(SOL_SOCKET, SO_LINGER, struct linger, 0) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int, 0) - TCPO(IPPROTO_TCP, TCP_NODELAY, int, 1) - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval, 0) - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval, 0) + TCPO(SOL_SOCKET, SO_LINGER, struct linger) + TCPO(SOL_SOCKET, SO_KEEPALIVE, int) + TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) + TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) + + TCPO(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int, 1) + TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) + TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) + TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif #undef TCPO @@ -219,7 +219,7 @@ vca_tcp_opt_test(const int sock, const unsigned uds) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; to->need = 1; ptr = calloc(1, to->sz); @@ -242,7 +242,7 @@ vca_tcp_opt_set(const int sock, const unsigned uds, const int force) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; if (to->need || force) { VTCP_Assert(setsockopt(sock, From nils.goroll at uplex.de Wed Nov 17 11:07:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:06 +0000 (UTC) Subject: [master] 40b4401e7 vca: Rename tcp_opt to a more general sock_opt Message-ID: <20211117110706.D3673613FF@lists.varnish-cache.org> commit 40b4401e78d17ccdcf3e5dea675da47d65d78e97 Author: Dridi Boukelmoune Date: Mon Sep 27 07:42:44 2021 +0200 vca: Rename tcp_opt to a more general sock_opt And conversely rename `to` variables to `so` for consistency. Better diff with the --word-diff --word-diff-regex='\w+' options. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 296737d49..ff988feb9 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -80,33 +80,33 @@ struct poolsock { * TCP options we want to control */ -static struct tcp_opt { +static struct sock_opt { int level; int optname; const char *strname; socklen_t sz; void *ptr; int need; -} tcp_opts[] = { -#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +} sock_opts[] = { +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, - TCPO(SOL_SOCKET, SO_LINGER, struct linger) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int) - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) + SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) + SOCK_OPT(SOL_SOCKET, SO_SNDTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_RCVTIMEO, struct timeval) - TCPO(IPPROTO_TCP, TCP_NODELAY, int) + SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPIDLE, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPCNT, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif -#undef TCPO +#undef SOCK_OPT }; -static const int n_tcp_opts = sizeof tcp_opts / sizeof tcp_opts[0]; +static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast @@ -147,11 +147,11 @@ vca_periodic(vtim_real t0) */ static int -vca_tcp_opt_init(void) +vca_sock_opt_init(void) { int n; int one = 1; - struct tcp_opt *to; + struct sock_opt *so; struct timeval tv; int chg = 0; int x; @@ -159,50 +159,50 @@ vca_tcp_opt_init(void) memset(&tv, 0, sizeof tv); memset(&x, 0, sizeof x); - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->ptr == NULL) - to->ptr = calloc(1, to->sz); - AN(to->ptr); - if (!strcmp(to->strname, "SO_LINGER")) { - assert(to->sz == sizeof linger); - memcpy(to->ptr, &linger, sizeof linger); - to->need = 1; - } else if (!strcmp(to->strname, "TCP_NODELAY")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; - } else if (!strcmp(to->strname, "SO_KEEPALIVE")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; -#define NEW_VAL(to, xx) \ + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->ptr == NULL) + so->ptr = calloc(1, so->sz); + AN(so->ptr); + if (!strcmp(so->strname, "SO_LINGER")) { + assert(so->sz == sizeof linger); + memcpy(so->ptr, &linger, sizeof linger); + so->need = 1; + } else if (!strcmp(so->strname, "TCP_NODELAY")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; + } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; +#define NEW_VAL(so, xx) \ do { \ - assert(to->sz == sizeof xx); \ - if (memcmp(to->ptr, &(xx), sizeof xx)) { \ - memcpy(to->ptr, &(xx), sizeof xx); \ - to->need = 1; \ + assert(so->sz == sizeof xx); \ + if (memcmp(so->ptr, &(xx), sizeof xx)) { \ + memcpy(so->ptr, &(xx), sizeof xx); \ + so->need = 1; \ chg = 1; \ need_test = 1; \ } \ } while (0) - } else if (!strcmp(to->strname, "SO_SNDTIMEO")) { + } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(to, tv); - } else if (!strcmp(to->strname, "SO_RCVTIMEO")) { + NEW_VAL(so, tv); + } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(to, tv); + NEW_VAL(so, tv); #ifdef HAVE_TCP_KEEP - } else if (!strcmp(to->strname, "TCP_KEEPIDLE")) { + } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPCNT")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPINTVL")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(to, x); + NEW_VAL(so, x); #endif } } @@ -210,24 +210,24 @@ vca_tcp_opt_init(void) } static void -vca_tcp_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const int sock, const unsigned uds) { int i, n; - struct tcp_opt *to; + struct sock_opt *so; socklen_t l; void *ptr; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - to->need = 1; - ptr = calloc(1, to->sz); + so->need = 1; + ptr = calloc(1, so->sz); AN(ptr); - l = to->sz; - i = getsockopt(sock, to->level, to->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, to->ptr, to->sz)) - to->need = 0; + l = so->sz; + i = getsockopt(sock, so->level, so->optname, ptr, &l); + if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + so->need = 0; free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); @@ -235,18 +235,18 @@ vca_tcp_opt_test(const int sock, const unsigned uds) } static void -vca_tcp_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const int sock, const unsigned uds, const int force) { int n; - struct tcp_opt *to; + struct sock_opt *so; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - if (to->need || force) { + if (so->need || force) { VTCP_Assert(setsockopt(sock, - to->level, to->optname, to->ptr, to->sz)); + so->level, so->optname, so->ptr, so->sz)); } } } @@ -394,10 +394,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_tcp_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); need_test = 0; } - vca_tcp_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); req = Req_New(sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -583,13 +583,13 @@ vca_acct(void *arg) while (1) { (void)sleep(1); - if (vca_tcp_opt_init()) { + if (vca_sock_opt_init()) { AZ(pthread_mutex_lock(&shut_mtx)); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -609,7 +609,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; - (void)vca_tcp_opt_init(); + (void)vca_sock_opt_init(); VTAILQ_FOREACH(ls, &heritage.socks, list) { CHECK_OBJ_NOTNULL(ls->transport, TRANSPORT_MAGIC); @@ -625,7 +625,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, "Kernel filtering: sock=%d, errno=%d %s", From nils.goroll at uplex.de Wed Nov 17 11:07:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:06 +0000 (UTC) Subject: [master] 42e1ca3b4 vca: Pass higher-level types to sock_opt functions Message-ID: <20211117110706.F0E6E61403@lists.varnish-cache.org> commit 42e1ca3b497558dd51ce5952254bfa2627054e18 Author: Dridi Boukelmoune Date: Mon Sep 27 08:19:09 2021 +0200 vca: Pass higher-level types to sock_opt functions The sess and listen_sock structs contain everything we need to find or infer the former `sock`, `uds` and `force` arguments. In particular, it helps distinguish between working on a connection vs listen socket. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index ff988feb9..fe1b3071a 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -210,22 +210,25 @@ vca_sock_opt_init(void) } static void -vca_sock_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { int i, n; struct sock_opt *so; socklen_t l; void *ptr; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; ptr = calloc(1, so->sz); AN(ptr); l = so->sz; - i = getsockopt(sock, so->level, so->optname, ptr, &l); + i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) so->need = 0; free(ptr); @@ -235,16 +238,20 @@ vca_sock_opt_test(const int sock, const unsigned uds) } static void -vca_sock_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n; + int n, sock; struct sock_opt *so; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_ORNULL(sp, SESS_MAGIC); + sock = sp != NULL ? sp->fd : ls->sock; + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || force) { + if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, so->level, so->optname, so->ptr, so->sz)); } @@ -394,10 +401,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(wa->acceptlsock, sp); need_test = 0; } - vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(wa->acceptlsock, sp); req = Req_New(sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -589,7 +596,7 @@ vca_acct(void *arg) if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -625,7 +632,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, "Kernel filtering: sock=%d, errno=%d %s", From nils.goroll at uplex.de Wed Nov 17 11:07:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:07 +0000 (UTC) Subject: [master] 303726fdd vca: Eliminate heap allocations of sock_opt arguments Message-ID: <20211117110707.182816140A@lists.varnish-cache.org> commit 303726fdd8c69264adcdb1eded33fea251688a83 Author: Dridi Boukelmoune Date: Mon Sep 27 11:41:27 2021 +0200 vca: Eliminate heap allocations of sock_opt arguments They can be stored directly in the sock_opts array or on the stack. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index fe1b3071a..c88c45fd3 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -80,15 +80,21 @@ struct poolsock { * TCP options we want to control */ +union sock_arg { + struct linger lg; + struct timeval tv; + int i; +}; + static struct sock_opt { int level; int optname; const char *strname; - socklen_t sz; - void *ptr; int need; + socklen_t sz; + union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -152,35 +158,30 @@ vca_sock_opt_init(void) int n; int one = 1; struct sock_opt *so; - struct timeval tv; + union sock_arg tmp; int chg = 0; - int x; - memset(&tv, 0, sizeof tv); - memset(&x, 0, sizeof x); + memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->ptr == NULL) - so->ptr = calloc(1, so->sz); - AN(so->ptr); if (!strcmp(so->strname, "SO_LINGER")) { assert(so->sz == sizeof linger); - memcpy(so->ptr, &linger, sizeof linger); + memcpy(so->arg, &linger, sizeof linger); so->need = 1; } else if (!strcmp(so->strname, "TCP_NODELAY")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; #define NEW_VAL(so, xx) \ do { \ assert(so->sz == sizeof xx); \ - if (memcmp(so->ptr, &(xx), sizeof xx)) { \ - memcpy(so->ptr, &(xx), sizeof xx); \ + if (memcmp(so->arg, &(xx), sizeof xx)) { \ + memcpy(so->arg, &(xx), sizeof xx); \ so->need = 1; \ chg = 1; \ need_test = 1; \ @@ -188,21 +189,21 @@ vca_sock_opt_init(void) } while (0) } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); + NEW_VAL(so, tmp.tv); } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->timeout_idle); + NEW_VAL(so, tmp.tv); #ifdef HAVE_TCP_KEEP } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_time); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_probes); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_intvl); + NEW_VAL(so, tmp.i); #endif } } @@ -212,10 +213,10 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { - int i, n; struct sock_opt *so; + union sock_arg tmp; socklen_t l; - void *ptr; + int i, n; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -225,13 +226,11 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; - ptr = calloc(1, so->sz); - AN(ptr); + memset(&tmp, 0, sizeof tmp); l = so->sz; - i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); + if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) so->need = 0; - free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -240,8 +239,8 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n, sock; struct sock_opt *so; + int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_ORNULL(sp, SESS_MAGIC); @@ -253,7 +252,7 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) continue; if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->ptr, so->sz)); + so->level, so->optname, so->arg, so->sz)); } } } From nils.goroll at uplex.de Wed Nov 17 11:07:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:07 +0000 (UTC) Subject: [master] df7070fb0 vca: Generalize the sock options test Message-ID: <20211117110707.30BE96140E@lists.varnish-cache.org> commit df7070fb0245f2aca20c205b840c51f6df1423f5 Author: Dridi Boukelmoune Date: Mon Sep 27 12:11:53 2021 +0200 vca: Generalize the sock options test Using the tmp sock_arg for storage, we can test all values with the same logic and only differentiate hard-coded options from parameterized ones. Stylistic polish by @mbgrydeland. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index c88c45fd3..73a341f07 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -155,57 +155,54 @@ vca_periodic(vtim_real t0) static int vca_sock_opt_init(void) { - int n; - int one = 1; struct sock_opt *so; union sock_arg tmp; - int chg = 0; + int n, chg = 0; + size_t sz; memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (!strcmp(so->strname, "SO_LINGER")) { - assert(so->sz == sizeof linger); - memcpy(so->arg, &linger, sizeof linger); - so->need = 1; - } else if (!strcmp(so->strname, "TCP_NODELAY")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; - } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; -#define NEW_VAL(so, xx) \ - do { \ - assert(so->sz == sizeof xx); \ - if (memcmp(so->arg, &(xx), sizeof xx)) { \ - memcpy(so->arg, &(xx), sizeof xx); \ - so->need = 1; \ - chg = 1; \ - need_test = 1; \ - } \ + +#define SET_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + assert(so->sz == sizeof so->arg->fld); \ + so->arg->fld = (val); \ + } \ + } while (0) + +#define NEW_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + sz = sizeof tmp.fld; \ + assert(so->sz == sz); \ + tmp.fld = (val); \ + if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ + memcpy(&so->arg->fld, &(tmp.fld), sz); \ + so->need = 1; \ + chg = 1; \ + need_test = 1; \ + } \ + } \ } while (0) - } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tmp.tv); - } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tmp.tv); + SET_VAL(SO_LINGER, so, lg, linger); + SET_VAL(SO_KEEPALIVE, so, i, 1); + NEW_VAL(SO_SNDTIMEO, so, tv, + VTIM_timeval(cache_param->idle_send_timeout)); + NEW_VAL(SO_RCVTIMEO, so, tv, + VTIM_timeval(cache_param->timeout_idle)); #ifdef HAVE_TCP_KEEP - } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - tmp.i = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - tmp.i = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - tmp.i = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, tmp.i); + SET_VAL(TCP_NODELAY, so, i, 1); + NEW_VAL(TCP_KEEPIDLE, so, i, + (int)cache_param->tcp_keepalive_time); + NEW_VAL(TCP_KEEPCNT, so, i, + (int)cache_param->tcp_keepalive_probes); + NEW_VAL(TCP_KEEPINTVL, so, i, + (int)cache_param->tcp_keepalive_intvl); #endif - } } return (chg); } From nils.goroll at uplex.de Wed Nov 17 11:07:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:07 +0000 (UTC) Subject: [master] 7e20f094e vca: Give all const socket options placeholers Message-ID: <20211117110707.49CD561415@lists.varnish-cache.org> commit 7e20f094ec317c8aae11b4b4ed3d0a3c370447dc Author: Dridi Boukelmoune Date: Mon Sep 27 12:42:54 2021 +0200 vca: Give all const socket options placeholers The SO_KEEPALIVE justification used to precede such a constant and was left confusingly lingering over the unrelated need_test variable. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 73a341f07..bd27ffd65 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -129,6 +129,13 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ +static const unsigned so_keepalive = 1; + +/* We disable Nagle's algorithm in favor of low latency setups. + */ + +static const unsigned tcp_nodelay = 1; + static unsigned need_test; /*-------------------------------------------------------------------- @@ -189,13 +196,13 @@ vca_sock_opt_init(void) } while (0) SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, 1); + SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); + SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); #ifdef HAVE_TCP_KEEP - SET_VAL(TCP_NODELAY, so, i, 1); NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); NEW_VAL(TCP_KEEPCNT, so, i, From nils.goroll at uplex.de Wed Nov 17 11:07:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:07 +0000 (UTC) Subject: [master] d05d08daf vca: Give sock_opt constant arguments better names Message-ID: <20211117110707.643A861419@lists.varnish-cache.org> commit d05d08daf351b0ac1849436a98fa836c8c20034e Author: Dridi Boukelmoune Date: Mon Sep 27 13:17:55 2021 +0200 vca: Give sock_opt constant arguments better names And while at it, update the SO_LINGER explanation to match reality. Refs 7eba94605b9f diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index bd27ffd65..c3023f318 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -116,11 +116,11 @@ static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast - * as absolutely possible, so we set them LINGER enabled with zero timeout, - * so that even if there are outstanding write data on the socket, a close(2) - * will return immediately. + * as absolutely possible, so we set them LINGER disabled, so that even if + * there are outstanding write data on the socket, a close(2) will return + * immediately. */ -static const struct linger linger = { +static const struct linger disable_so_linger = { .l_onoff = 0, }; @@ -129,12 +129,12 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ -static const unsigned so_keepalive = 1; +static const unsigned enable_so_keepalive = 1; /* We disable Nagle's algorithm in favor of low latency setups. */ -static const unsigned tcp_nodelay = 1; +static const unsigned enable_tcp_nodelay = 1; static unsigned need_test; @@ -195,13 +195,13 @@ vca_sock_opt_init(void) } \ } while (0) - SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); + SET_VAL(SO_LINGER, so, lg, disable_so_linger); + SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); - SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); + SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #ifdef HAVE_TCP_KEEP NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); From nils.goroll at uplex.de Wed Nov 17 11:07:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:07 +0000 (UTC) Subject: [master] 4eeb1e253 vca: Have one inheritance check per listen socket Message-ID: <20211117110707.8F73861421@lists.varnish-cache.org> commit 4eeb1e253d9abf36af87b6a6d36d48c03cebb093 Author: Dridi Boukelmoune Date: Mon Sep 27 14:53:56 2021 +0200 vca: Have one inheritance check per listen socket Instead of having a single global check that all acceptors may race towards, this check now happens on a per listen socket basis. For sockets with a different inheritance behavior on a single system, we avoid having the first connection dictate what may be inherited by a connection socket from its listen socket for all the other listen addresses. At least on Linux, Unix-domain sockets DO NOT inherit options like SO_{RCV,SND}TIMEO even though TCP sockets do. On the off chance that even sockets of the same family could behave differently, like for example a regular vs a loopback TCP session, this is done on a per listen address basis. To avoid cache-acceptor coordination with the acceptor worker threads of a given listen address, workers will individually perform this check once and for all when the first connection is accepted. We also stay defensive in the event of a parameter change, just in case a previous test would assume inheritance because the Varnish parameter value would match the kernel default value. Once a mismatch is observed for a given connection with a given socket, the inheritance test is no longer performed needlessly for this combination. A race still exists between acceptors from different thread pools for a given listen address, but this race is identical to the previous one based on the former global need_test variable. Although the inheritance check leaks into struct listen_sock, it is opaque so everything can remain contained inside cache_acceptor.c. Some aspects of this change (including the clarification comments) are from @mbgrydeland. Refs #2722 diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index c3023f318..1a07357ce 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -90,11 +90,13 @@ static struct sock_opt { int level; int optname; const char *strname; - int need; + unsigned mod; socklen_t sz; union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, + /* Note: Setting the mod counter to something not-zero is needed + * to force the setsockopt() calls on startup */ +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 1, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -114,6 +116,11 @@ static struct sock_opt { static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; +struct conn_heritage { + unsigned sess_set; + unsigned listen_mod; +}; + /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast * as absolutely possible, so we set them LINGER disabled, so that even if @@ -136,8 +143,6 @@ static const unsigned enable_so_keepalive = 1; static const unsigned enable_tcp_nodelay = 1; -static unsigned need_test; - /*-------------------------------------------------------------------- * lacking a better place, we put some generic periodic updates * into the vca_acct() loop which we are running anyway @@ -188,9 +193,8 @@ vca_sock_opt_init(void) tmp.fld = (val); \ if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ memcpy(&so->arg->fld, &(tmp.fld), sz); \ - so->need = 1; \ + so->mod++; \ chg = 1; \ - need_test = 1; \ } \ } \ } while (0) @@ -217,6 +221,7 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; union sock_arg tmp; socklen_t l; @@ -227,14 +232,16 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; + if (ch->sess_set) + continue; /* Already set, no need to retest */ if (so->level == IPPROTO_TCP && ls->uds) continue; - so->need = 1; memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) - so->need = 0; + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + ch->sess_set = 1; if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -243,6 +250,7 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; int n, sock; @@ -252,12 +260,17 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || sp == NULL) { - VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->arg, so->sz)); - } + if (sp == NULL && ch->listen_mod == so->mod) + continue; + if (sp != NULL && !ch->sess_set) + continue; + VTCP_Assert(setsockopt(sock, + so->level, so->optname, so->arg, so->sz)); + if (sp == NULL) + ch->listen_mod = so->mod; } } @@ -403,9 +416,9 @@ vca_make_session(struct worker *wrk, void *arg) vca_pace_good(); wrk->stats->sess_conn++; - if (need_test) { + if (wa->acceptlsock->test_heritage) { vca_sock_opt_test(wa->acceptlsock, sp); - need_test = 0; + wa->acceptlsock->test_heritage = 0; } vca_sock_opt_set(wa->acceptlsock, sp); @@ -600,6 +613,17 @@ vca_acct(void *arg) continue; // VCA_Shutdown assert (ls->sock > 0); vca_sock_opt_set(ls, NULL); + /* If one of the options on a socket has + * changed, also force a retest of whether + * the values are inherited to the + * accepted sockets. This should then + * catch any false positives from previous + * tests that could happen if the set + * value of an option happened to just be + * the OS default for that value, and + * wasn't actually inherited from the + * listening socket. */ + ls->test_heritage = 1; } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -635,6 +659,11 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } + AZ(ls->conn_heritage); + ls->conn_heritage = calloc(n_sock_opts, + sizeof *ls->conn_heritage); + AN(ls->conn_heritage); + ls->test_heritage = 1; vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, @@ -642,8 +671,6 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->sock, errno, VAS_errtxt(errno)); } - need_test = 1; - AZ(pthread_create(&VCA_thread, NULL, vca_acct, NULL)); } diff --git a/bin/varnishd/common/heritage.h b/bin/varnishd/common/heritage.h index f2b2e448f..8244f8046 100644 --- a/bin/varnishd/common/heritage.h +++ b/bin/varnishd/common/heritage.h @@ -37,6 +37,7 @@ struct listen_sock; struct transport; struct VCLS; struct uds_perms; +struct conn_heritage; struct listen_sock { unsigned magic; @@ -50,6 +51,8 @@ struct listen_sock { struct suckaddr *addr; const struct transport *transport; const struct uds_perms *perms; + unsigned test_heritage; + struct conn_heritage *conn_heritage; }; VTAILQ_HEAD(listen_sock_head, listen_sock); diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc new file mode 100644 index 000000000..e8a4eef61 --- /dev/null +++ b/bin/varnishtest/tests/r02722.vtc @@ -0,0 +1,37 @@ +varnishtest "TCP vs UDS sockopt inheritance" + +feature cmd {test $(uname) != SunOS} + +server s0 { + rxreqhdrs + non_fatal + rxreqbody + txresp +} -dispatch + +varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -cliok "param.set debug +flush_head" +varnish v1 -cliok "param.set timeout_idle 1" +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -req POST -hdr "Content-Length: 100" + send some + rxresp + expect resp.status == 503 +} + +# This run performs the inheritance test on a TCP connection +client c1 -run + +# This run relies on the inheritance test results +client c1 -run + +varnish v1 -vsl_catchup + +# This run checks that TCP results aren't applied to a UDS +client c1 -connect "${tmpdir}/v1.sock" +client c1 -run + +# And finally this run checks UDS inheritance test results +client c1 -run From nils.goroll at uplex.de Wed Nov 17 11:07:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:07:07 +0000 (UTC) Subject: [master] fc63f1298 vca: Log the outcome of sockopt inheritance Message-ID: <20211117110707.BA8606143A@lists.varnish-cache.org> commit fc63f1298948a129d5cfb5138c16106993f36347 Author: Dridi Boukelmoune Date: Mon Nov 15 12:31:02 2021 +0100 vca: Log the outcome of sockopt inheritance diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 1a07357ce..fd86f4835 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -233,15 +233,27 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (ch->sess_set) - continue; /* Already set, no need to retest */ - if (so->level == IPPROTO_TCP && ls->uds) + if (ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing nonhereditary %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); + continue; + } memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Test confirmed %s non heredity for %s=%s", + so->strname, ls->name, ls->endpoint); ch->sess_set = 1; + } if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -252,21 +264,44 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { struct conn_heritage *ch; struct sock_opt *so; + unsigned vxid; int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); - CHECK_OBJ_ORNULL(sp, SESS_MAGIC); - sock = sp != NULL ? sp->fd : ls->sock; + + if (sp != NULL) { + CHECK_OBJ(sp, SESS_MAGIC); + sock = sp->fd; + vxid = sp->vxid; + } else { + sock = ls->sock; + vxid = 0; + } for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (so->level == IPPROTO_TCP && ls->uds) + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp == NULL && ch->listen_mod == so->mod) + } + if (sp == NULL && ch->listen_mod == so->mod) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting unmodified %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp != NULL && !ch->sess_set) + } + if (sp != NULL && !ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: %s may be inherited for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + VSL(SLT_Debug, vxid, + "sockopt: Setting %s for %s=%s", + so->strname, ls->name, ls->endpoint); VTCP_Assert(setsockopt(sock, so->level, so->optname, so->arg, so->sz)); if (sp == NULL) diff --git a/bin/varnishtest/tests/l00000.vtc b/bin/varnishtest/tests/l00000.vtc index 1c732fc47..e7e316ccf 100644 --- a/bin/varnishtest/tests/l00000.vtc +++ b/bin/varnishtest/tests/l00000.vtc @@ -11,7 +11,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g session { expect 0 1000 Begin sess expect 0 = SessOpen - expect 0 = Link "req 1001" + expect * = Link "req 1001" expect 0 = SessClose expect 0 = End diff --git a/bin/varnishtest/tests/o00001.vtc b/bin/varnishtest/tests/o00001.vtc index 5a6b35913..ebe38bcb9 100644 --- a/bin/varnishtest/tests/o00001.vtc +++ b/bin/varnishtest/tests/o00001.vtc @@ -74,7 +74,7 @@ logexpect l1 -v v1 -g raw { expect * 1016 Proxy "2 1.2.3.4 2314 5.6.7.8 2828" expect * 1019 Proxy "2 102:304:506::d0e:f10 2314 8182:8384:8586::8d8e:8f80 2828" expect * 1022 Begin "^sess 0 PROXY" - expect 1 1022 SessClose "^RX_OVERFLOW" + expect * 1022 SessClose "^RX_OVERFLOW" } -start client c1 { diff --git a/bin/varnishtest/tests/o00006.vtc b/bin/varnishtest/tests/o00006.vtc index 5f7eb4638..e8adecb7c 100644 --- a/bin/varnishtest/tests/o00006.vtc +++ b/bin/varnishtest/tests/o00006.vtc @@ -12,7 +12,7 @@ varnish v1 -arg "-p pool_sess=0,0,0" -proto "PROXY" -vcl+backend {} -start logexpect l1 -v v1 -g raw { expect 0 1000 Begin "sess 0 PROXY" expect 0 = SessOpen - expect 0 = Proxy "2 217.70.181.33 60822 95.142.168.34 443" + expect * = Proxy "2 217.70.181.33 60822 95.142.168.34 443" expect 0 = Error {\Qinsufficient workspace (proto_priv)\E} expect 0 = SessClose "RX_JUNK" } -start diff --git a/bin/varnishtest/tests/r01804.vtc b/bin/varnishtest/tests/r01804.vtc index 252dd5845..d50bf9558 100644 --- a/bin/varnishtest/tests/r01804.vtc +++ b/bin/varnishtest/tests/r01804.vtc @@ -13,7 +13,7 @@ varnish v1 -vcl+backend "" -start logexpect l1 -v v1 -g session { expect * 1000 Begin {^sess .* PROXY$} expect 0 = SessOpen {^.* foo .*} - expect 0 = Proxy {^1 } + expect * = Proxy {^1 } expect * 1001 Begin {^req} } -start @@ -28,7 +28,7 @@ logexpect l1 -wait logexpect l2 -v v1 -g session { expect * 1003 Begin {^sess .* PROXY$} expect 0 = SessOpen {^.* foo .*} - expect 0 = Proxy {^2 } + expect * = Proxy {^2 } expect * 1004 Begin {^req} } -start diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc index e8a4eef61..1268864b5 100644 --- a/bin/varnishtest/tests/r02722.vtc +++ b/bin/varnishtest/tests/r02722.vtc @@ -9,7 +9,7 @@ server s0 { txresp } -dispatch -varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -arg {-a TCP=:0 -a "UDS=${tmpdir}/v1.sock"} varnish v1 -cliok "param.set debug +flush_head" varnish v1 -cliok "param.set timeout_idle 1" varnish v1 -vcl+backend { } -start From nils.goroll at uplex.de Wed Nov 17 11:44:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:06 +0000 (UTC) Subject: [7.0] 258471a36 vca: Remove the tcp_opt::iponly field Message-ID: <20211117114406.AD174635B8@lists.varnish-cache.org> commit 258471a366bccbd58fee3ae2d6766bda21f71354 Author: Dridi Boukelmoune Date: Mon Sep 27 07:18:29 2021 +0200 vca: Remove the tcp_opt::iponly field It is a 1:1 mapping with IPPROTO_TCP, so TCP_NODELAY was moved down to be with the other IPPROTO_TCP options. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 33dc99130..e55a262fd 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -87,26 +87,23 @@ static struct tcp_opt { socklen_t sz; void *ptr; int need; - int iponly; } tcp_opts[] = { -#define TCPO(lvl, nam, sz, ip) { lvl, nam, #nam, sizeof(sz), 0, 0, ip}, - - TCPO(SOL_SOCKET, SO_LINGER, struct linger, 0) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int, 0) - TCPO(IPPROTO_TCP, TCP_NODELAY, int, 1) +#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, + TCPO(SOL_SOCKET, SO_LINGER, struct linger) + TCPO(SOL_SOCKET, SO_KEEPALIVE, int) #ifdef SO_SNDTIMEO_WORKS - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval, 0) + TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) #endif - #ifdef SO_RCVTIMEO_WORKS - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval, 0) + TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) #endif + TCPO(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int, 1) + TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) + TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) + TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif #undef TCPO @@ -229,7 +226,7 @@ vca_tcp_opt_test(const int sock, const unsigned uds) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; to->need = 1; ptr = calloc(1, to->sz); @@ -252,7 +249,7 @@ vca_tcp_opt_set(const int sock, const unsigned uds, const int force) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; if (to->need || force) { VTCP_Assert(setsockopt(sock, From nils.goroll at uplex.de Wed Nov 17 11:44:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:06 +0000 (UTC) Subject: [7.0] 1780645d1 vca: Rename tcp_opt to a more general sock_opt Message-ID: <20211117114406.C14EE635BB@lists.varnish-cache.org> commit 1780645d1a98a523b458cbf1d4f6ea2b24043b82 Author: Dridi Boukelmoune Date: Mon Sep 27 07:42:44 2021 +0200 vca: Rename tcp_opt to a more general sock_opt And conversely rename `to` variables to `so` for consistency. Better diff with the --word-diff --word-diff-regex='\w+' options. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index e55a262fd..a89f9e044 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -80,36 +80,36 @@ struct poolsock { * TCP options we want to control */ -static struct tcp_opt { +static struct sock_opt { int level; int optname; const char *strname; socklen_t sz; void *ptr; int need; -} tcp_opts[] = { -#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +} sock_opts[] = { +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, - TCPO(SOL_SOCKET, SO_LINGER, struct linger) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int) + SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) + SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) #ifdef SO_SNDTIMEO_WORKS - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_SNDTIMEO, struct timeval) #endif #ifdef SO_RCVTIMEO_WORKS - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_RCVTIMEO, struct timeval) #endif - TCPO(IPPROTO_TCP, TCP_NODELAY, int) + SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPIDLE, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPCNT, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif -#undef TCPO +#undef SOCK_OPT }; -static const int n_tcp_opts = sizeof tcp_opts / sizeof tcp_opts[0]; +static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast @@ -150,11 +150,11 @@ vca_periodic(vtim_real t0) */ static int -vca_tcp_opt_init(void) +vca_sock_opt_init(void) { int n; int one = 1; - struct tcp_opt *to; + struct sock_opt *so; struct timeval tv; int chg = 0; int x; @@ -162,54 +162,54 @@ vca_tcp_opt_init(void) memset(&tv, 0, sizeof tv); memset(&x, 0, sizeof x); - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->ptr == NULL) - to->ptr = calloc(1, to->sz); - AN(to->ptr); - if (!strcmp(to->strname, "SO_LINGER")) { - assert(to->sz == sizeof linger); - memcpy(to->ptr, &linger, sizeof linger); - to->need = 1; - } else if (!strcmp(to->strname, "TCP_NODELAY")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; - } else if (!strcmp(to->strname, "SO_KEEPALIVE")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; -#define NEW_VAL(to, xx) \ + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->ptr == NULL) + so->ptr = calloc(1, so->sz); + AN(so->ptr); + if (!strcmp(so->strname, "SO_LINGER")) { + assert(so->sz == sizeof linger); + memcpy(so->ptr, &linger, sizeof linger); + so->need = 1; + } else if (!strcmp(so->strname, "TCP_NODELAY")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; + } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; +#define NEW_VAL(so, xx) \ do { \ - assert(to->sz == sizeof xx); \ - if (memcmp(to->ptr, &(xx), sizeof xx)) { \ - memcpy(to->ptr, &(xx), sizeof xx); \ - to->need = 1; \ + assert(so->sz == sizeof xx); \ + if (memcmp(so->ptr, &(xx), sizeof xx)) { \ + memcpy(so->ptr, &(xx), sizeof xx); \ + so->need = 1; \ chg = 1; \ need_test = 1; \ } \ } while (0) #ifdef SO_SNDTIMEO_WORKS - } else if (!strcmp(to->strname, "SO_SNDTIMEO")) { + } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(to, tv); + NEW_VAL(so, tv); #endif #ifdef SO_RCVTIMEO_WORKS - } else if (!strcmp(to->strname, "SO_RCVTIMEO")) { + } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(to, tv); + NEW_VAL(so, tv); #endif #ifdef HAVE_TCP_KEEP - } else if (!strcmp(to->strname, "TCP_KEEPIDLE")) { + } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPCNT")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPINTVL")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(to, x); + NEW_VAL(so, x); #endif } } @@ -217,24 +217,24 @@ vca_tcp_opt_init(void) } static void -vca_tcp_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const int sock, const unsigned uds) { int i, n; - struct tcp_opt *to; + struct sock_opt *so; socklen_t l; void *ptr; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - to->need = 1; - ptr = calloc(1, to->sz); + so->need = 1; + ptr = calloc(1, so->sz); AN(ptr); - l = to->sz; - i = getsockopt(sock, to->level, to->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, to->ptr, to->sz)) - to->need = 0; + l = so->sz; + i = getsockopt(sock, so->level, so->optname, ptr, &l); + if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + so->need = 0; free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); @@ -242,18 +242,18 @@ vca_tcp_opt_test(const int sock, const unsigned uds) } static void -vca_tcp_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const int sock, const unsigned uds, const int force) { int n; - struct tcp_opt *to; + struct sock_opt *so; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - if (to->need || force) { + if (so->need || force) { VTCP_Assert(setsockopt(sock, - to->level, to->optname, to->ptr, to->sz)); + so->level, so->optname, so->ptr, so->sz)); } } } @@ -401,10 +401,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_tcp_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); need_test = 0; } - vca_tcp_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -590,13 +590,13 @@ vca_acct(void *arg) while (1) { (void)sleep(1); - if (vca_tcp_opt_init()) { + if (vca_sock_opt_init()) { AZ(pthread_mutex_lock(&shut_mtx)); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -616,7 +616,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; - (void)vca_tcp_opt_init(); + (void)vca_sock_opt_init(); VTAILQ_FOREACH(ls, &heritage.socks, list) { CHECK_OBJ_NOTNULL(ls->transport, TRANSPORT_MAGIC); @@ -632,7 +632,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, "Kernel filtering: sock=%d, errno=%d %s", From nils.goroll at uplex.de Wed Nov 17 11:44:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:06 +0000 (UTC) Subject: [7.0] 741c872c7 vca: Pass higher-level types to sock_opt functions Message-ID: <20211117114406.DA9F7635BF@lists.varnish-cache.org> commit 741c872c756e8ed665f2e0c395aaae6c6aa295b3 Author: Dridi Boukelmoune Date: Mon Sep 27 08:19:09 2021 +0200 vca: Pass higher-level types to sock_opt functions The sess and listen_sock structs contain everything we need to find or infer the former `sock`, `uds` and `force` arguments. In particular, it helps distinguish between working on a connection vs listen socket. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index a89f9e044..5669383ba 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -217,22 +217,25 @@ vca_sock_opt_init(void) } static void -vca_sock_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { int i, n; struct sock_opt *so; socklen_t l; void *ptr; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; ptr = calloc(1, so->sz); AN(ptr); l = so->sz; - i = getsockopt(sock, so->level, so->optname, ptr, &l); + i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) so->need = 0; free(ptr); @@ -242,16 +245,20 @@ vca_sock_opt_test(const int sock, const unsigned uds) } static void -vca_sock_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n; + int n, sock; struct sock_opt *so; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_ORNULL(sp, SESS_MAGIC); + sock = sp != NULL ? sp->fd : ls->sock; + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || force) { + if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, so->level, so->optname, so->ptr, so->sz)); } @@ -401,10 +408,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(wa->acceptlsock, sp); need_test = 0; } - vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(wa->acceptlsock, sp); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -596,7 +603,7 @@ vca_acct(void *arg) if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -632,7 +639,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, "Kernel filtering: sock=%d, errno=%d %s", From nils.goroll at uplex.de Wed Nov 17 11:44:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:06 +0000 (UTC) Subject: [7.0] 763cc6ef0 vca: Eliminate heap allocations of sock_opt arguments Message-ID: <20211117114406.F21D7635C4@lists.varnish-cache.org> commit 763cc6ef0eaa5d805b4b25f4a495d34c9234f919 Author: Dridi Boukelmoune Date: Mon Sep 27 11:41:27 2021 +0200 vca: Eliminate heap allocations of sock_opt arguments They can be stored directly in the sock_opts array or on the stack. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 5669383ba..3a884f09e 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -80,15 +80,21 @@ struct poolsock { * TCP options we want to control */ +union sock_arg { + struct linger lg; + struct timeval tv; + int i; +}; + static struct sock_opt { int level; int optname; const char *strname; - socklen_t sz; - void *ptr; int need; + socklen_t sz; + union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -155,35 +161,30 @@ vca_sock_opt_init(void) int n; int one = 1; struct sock_opt *so; - struct timeval tv; + union sock_arg tmp; int chg = 0; - int x; - memset(&tv, 0, sizeof tv); - memset(&x, 0, sizeof x); + memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->ptr == NULL) - so->ptr = calloc(1, so->sz); - AN(so->ptr); if (!strcmp(so->strname, "SO_LINGER")) { assert(so->sz == sizeof linger); - memcpy(so->ptr, &linger, sizeof linger); + memcpy(so->arg, &linger, sizeof linger); so->need = 1; } else if (!strcmp(so->strname, "TCP_NODELAY")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; #define NEW_VAL(so, xx) \ do { \ assert(so->sz == sizeof xx); \ - if (memcmp(so->ptr, &(xx), sizeof xx)) { \ - memcpy(so->ptr, &(xx), sizeof xx); \ + if (memcmp(so->arg, &(xx), sizeof xx)) { \ + memcpy(so->arg, &(xx), sizeof xx); \ so->need = 1; \ chg = 1; \ need_test = 1; \ @@ -192,24 +193,24 @@ vca_sock_opt_init(void) #ifdef SO_SNDTIMEO_WORKS } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); + NEW_VAL(so, tmp.tv); #endif #ifdef SO_RCVTIMEO_WORKS } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->timeout_idle); + NEW_VAL(so, tmp.tv); #endif #ifdef HAVE_TCP_KEEP } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_time); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_probes); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_intvl); + NEW_VAL(so, tmp.i); #endif } } @@ -219,10 +220,10 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { - int i, n; struct sock_opt *so; + union sock_arg tmp; socklen_t l; - void *ptr; + int i, n; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -232,13 +233,11 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; - ptr = calloc(1, so->sz); - AN(ptr); + memset(&tmp, 0, sizeof tmp); l = so->sz; - i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); + if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) so->need = 0; - free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -247,8 +246,8 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n, sock; struct sock_opt *so; + int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_ORNULL(sp, SESS_MAGIC); @@ -260,7 +259,7 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) continue; if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->ptr, so->sz)); + so->level, so->optname, so->arg, so->sz)); } } } From nils.goroll at uplex.de Wed Nov 17 11:44:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:07 +0000 (UTC) Subject: [7.0] 32ae04135 vca: Generalize the sock options test Message-ID: <20211117114407.17CAB635CB@lists.varnish-cache.org> commit 32ae0413568782dea8d4f6e9eb66d7bac7b58f8d Author: Dridi Boukelmoune Date: Mon Sep 27 12:11:53 2021 +0200 vca: Generalize the sock options test Using the tmp sock_arg for storage, we can test all values with the same logic and only differentiate hard-coded options from parameterized ones. Stylistic polish by @mbgrydeland. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 3a884f09e..9d1250412 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -158,61 +158,58 @@ vca_periodic(vtim_real t0) static int vca_sock_opt_init(void) { - int n; - int one = 1; struct sock_opt *so; union sock_arg tmp; - int chg = 0; + int n, chg = 0; + size_t sz; memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (!strcmp(so->strname, "SO_LINGER")) { - assert(so->sz == sizeof linger); - memcpy(so->arg, &linger, sizeof linger); - so->need = 1; - } else if (!strcmp(so->strname, "TCP_NODELAY")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; - } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; -#define NEW_VAL(so, xx) \ - do { \ - assert(so->sz == sizeof xx); \ - if (memcmp(so->arg, &(xx), sizeof xx)) { \ - memcpy(so->arg, &(xx), sizeof xx); \ - so->need = 1; \ - chg = 1; \ - need_test = 1; \ - } \ + +#define SET_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + assert(so->sz == sizeof so->arg->fld); \ + so->arg->fld = (val); \ + } \ + } while (0) + +#define NEW_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + sz = sizeof tmp.fld; \ + assert(so->sz == sz); \ + tmp.fld = (val); \ + if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ + memcpy(&so->arg->fld, &(tmp.fld), sz); \ + so->need = 1; \ + chg = 1; \ + need_test = 1; \ + } \ + } \ } while (0) + SET_VAL(SO_LINGER, so, lg, linger); + SET_VAL(SO_KEEPALIVE, so, i, 1); #ifdef SO_SNDTIMEO_WORKS - } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tmp.tv); + NEW_VAL(SO_SNDTIMEO, so, tv, + VTIM_timeval(cache_param->idle_send_timeout)); #endif #ifdef SO_RCVTIMEO_WORKS - } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tmp.tv); + NEW_VAL(SO_RCVTIMEO, so, tv, + VTIM_timeval(cache_param->timeout_idle)); #endif #ifdef HAVE_TCP_KEEP - } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - tmp.i = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - tmp.i = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - tmp.i = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, tmp.i); + SET_VAL(TCP_NODELAY, so, i, 1); + NEW_VAL(TCP_KEEPIDLE, so, i, + (int)cache_param->tcp_keepalive_time); + NEW_VAL(TCP_KEEPCNT, so, i, + (int)cache_param->tcp_keepalive_probes); + NEW_VAL(TCP_KEEPINTVL, so, i, + (int)cache_param->tcp_keepalive_intvl); #endif - } } return (chg); } From nils.goroll at uplex.de Wed Nov 17 11:44:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:07 +0000 (UTC) Subject: [7.0] 439f2619e vca: Give all const socket options placeholers Message-ID: <20211117114407.2E8D6635D9@lists.varnish-cache.org> commit 439f2619ee996506a7c4d1ee5c3eda1f99884cb5 Author: Dridi Boukelmoune Date: Mon Sep 27 12:42:54 2021 +0200 vca: Give all const socket options placeholers The SO_KEEPALIVE justification used to precede such a constant and was left confusingly lingering over the unrelated need_test variable. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 9d1250412..9df90387b 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -132,6 +132,13 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ +static const unsigned so_keepalive = 1; + +/* We disable Nagle's algorithm in favor of low latency setups. + */ + +static const unsigned tcp_nodelay = 1; + static unsigned need_test; /*-------------------------------------------------------------------- @@ -192,7 +199,7 @@ vca_sock_opt_init(void) } while (0) SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, 1); + SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); #ifdef SO_SNDTIMEO_WORKS NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); @@ -201,8 +208,8 @@ vca_sock_opt_init(void) NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); #endif + SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); #ifdef HAVE_TCP_KEEP - SET_VAL(TCP_NODELAY, so, i, 1); NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); NEW_VAL(TCP_KEEPCNT, so, i, From nils.goroll at uplex.de Wed Nov 17 11:44:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:07 +0000 (UTC) Subject: [7.0] 58ac9f834 vca: Give sock_opt constant arguments better names Message-ID: <20211117114407.4A4E2635E8@lists.varnish-cache.org> commit 58ac9f8347c834dd111555cf49a62d0736c868e1 Author: Dridi Boukelmoune Date: Mon Sep 27 13:17:55 2021 +0200 vca: Give sock_opt constant arguments better names And while at it, update the SO_LINGER explanation to match reality. Refs 7eba94605b9f Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 9df90387b..a15461a54 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -119,11 +119,11 @@ static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast - * as absolutely possible, so we set them LINGER enabled with zero timeout, - * so that even if there are outstanding write data on the socket, a close(2) - * will return immediately. + * as absolutely possible, so we set them LINGER disabled, so that even if + * there are outstanding write data on the socket, a close(2) will return + * immediately. */ -static const struct linger linger = { +static const struct linger disable_so_linger = { .l_onoff = 0, }; @@ -132,12 +132,12 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ -static const unsigned so_keepalive = 1; +static const unsigned enable_so_keepalive = 1; /* We disable Nagle's algorithm in favor of low latency setups. */ -static const unsigned tcp_nodelay = 1; +static const unsigned enable_tcp_nodelay = 1; static unsigned need_test; @@ -198,8 +198,8 @@ vca_sock_opt_init(void) } \ } while (0) - SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); + SET_VAL(SO_LINGER, so, lg, disable_so_linger); + SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); #ifdef SO_SNDTIMEO_WORKS NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); @@ -208,7 +208,7 @@ vca_sock_opt_init(void) NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); #endif - SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); + SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #ifdef HAVE_TCP_KEEP NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); From nils.goroll at uplex.de Wed Nov 17 11:44:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:07 +0000 (UTC) Subject: [7.0] 9c6f6043f vca: Have one inheritance check per listen socket Message-ID: <20211117114407.6313B635F3@lists.varnish-cache.org> commit 9c6f6043fc6a7920100f495793790e7fb311ee89 Author: Dridi Boukelmoune Date: Mon Sep 27 14:53:56 2021 +0200 vca: Have one inheritance check per listen socket Instead of having a single global check that all acceptors may race towards, this check now happens on a per listen socket basis. For sockets with a different inheritance behavior on a single system, we avoid having the first connection dictate what may be inherited by a connection socket from its listen socket for all the other listen addresses. At least on Linux, Unix-domain sockets DO NOT inherit options like SO_{RCV,SND}TIMEO even though TCP sockets do. On the off chance that even sockets of the same family could behave differently, like for example a regular vs a loopback TCP session, this is done on a per listen address basis. To avoid cache-acceptor coordination with the acceptor worker threads of a given listen address, workers will individually perform this check once and for all when the first connection is accepted. We also stay defensive in the event of a parameter change, just in case a previous test would assume inheritance because the Varnish parameter value would match the kernel default value. Once a mismatch is observed for a given connection with a given socket, the inheritance test is no longer performed needlessly for this combination. A race still exists between acceptors from different thread pools for a given listen address, but this race is identical to the previous one based on the former global need_test variable. Although the inheritance check leaks into struct listen_sock, it is opaque so everything can remain contained inside cache_acceptor.c. Some aspects of this change (including the clarification comments) are from @mbgrydeland. Refs #2722 diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index a15461a54..d00725c0b 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -90,11 +90,13 @@ static struct sock_opt { int level; int optname; const char *strname; - int need; + unsigned mod; socklen_t sz; union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, + /* Note: Setting the mod counter to something not-zero is needed + * to force the setsockopt() calls on startup */ +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 1, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -117,6 +119,11 @@ static struct sock_opt { static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; +struct conn_heritage { + unsigned sess_set; + unsigned listen_mod; +}; + /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast * as absolutely possible, so we set them LINGER disabled, so that even if @@ -139,8 +146,6 @@ static const unsigned enable_so_keepalive = 1; static const unsigned enable_tcp_nodelay = 1; -static unsigned need_test; - /*-------------------------------------------------------------------- * lacking a better place, we put some generic periodic updates * into the vca_acct() loop which we are running anyway @@ -191,9 +196,8 @@ vca_sock_opt_init(void) tmp.fld = (val); \ if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ memcpy(&so->arg->fld, &(tmp.fld), sz); \ - so->need = 1; \ + so->mod++; \ chg = 1; \ - need_test = 1; \ } \ } \ } while (0) @@ -224,6 +228,7 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; union sock_arg tmp; socklen_t l; @@ -234,14 +239,16 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; + if (ch->sess_set) + continue; /* Already set, no need to retest */ if (so->level == IPPROTO_TCP && ls->uds) continue; - so->need = 1; memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) - so->need = 0; + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + ch->sess_set = 1; if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -250,6 +257,7 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; int n, sock; @@ -259,12 +267,17 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || sp == NULL) { - VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->arg, so->sz)); - } + if (sp == NULL && ch->listen_mod == so->mod) + continue; + if (sp != NULL && !ch->sess_set) + continue; + VTCP_Assert(setsockopt(sock, + so->level, so->optname, so->arg, so->sz)); + if (sp == NULL) + ch->listen_mod = so->mod; } } @@ -410,9 +423,9 @@ vca_make_session(struct worker *wrk, void *arg) vca_pace_good(); wrk->stats->sess_conn++; - if (need_test) { + if (wa->acceptlsock->test_heritage) { vca_sock_opt_test(wa->acceptlsock, sp); - need_test = 0; + wa->acceptlsock->test_heritage = 0; } vca_sock_opt_set(wa->acceptlsock, sp); @@ -607,6 +620,17 @@ vca_acct(void *arg) continue; // VCA_Shutdown assert (ls->sock > 0); vca_sock_opt_set(ls, NULL); + /* If one of the options on a socket has + * changed, also force a retest of whether + * the values are inherited to the + * accepted sockets. This should then + * catch any false positives from previous + * tests that could happen if the set + * value of an option happened to just be + * the OS default for that value, and + * wasn't actually inherited from the + * listening socket. */ + ls->test_heritage = 1; } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -642,6 +666,11 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } + AZ(ls->conn_heritage); + ls->conn_heritage = calloc(n_sock_opts, + sizeof *ls->conn_heritage); + AN(ls->conn_heritage); + ls->test_heritage = 1; vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, @@ -649,8 +678,6 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->sock, errno, VAS_errtxt(errno)); } - need_test = 1; - AZ(pthread_create(&VCA_thread, NULL, vca_acct, NULL)); } diff --git a/bin/varnishd/common/heritage.h b/bin/varnishd/common/heritage.h index f2b2e448f..8244f8046 100644 --- a/bin/varnishd/common/heritage.h +++ b/bin/varnishd/common/heritage.h @@ -37,6 +37,7 @@ struct listen_sock; struct transport; struct VCLS; struct uds_perms; +struct conn_heritage; struct listen_sock { unsigned magic; @@ -50,6 +51,8 @@ struct listen_sock { struct suckaddr *addr; const struct transport *transport; const struct uds_perms *perms; + unsigned test_heritage; + struct conn_heritage *conn_heritage; }; VTAILQ_HEAD(listen_sock_head, listen_sock); diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc new file mode 100644 index 000000000..e8a4eef61 --- /dev/null +++ b/bin/varnishtest/tests/r02722.vtc @@ -0,0 +1,37 @@ +varnishtest "TCP vs UDS sockopt inheritance" + +feature cmd {test $(uname) != SunOS} + +server s0 { + rxreqhdrs + non_fatal + rxreqbody + txresp +} -dispatch + +varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -cliok "param.set debug +flush_head" +varnish v1 -cliok "param.set timeout_idle 1" +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -req POST -hdr "Content-Length: 100" + send some + rxresp + expect resp.status == 503 +} + +# This run performs the inheritance test on a TCP connection +client c1 -run + +# This run relies on the inheritance test results +client c1 -run + +varnish v1 -vsl_catchup + +# This run checks that TCP results aren't applied to a UDS +client c1 -connect "${tmpdir}/v1.sock" +client c1 -run + +# And finally this run checks UDS inheritance test results +client c1 -run From nils.goroll at uplex.de Wed Nov 17 11:44:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 17 Nov 2021 11:44:07 +0000 (UTC) Subject: [7.0] 6093812b2 vca: Log the outcome of sockopt inheritance Message-ID: <20211117114407.7A8B9635F8@lists.varnish-cache.org> commit 6093812b22b2f09e99b4e1560d0aa6e275a4795b Author: Dridi Boukelmoune Date: Mon Nov 15 12:31:02 2021 +0100 vca: Log the outcome of sockopt inheritance diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index d00725c0b..2eaadb228 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -240,15 +240,27 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (ch->sess_set) - continue; /* Already set, no need to retest */ - if (so->level == IPPROTO_TCP && ls->uds) + if (ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing nonhereditary %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); + continue; + } memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Test confirmed %s non heredity for %s=%s", + so->strname, ls->name, ls->endpoint); ch->sess_set = 1; + } if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -259,21 +271,44 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { struct conn_heritage *ch; struct sock_opt *so; + unsigned vxid; int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); - CHECK_OBJ_ORNULL(sp, SESS_MAGIC); - sock = sp != NULL ? sp->fd : ls->sock; + + if (sp != NULL) { + CHECK_OBJ(sp, SESS_MAGIC); + sock = sp->fd; + vxid = sp->vxid; + } else { + sock = ls->sock; + vxid = 0; + } for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (so->level == IPPROTO_TCP && ls->uds) + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp == NULL && ch->listen_mod == so->mod) + } + if (sp == NULL && ch->listen_mod == so->mod) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting unmodified %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp != NULL && !ch->sess_set) + } + if (sp != NULL && !ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: %s may be inherited for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + VSL(SLT_Debug, vxid, + "sockopt: Setting %s for %s=%s", + so->strname, ls->name, ls->endpoint); VTCP_Assert(setsockopt(sock, so->level, so->optname, so->arg, so->sz)); if (sp == NULL) diff --git a/bin/varnishtest/tests/l00000.vtc b/bin/varnishtest/tests/l00000.vtc index 1c732fc47..e7e316ccf 100644 --- a/bin/varnishtest/tests/l00000.vtc +++ b/bin/varnishtest/tests/l00000.vtc @@ -11,7 +11,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g session { expect 0 1000 Begin sess expect 0 = SessOpen - expect 0 = Link "req 1001" + expect * = Link "req 1001" expect 0 = SessClose expect 0 = End diff --git a/bin/varnishtest/tests/o00001.vtc b/bin/varnishtest/tests/o00001.vtc index 5a6b35913..ebe38bcb9 100644 --- a/bin/varnishtest/tests/o00001.vtc +++ b/bin/varnishtest/tests/o00001.vtc @@ -74,7 +74,7 @@ logexpect l1 -v v1 -g raw { expect * 1016 Proxy "2 1.2.3.4 2314 5.6.7.8 2828" expect * 1019 Proxy "2 102:304:506::d0e:f10 2314 8182:8384:8586::8d8e:8f80 2828" expect * 1022 Begin "^sess 0 PROXY" - expect 1 1022 SessClose "^RX_OVERFLOW" + expect * 1022 SessClose "^RX_OVERFLOW" } -start client c1 { diff --git a/bin/varnishtest/tests/o00006.vtc b/bin/varnishtest/tests/o00006.vtc index 5f7eb4638..e8adecb7c 100644 --- a/bin/varnishtest/tests/o00006.vtc +++ b/bin/varnishtest/tests/o00006.vtc @@ -12,7 +12,7 @@ varnish v1 -arg "-p pool_sess=0,0,0" -proto "PROXY" -vcl+backend {} -start logexpect l1 -v v1 -g raw { expect 0 1000 Begin "sess 0 PROXY" expect 0 = SessOpen - expect 0 = Proxy "2 217.70.181.33 60822 95.142.168.34 443" + expect * = Proxy "2 217.70.181.33 60822 95.142.168.34 443" expect 0 = Error {\Qinsufficient workspace (proto_priv)\E} expect 0 = SessClose "RX_JUNK" } -start diff --git a/bin/varnishtest/tests/r01804.vtc b/bin/varnishtest/tests/r01804.vtc index 252dd5845..d50bf9558 100644 --- a/bin/varnishtest/tests/r01804.vtc +++ b/bin/varnishtest/tests/r01804.vtc @@ -13,7 +13,7 @@ varnish v1 -vcl+backend "" -start logexpect l1 -v v1 -g session { expect * 1000 Begin {^sess .* PROXY$} expect 0 = SessOpen {^.* foo .*} - expect 0 = Proxy {^1 } + expect * = Proxy {^1 } expect * 1001 Begin {^req} } -start @@ -28,7 +28,7 @@ logexpect l1 -wait logexpect l2 -v v1 -g session { expect * 1003 Begin {^sess .* PROXY$} expect 0 = SessOpen {^.* foo .*} - expect 0 = Proxy {^2 } + expect * = Proxy {^2 } expect * 1004 Begin {^req} } -start diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc index e8a4eef61..1268864b5 100644 --- a/bin/varnishtest/tests/r02722.vtc +++ b/bin/varnishtest/tests/r02722.vtc @@ -9,7 +9,7 @@ server s0 { txresp } -dispatch -varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -arg {-a TCP=:0 -a "UDS=${tmpdir}/v1.sock"} varnish v1 -cliok "param.set debug +flush_head" varnish v1 -cliok "param.set timeout_idle 1" varnish v1 -vcl+backend { } -start From dridi.boukelmoune at gmail.com Wed Nov 17 12:10:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 17 Nov 2021 12:10:07 +0000 (UTC) Subject: [7.0] 254faf07a build: Simply require that SO_???TIMEO are present Message-ID: <20211117121007.1F9466505E@lists.varnish-cache.org> commit 254faf07a80efc5174d520dd42c5cca269b36fd8 Author: Dridi Boukelmoune Date: Wed Sep 22 19:46:18 2021 +0200 build: Simply require that SO_???TIMEO are present Closes #3692 Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 2eaadb228..53763156b 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -100,12 +100,8 @@ static struct sock_opt { SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) -#ifdef SO_SNDTIMEO_WORKS SOCK_OPT(SOL_SOCKET, SO_SNDTIMEO, struct timeval) -#endif -#ifdef SO_RCVTIMEO_WORKS SOCK_OPT(SOL_SOCKET, SO_RCVTIMEO, struct timeval) -#endif SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP @@ -204,14 +200,10 @@ vca_sock_opt_init(void) SET_VAL(SO_LINGER, so, lg, disable_so_linger); SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); -#ifdef SO_SNDTIMEO_WORKS NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); -#endif -#ifdef SO_RCVTIMEO_WORKS NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); -#endif SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #ifdef HAVE_TCP_KEEP NEW_VAL(TCP_KEEPIDLE, so, i, diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 2b05aac01..2294e742c 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -1000,14 +1000,9 @@ HTTP_VAR(beresp) static inline void set_idle_send_timeout(const struct sess *sp, VCL_DURATION d) { -#ifdef SO_SNDTIMEO_WORKS struct timeval tv = VTIM_timeval(d); VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv)); -#else - (void)sp; - (void)d; -#endif } #define SESS_VAR_DUR(x, setter) \ diff --git a/bin/varnishtest/tests/b00020.vtc b/bin/varnishtest/tests/b00020.vtc index 1f0427c11..fc7c7c2d8 100644 --- a/bin/varnishtest/tests/b00020.vtc +++ b/bin/varnishtest/tests/b00020.vtc @@ -1,7 +1,5 @@ varnishtest "Check that between_bytes_timeout behaves from parameters" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00021.vtc b/bin/varnishtest/tests/b00021.vtc index 46be8cb4f..f0c4c0ce2 100644 --- a/bin/varnishtest/tests/b00021.vtc +++ b/bin/varnishtest/tests/b00021.vtc @@ -1,7 +1,5 @@ varnishtest "Check the between_bytes_timeout behaves from vcl" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00022.vtc b/bin/varnishtest/tests/b00022.vtc index 7bf6d9575..fee5db3d9 100644 --- a/bin/varnishtest/tests/b00022.vtc +++ b/bin/varnishtest/tests/b00022.vtc @@ -1,7 +1,5 @@ varnishtest "Check the between_bytes_timeout behaves from backend definition" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00023.vtc b/bin/varnishtest/tests/b00023.vtc index fd64cb2bd..5948d6bef 100644 --- a/bin/varnishtest/tests/b00023.vtc +++ b/bin/varnishtest/tests/b00023.vtc @@ -1,7 +1,5 @@ varnishtest "Check that the first_byte_timeout works" -feature SO_RCVTIMEO_WORKS - # From VCL server s1 { diff --git a/bin/varnishtest/tests/b00026.vtc b/bin/varnishtest/tests/b00026.vtc index 48fce004b..e12676985 100644 --- a/bin/varnishtest/tests/b00026.vtc +++ b/bin/varnishtest/tests/b00026.vtc @@ -1,7 +1,5 @@ varnishtest "Check the precedence for timeouts" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq expect req.url == "from_backend" diff --git a/bin/varnishtest/tests/s00010.vtc b/bin/varnishtest/tests/s00010.vtc index fea3ea89d..f9e0bbb15 100644 --- a/bin/varnishtest/tests/s00010.vtc +++ b/bin/varnishtest/tests/s00010.vtc @@ -3,8 +3,6 @@ varnishtest "client h1 send timeouts - tcp" # XXX See https://github.com/varnishcache/varnish-cache/pull/2980#issuecomment-486214661 feature cmd {test $(uname) != "SunOS" && test $(uname) != "Darwin"} -feature SO_RCVTIMEO_WORKS - barrier b1 cond 2 -cyclic barrier b2 cond 2 -cyclic diff --git a/bin/varnishtest/tests/s00012.vtc b/bin/varnishtest/tests/s00012.vtc index 9726f050f..e635ad03d 100644 --- a/bin/varnishtest/tests/s00012.vtc +++ b/bin/varnishtest/tests/s00012.vtc @@ -2,8 +2,6 @@ varnishtest "client h1 send timeouts - uds" feature cmd {test $(uname) != "SunOS"} -feature SO_RCVTIMEO_WORKS - server s1 { rxreq txresp -bodylen 100000 diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c index ac5f6df96..7ff023017 100644 --- a/bin/varnishtest/vtc_misc.c +++ b/bin/varnishtest/vtc_misc.c @@ -410,8 +410,6 @@ addr_no_randomize_works(void) * the test otherwise; or change the interpretation of the test, as * documented below. feature takes any number of arguments from this list: * - * SO_RCVTIMEO_WORKS - * The SO_RCVTIMEO socket option is working * 64bit * The environment is 64 bits * ipv4 @@ -508,12 +506,6 @@ static const unsigned with_persistent_storage = 1; static const unsigned with_persistent_storage = 0; #endif -#ifdef SO_RCVTIMEO_WORKS -static const unsigned so_rcvtimeo_works = 1; -#else -static const unsigned so_rcvtimeo_works = 0; -#endif - void v_matchproto_(cmd_f) cmd_feature(CMD_ARGS) { @@ -566,7 +558,6 @@ cmd_feature(CMD_ARGS) FEATURE("tsan", tsan); FEATURE("ubsan", ubsan); FEATURE("sanitizer", sanitizer); - FEATURE("SO_RCVTIMEO_WORKS", so_rcvtimeo_works); FEATURE("workspace_emulator", workspace_emulator); if (!strcmp(feat, "cmd")) { diff --git a/configure.ac b/configure.ac index 162a26d48..d9760807e 100644 --- a/configure.ac +++ b/configure.ac @@ -532,91 +532,24 @@ AC_CHECK_MEMBER([struct sockaddr.sa_len], AC_CHECK_DECL([SO_ACCEPTFILTER], AC_DEFINE(HAVE_ACCEPT_FILTERS,1,[Define to 1 if you have accept filters]), - , - [ -#include -#include - ] -) - -# Older Solaris versions define SO_{RCV,SND}TIMEO, but do not -# implement them. -# -# Varnish will build and run without these, but connections will not -# time out, which may leave Varnish vulnerable to denial-of-service -# attacks which would not be possible on other platforms. -# -# Newer Solaris releases with the Volo framework (Solaris 11, -# Opensolaris starting with onnv_106) do support SO_{RCV,SND}TIMEO -# (see PSARC 2007/587, initially committed into onnv-gate / -# OpenSolaris 8348:4137e18bfaf0 Thu Dec 11 20:04:13 2008) - -save_LIBS="${LIBS}" -LIBS="${LIBS} ${NET_LIBS}" -AC_CACHE_CHECK([whether SO_RCVTIMEO works], - [ac_cv_so_rcvtimeo_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include - ]],[[ -int s = socket(AF_INET, SOCK_STREAM, 0); -struct timeval tv = { 1, 0 }; -if (s < 0 && errno == EPROTONOSUPPORT) - s = socket(AF_INET6, SOCK_STREAM, 0); -if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) == 0) { - socklen_t l = sizeof tv; - if (getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, &l) == 0) { - return (l != sizeof tv); - } -} -return 1; - ]])], - [ac_cv_so_rcvtimeo_works=yes], - [ac_cv_so_rcvtimeo_works=no]) - ]) -if test "$ac_cv_so_rcvtimeo_works" = yes; then - AC_DEFINE([SO_RCVTIMEO_WORKS], [1], [Define if SO_RCVTIMEO works]) -fi -LIBS="${save_LIBS}" + [], [ + #include + #include + ]) -save_LIBS="${LIBS}" -LIBS="${LIBS} ${NET_LIBS}" -AC_CACHE_CHECK([whether SO_SNDTIMEO works], - [ac_cv_so_sndtimeo_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include - ]],[[ -int s = socket(AF_INET, SOCK_STREAM, 0); -struct timeval tv = { 1, 0 }; -if (s < 0 && errno == EPROTONOSUPPORT) - s = socket(AF_INET6, SOCK_STREAM, 0); -if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) == 0) { - socklen_t l = sizeof tv; - if (getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, &l) == 0) { - return (l != sizeof tv); - } -} -return 1; - ]])], - [ac_cv_so_sndtimeo_works=yes], - [ac_cv_so_sndtimeo_works=no]) - ]) -if test "$ac_cv_so_sndtimeo_works" = yes; then - AC_DEFINE([SO_SNDTIMEO_WORKS], [1], [Define if SO_SNDTIMEO works]) -fi +AC_CHECK_DECL([SO_RCVTIMEO], + [], + AC_MSG_ERROR([SO_RCVTIMEO is needed to build Varnish.]), [ + #include + #include + ]) -if test "$ac_cv_so_rcvtimeo_works" = no || - test "$ac_cv_so_sndtimeo_works" = no; then - AC_MSG_WARN([connection timeouts will not work]) -fi -LIBS="${save_LIBS}" +AC_CHECK_DECL([SO_SNDTIMEO], + [], + AC_MSG_ERROR([SO_SNDTIMEO is needed to build Varnish.]), [ + #include + #include + ]) # Check if the OS supports TCP_KEEP(CNT|IDLE|INTVL) socket options save_LIBS="${LIBS}" diff --git a/include/tbl/params.h b/include/tbl/params.h index 8f3eaf8d4..9a94e75c4 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -610,11 +610,6 @@ PARAM_SIMPLE( "of that the response is allowed to take up." ) -#if defined(SO_SNDTIMEO_WORKS) -# define PLATFORM_FLAGS DELAYED_EFFECT -#else -# define PLATFORM_FLAGS NOT_IMPLEMENTED -#endif PARAM_SIMPLE( /* name */ idle_send_timeout, /* type */ timeout, @@ -628,9 +623,8 @@ PARAM_SIMPLE( "When this timeout is hit, the session is closed.\n\n" "See the man page for `setsockopt(2)` or `socket(7)` under" " ``SO_SNDTIMEO`` for more information.", - /* flags */ PLATFORM_DEPENDENT | PLATFORM_FLAGS + /* flags */ DELAYED_EFFECT ) -#undef PLATFORM_FLAGS PARAM_SIMPLE( /* name */ listen_depth, @@ -781,11 +775,6 @@ PARAM_SIMPLE( /* flags */ EXPERIMENTAL ) -#if defined(SO_SNDTIMEO_WORKS) -# define PLATFORM_FLAGS DELAYED_EFFECT -#else -# define PLATFORM_FLAGS NOT_IMPLEMENTED -#endif PARAM_SIMPLE( /* name */ send_timeout, /* type */ timeout, @@ -800,9 +789,8 @@ PARAM_SIMPLE( " timeout is extended unless the total time already taken for sending" " the response in its entirety exceeds this many seconds.\n\n" "When this timeout is hit, the session is closed", - /* flags */ PLATFORM_DEPENDENT | PLATFORM_FLAGS + /* flags */ DELAYED_EFFECT ) -#undef PLATFORM_FLAGS PARAM_SIMPLE( /* name */ shortlived, @@ -914,11 +902,6 @@ PARAM_SIMPLE( ) #undef PLATFORM_FLAGS -#if defined(SO_RCVTIMEO_WORKS) -# define PLATFORM_FLAGS 0 -#else -# define PLATFORM_FLAGS NOT_IMPLEMENTED -#endif PARAM_SIMPLE( /* name */ timeout_idle, /* type */ timeout, @@ -932,10 +915,8 @@ PARAM_SIMPLE( " request headers.\n\n" "This parameter is particularly relevant for HTTP1 keepalive " " connections which are closed unless the next request is received" - " before this timeout is reached.", - /* flags */ PLATFORM_DEPENDENT | PLATFORM_FLAGS + " before this timeout is reached." ) -#undef PLATFORM_FLAGS PARAM_SIMPLE( /* name */ timeout_linger, diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index 9e43f5da0..6c1d154a2 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -349,8 +349,8 @@ VTCP_close(int *s) void VTCP_set_read_timeout(int s, vtim_dur seconds) { -#ifdef SO_RCVTIMEO_WORKS struct timeval timeout = VTIM_timeval(seconds); + /* * Solaris bug (present at least in snv_151 and older): If this fails * with EINVAL, the socket is half-closed (SS_CANTSENDMORE) and the @@ -359,10 +359,6 @@ VTCP_set_read_timeout(int s, vtim_dur seconds) */ VTCP_Assert(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); -#else - (void)s; - (void)seconds; -#endif } /*-------------------------------------------------------------------- From phk at FreeBSD.org Fri Nov 19 09:59:11 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 19 Nov 2021 09:59:11 +0000 (UTC) Subject: [master] a2ae115af Somebody forgot LIBUNWIND_CFLAGS Message-ID: <20211119095911.280B36E829@lists.varnish-cache.org> commit a2ae115afd4689fdf74ec587e8058a09df24f4f1 Author: Poul-Henning Kamp Date: Fri Nov 19 09:58:27 2021 +0000 Somebody forgot LIBUNWIND_CFLAGS diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 0e564a9bc..94ba2f436 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -185,7 +185,7 @@ varnishd_LDADD = \ ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} if WITH_UNWIND -varnishd_CFLAGS += -DUNW_LOCAL_ONLY +varnishd_CFLAGS += -DUNW_LOCAL_ONLY ${LIBUNWIND_CFLAGS} varnishd_LDADD += ${LIBUNWIND_LIBS} endif From dridi.boukelmoune at gmail.com Fri Nov 19 10:06:10 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 10:06:10 +0000 (UTC) Subject: [6.0] 2de3203d0 Fix base64 decoding for length= argument and non-padding decoding Message-ID: <20211119100610.42FCD6EDCB@lists.varnish-cache.org> commit 2de3203d0b3f133637e834ebb03ee462c3d84212 Author: Nils Goroll Date: Thu Aug 6 17:10:33 2020 +0200 Fix base64 decoding for length= argument and non-padding decoding When decoding only a substring, we naturally see no padding, so we must not base tail processing on the number of pad characters seen, but rather on the number of characters missing until the end of the current block of four. Fixes #3378 diff --git a/bin/varnishtest/tests/m00042.vtc b/bin/varnishtest/tests/m00042.vtc index 6e6004f63..34bf497c5 100644 --- a/bin/varnishtest/tests/m00042.vtc +++ b/bin/varnishtest/tests/m00042.vtc @@ -263,7 +263,7 @@ client c1 { expect resp.http.hexmix2hexlc == resp.http.hexmix2hex expect resp.http.hexparam == "0123456789" expect resp.http.b642b64 == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij" - expect resp.http.b64url2b64url == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefeQ==" + expect resp.http.b64url2b64url == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgg==" expect resp.http.b64urlnopad2b64urlnopad == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgg" } -run diff --git a/lib/libvmod_blob/base64.c b/lib/libvmod_blob/base64.c index 20a4ac877..1dea4c5e3 100644 --- a/lib/libvmod_blob/base64.c +++ b/lib/libvmod_blob/base64.c @@ -185,7 +185,7 @@ base64_decode(const enum encoding dec, char *restrict const buf, } } if (n) { - if (!alpha->padding) + if (n - term != 0) u <<= (6 * (4 - n)); if (decode(&dest, buf, buflen, u, n-term) < 0) return -1; From dridi.boukelmoune at gmail.com Fri Nov 19 10:06:10 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 10:06:10 +0000 (UTC) Subject: [6.0] a10584cd8 Somebody forgot LIBUNWIND_CFLAGS Message-ID: <20211119100610.498D46EDCC@lists.varnish-cache.org> commit a10584cd8cf54bc719c618137a2e91491ec542e4 Author: Poul-Henning Kamp Date: Fri Nov 19 09:58:27 2021 +0000 Somebody forgot LIBUNWIND_CFLAGS diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index bd7bce594..a1f870826 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -174,7 +174,7 @@ varnishd_LDADD = \ ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} if WITH_UNWIND -varnishd_CFLAGS += -DUNW_LOCAL_ONLY +varnishd_CFLAGS += -DUNW_LOCAL_ONLY ${LIBUNWIND_CFLAGS} varnishd_LDADD += ${LIBUNWIND_LIBS} endif From dridi.boukelmoune at gmail.com Fri Nov 19 10:33:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 10:33:09 +0000 (UTC) Subject: [6.0] f7715a8dc mac: Add brackets around IPv6 endpoints Message-ID: <20211119103309.1BDE4100C4F@lists.varnish-cache.org> commit f7715a8dc70bda38548c54c24d4aefc65fd96b8b Author: Dridi Boukelmoune Date: Mon Nov 15 12:44:59 2021 +0100 mac: Add brackets around IPv6 endpoints diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 2d04e6089..bb8c29484 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -201,7 +201,10 @@ mac_tcp(void *priv, const struct suckaddr *sa) ls->addr = VTCP_my_suckaddr(ls->sock); VTCP_myname(ls->sock, abuf, sizeof abuf, pbuf, sizeof pbuf); - bprintf(nbuf, "%s:%s", abuf, pbuf); + if (VSA_Get_Proto(sa) == AF_INET6) + bprintf(nbuf, "[%s]:%s", abuf, pbuf); + else + bprintf(nbuf, "%s:%s", abuf, pbuf); REPLACE(ls->endpoint, nbuf); } VTAILQ_INSERT_TAIL(&la->socks, ls, arglist); From dridi.boukelmoune at gmail.com Fri Nov 19 10:33:08 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 10:33:08 +0000 (UTC) Subject: [6.0] b12e2df81 mac: Polish Message-ID: <20211119103309.0E9BC100C4C@lists.varnish-cache.org> commit b12e2df81b90db09ac1b14413aa69dffe1b1c426 Author: Dridi Boukelmoune Date: Mon Nov 15 12:44:19 2021 +0100 mac: Polish diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index fbf7f2619..2d04e6089 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -151,8 +151,7 @@ mk_listen_sock(const struct listen_arg *la, const struct suckaddr *sa) ls->sock = -1; ls->addr = VSA_Clone(sa); AN(ls->addr); - ls->endpoint = strdup(la->endpoint); - AN(ls->endpoint); + REPLACE(ls->endpoint, la->endpoint); ls->name = la->name; ls->transport = la->transport; ls->perms = la->perms; From dridi.boukelmoune at gmail.com Fri Nov 19 10:33:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 10:33:09 +0000 (UTC) Subject: [6.0] 9b2fbebf5 vtc: Account for [braces] on IPv6-only systems Message-ID: <20211119103309.3F4AE100C53@lists.varnish-cache.org> commit 9b2fbebf512e7236d3643f72a5e94b2dd0e0e5bb Author: Dridi Boukelmoune Date: Mon Nov 15 18:39:53 2021 +0100 vtc: Account for [braces] on IPv6-only systems diff --git a/bin/varnishtest/tests/v00025.vtc b/bin/varnishtest/tests/v00025.vtc index d3d0cf684..866817f33 100644 --- a/bin/varnishtest/tests/v00025.vtc +++ b/bin/varnishtest/tests/v00025.vtc @@ -167,8 +167,8 @@ client c1 { expect resp.http.C-Sess-XID ~ "^[0-9]+$" expect resp.http.B-Sess-XID ~ "^[0-9]+$" expect resp.http.C-Sess-XID == resp.http.B-Sess-XID - expect resp.http.C-Endpoint == "${v1_addr}:${v1_port}" - expect resp.http.B-Endpoint == "${v1_addr}:${v1_port}" + expect resp.http.C-Endpoint ~ ".?${v1_addr}.?:${v1_port}" + expect resp.http.B-Endpoint ~ ".?${v1_addr}.?:${v1_port}" expect resp.http.C-Socket == "a0" expect resp.http.B-Socket == "a0" } -run From martin at varnish-software.com Fri Nov 19 14:58:10 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:10 +0000 (UTC) Subject: [6.0] a475d980e build: Simply require that SO_???TIMEO are present Message-ID: <20211119145810.CA932107CF5@lists.varnish-cache.org> commit a475d980e0d970471623c8c6b1a539ce6555d569 Author: Dridi Boukelmoune Date: Wed Sep 22 19:46:18 2021 +0200 build: Simply require that SO_???TIMEO are present Closes #3692 diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 035540ff6..68bc2047e 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -95,14 +95,8 @@ static struct tcp_opt { TCPO(SOL_SOCKET, SO_LINGER, struct linger, 0) TCPO(SOL_SOCKET, SO_KEEPALIVE, int, 0) TCPO(IPPROTO_TCP, TCP_NODELAY, int, 1) - -#ifdef SO_SNDTIMEO_WORKS TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval, 0) -#endif - -#ifdef SO_RCVTIMEO_WORKS TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval, 0) -#endif #ifdef HAVE_TCP_KEEP TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int, 1) @@ -194,16 +188,12 @@ vca_tcp_opt_init(void) } \ } while (0) -#ifdef SO_SNDTIMEO_WORKS } else if (!strcmp(to->strname, "SO_SNDTIMEO")) { tv = VTIM_timeval(cache_param->idle_send_timeout); NEW_VAL(to, tv); -#endif -#ifdef SO_RCVTIMEO_WORKS } else if (!strcmp(to->strname, "SO_RCVTIMEO")) { tv = VTIM_timeval(cache_param->timeout_idle); NEW_VAL(to, tv); -#endif #ifdef HAVE_TCP_KEEP } else if (!strcmp(to->strname, "TCP_KEEPIDLE")) { x = (int)(cache_param->tcp_keepalive_time); diff --git a/bin/varnishtest/tests/b00020.vtc b/bin/varnishtest/tests/b00020.vtc index 1f0427c11..fc7c7c2d8 100644 --- a/bin/varnishtest/tests/b00020.vtc +++ b/bin/varnishtest/tests/b00020.vtc @@ -1,7 +1,5 @@ varnishtest "Check that between_bytes_timeout behaves from parameters" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00021.vtc b/bin/varnishtest/tests/b00021.vtc index 46be8cb4f..f0c4c0ce2 100644 --- a/bin/varnishtest/tests/b00021.vtc +++ b/bin/varnishtest/tests/b00021.vtc @@ -1,7 +1,5 @@ varnishtest "Check the between_bytes_timeout behaves from vcl" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00022.vtc b/bin/varnishtest/tests/b00022.vtc index 7bf6d9575..fee5db3d9 100644 --- a/bin/varnishtest/tests/b00022.vtc +++ b/bin/varnishtest/tests/b00022.vtc @@ -1,7 +1,5 @@ varnishtest "Check the between_bytes_timeout behaves from backend definition" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00023.vtc b/bin/varnishtest/tests/b00023.vtc index 9ee5ed340..e2b7a3602 100644 --- a/bin/varnishtest/tests/b00023.vtc +++ b/bin/varnishtest/tests/b00023.vtc @@ -1,7 +1,5 @@ varnishtest "Check that the first_byte_timeout works" -feature SO_RCVTIMEO_WORKS - # From VCL server s1 { diff --git a/bin/varnishtest/tests/b00026.vtc b/bin/varnishtest/tests/b00026.vtc index 48fce004b..e12676985 100644 --- a/bin/varnishtest/tests/b00026.vtc +++ b/bin/varnishtest/tests/b00026.vtc @@ -1,7 +1,5 @@ varnishtest "Check the precedence for timeouts" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq expect req.url == "from_backend" diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c index 8a1f80285..060b8e36c 100644 --- a/bin/varnishtest/vtc_misc.c +++ b/bin/varnishtest/vtc_misc.c @@ -368,8 +368,6 @@ dns_works(void) * the test otherwise; or change the interpretation of the test, as * documented below. feature takes any number of arguments from this list: * - * SO_RCVTIMEO_WORKS - * The SO_RCVTIMEO socket option is working * 64bit * The environment is 64 bits * !OSX @@ -431,13 +429,6 @@ cmd_feature(CMD_ARGS) for (av++; *av != NULL; av++) { good = 0; - if (!strcmp(*av, "SO_RCVTIMEO_WORKS")) { -#ifdef SO_RCVTIMEO_WORKS - good = 1; -#else - vtc_stop = 2; -#endif - } if (!strcmp(*av, "!OSX")) { #if !defined(__APPLE__) || !defined(__MACH__) diff --git a/configure.ac b/configure.ac index 4d4618ec4..cc6ea4ae4 100644 --- a/configure.ac +++ b/configure.ac @@ -491,91 +491,24 @@ AM_MISSING_HAS_RUN AC_CHECK_DECL([SO_ACCEPTFILTER], AC_DEFINE(HAVE_ACCEPT_FILTERS,1,[Define to 1 if you have accept filters]), - , - [ -#include -#include - ] -) - -# Older Solaris versions define SO_{RCV,SND}TIMEO, but do not -# implement them. -# -# Varnish will build and run without these, but connections will not -# time out, which may leave Varnish vulnerable to denail-of-service -# attacks which would not be possible on other platforms. -# -# Newer Solaris releases with the Volo framework (Solaris 11, -# Opensolaris starting with onnv_106) do support SO_{RCV,SND}TIMEO -# (see PSARC 2007/587, initially committed into onnv-gate / -# OpenSolaris 8348:4137e18bfaf0 Thu Dec 11 20:04:13 2008) - -save_LIBS="${LIBS}" -LIBS="${LIBS} ${NET_LIBS}" -AC_CACHE_CHECK([whether SO_RCVTIMEO works], - [ac_cv_so_rcvtimeo_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include - ]],[[ -int s = socket(AF_INET, SOCK_STREAM, 0); -struct timeval tv = { 1, 0 }; -if (s < 0 && errno == EPROTONOSUPPORT) - s = socket(AF_INET6, SOCK_STREAM, 0); -if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) == 0) { - socklen_t l = sizeof tv; - if (getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, &l) == 0) { - return (l != sizeof tv); - } -} -return 1; - ]])], - [ac_cv_so_rcvtimeo_works=yes], - [ac_cv_so_rcvtimeo_works=no]) - ]) -if test "$ac_cv_so_rcvtimeo_works" = yes; then - AC_DEFINE([SO_RCVTIMEO_WORKS], [1], [Define if SO_RCVTIMEO works]) -fi -LIBS="${save_LIBS}" + [], [ + #include + #include + ]) -save_LIBS="${LIBS}" -LIBS="${LIBS} ${NET_LIBS}" -AC_CACHE_CHECK([whether SO_SNDTIMEO works], - [ac_cv_so_sndtimeo_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include - ]],[[ -int s = socket(AF_INET, SOCK_STREAM, 0); -struct timeval tv = { 1, 0 }; -if (s < 0 && errno == EPROTONOSUPPORT) - s = socket(AF_INET6, SOCK_STREAM, 0); -if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) == 0) { - socklen_t l = sizeof tv; - if (getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, &l) == 0) { - return (l != sizeof tv); - } -} -return 1; - ]])], - [ac_cv_so_sndtimeo_works=yes], - [ac_cv_so_sndtimeo_works=no]) - ]) -if test "$ac_cv_so_sndtimeo_works" = yes; then - AC_DEFINE([SO_SNDTIMEO_WORKS], [1], [Define if SO_SNDTIMEO works]) -fi +AC_CHECK_DECL([SO_RCVTIMEO], + [], + AC_MSG_ERROR([SO_RCVTIMEO is needed to build Varnish.]), [ + #include + #include + ]) -if test "$ac_cv_so_rcvtimeo_works" = no || - test "$ac_cv_so_sndtimeo_works" = no; then - AC_MSG_WARN([connection timeouts will not work]) -fi -LIBS="${save_LIBS}" +AC_CHECK_DECL([SO_SNDTIMEO], + [], + AC_MSG_ERROR([SO_SNDTIMEO is needed to build Varnish.]), [ + #include + #include + ]) # Check if the OS supports TCP_KEEP(CNT|IDLE|INTVL) socket options save_LIBS="${LIBS}" diff --git a/include/tbl/params.h b/include/tbl/params.h index 5fe1e2dd6..053666de4 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -746,15 +746,6 @@ PARAM( /* func */ NULL ) -#if defined(XYZZY) - #error "Temporary macro XYZZY already defined" -#endif - -#if defined(SO_SNDTIMEO_WORKS) - #define XYZZY DELAYED_EFFECT -#else - #define XYZZY NOT_IMPLEMENTED -#endif PARAM( /* name */ idle_send_timeout, /* typ */ timeout, @@ -762,7 +753,7 @@ PARAM( /* max */ NULL, /* default */ "60.000", /* units */ "seconds", - /* flags */ XYZZY, + /* flags */ DELAYED_EFFECT, /* s-text */ "Send timeout for individual pieces of data on client connections." " May get extended if 'send_timeout' applies.\n\n" @@ -772,7 +763,6 @@ PARAM( /* l-text */ "", /* func */ NULL ) -#undef XYZZY PARAM( /* name */ listen_depth, @@ -1010,15 +1000,6 @@ PARAM( /* func */ NULL ) -#if defined(XYZZY) - #error "Temporary macro XYZZY already defined" -#endif - -#if defined(SO_SNDTIMEO_WORKS) - #define XYZZY DELAYED_EFFECT -#else - #define XYZZY NOT_IMPLEMENTED -#endif PARAM( /* name */ send_timeout, /* typ */ timeout, @@ -1026,7 +1007,7 @@ PARAM( /* max */ NULL, /* default */ "600.000", /* units */ "seconds", - /* flags */ XYZZY, + /* flags */ DELAYED_EFFECT, /* s-text */ "Total timeout for ordinary HTTP1 responses. Does not apply to some" " internally generated errors and pipe mode.\n\n" @@ -1037,7 +1018,6 @@ PARAM( /* l-text */ "", /* func */ NULL ) -#undef XYZZY #if 0 /* actual location mgt_param_tbl.c */ @@ -1100,6 +1080,9 @@ PARAM( /* func */ NULL ) +#if defined(XYZZY) + #error "Temporary macro XYZZY already defined" +#endif #if defined(HAVE_TCP_FASTOPEN) #define XYZZY MUST_RESTART #else @@ -1425,15 +1408,6 @@ PARAM( ) #endif -#if defined(XYZZY) - #error "Temporary macro XYZZY already defined" -#endif - -#if defined(SO_RCVTIMEO_WORKS) - #define XYZZY 0 -#else - #define XYZZY NOT_IMPLEMENTED -#endif PARAM( /* name */ timeout_idle, /* typ */ timeout, @@ -1441,7 +1415,7 @@ PARAM( /* max */ NULL, /* default */ "5.000", /* units */ "seconds", - /* flags */ XYZZY, + /* flags */ 0, /* s-text */ "Idle timeout for client connections.\n\n" "A connection is considered idle until we have received the full" @@ -1452,7 +1426,6 @@ PARAM( /* l-text */ "", /* func */ NULL ) -#undef XYZZY PARAM( /* name */ timeout_linger, diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index b55d91341..602cff69a 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -349,8 +349,8 @@ VTCP_close(int *s) void VTCP_set_read_timeout(int s, vtim_dur seconds) { -#ifdef SO_RCVTIMEO_WORKS struct timeval timeout = VTIM_timeval(seconds); + /* * Solaris bug (present at least in snv_151 and older): If this fails * with EINVAL, the socket is half-closed (SS_CANTSENDMORE) and the @@ -359,10 +359,6 @@ VTCP_set_read_timeout(int s, vtim_dur seconds) */ VTCP_Assert(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); -#else - (void)s; - (void)seconds; -#endif } /*-------------------------------------------------------------------- From martin at varnish-software.com Fri Nov 19 14:58:10 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:10 +0000 (UTC) Subject: [6.0] 15b848152 vca: Remove the tcp_opt::iponly field Message-ID: <20211119145810.D8918107CF7@lists.varnish-cache.org> commit 15b848152f1bd4d790ce76f4aed30d8aa0d78d75 Author: Dridi Boukelmoune Date: Mon Sep 27 07:18:29 2021 +0200 vca: Remove the tcp_opt::iponly field It is a 1:1 mapping with IPPROTO_TCP, so TCP_NODELAY was moved down to be with the other IPPROTO_TCP options. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 68bc2047e..80583b945 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -88,20 +88,20 @@ static struct tcp_opt { socklen_t sz; void *ptr; int need; - int iponly; } tcp_opts[] = { -#define TCPO(lvl, nam, sz, ip) { lvl, nam, #nam, sizeof(sz), 0, 0, ip}, +#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, - TCPO(SOL_SOCKET, SO_LINGER, struct linger, 0) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int, 0) - TCPO(IPPROTO_TCP, TCP_NODELAY, int, 1) - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval, 0) - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval, 0) + TCPO(SOL_SOCKET, SO_LINGER, struct linger) + TCPO(SOL_SOCKET, SO_KEEPALIVE, int) + TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) + TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) + + TCPO(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int, 1) + TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) + TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) + TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif #undef TCPO @@ -220,7 +220,7 @@ vca_tcp_opt_test(const int sock, const unsigned uds) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; to->need = 1; ptr = calloc(1, to->sz); @@ -243,7 +243,7 @@ vca_tcp_opt_set(const int sock, const unsigned uds, const int force) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; if (to->need || force) { VTCP_Assert(setsockopt(sock, From martin at varnish-software.com Fri Nov 19 14:58:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:11 +0000 (UTC) Subject: [6.0] f78e9b3a7 vca: Rename tcp_opt to a more general sock_opt Message-ID: <20211119145811.09249107CFA@lists.varnish-cache.org> commit f78e9b3a79123c708eb264efb3ed7cb4c4f855ce Author: Dridi Boukelmoune Date: Mon Sep 27 07:42:44 2021 +0200 vca: Rename tcp_opt to a more general sock_opt And conversely rename `to` variables to `so` for consistency. Better diff with the --word-diff --word-diff-regex='\w+' options. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 80583b945..140c5bd96 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -81,33 +81,33 @@ struct poolsock { * TCP options we want to control */ -static struct tcp_opt { +static struct sock_opt { int level; int optname; const char *strname; socklen_t sz; void *ptr; int need; -} tcp_opts[] = { -#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +} sock_opts[] = { +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, - TCPO(SOL_SOCKET, SO_LINGER, struct linger) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int) - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) + SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) + SOCK_OPT(SOL_SOCKET, SO_SNDTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_RCVTIMEO, struct timeval) - TCPO(IPPROTO_TCP, TCP_NODELAY, int) + SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPIDLE, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPCNT, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif -#undef TCPO +#undef SOCK_OPT }; -static const int n_tcp_opts = sizeof tcp_opts / sizeof tcp_opts[0]; +static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast @@ -148,11 +148,11 @@ vca_periodic(vtim_real t0) */ static int -vca_tcp_opt_init(void) +vca_sock_opt_init(void) { int n; int one = 1; - struct tcp_opt *to; + struct sock_opt *so; struct timeval tv; int chg = 0; int x; @@ -160,50 +160,50 @@ vca_tcp_opt_init(void) memset(&tv, 0, sizeof tv); memset(&x, 0, sizeof x); - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->ptr == NULL) - to->ptr = calloc(1, to->sz); - AN(to->ptr); - if (!strcmp(to->strname, "SO_LINGER")) { - assert(to->sz == sizeof linger); - memcpy(to->ptr, &linger, sizeof linger); - to->need = 1; - } else if (!strcmp(to->strname, "TCP_NODELAY")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; - } else if (!strcmp(to->strname, "SO_KEEPALIVE")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; -#define NEW_VAL(to, xx) \ + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->ptr == NULL) + so->ptr = calloc(1, so->sz); + AN(so->ptr); + if (!strcmp(so->strname, "SO_LINGER")) { + assert(so->sz == sizeof linger); + memcpy(so->ptr, &linger, sizeof linger); + so->need = 1; + } else if (!strcmp(so->strname, "TCP_NODELAY")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; + } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; +#define NEW_VAL(so, xx) \ do { \ - assert(to->sz == sizeof xx); \ - if (memcmp(to->ptr, &(xx), sizeof xx)) { \ - memcpy(to->ptr, &(xx), sizeof xx); \ - to->need = 1; \ + assert(so->sz == sizeof xx); \ + if (memcmp(so->ptr, &(xx), sizeof xx)) { \ + memcpy(so->ptr, &(xx), sizeof xx); \ + so->need = 1; \ chg = 1; \ need_test = 1; \ } \ } while (0) - } else if (!strcmp(to->strname, "SO_SNDTIMEO")) { + } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(to, tv); - } else if (!strcmp(to->strname, "SO_RCVTIMEO")) { + NEW_VAL(so, tv); + } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(to, tv); + NEW_VAL(so, tv); #ifdef HAVE_TCP_KEEP - } else if (!strcmp(to->strname, "TCP_KEEPIDLE")) { + } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPCNT")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPINTVL")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(to, x); + NEW_VAL(so, x); #endif } } @@ -211,24 +211,24 @@ vca_tcp_opt_init(void) } static void -vca_tcp_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const int sock, const unsigned uds) { int i, n; - struct tcp_opt *to; + struct sock_opt *so; socklen_t l; void *ptr; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - to->need = 1; - ptr = calloc(1, to->sz); + so->need = 1; + ptr = calloc(1, so->sz); AN(ptr); - l = to->sz; - i = getsockopt(sock, to->level, to->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, to->ptr, to->sz)) - to->need = 0; + l = so->sz; + i = getsockopt(sock, so->level, so->optname, ptr, &l); + if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + so->need = 0; free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); @@ -236,18 +236,18 @@ vca_tcp_opt_test(const int sock, const unsigned uds) } static void -vca_tcp_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const int sock, const unsigned uds, const int force) { int n; - struct tcp_opt *to; + struct sock_opt *so; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - if (to->need || force) { + if (so->need || force) { VTCP_Assert(setsockopt(sock, - to->level, to->optname, to->ptr, to->sz)); + so->level, so->optname, so->ptr, so->sz)); } } } @@ -409,10 +409,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_tcp_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); need_test = 0; } - vca_tcp_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -582,13 +582,13 @@ vca_acct(void *arg) while (1) { (void)sleep(1); - if (vca_tcp_opt_init()) { + if (vca_sock_opt_init()) { AZ(pthread_mutex_lock(&shut_mtx)); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -608,7 +608,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; - (void)vca_tcp_opt_init(); + (void)vca_sock_opt_init(); VTAILQ_FOREACH(ls, &heritage.socks, list) { CHECK_OBJ_NOTNULL(ls->transport, TRANSPORT_MAGIC); @@ -627,7 +627,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, strerror(errno)); return; } - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); if (cache_param->accept_filter) { int i; i = VTCP_filter_http(ls->sock); From martin at varnish-software.com Fri Nov 19 14:58:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:11 +0000 (UTC) Subject: [6.0] 8e522f502 vca: Pass higher-level types to sock_opt functions Message-ID: <20211119145811.29FD9107CFF@lists.varnish-cache.org> commit 8e522f50271e72a085197c6d3d6838a872d373c3 Author: Dridi Boukelmoune Date: Mon Sep 27 08:19:09 2021 +0200 vca: Pass higher-level types to sock_opt functions The sess and listen_sock structs contain everything we need to find or infer the former `sock`, `uds` and `force` arguments. In particular, it helps distinguish between working on a connection vs listen socket. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 140c5bd96..815d512c1 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -211,22 +211,25 @@ vca_sock_opt_init(void) } static void -vca_sock_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { int i, n; struct sock_opt *so; socklen_t l; void *ptr; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; ptr = calloc(1, so->sz); AN(ptr); l = so->sz; - i = getsockopt(sock, so->level, so->optname, ptr, &l); + i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) so->need = 0; free(ptr); @@ -236,16 +239,20 @@ vca_sock_opt_test(const int sock, const unsigned uds) } static void -vca_sock_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n; + int n, sock; struct sock_opt *so; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_ORNULL(sp, SESS_MAGIC); + sock = sp != NULL ? sp->fd : ls->sock; + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || force) { + if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, so->level, so->optname, so->ptr, so->sz)); } @@ -409,10 +416,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(wa->acceptlsock, sp); need_test = 0; } - vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(wa->acceptlsock, sp); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -588,7 +595,7 @@ vca_acct(void *arg) if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -627,7 +634,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, strerror(errno)); return; } - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter) { int i; i = VTCP_filter_http(ls->sock); From martin at varnish-software.com Fri Nov 19 14:58:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:11 +0000 (UTC) Subject: [6.0] 57c21d9fd vca: Eliminate heap allocations of sock_opt arguments Message-ID: <20211119145811.57F71107D02@lists.varnish-cache.org> commit 57c21d9fdb8cf75eb8e982804ba28569aabf2f79 Author: Dridi Boukelmoune Date: Mon Sep 27 11:41:27 2021 +0200 vca: Eliminate heap allocations of sock_opt arguments They can be stored directly in the sock_opts array or on the stack. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 815d512c1..62a4a2dbe 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -81,15 +81,21 @@ struct poolsock { * TCP options we want to control */ +union sock_arg { + struct linger lg; + struct timeval tv; + int i; +}; + static struct sock_opt { int level; int optname; const char *strname; - socklen_t sz; - void *ptr; int need; + socklen_t sz; + union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -153,35 +159,30 @@ vca_sock_opt_init(void) int n; int one = 1; struct sock_opt *so; - struct timeval tv; + union sock_arg tmp; int chg = 0; - int x; - memset(&tv, 0, sizeof tv); - memset(&x, 0, sizeof x); + memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->ptr == NULL) - so->ptr = calloc(1, so->sz); - AN(so->ptr); if (!strcmp(so->strname, "SO_LINGER")) { assert(so->sz == sizeof linger); - memcpy(so->ptr, &linger, sizeof linger); + memcpy(so->arg, &linger, sizeof linger); so->need = 1; } else if (!strcmp(so->strname, "TCP_NODELAY")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; #define NEW_VAL(so, xx) \ do { \ assert(so->sz == sizeof xx); \ - if (memcmp(so->ptr, &(xx), sizeof xx)) { \ - memcpy(so->ptr, &(xx), sizeof xx); \ + if (memcmp(so->arg, &(xx), sizeof xx)) { \ + memcpy(so->arg, &(xx), sizeof xx); \ so->need = 1; \ chg = 1; \ need_test = 1; \ @@ -189,21 +190,21 @@ vca_sock_opt_init(void) } while (0) } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); + NEW_VAL(so, tmp.tv); } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->timeout_idle); + NEW_VAL(so, tmp.tv); #ifdef HAVE_TCP_KEEP } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_time); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_probes); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_intvl); + NEW_VAL(so, tmp.i); #endif } } @@ -213,10 +214,10 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { - int i, n; struct sock_opt *so; + union sock_arg tmp; socklen_t l; - void *ptr; + int i, n; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -226,13 +227,11 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; - ptr = calloc(1, so->sz); - AN(ptr); + memset(&tmp, 0, sizeof tmp); l = so->sz; - i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); + if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) so->need = 0; - free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -241,8 +240,8 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n, sock; struct sock_opt *so; + int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_ORNULL(sp, SESS_MAGIC); @@ -254,7 +253,7 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) continue; if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->ptr, so->sz)); + so->level, so->optname, so->arg, so->sz)); } } } From martin at varnish-software.com Fri Nov 19 14:58:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:11 +0000 (UTC) Subject: [6.0] 789186e91 vca: Generalize the sock options test Message-ID: <20211119145811.7F618107D07@lists.varnish-cache.org> commit 789186e91912bbbfda1a9ee8acedf04170d3a9b5 Author: Dridi Boukelmoune Date: Mon Sep 27 12:11:53 2021 +0200 vca: Generalize the sock options test Using the tmp sock_arg for storage, we can test all values with the same logic and only differentiate hard-coded options from parameterized ones. Stylistic polish by @mbgrydeland. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 62a4a2dbe..29128e581 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -156,57 +156,54 @@ vca_periodic(vtim_real t0) static int vca_sock_opt_init(void) { - int n; - int one = 1; struct sock_opt *so; union sock_arg tmp; - int chg = 0; + int n, chg = 0; + size_t sz; memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (!strcmp(so->strname, "SO_LINGER")) { - assert(so->sz == sizeof linger); - memcpy(so->arg, &linger, sizeof linger); - so->need = 1; - } else if (!strcmp(so->strname, "TCP_NODELAY")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; - } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; -#define NEW_VAL(so, xx) \ - do { \ - assert(so->sz == sizeof xx); \ - if (memcmp(so->arg, &(xx), sizeof xx)) { \ - memcpy(so->arg, &(xx), sizeof xx); \ - so->need = 1; \ - chg = 1; \ - need_test = 1; \ - } \ + +#define SET_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + assert(so->sz == sizeof so->arg->fld); \ + so->arg->fld = (val); \ + } \ + } while (0) + +#define NEW_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + sz = sizeof tmp.fld; \ + assert(so->sz == sz); \ + tmp.fld = (val); \ + if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ + memcpy(&so->arg->fld, &(tmp.fld), sz); \ + so->need = 1; \ + chg = 1; \ + need_test = 1; \ + } \ + } \ } while (0) - } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tmp.tv); - } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tmp.tv); + SET_VAL(SO_LINGER, so, lg, linger); + SET_VAL(SO_KEEPALIVE, so, i, 1); + NEW_VAL(SO_SNDTIMEO, so, tv, + VTIM_timeval(cache_param->idle_send_timeout)); + NEW_VAL(SO_RCVTIMEO, so, tv, + VTIM_timeval(cache_param->timeout_idle)); #ifdef HAVE_TCP_KEEP - } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - tmp.i = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - tmp.i = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - tmp.i = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, tmp.i); + SET_VAL(TCP_NODELAY, so, i, 1); + NEW_VAL(TCP_KEEPIDLE, so, i, + (int)cache_param->tcp_keepalive_time); + NEW_VAL(TCP_KEEPCNT, so, i, + (int)cache_param->tcp_keepalive_probes); + NEW_VAL(TCP_KEEPINTVL, so, i, + (int)cache_param->tcp_keepalive_intvl); #endif - } } return (chg); } From martin at varnish-software.com Fri Nov 19 14:58:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:11 +0000 (UTC) Subject: [6.0] 04ae469a7 vca: Give all const socket options placeholers Message-ID: <20211119145811.A8AF7107D0A@lists.varnish-cache.org> commit 04ae469a7f656f011aba790af3018424c745ad46 Author: Dridi Boukelmoune Date: Mon Sep 27 12:42:54 2021 +0200 vca: Give all const socket options placeholers The SO_KEEPALIVE justification used to precede such a constant and was left confusingly lingering over the unrelated need_test variable. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 29128e581..c141c9189 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -130,6 +130,13 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ +static const unsigned so_keepalive = 1; + +/* We disable Nagle's algorithm in favor of low latency setups. + */ + +static const unsigned tcp_nodelay = 1; + static unsigned need_test; /*-------------------------------------------------------------------- @@ -190,13 +197,13 @@ vca_sock_opt_init(void) } while (0) SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, 1); + SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); + SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); #ifdef HAVE_TCP_KEEP - SET_VAL(TCP_NODELAY, so, i, 1); NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); NEW_VAL(TCP_KEEPCNT, so, i, From martin at varnish-software.com Fri Nov 19 14:58:11 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:11 +0000 (UTC) Subject: [6.0] 81254091d vca: Give sock_opt constant arguments better names Message-ID: <20211119145811.CE735107D0F@lists.varnish-cache.org> commit 81254091d7d95756d935ccffd5f8aa5baba1ba21 Author: Dridi Boukelmoune Date: Mon Sep 27 13:17:55 2021 +0200 vca: Give sock_opt constant arguments better names And while at it, update the SO_LINGER explanation to match reality. Refs 7eba94605b9f diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index c141c9189..94d32b1f2 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -117,11 +117,11 @@ static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast - * as absolutely possible, so we set them LINGER enabled with zero timeout, - * so that even if there are outstanding write data on the socket, a close(2) - * will return immediately. + * as absolutely possible, so we set them LINGER disabled, so that even if + * there are outstanding write data on the socket, a close(2) will return + * immediately. */ -static const struct linger linger = { +static const struct linger disable_so_linger = { .l_onoff = 0, }; @@ -130,12 +130,12 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ -static const unsigned so_keepalive = 1; +static const unsigned enable_so_keepalive = 1; /* We disable Nagle's algorithm in favor of low latency setups. */ -static const unsigned tcp_nodelay = 1; +static const unsigned enable_tcp_nodelay = 1; static unsigned need_test; @@ -196,13 +196,13 @@ vca_sock_opt_init(void) } \ } while (0) - SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); + SET_VAL(SO_LINGER, so, lg, disable_so_linger); + SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); - SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); + SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #ifdef HAVE_TCP_KEEP NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); From martin at varnish-software.com Fri Nov 19 14:58:12 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:12 +0000 (UTC) Subject: [6.0] ca928ab3d vca: Have one inheritance check per listen socket Message-ID: <20211119145812.11CA1107D13@lists.varnish-cache.org> commit ca928ab3d0766759c4b3aa56d307733fcdae5abc Author: Dridi Boukelmoune Date: Mon Sep 27 14:53:56 2021 +0200 vca: Have one inheritance check per listen socket Instead of having a single global check that all acceptors may race towards, this check now happens on a per listen socket basis. For sockets with a different inheritance behavior on a single system, we avoid having the first connection dictate what may be inherited by a connection socket from its listen socket for all the other listen addresses. At least on Linux, Unix-domain sockets DO NOT inherit options like SO_{RCV,SND}TIMEO even though TCP sockets do. On the off chance that even sockets of the same family could behave differently, like for example a regular vs a loopback TCP session, this is done on a per listen address basis. To avoid cache-acceptor coordination with the acceptor worker threads of a given listen address, workers will individually perform this check once and for all when the first connection is accepted. We also stay defensive in the event of a parameter change, just in case a previous test would assume inheritance because the Varnish parameter value would match the kernel default value. Once a mismatch is observed for a given connection with a given socket, the inheritance test is no longer performed needlessly for this combination. A race still exists between acceptors from different thread pools for a given listen address, but this race is identical to the previous one based on the former global need_test variable. Although the inheritance check leaks into struct listen_sock, it is opaque so everything can remain contained inside cache_acceptor.c. Some aspects of this change (including the clarification comments) are from @mbgrydeland. Refs #2722 diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 94d32b1f2..b217a5863 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -91,11 +91,13 @@ static struct sock_opt { int level; int optname; const char *strname; - int need; + unsigned mod; socklen_t sz; union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, + /* Note: Setting the mod counter to something not-zero is needed + * to force the setsockopt() calls on startup */ +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 1, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -115,6 +117,11 @@ static struct sock_opt { static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; +struct conn_heritage { + unsigned sess_set; + unsigned listen_mod; +}; + /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast * as absolutely possible, so we set them LINGER disabled, so that even if @@ -137,8 +144,6 @@ static const unsigned enable_so_keepalive = 1; static const unsigned enable_tcp_nodelay = 1; -static unsigned need_test; - /*-------------------------------------------------------------------- * lacking a better place, we put some generic periodic updates * into the vca_acct() loop which we are running anyway @@ -189,9 +194,8 @@ vca_sock_opt_init(void) tmp.fld = (val); \ if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ memcpy(&so->arg->fld, &(tmp.fld), sz); \ - so->need = 1; \ + so->mod++; \ chg = 1; \ - need_test = 1; \ } \ } \ } while (0) @@ -218,6 +222,7 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; union sock_arg tmp; socklen_t l; @@ -228,14 +233,16 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; + if (ch->sess_set) + continue; /* Already set, no need to retest */ if (so->level == IPPROTO_TCP && ls->uds) continue; - so->need = 1; memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) - so->need = 0; + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + ch->sess_set = 1; if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -244,6 +251,7 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; int n, sock; @@ -253,12 +261,17 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || sp == NULL) { - VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->arg, so->sz)); - } + if (sp == NULL && ch->listen_mod == so->mod) + continue; + if (sp != NULL && !ch->sess_set) + continue; + VTCP_Assert(setsockopt(sock, + so->level, so->optname, so->arg, so->sz)); + if (sp == NULL) + ch->listen_mod = so->mod; } } @@ -418,9 +431,9 @@ vca_make_session(struct worker *wrk, void *arg) vca_pace_good(); wrk->stats->sess_conn++; - if (need_test) { + if (wa->acceptlsock->test_heritage) { vca_sock_opt_test(wa->acceptlsock, sp); - need_test = 0; + wa->acceptlsock->test_heritage = 0; } vca_sock_opt_set(wa->acceptlsock, sp); @@ -599,6 +612,17 @@ vca_acct(void *arg) continue; // VCA_Shutdown assert (ls->sock > 0); vca_sock_opt_set(ls, NULL); + /* If one of the options on a socket has + * changed, also force a retest of whether + * the values are inherited to the + * accepted sockets. This should then + * catch any false positives from previous + * tests that could happen if the set + * value of an option happened to just be + * the OS default for that value, and + * wasn't actually inherited from the + * listening socket. */ + ls->test_heritage = 1; } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -637,6 +661,11 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, strerror(errno)); return; } + AZ(ls->conn_heritage); + ls->conn_heritage = calloc(n_sock_opts, + sizeof *ls->conn_heritage); + AN(ls->conn_heritage); + ls->test_heritage = 1; vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter) { int i; @@ -648,8 +677,6 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) } } - need_test = 1; - AZ(pthread_create(&VCA_thread, NULL, vca_acct, NULL)); } diff --git a/bin/varnishd/common/heritage.h b/bin/varnishd/common/heritage.h index db1dd37d6..3d0157133 100644 --- a/bin/varnishd/common/heritage.h +++ b/bin/varnishd/common/heritage.h @@ -36,6 +36,7 @@ struct listen_sock; struct transport; struct VCLS; struct uds_perms; +struct conn_heritage; struct listen_sock { unsigned magic; @@ -49,6 +50,8 @@ struct listen_sock { struct suckaddr *addr; const struct transport *transport; const struct uds_perms *perms; + unsigned test_heritage; + struct conn_heritage *conn_heritage; }; VTAILQ_HEAD(listen_sock_head, listen_sock); diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc new file mode 100644 index 000000000..e8a4eef61 --- /dev/null +++ b/bin/varnishtest/tests/r02722.vtc @@ -0,0 +1,37 @@ +varnishtest "TCP vs UDS sockopt inheritance" + +feature cmd {test $(uname) != SunOS} + +server s0 { + rxreqhdrs + non_fatal + rxreqbody + txresp +} -dispatch + +varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -cliok "param.set debug +flush_head" +varnish v1 -cliok "param.set timeout_idle 1" +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -req POST -hdr "Content-Length: 100" + send some + rxresp + expect resp.status == 503 +} + +# This run performs the inheritance test on a TCP connection +client c1 -run + +# This run relies on the inheritance test results +client c1 -run + +varnish v1 -vsl_catchup + +# This run checks that TCP results aren't applied to a UDS +client c1 -connect "${tmpdir}/v1.sock" +client c1 -run + +# And finally this run checks UDS inheritance test results +client c1 -run From martin at varnish-software.com Fri Nov 19 14:58:12 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 19 Nov 2021 14:58:12 +0000 (UTC) Subject: [6.0] 4ac50ab2d vca: Log the outcome of sockopt inheritance Message-ID: <20211119145812.41A1D107D1A@lists.varnish-cache.org> commit 4ac50ab2d91a8563193e855e9fb776fe934bf942 Author: Dridi Boukelmoune Date: Mon Nov 15 12:31:02 2021 +0100 vca: Log the outcome of sockopt inheritance diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index b217a5863..cc9fe24b9 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -234,15 +234,27 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (ch->sess_set) - continue; /* Already set, no need to retest */ - if (so->level == IPPROTO_TCP && ls->uds) + if (ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing nonhereditary %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); + continue; + } memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Test confirmed %s non heredity for %s=%s", + so->strname, ls->name, ls->endpoint); ch->sess_set = 1; + } if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -253,21 +265,44 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { struct conn_heritage *ch; struct sock_opt *so; + unsigned vxid; int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); - CHECK_OBJ_ORNULL(sp, SESS_MAGIC); - sock = sp != NULL ? sp->fd : ls->sock; + + if (sp != NULL) { + CHECK_OBJ(sp, SESS_MAGIC); + sock = sp->fd; + vxid = sp->vxid; + } else { + sock = ls->sock; + vxid = 0; + } for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (so->level == IPPROTO_TCP && ls->uds) + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp == NULL && ch->listen_mod == so->mod) + } + if (sp == NULL && ch->listen_mod == so->mod) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting unmodified %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp != NULL && !ch->sess_set) + } + if (sp != NULL && !ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: %s may be inherited for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + VSL(SLT_Debug, vxid, + "sockopt: Setting %s for %s=%s", + so->strname, ls->name, ls->endpoint); VTCP_Assert(setsockopt(sock, so->level, so->optname, so->arg, so->sz)); if (sp == NULL) diff --git a/bin/varnishtest/tests/l00000.vtc b/bin/varnishtest/tests/l00000.vtc index 1c732fc47..e7e316ccf 100644 --- a/bin/varnishtest/tests/l00000.vtc +++ b/bin/varnishtest/tests/l00000.vtc @@ -11,7 +11,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g session { expect 0 1000 Begin sess expect 0 = SessOpen - expect 0 = Link "req 1001" + expect * = Link "req 1001" expect 0 = SessClose expect 0 = End diff --git a/bin/varnishtest/tests/r01804.vtc b/bin/varnishtest/tests/r01804.vtc index 983091d88..f6065a529 100644 --- a/bin/varnishtest/tests/r01804.vtc +++ b/bin/varnishtest/tests/r01804.vtc @@ -9,15 +9,11 @@ server s1 { varnish v1 -arg "-afoo=127.0.0.1:0,PROXY" -vcl+backend { } -start -logexpect l1 -v v1 -d 0 -g session { - expect * * Begin {^sess .* PROXY$} - expect * = SessOpen {^.* foo .*} - expect * = Proxy {^1 } - expect * * Begin {^req} - expect * * Begin {^sess .* PROXY$} - expect * = SessOpen {^.* foo .*} - expect * = Proxy {^2 } - expect * * Begin {^req} +logexpect l1 -v v1 -g session { + expect * 1000 Begin {^sess .* PROXY$} + expect 0 = SessOpen {^.* foo .*} + expect * = Proxy {^1 } + expect * 1001 Begin {^req} } -start client c1 { @@ -26,6 +22,15 @@ client c1 { rxresp } -run +logexpect l1 -wait + +logexpect l2 -v v1 -g session { + expect * 1003 Begin {^sess .* PROXY$} + expect 0 = SessOpen {^.* foo .*} + expect * = Proxy {^2 } + expect * 1004 Begin {^req} +} -start + client c2 { # good IPv4 sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" @@ -38,4 +43,4 @@ client c2 { rxresp } -run -logexpect l1 -wait +logexpect l2 -wait diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc index e8a4eef61..1268864b5 100644 --- a/bin/varnishtest/tests/r02722.vtc +++ b/bin/varnishtest/tests/r02722.vtc @@ -9,7 +9,7 @@ server s0 { txresp } -dispatch -varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -arg {-a TCP=:0 -a "UDS=${tmpdir}/v1.sock"} varnish v1 -cliok "param.set debug +flush_head" varnish v1 -cliok "param.set timeout_idle 1" varnish v1 -vcl+backend { } -start From dridi.boukelmoune at gmail.com Fri Nov 19 16:25:10 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 16:25:10 +0000 (UTC) Subject: [master] efd7e382d vtc: Get a hint on why u6 may fail the grep Message-ID: <20211119162510.9FF7510D165@lists.varnish-cache.org> commit efd7e382d84637462e4a9a362f60180e96eb96db Author: Dridi Boukelmoune Date: Fri Nov 19 17:23:50 2021 +0100 vtc: Get a hint on why u6 may fail the grep Refs #3740 diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index e420aa18d..3994c17b7 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -120,6 +120,7 @@ shell -err -expect "-R: Syntax error" \ "varnishlog -R 1000000000/1000000000000000000000000000000s" process p1 -wait +shell {cat ${tmpdir}/vlog} shell {grep -q "0 CLI" ${tmpdir}/vlog} shell -match "0 CLI[ ]+- Wr 200 [0-9]+ PONG" \ {varnishlog -n ${v1_name} -d -g raw -X "Wr 200 [0-9]+ [^P]"} From phk at FreeBSD.org Fri Nov 19 18:52:07 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 19 Nov 2021 18:52:07 +0000 (UTC) Subject: [master] d497ec099 Hopefully fix u00006 on various platforms. Message-ID: <20211119185207.6670E110F87@lists.varnish-cache.org> commit d497ec0998f3670af1942cb60a9f4316fc2f3cba Author: Poul-Henning Kamp Date: Fri Nov 19 18:51:03 2021 +0000 Hopefully fix u00006 on various platforms. Dont limit ourselves to a set number of VSL records to include the "0 CLI" we want, various platforms emit a number of Debug messages relating to sockopt Use the `process p%d -expect-text` mechanism to wait only as long as necessary for the "0 CLI" diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index 3994c17b7..a79d592e8 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -7,9 +7,11 @@ server s1 -repeat 2 { varnish v1 -vcl+backend {} -start +# We use this to make sure we know there is a "0 CLI" in the binary log. process p1 { - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A + exec varnishlog -n ${v1_name} -g raw -u -A } -start + shell { exec varnishlog -n ${v1_name} -D -P ${tmpdir}/vlog.pid \ -w ${tmpdir}/vlog.bin -R 10/s \ @@ -119,9 +121,11 @@ shell -err -expect "-R: Syntax error: Invalid duration" \ shell -err -expect "-R: Syntax error" \ "varnishlog -R 1000000000/1000000000000000000000000000000s" -process p1 -wait -shell {cat ${tmpdir}/vlog} -shell {grep -q "0 CLI" ${tmpdir}/vlog} +# Wait until the binary also (must) contain a "0 CLI" +process p1 -expect-text 0 0 "0 CLI" +process p1 -screen_dump +process p1 -stop + shell -match "0 CLI[ ]+- Wr 200 [0-9]+ PONG" \ {varnishlog -n ${v1_name} -d -g raw -X "Wr 200 [0-9]+ [^P]"} From dridi at varni.sh Fri Nov 19 20:09:43 2021 From: dridi at varni.sh (Dridi Boukelmoune) Date: Fri, 19 Nov 2021 20:09:43 +0000 Subject: [master] d497ec099 Hopefully fix u00006 on various platforms. In-Reply-To: <20211119185207.6670E110F87@lists.varnish-cache.org> References: <20211119185207.6670E110F87@lists.varnish-cache.org> Message-ID: On Fri, Nov 19, 2021 at 6:52 PM Poul-Henning Kamp wrote: > > > commit d497ec0998f3670af1942cb60a9f4316fc2f3cba > Author: Poul-Henning Kamp > Date: Fri Nov 19 18:51:03 2021 +0000 > > Hopefully fix u00006 on various platforms. > > Dont limit ourselves to a set number of VSL records to include > the "0 CLI" we want, various platforms emit a number of Debug > messages relating to sockopt > > Use the `process p%d -expect-text` mechanism to wait only as > long as necessary for the "0 CLI" > > diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc > index 3994c17b7..a79d592e8 100644 > --- a/bin/varnishtest/tests/u00006.vtc > +++ b/bin/varnishtest/tests/u00006.vtc > @@ -7,9 +7,11 @@ server s1 -repeat 2 { > > varnish v1 -vcl+backend {} -start > > +# We use this to make sure we know there is a "0 CLI" in the binary log. > process p1 { > - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A > + exec varnishlog -n ${v1_name} -g raw -u -A > } -start This is removing -A coverage since it only takes effect with -w. Should it become a runtime failure to have -A without -w? > + > shell { > exec varnishlog -n ${v1_name} -D -P ${tmpdir}/vlog.pid \ > -w ${tmpdir}/vlog.bin -R 10/s \ > @@ -119,9 +121,11 @@ shell -err -expect "-R: Syntax error: Invalid duration" \ > shell -err -expect "-R: Syntax error" \ > "varnishlog -R 1000000000/1000000000000000000000000000000s" > > -process p1 -wait > -shell {cat ${tmpdir}/vlog} > -shell {grep -q "0 CLI" ${tmpdir}/vlog} > +# Wait until the binary also (must) contain a "0 CLI" > +process p1 -expect-text 0 0 "0 CLI" > +process p1 -screen_dump > +process p1 -stop > + > shell -match "0 CLI[ ]+- Wr 200 [0-9]+ PONG" \ > {varnishlog -n ${v1_name} -d -g raw -X "Wr 200 [0-9]+ [^P]"} > > _______________________________________________ > varnish-commit mailing list > varnish-commit at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit From phk at phk.freebsd.dk Fri Nov 19 20:12:23 2021 From: phk at phk.freebsd.dk (Poul-Henning Kamp) Date: Fri, 19 Nov 2021 20:12:23 +0000 Subject: [master] d497ec099 Hopefully fix u00006 on various platforms. In-Reply-To: References: <20211119185207.6670E110F87@lists.varnish-cache.org> Message-ID: <202111192012.1AJKCNI1096458@critter.freebsd.dk> -------- Dridi Boukelmoune writes: > > +# We use this to make sure we know there is a "0 CLI" in the binary log. > > process p1 { > > - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A > > + exec varnishlog -n ${v1_name} -g raw -u -A > > } -start > > This is removing -A coverage since it only takes effect with -w. Teach -w to take a "-" argument to mean stdout ? I was surprised we didn't do that already... -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk at FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence. From dridi at varni.sh Mon Nov 22 06:43:53 2021 From: dridi at varni.sh (Dridi Boukelmoune) Date: Mon, 22 Nov 2021 06:43:53 +0000 Subject: [master] d497ec099 Hopefully fix u00006 on various platforms. In-Reply-To: <202111192012.1AJKCNI1096458@critter.freebsd.dk> References: <20211119185207.6670E110F87@lists.varnish-cache.org> <202111192012.1AJKCNI1096458@critter.freebsd.dk> Message-ID: On Fri, Nov 19, 2021 at 8:12 PM Poul-Henning Kamp wrote: > > -------- > Dridi Boukelmoune writes: > > > > +# We use this to make sure we know there is a "0 CLI" in the binary log. > > > process p1 { > > > - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A > > > + exec varnishlog -n ${v1_name} -g raw -u -A > > > } -start > > > > This is removing -A coverage since it only takes effect with -w. > > Teach -w to take a "-" argument to mean stdout ? > > I was surprised we didn't do that already... I haven't checked but if we do that we shouldn't allow it in daemon mode. From phk at phk.freebsd.dk Mon Nov 22 07:44:20 2021 From: phk at phk.freebsd.dk (Poul-Henning Kamp) Date: Mon, 22 Nov 2021 07:44:20 +0000 Subject: [master] d497ec099 Hopefully fix u00006 on various platforms. In-Reply-To: References: <20211119185207.6670E110F87@lists.varnish-cache.org> <202111192012.1AJKCNI1096458@critter.freebsd.dk> Message-ID: <202111220744.1AM7iK62018601@critter.freebsd.dk> -------- Dridi Boukelmoune writes: > On Fri, Nov 19, 2021 at 8:12 PM Poul-Henning Kamp wrote: > > > > -------- > > Dridi Boukelmoune writes: > > > > > > +# We use this to make sure we know there is a "0 CLI" in the binary log. > > > > process p1 { > > > > - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A > > > > + exec varnishlog -n ${v1_name} -g raw -u -A > > > > } -start > > > > > > This is removing -A coverage since it only takes effect with -w. > > > > Teach -w to take a "-" argument to mean stdout ? > > > > I was surprised we didn't do that already... > > I haven't checked but if we do that we shouldn't allow it in daemon mode. Strictly speaking it is not daemon mode but restartability that is prevented. -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk at FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence. From dridi at varni.sh Mon Nov 22 08:18:40 2021 From: dridi at varni.sh (Dridi Boukelmoune) Date: Mon, 22 Nov 2021 08:18:40 +0000 Subject: [master] d497ec099 Hopefully fix u00006 on various platforms. In-Reply-To: <202111220744.1AM7iK62018601@critter.freebsd.dk> References: <20211119185207.6670E110F87@lists.varnish-cache.org> <202111192012.1AJKCNI1096458@critter.freebsd.dk> <202111220744.1AM7iK62018601@critter.freebsd.dk> Message-ID: > > I haven't checked but if we do that we shouldn't allow it in daemon mode. > > Strictly speaking it is not daemon mode but restartability that is prevented. Probably both, continuing the discussion on github. https://github.com/varnishcache/varnish-cache/issues/3740#issuecomment-975240592 From martin at varnish-software.com Mon Nov 22 15:02:07 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 22 Nov 2021 15:02:07 +0000 (UTC) Subject: [7.0] bec768df9 Hopefully fix u00006 on various platforms. Message-ID: <20211122150207.35A7A11402C@lists.varnish-cache.org> commit bec768df97ca2a0b50b3ed5bd169ac40e5e1d830 Author: Poul-Henning Kamp Date: Fri Nov 19 18:51:03 2021 +0000 Hopefully fix u00006 on various platforms. Dont limit ourselves to a set number of VSL records to include the "0 CLI" we want, various platforms emit a number of Debug messages relating to sockopt Use the `process p%d -expect-text` mechanism to wait only as long as necessary for the "0 CLI" diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index e420aa18d..a79d592e8 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -7,9 +7,11 @@ server s1 -repeat 2 { varnish v1 -vcl+backend {} -start +# We use this to make sure we know there is a "0 CLI" in the binary log. process p1 { - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A + exec varnishlog -n ${v1_name} -g raw -u -A } -start + shell { exec varnishlog -n ${v1_name} -D -P ${tmpdir}/vlog.pid \ -w ${tmpdir}/vlog.bin -R 10/s \ @@ -119,8 +121,11 @@ shell -err -expect "-R: Syntax error: Invalid duration" \ shell -err -expect "-R: Syntax error" \ "varnishlog -R 1000000000/1000000000000000000000000000000s" -process p1 -wait -shell {grep -q "0 CLI" ${tmpdir}/vlog} +# Wait until the binary also (must) contain a "0 CLI" +process p1 -expect-text 0 0 "0 CLI" +process p1 -screen_dump +process p1 -stop + shell -match "0 CLI[ ]+- Wr 200 [0-9]+ PONG" \ {varnishlog -n ${v1_name} -d -g raw -X "Wr 200 [0-9]+ [^P]"} From dridi.boukelmoune at gmail.com Tue Nov 23 06:48:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 06:48:05 +0000 (UTC) Subject: [master] bc7ac9c80 vrnd: Typo Message-ID: <20211123064805.E147F107867@lists.varnish-cache.org> commit bc7ac9c8089a135f0b0de8133c1f19a7e62772e7 Author: Dridi Boukelmoune Date: Tue Nov 23 07:47:19 2021 +0100 vrnd: Typo diff --git a/lib/libvarnish/vrnd.c b/lib/libvarnish/vrnd.c index 8e189f771..d72b697ad 100644 --- a/lib/libvarnish/vrnd.c +++ b/lib/libvarnish/vrnd.c @@ -53,7 +53,7 @@ vrnd_lock_f *VRND_Unlock; /********************************************************************** * Stripped down random(3) implementation from FreeBSD, to provide - * predicatable "random" numbers of testing purposes. + * predictable "random" numbers of testing purposes. */ #define TYPE_3 3 /* x**31 + x**3 + 1 */ @@ -83,7 +83,7 @@ good_rand(uint32_t ctx) { /* * Compute x = (7^5 * x) mod (2^31 - 1) - * wihout overflowing 31 bits: + * without overflowing 31 bits: * (2^31 - 1) = 127773 * (7^5) + 2836 * From "Random number generators: good ones are hard to find", * Park and Miller, Communications of the ACM, vol. 31, no. 10, From martin at varnish-software.com Tue Nov 23 10:00:10 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 10:00:10 +0000 (UTC) Subject: [7.0] 885a9fd7f Changelog for 7.0.1 Message-ID: <20211123100010.38C7A10EAB6@lists.varnish-cache.org> commit 885a9fd7fb5b3bb84c8f024bd73fcce5c5d38916 Author: Martin Blix Grydeland Date: Tue Nov 23 10:31:40 2021 +0100 Changelog for 7.0.1 diff --git a/doc/changes.rst b/doc/changes.rst index c290a644c..b105f4717 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -31,6 +31,46 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. +================================ +Varnish Cache 7.0.1 (unreleased) +================================ + +* An assertion failure has been fixed which triggered when matching bans + on non-existing headers (3706_). + +* A VCL compilation issue has been fixed when calling builtin functions + directly (3719_). + +* It is now again possible to concatenate static strings to produce + combined strings of type VCL_REGEX (3721_). + +* An issue has been fixed that would cause the VCL dependency checker to + incorrectly flag VCLs as dependants of other VCLs when using labels, + preventing them from being discarded (3734_). + +* VCLs loaded through CLI or the use of startup CLI scripts (-I option to + `varnishd`) will, when no active VCL has previously been set, no longer + automatically set the first VCL loaded to the active VCL. This prevents + situations where it was possible to make a cold VCL the active VCL + (3737_). + +* There is now a `configure` build-time requirement on working SO_RCVTIMEO + and SO_SNDTIMEO socket options. + +* The socket option inheritance checks now correctly identifies situations + where UDS and TCP listening sockets behave differently, and are no + longer subject to the order the inheritance checks happens to be + executed (3732_). + +* IPv6 listen endpoint address strings are now printed using brackets. + +.. _3706: https://github.com/varnishcache/varnish-cache/issues/3706 +.. _3719: https://github.com/varnishcache/varnish-cache/issues/3719 +.. _3721: https://github.com/varnishcache/varnish-cache/issues/3726 +.. _3734: https://github.com/varnishcache/varnish-cache/issues/3734 +.. _3737: https://github.com/varnishcache/varnish-cache/pull/3737 +.. _3732: https://github.com/varnishcache/varnish-cache/pull/3732 + ================================ Varnish Cache 7.0.0 (2021-09-15) ================================ From martin at varnish-software.com Tue Nov 23 10:00:10 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 10:00:10 +0000 (UTC) Subject: [7.0] d454d0ed7 Prepare for 7.0.1 Message-ID: <20211123100010.515EB10EAB8@lists.varnish-cache.org> commit d454d0ed759ce8ed2b5c7bf244090a73487e8021 Author: Martin Blix Grydeland Date: Tue Nov 23 10:39:47 2021 +0100 Prepare for 7.0.1 diff --git a/configure.ac b/configure.ac index d9760807e..f21a8f85c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.69) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2021 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [7.0.0], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [7.0.1], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index b105f4717..19af0b100 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -32,7 +32,7 @@ individual releases. These documents are updated as part of the release process. ================================ -Varnish Cache 7.0.1 (unreleased) +Varnish Cache 7.0.1 (2021-11-23) ================================ * An assertion failure has been fixed which triggered when matching bans From phk at FreeBSD.org Tue Nov 23 11:42:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 23 Nov 2021 11:42:05 +0000 (UTC) Subject: [master] bdf2e0608 Polish implementation of "cli help" Message-ID: <20211123114206.02C6A1117DD@lists.varnish-cache.org> commit bdf2e0608436b17b903393e65adc57514b6eb89c Author: Poul-Henning Kamp Date: Tue Nov 23 09:51:36 2021 +0000 Polish implementation of "cli help" diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc index 4fdf4205b..755d6e4b4 100644 --- a/bin/varnishtest/tests/b00008.vtc +++ b/bin/varnishtest/tests/b00008.vtc @@ -10,6 +10,8 @@ varnish v1 -cliok "help -a" varnish v1 -cliok "help -d" +varnish v1 -clierr 101 "help -x" + varnish v1 -cliok "help vcl.load" varnish v1 -clierr 101 "help ban" diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index 1dcbb7da5..c5b8c82fa 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -120,25 +120,30 @@ void v_matchproto_(cli_func_t) VCLS_func_help(struct cli *cli, const char * const *av, void *priv) { struct cli_proto *clp; - unsigned all, debug, d; + unsigned all = 0, debug = 0, d; struct VCLS *cs; (void)priv; cs = cli->cls; CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC); - if (av[2] == NULL) { - all = debug = 0; - } else if (!strcmp(av[2], "-a")) { - all = 1; - debug = 0; - } else if (!strcmp(av[2], "-d")) { - all = 0; - debug = 1; - } else { + for (av += 2; av[0] != NULL && av[0][0] == '-'; av++) { + if (!strcmp(av[0], "-a")) { + all = 1; + debug = 0; + } else if (!strcmp(av[0], "-d")) { + all = 0; + debug = 1; + } else { + VCLI_Out(cli, "Unknown flag\n"); + VCLI_SetResult(cli, CLIS_UNKNOWN); + return; + } + } + if (av[0] != NULL) { VTAILQ_FOREACH(clp, &cs->funcs, list) { if (clp->auth <= cli->auth && - !strcmp(clp->desc->request, av[2])) { + !strcmp(clp->desc->request, av[0])) { VCLI_Out(cli, "%s\n%s\n", clp->desc->syntax, clp->desc->help); return; @@ -151,13 +156,13 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv) VTAILQ_FOREACH(clp, &cs->funcs, list) { if (clp->auth > cli->auth) continue; - d = strchr(clp->flags, 'd') != NULL ? 1 : 0; + d = strchr(clp->flags, 'd') != NULL ? 1 : 0; if (d && (!all && !debug)) continue; if (debug && !d) continue; - if (clp->desc->syntax != NULL) - VCLI_Out(cli, "%s\n", clp->desc->syntax); + AN(clp->desc->syntax); + VCLI_Out(cli, "%s\n", clp->desc->syntax); } } From phk at FreeBSD.org Tue Nov 23 11:42:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 23 Nov 2021 11:42:06 +0000 (UTC) Subject: [master] bb5eed177 White space OCD Message-ID: <20211123114206.37DCF1117E1@lists.varnish-cache.org> commit bb5eed1771926f0ebd5acdb533e367827db4f2e4 Author: Poul-Henning Kamp Date: Tue Nov 23 09:55:15 2021 +0000 White space OCD diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 07af11e37..c3c78fb91 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -800,10 +800,10 @@ ved_gzgz_fini(struct vdp_ctx *vdc, void **priv) } static const struct vdp ved_gzgz = { - .name = "VZZ", - .init = ved_gzgz_init, - .bytes = ved_gzgz_bytes, - .fini = ved_gzgz_fini, + .name = "VZZ", + .init = ved_gzgz_init, + .bytes = ved_gzgz_bytes, + .fini = ved_gzgz_fini, }; /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index b44aa23bc..54170600d 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -437,9 +437,9 @@ Pool_Work_Thread(struct pool *pp, struct worker *wrk) else if (wrk->wpriv->vcl == NULL) tmo = 0; else if (DO_DEBUG(DBG_VTC_MODE)) - tmo = now + 1.; + tmo = now + 1.; else - tmo = now + 60.; + tmo = now + 60.; (void)Lck_CondWaitUntil( &wrk->cond, &pp->mtx, tmo); if (wrk->task->func != NULL) { diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 572275392..df5d4bc2e 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -1393,8 +1393,8 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2) if (h2->do_sweep) (void)h2_sweep(wrk, h2); - h2->rxf_len = vbe32dec(h2->htc->rxbuf_b) >> 8; - h2->rxf_type = h2->htc->rxbuf_b[3]; + h2->rxf_len = vbe32dec(h2->htc->rxbuf_b) >> 8; + h2->rxf_type = h2->htc->rxbuf_b[3]; h2->rxf_flags = h2->htc->rxbuf_b[4]; h2->rxf_stream = vbe32dec(h2->htc->rxbuf_b + 5); h2->rxf_stream &= ~(1LU<<31); // rfc7540,l,690,692 diff --git a/bin/varnishtest/vtc_h2_hpack.c b/bin/varnishtest/vtc_h2_hpack.c index 085741323..d4580196a 100644 --- a/bin/varnishtest/vtc_h2_hpack.c +++ b/bin/varnishtest/vtc_h2_hpack.c @@ -206,7 +206,7 @@ num_encode(struct hpk_iter *iter, uint8_t prefix, uint32_t num) uint8_t pmax = (1U << prefix) - 1U; *iter->buf &= 0xffU << prefix; - if (num <= pmax) { + if (num <= pmax) { *iter->buf++ |= num; return (ITER_DONE(iter)); } else if (iter->end - iter->buf < 2) diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 2194d6621..9dccb70bb 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -527,7 +527,7 @@ i_mode(void) "could not find 'abs_top_builddir' in Makefile\n"); exit(2); } - topbuild = strchr(p + 1, '\n'); + topbuild = strchr(p + 1, '\n'); if (topbuild == NULL) { fprintf(stderr, "No NL after 'abs_top_builddir' in Makefile\n"); diff --git a/include/vapi/vsl.h b/include/vapi/vsl.h index 7d75ef772..4df8e14dc 100644 --- a/include/vapi/vsl.h +++ b/include/vapi/vsl.h @@ -327,7 +327,7 @@ enum vsl_check { vsl_check_e_notsupp = -1, vsl_check_e_inval = 0, vsl_check_warn = 1, - vsl_check_valid = 2 + vsl_check_valid = 2 }; enum vsl_check diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index 266d194f0..aee0a9350 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -1055,15 +1055,15 @@ xyzzy_get_ip(VRT_CTX) extern const struct vmod_data Vmod_wrong0_Data; const struct vmod_data Vmod_wrong0_Data = { - .vrt_major = 0, - .vrt_minor = 0, + .vrt_major = 0, + .vrt_minor = 0, }; //lint -save -e835 A zero has been given as left argument to operatorp'+' extern const struct vmod_data Vmod_wrong1_Data; const struct vmod_data Vmod_wrong1_Data = { - .vrt_major = VRT_MAJOR_VERSION, - .vrt_minor = VRT_MINOR_VERSION + 1, + .vrt_major = VRT_MAJOR_VERSION, + .vrt_minor = VRT_MINOR_VERSION + 1, }; //lint -restore @@ -1073,8 +1073,8 @@ static const struct foo { extern const struct vmod_data Vmod_wrong2_Data; const struct vmod_data Vmod_wrong2_Data = { - .vrt_major = VRT_MAJOR_VERSION, - .vrt_minor = VRT_MINOR_VERSION, + .vrt_major = VRT_MAJOR_VERSION, + .vrt_minor = VRT_MINOR_VERSION, .name = "wrongN", .func = foo_struct, .func_len = sizeof foo_struct, @@ -1084,8 +1084,8 @@ const struct vmod_data Vmod_wrong2_Data = { extern const struct vmod_data Vmod_wrong3_Data; const struct vmod_data Vmod_wrong3_Data = { - .vrt_major = VRT_MAJOR_VERSION, - .vrt_minor = VRT_MINOR_VERSION, + .vrt_major = VRT_MAJOR_VERSION, + .vrt_minor = VRT_MINOR_VERSION, .name = "wrongN", .func = foo_struct, .func_len = sizeof foo_struct, From phk at FreeBSD.org Tue Nov 23 11:42:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 23 Nov 2021 11:42:06 +0000 (UTC) Subject: [master] c6816e9f6 Simplify VCLS_func_help() a bit. Message-ID: <20211123114206.5EEA41117E4@lists.varnish-cache.org> commit c6816e9f65c17955e657fe5e4afaee267604225e Author: Poul-Henning Kamp Date: Tue Nov 23 10:26:17 2021 +0000 Simplify VCLS_func_help() a bit. diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index c5b8c82fa..29510e9e8 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -116,11 +116,21 @@ VCLS_func_ping_json(struct cli *cli, const char * const *av, void *priv) /*--------------------------------------------------------------------*/ +static void +help_helper(struct cli *cli, struct cli_proto *clp, const char * const *av) +{ + AN(clp->desc->syntax); + if (av[0] != NULL) + VCLI_Out(cli, "%s\n%s\n", clp->desc->syntax, clp->desc->help); + else + VCLI_Out(cli, "%s\n", clp->desc->syntax); +} + void v_matchproto_(cli_func_t) VCLS_func_help(struct cli *cli, const char * const *av, void *priv) { struct cli_proto *clp; - unsigned all = 0, debug = 0, d; + unsigned filter = 1, d; struct VCLS *cs; (void)priv; @@ -129,40 +139,30 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv) for (av += 2; av[0] != NULL && av[0][0] == '-'; av++) { if (!strcmp(av[0], "-a")) { - all = 1; - debug = 0; + filter = 3; } else if (!strcmp(av[0], "-d")) { - all = 0; - debug = 1; + filter = 2; } else { VCLI_Out(cli, "Unknown flag\n"); VCLI_SetResult(cli, CLIS_UNKNOWN); return; } } - if (av[0] != NULL) { - VTAILQ_FOREACH(clp, &cs->funcs, list) { - if (clp->auth <= cli->auth && - !strcmp(clp->desc->request, av[0])) { - VCLI_Out(cli, "%s\n%s\n", - clp->desc->syntax, clp->desc->help); - return; - } - } - VCLI_Out(cli, "Unknown request.\nType 'help' for more info.\n"); - VCLI_SetResult(cli, CLIS_UNKNOWN); - return; - } VTAILQ_FOREACH(clp, &cs->funcs, list) { if (clp->auth > cli->auth) continue; - d = strchr(clp->flags, 'd') != NULL ? 1 : 0; - if (d && (!all && !debug)) - continue; - if (debug && !d) - continue; - AN(clp->desc->syntax); - VCLI_Out(cli, "%s\n", clp->desc->syntax); + if (av[0] != NULL && !strcmp(clp->desc->request, av[0])) { + help_helper(cli, clp, av); + return; + } else if (av[0] == NULL) { + d = strchr(clp->flags, 'd') != NULL ? 2 : 1; + if (filter & d) + help_helper(cli, clp, av); + } + } + if (av[0] != NULL) { + VCLI_Out(cli, "Unknown request.\nType 'help' for more info.\n"); + VCLI_SetResult(cli, CLIS_UNKNOWN); } } From phk at FreeBSD.org Tue Nov 23 11:42:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 23 Nov 2021 11:42:06 +0000 (UTC) Subject: [master] bdc1620cf Polish Message-ID: <20211123114206.A14941117EA@lists.varnish-cache.org> commit bdc1620cf4c48c9ddc64439972799db671609856 Author: Poul-Henning Kamp Date: Tue Nov 23 10:26:42 2021 +0000 Polish diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 54170600d..3cbb99fe2 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -683,7 +683,7 @@ pool_herder(void *priv) Lck_Unlock(&pool_mtx); delay = cache_param->wthread_destroy_delay; } else - delay = vmax(delay, + delay = vmax(delay, cache_param->wthread_destroy_delay); } diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h index 7134c0c20..3814a1615 100644 --- a/include/tbl/cli_cmds.h +++ b/include/tbl/cli_cmds.h @@ -227,7 +227,7 @@ CLI_CMD(PING, CLI_CMD(HELP, "help", - "help [-j] []", + "help [-j|]", "Show command/protocol help.", " ``-j`` specifies JSON output.", 0, 1 From martin at varnish-software.com Tue Nov 23 12:31:06 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:06 +0000 (UTC) Subject: [master] fd41231a1 Prepare the release branch for package building Message-ID: <20211123123106.D704A115C8D@lists.varnish-cache.org> commit fd41231a1edfdf52bc110901517e74350404e5dd Author: Martin Blix Grydeland Date: Wed Sep 15 13:35:41 2021 +0200 Prepare the release branch for package building The CircleCI default commit behaviour is changed to package building now that this is a release branch. diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b834c526..705a0162c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,7 +6,7 @@ parameters: default: "HEAD" pkg-commit: type: string - default: "master" + default: "7.0" configure_args: type: string default: | @@ -312,43 +312,6 @@ jobs: workflows: version: 2 commit: - jobs: - - dist - - distcheck: - name: distcheck_centos_7 - dist: centos - release: "7" - - distcheck: - name: distcheck_centos_8 - dist: centos - release: "8" - - distcheck: - name: distcheck_debian_buster - dist: debian - release: buster - extra_conf: --enable-asan --enable-ubsan --enable-workspace-emulator - - distcheck: - name: distcheck_ubuntu_bionic - dist: ubuntu - release: bionic - extra_conf: CFLAGS='-g -O2 -m32' - - distcheck: - name: distcheck_alpine - dist: alpine - release: "latest" - #extra_conf: --without-jemalloc - - distcheck: - name: distcheck_archlinux - dist: archlinux - release: "latest" - nightly: - triggers: - - schedule: - cron: "0 4 * * *" - filters: - branches: - only: - - master jobs: - dist - tar_pkg_tools From martin at varnish-software.com Tue Nov 23 12:31:06 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:06 +0000 (UTC) Subject: [master] d24694967 Adjust CircleCI config to take dist-url as an arg Message-ID: <20211123123106.ECCCC115C90@lists.varnish-cache.org> commit d24694967ff2b6a6d88f91257443512141a62569 Author: Martin Blix Grydeland Date: Wed Sep 15 14:03:38 2021 +0200 Adjust CircleCI config to take dist-url as an arg diff --git a/.circleci/config.yml b/.circleci/config.yml index 705a0162c..d9ba4fa58 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,6 +7,12 @@ parameters: pkg-commit: type: string default: "7.0" + dist-url: + type: string + default: "" + dist-url-sha256: + type: string + default: "" configure_args: type: string default: | @@ -17,7 +23,7 @@ parameters: --with-persistent-storage \ jobs: dist: - description: Builds varnish-x.y.z.tar.gz that is used later for the packaging jobs + description: Build or download varnish-x.y.z.tar.gz that is used later for the packaging jobs docker: - image: centos:7 steps: @@ -37,17 +43,40 @@ jobs: python3 \ python-sphinx - checkout - - run: - name: Create the dist tarball - command: | - git checkout << pipeline.parameters.vc-commit >> - # if version is "trunk", it's a weekly tarball, override the version - if grep 'AC_INIT.*trunk.*' ./configure.ac; then - sed -i -e "s/^AC_INIT.*trunk.*/AC_INIT([Varnish], [$(date +%Y%m%d)], [varnish-dev at varnish-cache.org])/" ./configure.ac - touch .is_weekly - fi - ./autogen.des --quiet - make dist -j 16 + - when: + condition: << pipeline.parameters.dist-url >> + steps: + - run: + name: Download the dist tarball + command: | + curl -s << pipeline.parameters.dist-url >> -o varnish-dist.tar.gz + - when: + condition: << pipeline.parameters.dist-url-sha256 >> + steps: + - run: + name: Verify downloaded tarball + command: | + echo "<< pipeline.parameters.dist-url-sha256 >> varnish-dist.tar.gz" | sha256sum -c + -run: + name: Rename the dist tarball by parsed version + command: | + mkdir parse-version-tmp + cd parse-version-tmp + tar xzf ../varnish-dist.tar.gz + VERSION=$(varnish-*/configure --version | awk 'NR == 1 {print $NF}') + cd .. + mv -v varnish-dist.tar.gz varnish-${VERSION}.tar.gz + - unless: + condition: << pipeline.parameters.dist-url >> + steps: + - run: + name: Create the dist tarball + command: | + git checkout << pipeline.parameters.vc-commit >> + # Locally built tarballs are always weekly - built with date in package name + touch .is_weekly + ./autogen.des --quiet + make dist -j 16 - persist_to_workspace: root: . paths: From martin at varnish-software.com Tue Nov 23 12:31:07 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:07 +0000 (UTC) Subject: [master] 0e73c0f85 Fix up yaml syntax Message-ID: <20211123123107.12E16115C94@lists.varnish-cache.org> commit 0e73c0f85338b589bbeb4db1d8395ce6681f3d0c Author: Martin Blix Grydeland Date: Wed Sep 15 14:06:16 2021 +0200 Fix up yaml syntax diff --git a/.circleci/config.yml b/.circleci/config.yml index d9ba4fa58..f6d0cbc91 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,15 +57,15 @@ jobs: name: Verify downloaded tarball command: | echo "<< pipeline.parameters.dist-url-sha256 >> varnish-dist.tar.gz" | sha256sum -c - -run: - name: Rename the dist tarball by parsed version - command: | - mkdir parse-version-tmp - cd parse-version-tmp - tar xzf ../varnish-dist.tar.gz - VERSION=$(varnish-*/configure --version | awk 'NR == 1 {print $NF}') - cd .. - mv -v varnish-dist.tar.gz varnish-${VERSION}.tar.gz + - run: + name: Rename the dist tarball by parsed version + command: | + mkdir parse-version-tmp + cd parse-version-tmp + tar xzf ../varnish-dist.tar.gz + VERSION=$(varnish-*/configure --version | awk 'NR == 1 {print $NF}') + cd .. + mv -v varnish-dist.tar.gz varnish-${VERSION}.tar.gz - unless: condition: << pipeline.parameters.dist-url >> steps: From nils.goroll at uplex.de Tue Nov 23 12:31:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:07 +0000 (UTC) Subject: [master] 46bbfe258 ban_evaluate(): Do not call VRE_match on a NULL subject Message-ID: <20211123123107.34582115C98@lists.varnish-cache.org> commit 46bbfe2584380dec4c9036cfdc4a28d6c3d1ab9c Author: Nils Goroll Date: Tue Sep 28 16:44:24 2021 +0200 ban_evaluate(): Do not call VRE_match on a NULL subject Fixes #3706 diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index bd02f3001..ab523cd6e 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -568,15 +568,19 @@ ban_evaluate(struct worker *wrk, const uint8_t *bsarg, struct objcore *oc, } break; case BANS_OPER_MATCH: + if (arg1 == NULL) + return (0); rv = VRE_match(bt.arg2_spec, arg1, 0, 0, NULL); xxxassert(rv >= -1); - if (arg1 == NULL || rv < 0) + if (rv < 0) return (0); break; case BANS_OPER_NMATCH: + if (arg1 == NULL) + return (0); rv = VRE_match(bt.arg2_spec, arg1, 0, 0, NULL); xxxassert(rv >= -1); - if (arg1 == NULL || rv >= 0) + if (rv >= 0) return (0); break; case BANS_OPER_GT: From nils.goroll at uplex.de Tue Nov 23 12:31:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:07 +0000 (UTC) Subject: [master] 1996366df vtc: Test case for #3706 Message-ID: <20211123123107.55743115C9C@lists.varnish-cache.org> commit 1996366df42bf5c89e7f2e74a8871f247e4693a3 Author: Dridi Boukelmoune Date: Tue Sep 28 17:45:22 2021 +0200 vtc: Test case for #3706 diff --git a/bin/varnishtest/tests/r03706.vtc b/bin/varnishtest/tests/r03706.vtc new file mode 100644 index 000000000..582c6f922 --- /dev/null +++ b/bin/varnishtest/tests/r03706.vtc @@ -0,0 +1,18 @@ +varnishtest "Null regex subject in ban expression" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { } -start + +client c1 { + txreq + rxresp + expect resp.status == 200 +} -run + +varnish v1 -cliok "ban req.http.nonexistent ~ foo" + +client c1 -run From nils.goroll at uplex.de Tue Nov 23 12:31:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:07 +0000 (UTC) Subject: [master] f5798fd1f vcc: do not overwrite SUB symbol properties when call'ing Message-ID: <20211123123107.8C96C115CA1@lists.varnish-cache.org> commit f5798fd1f9362e2a56933c457ead9b85e9d97c79 Author: Nils Goroll Date: Mon Oct 25 18:46:14 2021 +0200 vcc: do not overwrite SUB symbol properties when call'ing vcc_act_call() implements use-before-define semantics. To do so, it needs to instantiate SUB symbols if they do not exist. However, it wrongly called VCC_GlobalSymbol() also for existing symbols, overwriting symbol properties. In the case of the built-in subs, the symbol's lname (historically) still is the unescaped literal name, while user defined subs have their name escaped via VCC_GlobalSymbol() -> VCC_PrintCName(). This made the wrong call to VCC_GlobalSymbol() apparent when a built-in sub was called with an explicit "call" action. Besides fixing the VCC_GlobalSymbol() call, we also need to set the lname and rname attributes for built-in SUB symbols initialized in VCC_New(). Alternatively, we could also have used VCC_GlobalSymbol() there, but that would have affected other places where we (still) rely on the known name scheme of built-in subs, e.h. EmitStruct(). While the name unifaction was nice in general, I found the necessary changes (look up SUB symbols) not worth the benefit. Fixes #3719 diff --git a/bin/varnishtest/tests/m00053.vtc b/bin/varnishtest/tests/m00053.vtc index d5c501ea4..97ed034ce 100644 --- a/bin/varnishtest/tests/m00053.vtc +++ b/bin/varnishtest/tests/m00053.vtc @@ -92,9 +92,12 @@ varnish v1 -vcl { sub vcl_backend_fetch { debug.call(priv_top); } + sub vcl_backend_response { + set beresp.status = 200; + } sub vcl_backend_error { # falling through to None backend would be success - set beresp.status = 200; + call vcl_backend_response; return (deliver); } } -start diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c index 7c7a57714..0ed675da6 100644 --- a/lib/libvcc/vcc_action.c +++ b/lib/libvcc/vcc_action.c @@ -52,16 +52,16 @@ vcc_act_call(struct vcc *tl, struct token *t, struct symbol *sym) t0 = tl->t; sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL_NOERR, XREF_REF); - if (sym == NULL) + if (sym == NULL) { sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_SUB, SYMTAB_CREATE, XREF_REF); - - if (sym == NULL) - return; + if (sym == NULL) + return; + VCC_GlobalSymbol(sym, SUB); + } if (sym->kind == SYM_SUB) { vcc_AddCall(tl, t0, sym); - VCC_GlobalSymbol(sym, SUB); Fb(tl, 1, "%s(ctx, VSUB_STATIC, NULL);\n", sym->lname); SkipToken(tl, ';'); diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index 60427d526..d954ea8b9 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -820,6 +820,7 @@ VCC_New(void) struct vcc *tl; struct symbol *sym; struct proc *p; + struct vsb *vsb; int i; ALLOC_OBJ(tl, VCC_MAGIC); @@ -849,7 +850,25 @@ VCC_New(void) SYM_MAIN, SYM_SUB, VCL_LOW, VCL_HIGH); p = vcc_NewProc(tl, sym); p->method = &method_tab[i]; - VSB_printf(p->cname, "VGC_function_%s", p->method->name); + + // see also VCC_GlobalSymbol() + vsb = VSB_new_auto(); + AN(vsb); + VSB_printf(vsb, "%s_%s", SUB->global_pfx, p->method->name); + AZ(VSB_finish(vsb)); + + AZ(VSB_bcat(p->cname, VSB_data(vsb), VSB_len(vsb))); + + sym->lname = strdup(VSB_data(vsb)); + AN(sym->lname); + + VSB_clear(vsb); + VSB_printf(vsb, "sub_%s", sym->lname); + AZ(VSB_finish(vsb)); + + sym->rname = strdup(VSB_data(vsb)); + AN(sym->rname); + VSB_destroy(&vsb); } tl->sb = VSB_new_auto(); AN(tl->sb); From nils.goroll at uplex.de Tue Nov 23 12:31:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:07 +0000 (UTC) Subject: [master] 2fd71469f vcc: Fix dynamic calls to built-in SUBs and properly check evaluation context Message-ID: <20211123123107.C7EE2115CA6@lists.varnish-cache.org> commit 2fd71469f60e56683723b9fddb6ae34ed9b79997 Author: Nils Goroll Date: Tue Oct 26 13:33:23 2021 +0200 vcc: Fix dynamic calls to built-in SUBs and properly check evaluation context As a follow-up issue from #3719, it was noticed that dynamic calls to built-in SUBs did not work. This issue was caused by more (struct symbol) members missing initialization in VCC_New(). In turn, it became apparent that the evaluation context check in vcc_expr5() as tested in v00020.vtc only worked by accident, and only for built-in subs because (struct symbol).eval was NULL for built-in subs. We fix SUB type expression evaluation with a type specific evaluation function which allows expression evaluation from explicit SUB contexts only. Fixes #3720 diff --git a/bin/varnishtest/tests/m00053.vtc b/bin/varnishtest/tests/m00053.vtc index 97ed034ce..72e54ab89 100644 --- a/bin/varnishtest/tests/m00053.vtc +++ b/bin/varnishtest/tests/m00053.vtc @@ -98,6 +98,7 @@ varnish v1 -vcl { sub vcl_backend_error { # falling through to None backend would be success call vcl_backend_response; + debug.call(vcl_backend_response); return (deliver); } } -start @@ -205,6 +206,7 @@ varnish v1 -vcl { } sub vcl_init { + new vbr = debug.caller(vcl_backend_response); new c = debug.caller(foo); } diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index 603f3a251..a5b37eed3 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -31,12 +31,31 @@ varnish v1 -errvcl {Comparison of different types: INT '!=' STRING} { } } -varnish v1 -errvcl {Symbol 'vcl_recv' type (sub) can not be used in expression.} { +varnish v1 -errvcl {Symbol 'vcl_recv' can only be used as a SUB expression} { + backend proforma none; sub vcl_recv { set req.http.foo = vcl_recv; } } +varnish v1 -errvcl {Symbol 'vcl_recv' can only be used as a SUB expression} { + backend proforma none; + sub vcl_recv { + return (synth(200)); + } + sub vcl_synth { + set req.http.foo = vcl_recv; + } +} + +varnish v1 -errvcl {Symbol 'asub' can only be used as a SUB expression} { + backend proforma none; + sub asub {} + sub vcl_recv { + set req.http.foo = asub; + } +} + varnish v1 -errvcl {Symbol 'acl' type (reserved) can not be used in expression.} { import std; sub vcl_recv { call acl; } diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index d954ea8b9..d3acb0383 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -64,6 +64,7 @@ #include "libvcc.h" #include "vfil.h" +#include "vct.h" static const struct method method_tab[] = { { "none", 0U, 0}, @@ -869,6 +870,11 @@ VCC_New(void) sym->rname = strdup(VSB_data(vsb)); AN(sym->rname); VSB_destroy(&vsb); + + sym->type = SUB; + sym->kind = VCC_HandleKind(SUB); + AZ(VCT_invalid_name(sym->rname, NULL)); + sym->eval = vcc_Eval_Sub; } tl->sb = VSB_new_auto(); AN(tl->sb); diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 3f3ccc3c0..6ce150c4c 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -351,6 +351,7 @@ sym_act_f vcc_Act_Obj; void vcc_Expr_Init(struct vcc *tl); sym_expr_t vcc_Eval_Var; sym_expr_t vcc_Eval_Handle; +sym_expr_t vcc_Eval_Sub; sym_expr_t vcc_Eval_SymFunc; sym_expr_t vcc_Eval_TypeMethod; void vcc_Eval_Func(struct vcc *, const struct vjsn_val *, @@ -377,6 +378,7 @@ void vcc_lex_source(struct vcc *tl, struct source *sp, int eoi); void vcc_stevedore(struct vcc *vcc, const char *stv_name); /* vcc_symb.c */ +vcc_kind_t VCC_HandleKind(vcc_type_t fmt); void VCC_PrintCName(struct vsb *vsb, const char *b, const char *e); struct symbol *VCC_MkSym(struct vcc *tl, const char *b, vcc_ns_t, vcc_kind_t, int, int); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index c2e25c871..598a283b4 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -329,6 +329,29 @@ vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t, } } +void v_matchproto_(sym_expr_t) +vcc_Eval_Sub(struct vcc *tl, struct expr **e, struct token *t, + struct symbol *sym, vcc_type_t type) +{ + + (void)t; + (void)tl; + AN(sym->rname); + AZ(type->stringform); + + assert (sym->type == SUB); + + if (type == SUB) { + *e = vcc_mk_expr(sym->type, "%s", sym->rname); + (*e)->constant = EXPR_CONST; + return; + } + + VSB_printf(tl->sb, "Symbol '%s' can only be used as a %s expression\n", + sym->name, sym->type->name); + vcc_ErrWhere(tl, tl->t); +} + /*-------------------------------------------------------------------- */ diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c index 5125cda3e..25d824b91 100644 --- a/lib/libvcc/vcc_symb.c +++ b/lib/libvcc/vcc_symb.c @@ -76,7 +76,7 @@ struct symtab { VTAILQ_HEAD(,symbol) symbols; }; -static vcc_kind_t +vcc_kind_t VCC_HandleKind(vcc_type_t fmt) { if (fmt == ACL) return (SYM_ACL); @@ -510,7 +510,10 @@ VCC_GlobalSymbol(struct symbol *sym, vcc_type_t type) sym->kind = VCC_HandleKind(sym->type); if (sym->kind != SYM_NONE) { AZ(VCT_invalid_name(sym->rname, NULL)); - sym->eval = vcc_Eval_Handle; + if (type == SUB) + sym->eval = vcc_Eval_Sub; + else + sym->eval = vcc_Eval_Handle; } else { WRONG("Wrong kind of global symbol"); } From nils.goroll at uplex.de Tue Nov 23 12:31:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:07 +0000 (UTC) Subject: [master] 464dad5eb Split out dns-dependent test Message-ID: <20211123123107.EACB9115CAD@lists.varnish-cache.org> commit 464dad5ebfb787d4723a20b6cbf51c0a5a7ce12b Author: Nils Goroll Date: Fri Oct 29 16:58:57 2021 +0200 Split out dns-dependent test Conflicts: bin/varnishtest/tests/v00022.vtc diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index f4421a166..8a8dc1cf3 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -1,7 +1,5 @@ varnishtest "Various VCL compiler coverage tests" -feature dns - shell "true > ${tmpdir}/_varnishtest_empty_file" varnish v1 -vcl { @@ -82,13 +80,6 @@ varnish v1 -errvcl {Regexp compilation error:} { } } -varnish v1 -errvcl {resolves to too many addresses} { - backend b { .host = "${localhost}"; } - sub vcl_recv { - if (remote.ip == "dns-canary-multi.varnish-cache.org") {} - } -} - varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; backend b { .host = "${localhost}"; } diff --git a/bin/varnishtest/tests/v00022.vtc b/bin/varnishtest/tests/v00022.vtc new file mode 100644 index 000000000..fcb8014da --- /dev/null +++ b/bin/varnishtest/tests/v00022.vtc @@ -0,0 +1,10 @@ +varnishtest "Various VCL compiler coverage tests - DNS dependent" + +feature dns + +varnish v1 -errvcl {resolves to too many addresses} { + backend b { .host = "${localhost}"; } + sub vcl_recv { + if (remote.ip == "dns-canary-multi.varnish-cache.org") {} + } +} From nils.goroll at uplex.de Tue Nov 23 12:31:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:08 +0000 (UTC) Subject: [master] 5e1589bf4 Use backend none more Message-ID: <20211123123108.25647115CC6@lists.varnish-cache.org> commit 5e1589bf469be312e9af6ee98053936d55cfb7ce Author: Nils Goroll Date: Fri Oct 29 17:00:05 2021 +0200 Use backend none more diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index 8a8dc1cf3..f1971efad 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -8,14 +8,14 @@ varnish v1 -vcl { } varnish v1 -errvcl {include not followed by semicolon.} { - backend b { .host = "${localhost}"; } + backend b none; include "${tmpdir}/_varnishtest_empty_file" | } shell "rm -f ${tmpdir}/_varnishtest_empty_file" varnish v1 -errvcl {include not followed by string constant.} { - backend b { .host = "${localhost}"; } + backend b none; include << } @@ -29,18 +29,18 @@ varnish v1 -errvcl {include not followed by string constant.} { } varnish v1 -errvcl {Unknown duration unit 'k'} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_backend_response { set beresp.ttl = 1. k; } } varnish v1 -errvcl {Operator > not possible on BACKEND} { - backend a { .host = "${localhost}"; } - backend b { .host = "${localhost}"; } + backend a none; + backend b none; sub vcl_recv { if (a > b) { } } } varnish v1 -errvcl {Unknown property 'foo' for type HTTP} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_hash { if (req.foo != "bar") { } } } @@ -51,21 +51,21 @@ varnish v1 -errvcl {Symbol not found: 'foo.bar'} { } varnish v1 -errvcl {Cannot be set in subroutine 'vcl_pipe'} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_pipe { set bereq.first_byte_timeout = 10s; } } varnish v1 -errvcl {Cannot be set in subroutine 'vcl_pipe'.} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_pipe { set bereq.between_bytes_timeout = 10s; } } varnish v1 -errvcl {Undefined backend c, first reference:} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_backend_response { if (beresp.backend == c) { set beresp.ttl = 1h; @@ -74,7 +74,7 @@ varnish v1 -errvcl {Undefined backend c, first reference:} { } varnish v1 -errvcl {Regexp compilation error:} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_recv { if (req.url ~ "[a") {} } @@ -82,7 +82,7 @@ varnish v1 -errvcl {Regexp compilation error:} { varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; - backend b { .host = "${localhost}"; } + backend b none; sub vcl_init { new foo = directors.shard(); @@ -96,7 +96,7 @@ varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { varnish v1 -syntax 4.0 -errvcl {Expression has type directors.shard, expected ACL} { import directors; - backend b { .host = "${localhost}"; } + backend b none; sub vcl_init { new foo = directors.shard(); @@ -121,7 +121,7 @@ varnish v1 -errvcl {Undefined sub foo} { varnish v1 -syntax 4.0 -errvcl {Symbol not found: 'directors.foo' At:} { import directors; - backend b { .host = "${localhost}"; } + backend b none; sub vcl_init { new foo = directors.foo(); @@ -130,7 +130,7 @@ At:} { # 'foo' overloaded varnish v1 -syntax 4.0 -errvcl {Symbol not found: 'foo'} { - backend b { .host = "${localhost}"; } + backend b none; acl foo -pedantic { "${localhost}"/32; diff --git a/bin/varnishtest/tests/v00022.vtc b/bin/varnishtest/tests/v00022.vtc index fcb8014da..953882fd8 100644 --- a/bin/varnishtest/tests/v00022.vtc +++ b/bin/varnishtest/tests/v00022.vtc @@ -3,7 +3,7 @@ varnishtest "Various VCL compiler coverage tests - DNS dependent" feature dns varnish v1 -errvcl {resolves to too many addresses} { - backend b { .host = "${localhost}"; } + backend b none; sub vcl_recv { if (remote.ip == "dns-canary-multi.varnish-cache.org") {} } From nils.goroll at uplex.de Tue Nov 23 12:31:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:08 +0000 (UTC) Subject: [master] 8a4a7cc61 VCL_REGEX: Support concatenation of constant strings Message-ID: <20211123123108.511AE115CD8@lists.varnish-cache.org> commit 8a4a7cc612253267b5ff97d3d52130953618c3c2 Author: Nils Goroll Date: Fri Oct 29 16:51:04 2021 +0200 VCL_REGEX: Support concatenation of constant strings For the REGEX type, we now peek ahead after the first CSTR token if a '+' operator follows and, if yes, create the pattern as a concatenation. Fixes #3726 diff --git a/bin/varnishtest/tests/b00028.vtc b/bin/varnishtest/tests/b00028.vtc index 074595956..4280e8e6c 100644 --- a/bin/varnishtest/tests/b00028.vtc +++ b/bin/varnishtest/tests/b00028.vtc @@ -8,7 +8,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_backend_response { - if (beresp.http.foo ~ "bar") { + if (beresp.http.foo ~ "b" + "ar") { set beresp.http.foo1 = "1"; } else { set beresp.status = 999; diff --git a/bin/varnishtest/tests/c00103.vtc b/bin/varnishtest/tests/c00103.vtc index 11da0f0b9..75dc18ed3 100644 --- a/bin/varnishtest/tests/c00103.vtc +++ b/bin/varnishtest/tests/c00103.vtc @@ -8,7 +8,8 @@ varnish v1 -vcl { # on purpose to ensure we don't treat REGEX expressions # differently. if (req.url ~ (debug.just_return_regex( - debug.just_return_regex("hello")))) { + debug.just_return_regex("he" + + "l" + "lo")))) { return (synth(200)); } return (synth(500)); diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc index f1971efad..8404b2552 100644 --- a/bin/varnishtest/tests/v00016.vtc +++ b/bin/varnishtest/tests/v00016.vtc @@ -80,6 +80,27 @@ varnish v1 -errvcl {Regexp compilation error:} { } } +varnish v1 -errvcl {Regexp compilation error:} { + backend b none; + sub vcl_recv { + if (req.url ~ "[" + "a") {} + } +} + +varnish v1 -errvcl {Expected CSTR got 'req'} { + backend b none; + sub vcl_recv { + if (req.url ~ "a" + req.http.foo) {} + } +} + +varnish v1 -errvcl {Expected ')' got '-'} { + backend b none; + sub vcl_recv { + if (req.url ~ "a" - "b") {} + } +} + varnish v1 -errvcl {Expression has type directors.shard, expected ACL} { import directors; backend b none; diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 04dca950d..5633f83f4 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -51,19 +51,38 @@ void vcc_regexp(struct vcc *tl, struct vsb *vgc_name) { + struct vsb *pattern; char buf[BUFSIZ]; vre_t *t; int error, erroroffset; + struct token *t1; struct inifin *ifp; + pattern = VSB_new_auto(); + AN(pattern); + assert(tl->t->tok == CSTR); + VSB_cat(pattern, tl->t->dec); + + t1 = vcc_PeekToken(tl); + AN(t1); + while (t1->tok == '+') { + vcc_NextToken(tl); + SkipToken(tl, '+'); + ExpectErr(tl, CSTR); + VSB_cat(pattern, tl->t->dec); + t1 = vcc_PeekToken(tl); + AN(t1); + } + AZ(VSB_finish(pattern)); - t = VRE_compile(tl->t->dec, 0, &error, &erroroffset, 0); + t = VRE_compile(VSB_data(pattern), 0, &error, &erroroffset, 0); if (t == NULL) { VSB_cat(tl->sb, "Regexp compilation error:\n\n"); AZ(VRE_error(tl->sb, error)); VSB_cat(tl->sb, "\n\n"); vcc_ErrWhere(tl, tl->t); + VSB_destroy(&pattern); return; } VRE_free(&t); @@ -74,9 +93,10 @@ vcc_regexp(struct vcc *tl, struct vsb *vgc_name) Fh(tl, 0, "static struct vre *%s;\n", buf); ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\tVPI_re_init(&%s, ",buf); - EncToken(ifp->ini, tl->t); + VSB_quote(ifp->ini, VSB_data(pattern), -1, VSB_QUOTE_CSTR); VSB_cat(ifp->ini, ");"); VSB_printf(ifp->fin, "\t\tVPI_re_fini(%s);", buf); + VSB_destroy(&pattern); } /* From dridi.boukelmoune at gmail.com Tue Nov 23 12:31:08 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 12:31:08 +0000 (UTC) Subject: [master] f5077e639 Use correct list var name in mgt_vcl_discard_depcheck Message-ID: <20211123123108.8281E115CDC@lists.varnish-cache.org> commit f5077e6399a359548beca2c3e5c827dccb5231fb Author: Martin Blix Grydeland Date: Fri Nov 12 11:39:11 2021 +0100 Use correct list var name in mgt_vcl_discard_depcheck Using the wrong list variable would cause the dependency check to consider VCLs that were not attempted discarded. Fixes: #3734 diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index df77dd0c8..000b6b11e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -754,7 +754,7 @@ mgt_vcl_discard_depcheck(struct cli *cli) struct vclprog *vp; struct vcldep *vd; - VTAILQ_FOREACH(vp, &discardhead, list) { + VTAILQ_FOREACH(vp, &discardhead, discard_list) { VTAILQ_FOREACH(vd, &vp->dto, lto) if (!vd->from->discard) { mgt_vcl_discard_depfail(cli, vp); diff --git a/bin/varnishtest/tests/r03734.vtc b/bin/varnishtest/tests/r03734.vtc new file mode 100644 index 000000000..a34ebefd0 --- /dev/null +++ b/bin/varnishtest/tests/r03734.vtc @@ -0,0 +1,44 @@ +varnishtest "Issue 3734 - Discard dependency check and labels" + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + return (synth(200, "vcl1")); + } +} -start + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + return (synth(200, "vcl2")); + } +} + +varnish v1 -cliok { vcl.label lbl_vcl2 vcl2 } + +varnish v1 -vcl { + backend default none; + + sub vcl_recv { + if (req.url == "/label") { + return (vcl(lbl_vcl2)); + } + return (synth(200, "vcl3")); + } +} + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.reason == vcl3 + + txreq -url /label + rxresp + expect resp.status == 200 + expect resp.reason == vcl2 +} -run + +varnish v1 -cliok { vcl.discard vcl1 } From nils.goroll at uplex.de Tue Nov 23 12:31:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:08 +0000 (UTC) Subject: [master] 4f9785ec5 Do not select active VCL automatically in the child process Message-ID: <20211123123108.AFA9F115CE0@lists.varnish-cache.org> commit 4f9785ec56c187eb62cc6bffad433da7a74d9f97 Author: AlveElde Date: Wed Aug 25 17:38:47 2021 +0200 Do not select active VCL automatically in the child process Do not select the first VCL present as the active VCL in the child process. Instead it should always use what the mgt process tells it through the explicit 'vcl.use' commands it will send. Previously, the child could select a cold VCL as the active VCL if that happened to be the first one present to it during restarts. This could lead to asserts as that is not an allowed state. diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 0efded131..ac72ede22 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -707,10 +707,6 @@ vcl_load(struct cli *cli, VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name); VTAILQ_INSERT_TAIL(&vcl_head, vcl, list); - Lck_Lock(&vcl_mtx); - if (vcl_active == NULL) - vcl_active = vcl; - Lck_Unlock(&vcl_mtx); VSC_C_main->n_vcl++; VSC_C_main->n_vcl_avail++; } From nils.goroll at uplex.de Tue Nov 23 12:31:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:08 +0000 (UTC) Subject: [master] d13663f5b Enforce invariant on vcl_active in the child process Message-ID: <20211123123108.E2450115CE4@lists.varnish-cache.org> commit d13663f5b774a0bd827390517b5b0d5fc90962e0 Author: Martin Blix Grydeland Date: Tue Oct 19 11:46:09 2021 +0200 Enforce invariant on vcl_active in the child process Add a ASSERT_VCL_ACTIVE() macro that asserts that vcl_active either is NULL or points to a VCL that is warm. Sprinkle this macro in the various calls throughout the child process that are involved in VCL handling. Patch by: @alveelde diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index ac72ede22..c69e1e5c7 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -213,6 +213,7 @@ vcl_send_event(struct vcl *vcl, enum vcl_event_e ev, struct vsb **msg) struct vrt_ctx *ctx; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); @@ -337,6 +338,7 @@ VCL_Update(struct vcl **vcc, struct vcl *vcl) *vcc = NULL; CHECK_OBJ_ORNULL(old, VCL_MAGIC); + ASSERT_VCL_ACTIVE(); Lck_Lock(&vcl_mtx); if (old != NULL) { @@ -393,6 +395,7 @@ VCL_IterDirector(struct cli *cli, const char *pat, struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vsb = VSB_new_auto(); AN(vsb); if (pat == NULL || *pat == '\0' || !strcmp(pat, "*")) { @@ -665,6 +668,7 @@ vcl_load(struct cli *cli, struct vsb *msg; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vcl = vcl_find(name); AZ(vcl); @@ -720,6 +724,7 @@ VCL_Poll(void) struct vcl *vcl, *vcl2; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); VTAILQ_FOREACH_SAFE(vcl, &vcl_head, list, vcl2) { if (vcl->temp == VCL_TEMP_BUSY || vcl->temp == VCL_TEMP_COOLING) @@ -755,6 +760,7 @@ vcl_cli_list(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); vsb = VSB_new_auto(); AN(vsb); VTAILQ_FOREACH(vcl, &vcl_head, list) { @@ -787,6 +793,7 @@ vcl_cli_list_json(struct cli *cli, const char * const *av, void *priv) (void)priv; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); VCLI_JSON_begin(cli, 2, av); VCLI_Out(cli, ",\n"); VTAILQ_FOREACH(vcl, &vcl_head, list) { @@ -844,6 +851,7 @@ vcl_cli_state(struct cli *cli, const char * const *av, void *priv) AZ(priv); ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AN(av[2]); AN(av[3]); @@ -869,6 +877,7 @@ vcl_cli_discard(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); (void)cli; AZ(priv); vcl = vcl_find(av[2]); @@ -902,6 +911,7 @@ vcl_cli_label(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); (void)cli; (void)priv; vcl = vcl_find(av[3]); @@ -927,6 +937,7 @@ vcl_cli_use(struct cli *cli, const char * const *av, void *priv) struct vcl *vcl; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AN(cli); AZ(priv); vcl = vcl_find(av[2]); @@ -945,6 +956,7 @@ vcl_cli_show(struct cli *cli, const char * const *av, void *priv) int i; ASSERT_CLI(); + ASSERT_VCL_ACTIVE(); AZ(priv); if (!strcmp(av[2], "-v") && av[3] == NULL) { VCLI_Out(cli, "Too few parameters"); diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h index 0c72c22ec..355cccf59 100644 --- a/bin/varnishd/cache/cache_vcl.h +++ b/bin/varnishd/cache/cache_vcl.h @@ -88,3 +88,9 @@ extern const struct vcltemp VCL_TEMP_COLD[1]; extern const struct vcltemp VCL_TEMP_WARM[1]; extern const struct vcltemp VCL_TEMP_BUSY[1]; extern const struct vcltemp VCL_TEMP_COOLING[1]; + +#define ASSERT_VCL_ACTIVE() \ + do { \ + assert(vcl_active == NULL || \ + vcl_active->temp->is_warm); \ + } while (0) diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index f7bcf2017..3fd34e42e 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -84,6 +84,7 @@ VCL_Refresh(struct vcl **vcc) while (vcl_active == NULL) (void)usleep(100000); + ASSERT_VCL_ACTIVE(); if (*vcc == vcl_active) return; @@ -97,6 +98,7 @@ VCL_Recache(const struct worker *wrk, struct vcl **vclp) AN(wrk); AN(vclp); CHECK_OBJ_NOTNULL(*vclp, VCL_MAGIC); + ASSERT_VCL_ACTIVE(); if (*vclp != vcl_active || wrk->wpriv->vcl == vcl_active) { VCL_Rel(vclp); From nils.goroll at uplex.de Tue Nov 23 12:31:09 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:09 +0000 (UTC) Subject: [master] 9228395ea Rename active_vcl to mgt_vcl_active Message-ID: <20211123123109.172D4115CEB@lists.varnish-cache.org> commit 9228395ea5d13693fe5965b29abfeb4c0e34ee77 Author: Martin Blix Grydeland Date: Tue Oct 19 14:02:33 2021 +0200 Rename active_vcl to mgt_vcl_active It is very easy to confuse the child process' vcl_active and the management process' active_vcl variables. Rename mgt's active_vcl to mgt_vcl_active, following the naming scheme used elsewhere. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index 000b6b11e..b5507d3ff 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -63,7 +63,7 @@ static unsigned vcl_count; struct vclproghead vclhead = VTAILQ_HEAD_INITIALIZER(vclhead); static struct vclproghead discardhead = VTAILQ_HEAD_INITIALIZER(discardhead); struct vmodfilehead vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead); -static struct vclprog *active_vcl; +static struct vclprog *mgt_vcl_active; static struct vev *e_poker; static int mgt_vcl_setstate(struct cli *, struct vclprog *, @@ -300,7 +300,7 @@ mgt_vcl_set_cooldown(struct vclprog *vp, vtim_mono now) { CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC); - if (vp == active_vcl || + if (vp == mgt_vcl_active || vp->state != VCL_STATE_AUTO || vp->warm == 0 || !VTAILQ_EMPTY(&vp->dto) || @@ -401,7 +401,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) os = vp->state; vp->state = vs; - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { assert (vs == VCL_STATE_WARM || vs == VCL_STATE_AUTO); AN(vp->warm); warm = 1; @@ -458,8 +458,8 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, AZ(C_flag); vp->fname = lib; - if (active_vcl == NULL) - active_vcl = vp; + if (mgt_vcl_active == NULL) + mgt_vcl_active = vp; if ((cli->result == CLIS_OK || cli->result == CLIS_TRUNCATED) && vcl_count > mgt_param.max_vcl && @@ -501,7 +501,7 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - active_vcl = NULL; + mgt_vcl_active = NULL; (void)mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); } @@ -514,7 +514,7 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) struct vcldep *vd; int done; - AN(active_vcl); + AN(mgt_vcl_active); /* The VCL has not been loaded yet, it cannot fail */ (void)cli; @@ -554,8 +554,10 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) } } while (!done); - if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", active_vcl->name)) + if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", + mgt_vcl_active->name)) { return (1); + } free(*p); *p = NULL; return (0); @@ -617,7 +619,7 @@ mcf_vcl_state(struct cli *cli, const char * const *av, void *priv) VCLI_SetResult(cli, CLIS_CANT); return; } - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { VCLI_Out(cli, "Cannot set the active VCL cold."); VCLI_SetResult(cli, CLIS_CANT); return; @@ -639,7 +641,7 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv) vp = mcf_find_vcl(cli, av[2]); if (vp == NULL) return; - if (vp == active_vcl) + if (vp == mgt_vcl_active) return; if (mgt_vcl_requirewarm(cli, vp)) @@ -651,8 +653,8 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "%s", p); } else { VCLI_Out(cli, "VCL '%s' now active", av[2]); - vp2 = active_vcl; - active_vcl = vp; + vp2 = mgt_vcl_active; + mgt_vcl_active = vp; now = VTIM_mono(); mgt_vcl_set_cooldown(vp, now); if (vp2 != NULL) @@ -669,7 +671,7 @@ mgt_vcl_discard(struct cli *cli, struct vclprog *vp) AN(vp); AN(vp->discard); - assert(vp != active_vcl); + assert(vp != mgt_vcl_active); while (!VTAILQ_EMPTY(&vp->dto)) mgt_vcl_discard(cli, VTAILQ_FIRST(&vp->dto)->from); @@ -699,7 +701,7 @@ mgt_vcl_discard_mark(struct cli *cli, const char *glob) VTAILQ_FOREACH(vp, &vclhead, list) { if (fnmatch(glob, vp->name, 0)) continue; - if (vp == active_vcl) { + if (vp == mgt_vcl_active) { VCLI_SetResult(cli, CLIS_CANT); VCLI_Out(cli, "Cannot discard active VCL program %s\n", vp->name); @@ -829,7 +831,7 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv) VTAILQ_FOREACH(vp, &vclhead, list) { VSB_printf(vsb, "%s", - vp == active_vcl ? "active" : "available"); + vp == mgt_vcl_active ? "active" : "available"); vs = vp->warm ? VCL_STATE_WARM : VCL_STATE_COLD; VSB_printf(vsb, "\t%s\t%s", vp->state->name, vs->name); VSB_printf(vsb, "\t%6s\t%s", "-", vp->name); @@ -875,7 +877,7 @@ mcf_vcl_list_json(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "{\n"); VSB_indent(cli->sb, 2); VCLI_Out(cli, "\"status\": \"%s\",\n", - vp == active_vcl ? "active" : "available"); + vp == mgt_vcl_active ? "active" : "available"); VCLI_Out(cli, "\"state\": \"%s\",\n", vp->state->name); vs = vp->warm ? VCL_STATE_WARM : VCL_STATE_COLD; VCLI_Out(cli, "\"temperature\": \"%s\",\n", vs->name); @@ -1097,7 +1099,7 @@ mgt_vcl_atexit(void) if (getpid() != heritage.mgt_pid) return; - active_vcl = NULL; + mgt_vcl_active = NULL; while (!VTAILQ_EMPTY(&vclhead)) VTAILQ_FOREACH_SAFE(vp, &vclhead, list, vp2) if (VTAILQ_EMPTY(&vp->dto)) From nils.goroll at uplex.de Tue Nov 23 12:31:09 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:09 +0000 (UTC) Subject: [master] 506c452a0 Make mgt_has_vcl() return an error string Message-ID: <20211123123109.A0375115D1E@lists.varnish-cache.org> commit 506c452a06d1d5e8efd9beea961d6b140996c18a Author: Martin Blix Grydeland Date: Tue Oct 19 13:56:16 2021 +0200 Make mgt_has_vcl() return an error string mgt_has_vcl() now returns an error string describing why it doesn't have a valid VCL. This is taken from #3711 by @bsdphk diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h index c8db1954e..f2d2f0f7e 100644 --- a/bin/varnishd/mgt/mgt.h +++ b/bin/varnishd/mgt/mgt.h @@ -231,7 +231,7 @@ void mgt_vcl_init(void); void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin, const char *vclname, int Cflag); int mgt_push_vcls(struct cli *, unsigned *status, char **p); -int mgt_has_vcl(void); +const char *mgt_has_vcl(void); extern char *mgt_cc_cmd; extern const char *mgt_vcl_path; extern const char *mgt_vmod_path; diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index 5af419fed..6248ca1d7 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -707,15 +707,17 @@ mch_pid_json(struct cli *cli, const char * const *av, void *priv) static void v_matchproto_(cli_func_t) mch_cli_server_start(struct cli *cli, const char * const *av, void *priv) { + const char *err; (void)av; (void)priv; if (child_state == CH_STOPPED) { - if (mgt_has_vcl()) { + err = mgt_has_vcl(); + if (err == NULL) { mgt_launch_child(cli); } else { VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No VCL available"); + VCLI_Out(cli, "%s", err); } } else { VCLI_SetResult(cli, CLIS_CANT); diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index f5d2ede33..ecc09dc3f 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -483,6 +483,7 @@ main(int argc, char * const *argv) char *p; struct cli cli[1]; char **av; + const char *err; unsigned u; struct sigaction sac; struct vev *e; @@ -909,10 +910,11 @@ main(int argc, char * const *argv) } assert(I_fd == -1); - if (!d_flag && !mgt_has_vcl() && !novcl) - MGT_Complain(C_ERR, "No VCL loaded yet"); + err = mgt_has_vcl(); + if (!d_flag && err != NULL && !novcl) + MGT_Complain(C_ERR, "%s", err); - if (mgt_has_vcl() && ! d_flag) + if (err == NULL && !d_flag) u = MCH_Start_Child(); else u = 0; diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index b5507d3ff..d14c9d95c 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -281,11 +281,16 @@ mgt_vcl_del(struct vclprog *vp) FREE_OBJ(vp); } -int +const char * mgt_has_vcl(void) { - - return (!VTAILQ_EMPTY(&vclhead)); + if (VTAILQ_EMPTY(&vclhead)) + return ("No VCL loaded"); + if (mgt_vcl_active == NULL) + return ("No active VCL"); + CHECK_OBJ_NOTNULL(mgt_vcl_active, VCLPROG_MAGIC); + AN(mgt_vcl_active->warm); + return (NULL); } /* From nils.goroll at uplex.de Tue Nov 23 12:31:09 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:09 +0000 (UTC) Subject: [master] a2c70c5e9 Change mgt_new_vcl() to return the newly compiled vclprog Message-ID: <20211123123109.E2868115D34@lists.varnish-cache.org> commit a2c70c5e9ee20b7474bf982ee30a20e5985a5b9f Author: Martin Blix Grydeland Date: Thu Nov 11 14:19:18 2021 +0100 Change mgt_new_vcl() to return the newly compiled vclprog mgt_new_vcl() now returns a pointer to the newly compiled VCL program, or NULL on failure. This also fixes a wrong return value used previously which would cause a "VCL compiled.\n" to be output to CLI when the child is not running even when the VCL compilation step failed. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index d14c9d95c..a45645e5d 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -426,7 +426,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) /*--------------------------------------------------------------------*/ -static int +static struct vclprog * mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, const char *vclsrcfile, const char *state, int C_flag) { @@ -442,7 +442,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, VCLI_Out(cli, "Too many (%d) VCLs already loaded\n", vcl_count); VCLI_Out(cli, "(See max_vcl and max_vcl_handling parameters)"); VCLI_SetResult(cli, CLIS_CANT); - return (0); + return (NULL); } if (state == NULL) @@ -451,13 +451,13 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, vs = mcf_vcl_parse_state(cli, state); if (vs == NULL) - return (0); + return (NULL); vp = mgt_vcl_add(vclname, vs); lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfile, C_flag); if (lib == NULL) { mgt_vcl_del(vp); - return (0); + return (NULL); } AZ(C_flag); @@ -475,7 +475,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, } if (!MCH_Running()) - return (0); + return (vp); if (mgt_cli_askchild(&status, &p, "vcl.load %s %s %d%s\n", vp->name, vp->fname, vp->warm, vp->state->name)) { @@ -483,12 +483,12 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, VCLI_Out(cli, "%s", p); VCLI_SetResult(cli, status); free(p); - return (0); + return (NULL); } free(p); mgt_vcl_set_cooldown(vp, VTIM_mono()); - return (1); + return (vp); } /*--------------------------------------------------------------------*/ @@ -573,25 +573,29 @@ mgt_push_vcls(struct cli *cli, unsigned *status, char **p) static void v_matchproto_(cli_func_t) mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv) { + struct vclprog *vp; (void)priv; if (!mcf_find_no_vcl(cli, av[2])) return; - if (!mgt_new_vcl(cli, av[2], av[3], "", av[4], 0)) + vp = mgt_new_vcl(cli, av[2], av[3], "", av[4], 0); + if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } static void v_matchproto_(cli_func_t) mcf_vcl_load(struct cli *cli, const char * const *av, void *priv) { + struct vclprog *vp; (void)priv; if (!mcf_find_no_vcl(cli, av[2])) return; - if (!mgt_new_vcl(cli, av[2], NULL, av[3], av[4], 0)) + vp = mgt_new_vcl(cli, av[2], NULL, av[3], av[4], 0); + if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } From nils.goroll at uplex.de Tue Nov 23 12:31:10 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:10 +0000 (UTC) Subject: [master] dda20238b Limit automatic active VCL selection to startup VCLs Message-ID: <20211123123110.205AA115D4C@lists.varnish-cache.org> commit dda20238b9dc27f4c907e50fe6e207501683fa9a Author: Martin Blix Grydeland Date: Thu Nov 11 14:33:23 2021 +0100 Limit automatic active VCL selection to startup VCLs Limit the selection of the active VCL from MGT's view point to be the last startup VCL given. That would be the VCL from the very last -f argument given to varnishd, or the autogenerated VCL from the -b argument (-f and -b are mutually exclusive). Because all startup VCLs are always set to state AUTO, and AUTO VCLs are made warm when the child is not running (which it is not at the time the startup VCLs are compiled), this ensures that it is a warm VCL that is selected as the active VCL. With this patch, VCLs loaded through the use of an initial CLI command script (-I option) will not cause a VCL to automatically be selected as the active VCL. Rather, it is expected that the initial CLI command script should have an explicit 'vcl.use' statement to select the active VCL. When an active VCL is not set, attempts to start the child will fail, which again will fail the varnishd daemon startup (unless -d is given) with an error code. The behaviour prior to this patch when using -I, -f '' (empty field), -F or -d was not well defined. The first VCL loaded (either by -I startup CLI script or a CLI 'vcl.load' command) would become the active VCL, even if that VCL is loaded cold. That is an illegal state and would lead to asserts. It is also not very useful functionality, given the typical use case for -I is to set up VCL labels. Those require the tips of the VCL tree dependency graph to be loaded first, and then the VCLs that selects the label. This means that the active VCL will typically be the last VCL loaded, which then will require the use of a 'vcl.use' statement in the -I script anyways. This makes it an acceptable change of default behaviour that should not affect users. diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index a45645e5d..69b35371e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -463,9 +463,6 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, AZ(C_flag); vp->fname = lib; - if (mgt_vcl_active == NULL) - mgt_vcl_active = vp; - if ((cli->result == CLIS_OK || cli->result == CLIS_TRUNCATED) && vcl_count > mgt_param.max_vcl && mgt_param.max_vcl_handling == 1) { @@ -499,6 +496,9 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, { char buf[20]; static int n = 0; + struct vclprog *vp; + + AZ(MCH_Running()); AN(vclsrc); AN(origin); @@ -506,8 +506,13 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - mgt_vcl_active = NULL; - (void)mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); + vp = mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, C_flag); + if (vp != NULL) { + /* Last startup VCL becomes the automatically selected + * active VCL. */ + AN(vp->warm); + mgt_vcl_active = vp; + } } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishtest/tests/u00000.vtc b/bin/varnishtest/tests/u00000.vtc index dbed3ce58..5103f85b3 100644 --- a/bin/varnishtest/tests/u00000.vtc +++ b/bin/varnishtest/tests/u00000.vtc @@ -105,6 +105,10 @@ shell -expect {VCL compiled.} { varnishadm -n ${tmpdir}/v1 vcl.load vcl1 ${tmpdir}/vcl } +shell -expect {VCL 'vcl1' now active} { + varnishadm -n ${tmpdir}/v1 vcl.use vcl1 +} + shell -expect {active auto warm - vcl1} { varnishadm -n ${tmpdir}/v1 vcl.list } From nils.goroll at uplex.de Tue Nov 23 12:31:10 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:10 +0000 (UTC) Subject: [master] a72a28a2b Test case for handling initially cold VCLs Message-ID: <20211123123110.4C809115D70@lists.varnish-cache.org> commit a72a28a2bec375e67ad5d5b1b10ff913e8d3c80c Author: AlveElde Date: Wed Aug 25 17:38:47 2021 +0200 Test case for handling initially cold VCLs diff --git a/bin/varnishtest/tests/v00067.vtc b/bin/varnishtest/tests/v00067.vtc new file mode 100644 index 000000000..46c72c18a --- /dev/null +++ b/bin/varnishtest/tests/v00067.vtc @@ -0,0 +1,41 @@ +varnishtest "The active VCL must always be warm" + +shell { + cat >${tmpdir}/f1 <<-EOF + vcl 4.1; + backend default none; + EOF +} + +# Load a cold VCL. This should not become the active VCL. +varnish v1 -cliok "vcl.load vcl_cold ${tmpdir}/f1 cold" +varnish v1 -cliexpect "available *cold *cold *- *vcl_cold" "vcl.list" + +# The cache should not start without a warm VCL. +varnish v1 -clierr 300 "start" + +# Load a warm VCL and make it the active VCL. +varnish v1 -cliok "vcl.load vcl_warm ${tmpdir}/f1 warm" +varnish v1 -cliok "vcl.use vcl_warm" +varnish v1 -cliexpect "active *warm *warm *- *vcl_warm" "vcl.list" + +# The cache now starts. +varnish v1 -cliok "start" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_cold" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_warm" "vcl.list" + +# Load an automatically warming VCL, and set it as the active VCL. +varnish v1 -cliok "vcl.load vcl_auto ${tmpdir}/f1 warm" +varnish v1 -cliok "vcl.use vcl_auto" +varnish v1 -cliexpect "available *warm *warm *0 *vcl_warm" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_auto" "vcl.list" + +# Cool the previous active VCL. +varnish v1 -cliok "vcl.state vcl_warm cold" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_warm" "vcl.list" + +# Restart the cache. +varnish v1 -cliok "stop" -cliok "start" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_cold" "vcl.list" +varnish v1 -cliexpect "available *cold *cold *0 *vcl_warm" "vcl.list" +varnish v1 -cliexpect "active *warm *warm *0 *vcl_auto" "vcl.list" From nils.goroll at uplex.de Tue Nov 23 12:31:10 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:10 +0000 (UTC) Subject: [master] d084467a4 Amend the docs on the '-I' option Message-ID: <20211123123110.7AEBE115D91@lists.varnish-cache.org> commit d084467a4e478adbd09da1231229bb8db8d3ceee Author: Martin Blix Grydeland Date: Thu Nov 11 16:31:32 2021 +0100 Amend the docs on the '-I' option Make a note in the documentation of CLI Command File that it is necessary to include an explicit 'vcl.use' command in the script. diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 844487467..cdb08d40e 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -510,6 +510,10 @@ a newline or carriage return. If a command in the file is prefixed with '-', failure will not abort the startup. +Note that it is necessary to include an explicit `vcl.use` command to +select which VCL should be the active VCL when relying on CLI Command File +to load the configurations at startup. + .. _ref-varnishd-params: RUN TIME PARAMETERS From nils.goroll at uplex.de Tue Nov 23 12:31:10 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:10 +0000 (UTC) Subject: [master] 258471a36 vca: Remove the tcp_opt::iponly field Message-ID: <20211123123110.ABC2E115DA1@lists.varnish-cache.org> commit 258471a366bccbd58fee3ae2d6766bda21f71354 Author: Dridi Boukelmoune Date: Mon Sep 27 07:18:29 2021 +0200 vca: Remove the tcp_opt::iponly field It is a 1:1 mapping with IPPROTO_TCP, so TCP_NODELAY was moved down to be with the other IPPROTO_TCP options. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 33dc99130..e55a262fd 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -87,26 +87,23 @@ static struct tcp_opt { socklen_t sz; void *ptr; int need; - int iponly; } tcp_opts[] = { -#define TCPO(lvl, nam, sz, ip) { lvl, nam, #nam, sizeof(sz), 0, 0, ip}, - - TCPO(SOL_SOCKET, SO_LINGER, struct linger, 0) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int, 0) - TCPO(IPPROTO_TCP, TCP_NODELAY, int, 1) +#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, + TCPO(SOL_SOCKET, SO_LINGER, struct linger) + TCPO(SOL_SOCKET, SO_KEEPALIVE, int) #ifdef SO_SNDTIMEO_WORKS - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval, 0) + TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) #endif - #ifdef SO_RCVTIMEO_WORKS - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval, 0) + TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) #endif + TCPO(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int, 1) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int, 1) + TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) + TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) + TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif #undef TCPO @@ -229,7 +226,7 @@ vca_tcp_opt_test(const int sock, const unsigned uds) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; to->need = 1; ptr = calloc(1, to->sz); @@ -252,7 +249,7 @@ vca_tcp_opt_set(const int sock, const unsigned uds, const int force) for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && uds) + if (to->level == IPPROTO_TCP && uds) continue; if (to->need || force) { VTCP_Assert(setsockopt(sock, From nils.goroll at uplex.de Tue Nov 23 12:31:10 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:10 +0000 (UTC) Subject: [master] 1780645d1 vca: Rename tcp_opt to a more general sock_opt Message-ID: <20211123123110.D67C8115DB3@lists.varnish-cache.org> commit 1780645d1a98a523b458cbf1d4f6ea2b24043b82 Author: Dridi Boukelmoune Date: Mon Sep 27 07:42:44 2021 +0200 vca: Rename tcp_opt to a more general sock_opt And conversely rename `to` variables to `so` for consistency. Better diff with the --word-diff --word-diff-regex='\w+' options. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index e55a262fd..a89f9e044 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -80,36 +80,36 @@ struct poolsock { * TCP options we want to control */ -static struct tcp_opt { +static struct sock_opt { int level; int optname; const char *strname; socklen_t sz; void *ptr; int need; -} tcp_opts[] = { -#define TCPO(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +} sock_opts[] = { +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, - TCPO(SOL_SOCKET, SO_LINGER, struct linger) - TCPO(SOL_SOCKET, SO_KEEPALIVE, int) + SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) + SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) #ifdef SO_SNDTIMEO_WORKS - TCPO(SOL_SOCKET, SO_SNDTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_SNDTIMEO, struct timeval) #endif #ifdef SO_RCVTIMEO_WORKS - TCPO(SOL_SOCKET, SO_RCVTIMEO, struct timeval) + SOCK_OPT(SOL_SOCKET, SO_RCVTIMEO, struct timeval) #endif - TCPO(IPPROTO_TCP, TCP_NODELAY, int) + SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP - TCPO(IPPROTO_TCP, TCP_KEEPIDLE, int) - TCPO(IPPROTO_TCP, TCP_KEEPCNT, int) - TCPO(IPPROTO_TCP, TCP_KEEPINTVL, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPIDLE, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPCNT, int) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPINTVL, int) #endif -#undef TCPO +#undef SOCK_OPT }; -static const int n_tcp_opts = sizeof tcp_opts / sizeof tcp_opts[0]; +static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast @@ -150,11 +150,11 @@ vca_periodic(vtim_real t0) */ static int -vca_tcp_opt_init(void) +vca_sock_opt_init(void) { int n; int one = 1; - struct tcp_opt *to; + struct sock_opt *so; struct timeval tv; int chg = 0; int x; @@ -162,54 +162,54 @@ vca_tcp_opt_init(void) memset(&tv, 0, sizeof tv); memset(&x, 0, sizeof x); - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->ptr == NULL) - to->ptr = calloc(1, to->sz); - AN(to->ptr); - if (!strcmp(to->strname, "SO_LINGER")) { - assert(to->sz == sizeof linger); - memcpy(to->ptr, &linger, sizeof linger); - to->need = 1; - } else if (!strcmp(to->strname, "TCP_NODELAY")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; - } else if (!strcmp(to->strname, "SO_KEEPALIVE")) { - assert(to->sz == sizeof one); - memcpy(to->ptr, &one, sizeof one); - to->need = 1; -#define NEW_VAL(to, xx) \ + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->ptr == NULL) + so->ptr = calloc(1, so->sz); + AN(so->ptr); + if (!strcmp(so->strname, "SO_LINGER")) { + assert(so->sz == sizeof linger); + memcpy(so->ptr, &linger, sizeof linger); + so->need = 1; + } else if (!strcmp(so->strname, "TCP_NODELAY")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; + } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { + assert(so->sz == sizeof one); + memcpy(so->ptr, &one, sizeof one); + so->need = 1; +#define NEW_VAL(so, xx) \ do { \ - assert(to->sz == sizeof xx); \ - if (memcmp(to->ptr, &(xx), sizeof xx)) { \ - memcpy(to->ptr, &(xx), sizeof xx); \ - to->need = 1; \ + assert(so->sz == sizeof xx); \ + if (memcmp(so->ptr, &(xx), sizeof xx)) { \ + memcpy(so->ptr, &(xx), sizeof xx); \ + so->need = 1; \ chg = 1; \ need_test = 1; \ } \ } while (0) #ifdef SO_SNDTIMEO_WORKS - } else if (!strcmp(to->strname, "SO_SNDTIMEO")) { + } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(to, tv); + NEW_VAL(so, tv); #endif #ifdef SO_RCVTIMEO_WORKS - } else if (!strcmp(to->strname, "SO_RCVTIMEO")) { + } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(to, tv); + NEW_VAL(so, tv); #endif #ifdef HAVE_TCP_KEEP - } else if (!strcmp(to->strname, "TCP_KEEPIDLE")) { + } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPCNT")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(to, x); - } else if (!strcmp(to->strname, "TCP_KEEPINTVL")) { + NEW_VAL(so, x); + } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(to, x); + NEW_VAL(so, x); #endif } } @@ -217,24 +217,24 @@ vca_tcp_opt_init(void) } static void -vca_tcp_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const int sock, const unsigned uds) { int i, n; - struct tcp_opt *to; + struct sock_opt *so; socklen_t l; void *ptr; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - to->need = 1; - ptr = calloc(1, to->sz); + so->need = 1; + ptr = calloc(1, so->sz); AN(ptr); - l = to->sz; - i = getsockopt(sock, to->level, to->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, to->ptr, to->sz)) - to->need = 0; + l = so->sz; + i = getsockopt(sock, so->level, so->optname, ptr, &l); + if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + so->need = 0; free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); @@ -242,18 +242,18 @@ vca_tcp_opt_test(const int sock, const unsigned uds) } static void -vca_tcp_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const int sock, const unsigned uds, const int force) { int n; - struct tcp_opt *to; + struct sock_opt *so; - for (n = 0; n < n_tcp_opts; n++) { - to = &tcp_opts[n]; - if (to->level == IPPROTO_TCP && uds) + for (n = 0; n < n_sock_opts; n++) { + so = &sock_opts[n]; + if (so->level == IPPROTO_TCP && uds) continue; - if (to->need || force) { + if (so->need || force) { VTCP_Assert(setsockopt(sock, - to->level, to->optname, to->ptr, to->sz)); + so->level, so->optname, so->ptr, so->sz)); } } } @@ -401,10 +401,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_tcp_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); need_test = 0; } - vca_tcp_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -590,13 +590,13 @@ vca_acct(void *arg) while (1) { (void)sleep(1); - if (vca_tcp_opt_init()) { + if (vca_sock_opt_init()) { AZ(pthread_mutex_lock(&shut_mtx)); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -616,7 +616,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) (void)av; (void)priv; - (void)vca_tcp_opt_init(); + (void)vca_sock_opt_init(); VTAILQ_FOREACH(ls, &heritage.socks, list) { CHECK_OBJ_NOTNULL(ls->transport, TRANSPORT_MAGIC); @@ -632,7 +632,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } - vca_tcp_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls->sock, ls->uds, 1); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, "Kernel filtering: sock=%d, errno=%d %s", From nils.goroll at uplex.de Tue Nov 23 12:31:11 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:11 +0000 (UTC) Subject: [master] 741c872c7 vca: Pass higher-level types to sock_opt functions Message-ID: <20211123123111.0D16E115DC0@lists.varnish-cache.org> commit 741c872c756e8ed665f2e0c395aaae6c6aa295b3 Author: Dridi Boukelmoune Date: Mon Sep 27 08:19:09 2021 +0200 vca: Pass higher-level types to sock_opt functions The sess and listen_sock structs contain everything we need to find or infer the former `sock`, `uds` and `force` arguments. In particular, it helps distinguish between working on a connection vs listen socket. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index a89f9e044..5669383ba 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -217,22 +217,25 @@ vca_sock_opt_init(void) } static void -vca_sock_opt_test(const int sock, const unsigned uds) +vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { int i, n; struct sock_opt *so; socklen_t l; void *ptr; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; ptr = calloc(1, so->sz); AN(ptr); l = so->sz; - i = getsockopt(sock, so->level, so->optname, ptr, &l); + i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) so->need = 0; free(ptr); @@ -242,16 +245,20 @@ vca_sock_opt_test(const int sock, const unsigned uds) } static void -vca_sock_opt_set(const int sock, const unsigned uds, const int force) +vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n; + int n, sock; struct sock_opt *so; + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + CHECK_OBJ_ORNULL(sp, SESS_MAGIC); + sock = sp != NULL ? sp->fd : ls->sock; + for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->level == IPPROTO_TCP && uds) + if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || force) { + if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, so->level, so->optname, so->ptr, so->sz)); } @@ -401,10 +408,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_sock_opt_test(sp->fd, wa->acceptlsock->uds); + vca_sock_opt_test(wa->acceptlsock, sp); need_test = 0; } - vca_sock_opt_set(sp->fd, wa->acceptlsock->uds, 0); + vca_sock_opt_set(wa->acceptlsock, sp); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -596,7 +603,7 @@ vca_acct(void *arg) if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -632,7 +639,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } - vca_sock_opt_set(ls->sock, ls->uds, 1); + vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, "Kernel filtering: sock=%d, errno=%d %s", From nils.goroll at uplex.de Tue Nov 23 12:31:11 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:11 +0000 (UTC) Subject: [master] 763cc6ef0 vca: Eliminate heap allocations of sock_opt arguments Message-ID: <20211123123111.37946115DD4@lists.varnish-cache.org> commit 763cc6ef0eaa5d805b4b25f4a495d34c9234f919 Author: Dridi Boukelmoune Date: Mon Sep 27 11:41:27 2021 +0200 vca: Eliminate heap allocations of sock_opt arguments They can be stored directly in the sock_opts array or on the stack. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 5669383ba..3a884f09e 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -80,15 +80,21 @@ struct poolsock { * TCP options we want to control */ +union sock_arg { + struct linger lg; + struct timeval tv; + int i; +}; + static struct sock_opt { int level; int optname; const char *strname; - socklen_t sz; - void *ptr; int need; + socklen_t sz; + union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 }, +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -155,35 +161,30 @@ vca_sock_opt_init(void) int n; int one = 1; struct sock_opt *so; - struct timeval tv; + union sock_arg tmp; int chg = 0; - int x; - memset(&tv, 0, sizeof tv); - memset(&x, 0, sizeof x); + memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (so->ptr == NULL) - so->ptr = calloc(1, so->sz); - AN(so->ptr); if (!strcmp(so->strname, "SO_LINGER")) { assert(so->sz == sizeof linger); - memcpy(so->ptr, &linger, sizeof linger); + memcpy(so->arg, &linger, sizeof linger); so->need = 1; } else if (!strcmp(so->strname, "TCP_NODELAY")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { assert(so->sz == sizeof one); - memcpy(so->ptr, &one, sizeof one); + memcpy(so->arg, &one, sizeof one); so->need = 1; #define NEW_VAL(so, xx) \ do { \ assert(so->sz == sizeof xx); \ - if (memcmp(so->ptr, &(xx), sizeof xx)) { \ - memcpy(so->ptr, &(xx), sizeof xx); \ + if (memcmp(so->arg, &(xx), sizeof xx)) { \ + memcpy(so->arg, &(xx), sizeof xx); \ so->need = 1; \ chg = 1; \ need_test = 1; \ @@ -192,24 +193,24 @@ vca_sock_opt_init(void) #ifdef SO_SNDTIMEO_WORKS } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); + NEW_VAL(so, tmp.tv); #endif #ifdef SO_RCVTIMEO_WORKS } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tv); + tmp.tv = VTIM_timeval(cache_param->timeout_idle); + NEW_VAL(so, tmp.tv); #endif #ifdef HAVE_TCP_KEEP } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - x = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_time); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - x = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_probes); + NEW_VAL(so, tmp.i); } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - x = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, x); + tmp.i = (int)(cache_param->tcp_keepalive_intvl); + NEW_VAL(so, tmp.i); #endif } } @@ -219,10 +220,10 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { - int i, n; struct sock_opt *so; + union sock_arg tmp; socklen_t l; - void *ptr; + int i, n; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -232,13 +233,11 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) if (so->level == IPPROTO_TCP && ls->uds) continue; so->need = 1; - ptr = calloc(1, so->sz); - AN(ptr); + memset(&tmp, 0, sizeof tmp); l = so->sz; - i = getsockopt(sp->fd, so->level, so->optname, ptr, &l); - if (i == 0 && !memcmp(ptr, so->ptr, so->sz)) + i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); + if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) so->need = 0; - free(ptr); if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -247,8 +246,8 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { - int n, sock; struct sock_opt *so; + int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); CHECK_OBJ_ORNULL(sp, SESS_MAGIC); @@ -260,7 +259,7 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) continue; if (so->need || sp == NULL) { VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->ptr, so->sz)); + so->level, so->optname, so->arg, so->sz)); } } } From nils.goroll at uplex.de Tue Nov 23 12:31:11 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:11 +0000 (UTC) Subject: [master] 32ae04135 vca: Generalize the sock options test Message-ID: <20211123123111.5CC77115DEB@lists.varnish-cache.org> commit 32ae0413568782dea8d4f6e9eb66d7bac7b58f8d Author: Dridi Boukelmoune Date: Mon Sep 27 12:11:53 2021 +0200 vca: Generalize the sock options test Using the tmp sock_arg for storage, we can test all values with the same logic and only differentiate hard-coded options from parameterized ones. Stylistic polish by @mbgrydeland. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 3a884f09e..9d1250412 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -158,61 +158,58 @@ vca_periodic(vtim_real t0) static int vca_sock_opt_init(void) { - int n; - int one = 1; struct sock_opt *so; union sock_arg tmp; - int chg = 0; + int n, chg = 0; + size_t sz; memset(&tmp, 0, sizeof tmp); for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; - if (!strcmp(so->strname, "SO_LINGER")) { - assert(so->sz == sizeof linger); - memcpy(so->arg, &linger, sizeof linger); - so->need = 1; - } else if (!strcmp(so->strname, "TCP_NODELAY")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; - } else if (!strcmp(so->strname, "SO_KEEPALIVE")) { - assert(so->sz == sizeof one); - memcpy(so->arg, &one, sizeof one); - so->need = 1; -#define NEW_VAL(so, xx) \ - do { \ - assert(so->sz == sizeof xx); \ - if (memcmp(so->arg, &(xx), sizeof xx)) { \ - memcpy(so->arg, &(xx), sizeof xx); \ - so->need = 1; \ - chg = 1; \ - need_test = 1; \ - } \ + +#define SET_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + assert(so->sz == sizeof so->arg->fld); \ + so->arg->fld = (val); \ + } \ + } while (0) + +#define NEW_VAL(nm, so, fld, val) \ + do { \ + if (!strcmp(#nm, so->strname)) { \ + sz = sizeof tmp.fld; \ + assert(so->sz == sz); \ + tmp.fld = (val); \ + if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ + memcpy(&so->arg->fld, &(tmp.fld), sz); \ + so->need = 1; \ + chg = 1; \ + need_test = 1; \ + } \ + } \ } while (0) + SET_VAL(SO_LINGER, so, lg, linger); + SET_VAL(SO_KEEPALIVE, so, i, 1); #ifdef SO_SNDTIMEO_WORKS - } else if (!strcmp(so->strname, "SO_SNDTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->idle_send_timeout); - NEW_VAL(so, tmp.tv); + NEW_VAL(SO_SNDTIMEO, so, tv, + VTIM_timeval(cache_param->idle_send_timeout)); #endif #ifdef SO_RCVTIMEO_WORKS - } else if (!strcmp(so->strname, "SO_RCVTIMEO")) { - tmp.tv = VTIM_timeval(cache_param->timeout_idle); - NEW_VAL(so, tmp.tv); + NEW_VAL(SO_RCVTIMEO, so, tv, + VTIM_timeval(cache_param->timeout_idle)); #endif #ifdef HAVE_TCP_KEEP - } else if (!strcmp(so->strname, "TCP_KEEPIDLE")) { - tmp.i = (int)(cache_param->tcp_keepalive_time); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPCNT")) { - tmp.i = (int)(cache_param->tcp_keepalive_probes); - NEW_VAL(so, tmp.i); - } else if (!strcmp(so->strname, "TCP_KEEPINTVL")) { - tmp.i = (int)(cache_param->tcp_keepalive_intvl); - NEW_VAL(so, tmp.i); + SET_VAL(TCP_NODELAY, so, i, 1); + NEW_VAL(TCP_KEEPIDLE, so, i, + (int)cache_param->tcp_keepalive_time); + NEW_VAL(TCP_KEEPCNT, so, i, + (int)cache_param->tcp_keepalive_probes); + NEW_VAL(TCP_KEEPINTVL, so, i, + (int)cache_param->tcp_keepalive_intvl); #endif - } } return (chg); } From nils.goroll at uplex.de Tue Nov 23 12:31:11 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:11 +0000 (UTC) Subject: [master] 439f2619e vca: Give all const socket options placeholers Message-ID: <20211123123111.84077115E08@lists.varnish-cache.org> commit 439f2619ee996506a7c4d1ee5c3eda1f99884cb5 Author: Dridi Boukelmoune Date: Mon Sep 27 12:42:54 2021 +0200 vca: Give all const socket options placeholers The SO_KEEPALIVE justification used to precede such a constant and was left confusingly lingering over the unrelated need_test variable. Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 9d1250412..9df90387b 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -132,6 +132,13 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ +static const unsigned so_keepalive = 1; + +/* We disable Nagle's algorithm in favor of low latency setups. + */ + +static const unsigned tcp_nodelay = 1; + static unsigned need_test; /*-------------------------------------------------------------------- @@ -192,7 +199,7 @@ vca_sock_opt_init(void) } while (0) SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, 1); + SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); #ifdef SO_SNDTIMEO_WORKS NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); @@ -201,8 +208,8 @@ vca_sock_opt_init(void) NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); #endif + SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); #ifdef HAVE_TCP_KEEP - SET_VAL(TCP_NODELAY, so, i, 1); NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); NEW_VAL(TCP_KEEPCNT, so, i, From nils.goroll at uplex.de Tue Nov 23 12:31:11 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:11 +0000 (UTC) Subject: [master] 58ac9f834 vca: Give sock_opt constant arguments better names Message-ID: <20211123123111.AD111115E20@lists.varnish-cache.org> commit 58ac9f8347c834dd111555cf49a62d0736c868e1 Author: Dridi Boukelmoune Date: Mon Sep 27 13:17:55 2021 +0200 vca: Give sock_opt constant arguments better names And while at it, update the SO_LINGER explanation to match reality. Refs 7eba94605b9f Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 9df90387b..a15461a54 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -119,11 +119,11 @@ static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast - * as absolutely possible, so we set them LINGER enabled with zero timeout, - * so that even if there are outstanding write data on the socket, a close(2) - * will return immediately. + * as absolutely possible, so we set them LINGER disabled, so that even if + * there are outstanding write data on the socket, a close(2) will return + * immediately. */ -static const struct linger linger = { +static const struct linger disable_so_linger = { .l_onoff = 0, }; @@ -132,12 +132,12 @@ static const struct linger linger = { * hung up on connections returning from waitinglists */ -static const unsigned so_keepalive = 1; +static const unsigned enable_so_keepalive = 1; /* We disable Nagle's algorithm in favor of low latency setups. */ -static const unsigned tcp_nodelay = 1; +static const unsigned enable_tcp_nodelay = 1; static unsigned need_test; @@ -198,8 +198,8 @@ vca_sock_opt_init(void) } \ } while (0) - SET_VAL(SO_LINGER, so, lg, linger); - SET_VAL(SO_KEEPALIVE, so, i, so_keepalive); + SET_VAL(SO_LINGER, so, lg, disable_so_linger); + SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); #ifdef SO_SNDTIMEO_WORKS NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); @@ -208,7 +208,7 @@ vca_sock_opt_init(void) NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); #endif - SET_VAL(TCP_NODELAY, so, i, tcp_nodelay); + SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #ifdef HAVE_TCP_KEEP NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); From nils.goroll at uplex.de Tue Nov 23 12:31:11 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:11 +0000 (UTC) Subject: [master] 9c6f6043f vca: Have one inheritance check per listen socket Message-ID: <20211123123111.ED458115E32@lists.varnish-cache.org> commit 9c6f6043fc6a7920100f495793790e7fb311ee89 Author: Dridi Boukelmoune Date: Mon Sep 27 14:53:56 2021 +0200 vca: Have one inheritance check per listen socket Instead of having a single global check that all acceptors may race towards, this check now happens on a per listen socket basis. For sockets with a different inheritance behavior on a single system, we avoid having the first connection dictate what may be inherited by a connection socket from its listen socket for all the other listen addresses. At least on Linux, Unix-domain sockets DO NOT inherit options like SO_{RCV,SND}TIMEO even though TCP sockets do. On the off chance that even sockets of the same family could behave differently, like for example a regular vs a loopback TCP session, this is done on a per listen address basis. To avoid cache-acceptor coordination with the acceptor worker threads of a given listen address, workers will individually perform this check once and for all when the first connection is accepted. We also stay defensive in the event of a parameter change, just in case a previous test would assume inheritance because the Varnish parameter value would match the kernel default value. Once a mismatch is observed for a given connection with a given socket, the inheritance test is no longer performed needlessly for this combination. A race still exists between acceptors from different thread pools for a given listen address, but this race is identical to the previous one based on the former global need_test variable. Although the inheritance check leaks into struct listen_sock, it is opaque so everything can remain contained inside cache_acceptor.c. Some aspects of this change (including the clarification comments) are from @mbgrydeland. Refs #2722 diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index a15461a54..d00725c0b 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -90,11 +90,13 @@ static struct sock_opt { int level; int optname; const char *strname; - int need; + unsigned mod; socklen_t sz; union sock_arg arg[1]; } sock_opts[] = { -#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) }, + /* Note: Setting the mod counter to something not-zero is needed + * to force the setsockopt() calls on startup */ +#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 1, sizeof(typ) }, SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) @@ -117,6 +119,11 @@ static struct sock_opt { static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0]; +struct conn_heritage { + unsigned sess_set; + unsigned listen_mod; +}; + /*-------------------------------------------------------------------- * We want to get out of any kind of trouble-hit TCP connections as fast * as absolutely possible, so we set them LINGER disabled, so that even if @@ -139,8 +146,6 @@ static const unsigned enable_so_keepalive = 1; static const unsigned enable_tcp_nodelay = 1; -static unsigned need_test; - /*-------------------------------------------------------------------- * lacking a better place, we put some generic periodic updates * into the vca_acct() loop which we are running anyway @@ -191,9 +196,8 @@ vca_sock_opt_init(void) tmp.fld = (val); \ if (memcmp(&so->arg->fld, &(tmp.fld), sz)) { \ memcpy(&so->arg->fld, &(tmp.fld), sz); \ - so->need = 1; \ + so->mod++; \ chg = 1; \ - need_test = 1; \ } \ } \ } while (0) @@ -224,6 +228,7 @@ vca_sock_opt_init(void) static void vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; union sock_arg tmp; socklen_t l; @@ -234,14 +239,16 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; + if (ch->sess_set) + continue; /* Already set, no need to retest */ if (so->level == IPPROTO_TCP && ls->uds) continue; - so->need = 1; memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && !memcmp(&tmp, so->arg, so->sz)) - so->need = 0; + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + ch->sess_set = 1; if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -250,6 +257,7 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) static void vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { + struct conn_heritage *ch; struct sock_opt *so; int n, sock; @@ -259,12 +267,17 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; + ch = &ls->conn_heritage[n]; if (so->level == IPPROTO_TCP && ls->uds) continue; - if (so->need || sp == NULL) { - VTCP_Assert(setsockopt(sock, - so->level, so->optname, so->arg, so->sz)); - } + if (sp == NULL && ch->listen_mod == so->mod) + continue; + if (sp != NULL && !ch->sess_set) + continue; + VTCP_Assert(setsockopt(sock, + so->level, so->optname, so->arg, so->sz)); + if (sp == NULL) + ch->listen_mod = so->mod; } } @@ -410,9 +423,9 @@ vca_make_session(struct worker *wrk, void *arg) vca_pace_good(); wrk->stats->sess_conn++; - if (need_test) { + if (wa->acceptlsock->test_heritage) { vca_sock_opt_test(wa->acceptlsock, sp); - need_test = 0; + wa->acceptlsock->test_heritage = 0; } vca_sock_opt_set(wa->acceptlsock, sp); @@ -607,6 +620,17 @@ vca_acct(void *arg) continue; // VCA_Shutdown assert (ls->sock > 0); vca_sock_opt_set(ls, NULL); + /* If one of the options on a socket has + * changed, also force a retest of whether + * the values are inherited to the + * accepted sockets. This should then + * catch any false positives from previous + * tests that could happen if the set + * value of an option happened to just be + * the OS default for that value, and + * wasn't actually inherited from the + * listening socket. */ + ls->test_heritage = 1; } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -642,6 +666,11 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, VAS_errtxt(errno)); return; } + AZ(ls->conn_heritage); + ls->conn_heritage = calloc(n_sock_opts, + sizeof *ls->conn_heritage); + AN(ls->conn_heritage); + ls->test_heritage = 1; vca_sock_opt_set(ls, NULL); if (cache_param->accept_filter && VTCP_filter_http(ls->sock)) VSL(SLT_Error, 0, @@ -649,8 +678,6 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->sock, errno, VAS_errtxt(errno)); } - need_test = 1; - AZ(pthread_create(&VCA_thread, NULL, vca_acct, NULL)); } diff --git a/bin/varnishd/common/heritage.h b/bin/varnishd/common/heritage.h index f2b2e448f..8244f8046 100644 --- a/bin/varnishd/common/heritage.h +++ b/bin/varnishd/common/heritage.h @@ -37,6 +37,7 @@ struct listen_sock; struct transport; struct VCLS; struct uds_perms; +struct conn_heritage; struct listen_sock { unsigned magic; @@ -50,6 +51,8 @@ struct listen_sock { struct suckaddr *addr; const struct transport *transport; const struct uds_perms *perms; + unsigned test_heritage; + struct conn_heritage *conn_heritage; }; VTAILQ_HEAD(listen_sock_head, listen_sock); diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc new file mode 100644 index 000000000..e8a4eef61 --- /dev/null +++ b/bin/varnishtest/tests/r02722.vtc @@ -0,0 +1,37 @@ +varnishtest "TCP vs UDS sockopt inheritance" + +feature cmd {test $(uname) != SunOS} + +server s0 { + rxreqhdrs + non_fatal + rxreqbody + txresp +} -dispatch + +varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -cliok "param.set debug +flush_head" +varnish v1 -cliok "param.set timeout_idle 1" +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -req POST -hdr "Content-Length: 100" + send some + rxresp + expect resp.status == 503 +} + +# This run performs the inheritance test on a TCP connection +client c1 -run + +# This run relies on the inheritance test results +client c1 -run + +varnish v1 -vsl_catchup + +# This run checks that TCP results aren't applied to a UDS +client c1 -connect "${tmpdir}/v1.sock" +client c1 -run + +# And finally this run checks UDS inheritance test results +client c1 -run From nils.goroll at uplex.de Tue Nov 23 12:31:12 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 23 Nov 2021 12:31:12 +0000 (UTC) Subject: [master] 6093812b2 vca: Log the outcome of sockopt inheritance Message-ID: <20211123123112.300EA115E51@lists.varnish-cache.org> commit 6093812b22b2f09e99b4e1560d0aa6e275a4795b Author: Dridi Boukelmoune Date: Mon Nov 15 12:31:02 2021 +0100 vca: Log the outcome of sockopt inheritance diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index d00725c0b..2eaadb228 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -240,15 +240,27 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp) for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (ch->sess_set) - continue; /* Already set, no need to retest */ - if (so->level == IPPROTO_TCP && ls->uds) + if (ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing nonhereditary %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Not testing incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); + continue; + } memset(&tmp, 0, sizeof tmp); l = so->sz; i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l); - if (i == 0 && memcmp(&tmp, so->arg, so->sz)) + if (i == 0 && memcmp(&tmp, so->arg, so->sz)) { + VSL(SLT_Debug, sp->vxid, + "sockopt: Test confirmed %s non heredity for %s=%s", + so->strname, ls->name, ls->endpoint); ch->sess_set = 1; + } if (i && errno != ENOPROTOOPT) VTCP_Assert(i); } @@ -259,21 +271,44 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp) { struct conn_heritage *ch; struct sock_opt *so; + unsigned vxid; int n, sock; CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); - CHECK_OBJ_ORNULL(sp, SESS_MAGIC); - sock = sp != NULL ? sp->fd : ls->sock; + + if (sp != NULL) { + CHECK_OBJ(sp, SESS_MAGIC); + sock = sp->fd; + vxid = sp->vxid; + } else { + sock = ls->sock; + vxid = 0; + } for (n = 0; n < n_sock_opts; n++) { so = &sock_opts[n]; ch = &ls->conn_heritage[n]; - if (so->level == IPPROTO_TCP && ls->uds) + if (so->level == IPPROTO_TCP && ls->uds) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting incompatible %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp == NULL && ch->listen_mod == so->mod) + } + if (sp == NULL && ch->listen_mod == so->mod) { + VSL(SLT_Debug, vxid, + "sockopt: Not setting unmodified %s for %s=%s", + so->strname, ls->name, ls->endpoint); continue; - if (sp != NULL && !ch->sess_set) + } + if (sp != NULL && !ch->sess_set) { + VSL(SLT_Debug, sp->vxid, + "sockopt: %s may be inherited for %s=%s", + so->strname, ls->name, ls->endpoint); continue; + } + VSL(SLT_Debug, vxid, + "sockopt: Setting %s for %s=%s", + so->strname, ls->name, ls->endpoint); VTCP_Assert(setsockopt(sock, so->level, so->optname, so->arg, so->sz)); if (sp == NULL) diff --git a/bin/varnishtest/tests/l00000.vtc b/bin/varnishtest/tests/l00000.vtc index 1c732fc47..e7e316ccf 100644 --- a/bin/varnishtest/tests/l00000.vtc +++ b/bin/varnishtest/tests/l00000.vtc @@ -11,7 +11,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g session { expect 0 1000 Begin sess expect 0 = SessOpen - expect 0 = Link "req 1001" + expect * = Link "req 1001" expect 0 = SessClose expect 0 = End diff --git a/bin/varnishtest/tests/o00001.vtc b/bin/varnishtest/tests/o00001.vtc index 5a6b35913..ebe38bcb9 100644 --- a/bin/varnishtest/tests/o00001.vtc +++ b/bin/varnishtest/tests/o00001.vtc @@ -74,7 +74,7 @@ logexpect l1 -v v1 -g raw { expect * 1016 Proxy "2 1.2.3.4 2314 5.6.7.8 2828" expect * 1019 Proxy "2 102:304:506::d0e:f10 2314 8182:8384:8586::8d8e:8f80 2828" expect * 1022 Begin "^sess 0 PROXY" - expect 1 1022 SessClose "^RX_OVERFLOW" + expect * 1022 SessClose "^RX_OVERFLOW" } -start client c1 { diff --git a/bin/varnishtest/tests/o00006.vtc b/bin/varnishtest/tests/o00006.vtc index 5f7eb4638..e8adecb7c 100644 --- a/bin/varnishtest/tests/o00006.vtc +++ b/bin/varnishtest/tests/o00006.vtc @@ -12,7 +12,7 @@ varnish v1 -arg "-p pool_sess=0,0,0" -proto "PROXY" -vcl+backend {} -start logexpect l1 -v v1 -g raw { expect 0 1000 Begin "sess 0 PROXY" expect 0 = SessOpen - expect 0 = Proxy "2 217.70.181.33 60822 95.142.168.34 443" + expect * = Proxy "2 217.70.181.33 60822 95.142.168.34 443" expect 0 = Error {\Qinsufficient workspace (proto_priv)\E} expect 0 = SessClose "RX_JUNK" } -start diff --git a/bin/varnishtest/tests/r01804.vtc b/bin/varnishtest/tests/r01804.vtc index 252dd5845..d50bf9558 100644 --- a/bin/varnishtest/tests/r01804.vtc +++ b/bin/varnishtest/tests/r01804.vtc @@ -13,7 +13,7 @@ varnish v1 -vcl+backend "" -start logexpect l1 -v v1 -g session { expect * 1000 Begin {^sess .* PROXY$} expect 0 = SessOpen {^.* foo .*} - expect 0 = Proxy {^1 } + expect * = Proxy {^1 } expect * 1001 Begin {^req} } -start @@ -28,7 +28,7 @@ logexpect l1 -wait logexpect l2 -v v1 -g session { expect * 1003 Begin {^sess .* PROXY$} expect 0 = SessOpen {^.* foo .*} - expect 0 = Proxy {^2 } + expect * = Proxy {^2 } expect * 1004 Begin {^req} } -start diff --git a/bin/varnishtest/tests/r02722.vtc b/bin/varnishtest/tests/r02722.vtc index e8a4eef61..1268864b5 100644 --- a/bin/varnishtest/tests/r02722.vtc +++ b/bin/varnishtest/tests/r02722.vtc @@ -9,7 +9,7 @@ server s0 { txresp } -dispatch -varnish v1 -arg {-a :0 -a "${tmpdir}/v1.sock"} +varnish v1 -arg {-a TCP=:0 -a "UDS=${tmpdir}/v1.sock"} varnish v1 -cliok "param.set debug +flush_head" varnish v1 -cliok "param.set timeout_idle 1" varnish v1 -vcl+backend { } -start From dridi.boukelmoune at gmail.com Tue Nov 23 12:31:12 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 12:31:12 +0000 (UTC) Subject: [master] 254faf07a build: Simply require that SO_???TIMEO are present Message-ID: <20211123123112.81628115E7E@lists.varnish-cache.org> commit 254faf07a80efc5174d520dd42c5cca269b36fd8 Author: Dridi Boukelmoune Date: Wed Sep 22 19:46:18 2021 +0200 build: Simply require that SO_???TIMEO are present Closes #3692 Conflicts: bin/varnishd/cache/cache_acceptor.c diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 2eaadb228..53763156b 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -100,12 +100,8 @@ static struct sock_opt { SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger) SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int) -#ifdef SO_SNDTIMEO_WORKS SOCK_OPT(SOL_SOCKET, SO_SNDTIMEO, struct timeval) -#endif -#ifdef SO_RCVTIMEO_WORKS SOCK_OPT(SOL_SOCKET, SO_RCVTIMEO, struct timeval) -#endif SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) #ifdef HAVE_TCP_KEEP @@ -204,14 +200,10 @@ vca_sock_opt_init(void) SET_VAL(SO_LINGER, so, lg, disable_so_linger); SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); -#ifdef SO_SNDTIMEO_WORKS NEW_VAL(SO_SNDTIMEO, so, tv, VTIM_timeval(cache_param->idle_send_timeout)); -#endif -#ifdef SO_RCVTIMEO_WORKS NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); -#endif SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #ifdef HAVE_TCP_KEEP NEW_VAL(TCP_KEEPIDLE, so, i, diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 2b05aac01..2294e742c 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -1000,14 +1000,9 @@ HTTP_VAR(beresp) static inline void set_idle_send_timeout(const struct sess *sp, VCL_DURATION d) { -#ifdef SO_SNDTIMEO_WORKS struct timeval tv = VTIM_timeval(d); VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv)); -#else - (void)sp; - (void)d; -#endif } #define SESS_VAR_DUR(x, setter) \ diff --git a/bin/varnishtest/tests/b00020.vtc b/bin/varnishtest/tests/b00020.vtc index 1f0427c11..fc7c7c2d8 100644 --- a/bin/varnishtest/tests/b00020.vtc +++ b/bin/varnishtest/tests/b00020.vtc @@ -1,7 +1,5 @@ varnishtest "Check that between_bytes_timeout behaves from parameters" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00021.vtc b/bin/varnishtest/tests/b00021.vtc index 46be8cb4f..f0c4c0ce2 100644 --- a/bin/varnishtest/tests/b00021.vtc +++ b/bin/varnishtest/tests/b00021.vtc @@ -1,7 +1,5 @@ varnishtest "Check the between_bytes_timeout behaves from vcl" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00022.vtc b/bin/varnishtest/tests/b00022.vtc index 7bf6d9575..fee5db3d9 100644 --- a/bin/varnishtest/tests/b00022.vtc +++ b/bin/varnishtest/tests/b00022.vtc @@ -1,7 +1,5 @@ varnishtest "Check the between_bytes_timeout behaves from backend definition" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" diff --git a/bin/varnishtest/tests/b00023.vtc b/bin/varnishtest/tests/b00023.vtc index fd64cb2bd..5948d6bef 100644 --- a/bin/varnishtest/tests/b00023.vtc +++ b/bin/varnishtest/tests/b00023.vtc @@ -1,7 +1,5 @@ varnishtest "Check that the first_byte_timeout works" -feature SO_RCVTIMEO_WORKS - # From VCL server s1 { diff --git a/bin/varnishtest/tests/b00026.vtc b/bin/varnishtest/tests/b00026.vtc index 48fce004b..e12676985 100644 --- a/bin/varnishtest/tests/b00026.vtc +++ b/bin/varnishtest/tests/b00026.vtc @@ -1,7 +1,5 @@ varnishtest "Check the precedence for timeouts" -feature SO_RCVTIMEO_WORKS - server s1 { rxreq expect req.url == "from_backend" diff --git a/bin/varnishtest/tests/s00010.vtc b/bin/varnishtest/tests/s00010.vtc index fea3ea89d..f9e0bbb15 100644 --- a/bin/varnishtest/tests/s00010.vtc +++ b/bin/varnishtest/tests/s00010.vtc @@ -3,8 +3,6 @@ varnishtest "client h1 send timeouts - tcp" # XXX See https://github.com/varnishcache/varnish-cache/pull/2980#issuecomment-486214661 feature cmd {test $(uname) != "SunOS" && test $(uname) != "Darwin"} -feature SO_RCVTIMEO_WORKS - barrier b1 cond 2 -cyclic barrier b2 cond 2 -cyclic diff --git a/bin/varnishtest/tests/s00012.vtc b/bin/varnishtest/tests/s00012.vtc index 9726f050f..e635ad03d 100644 --- a/bin/varnishtest/tests/s00012.vtc +++ b/bin/varnishtest/tests/s00012.vtc @@ -2,8 +2,6 @@ varnishtest "client h1 send timeouts - uds" feature cmd {test $(uname) != "SunOS"} -feature SO_RCVTIMEO_WORKS - server s1 { rxreq txresp -bodylen 100000 diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c index ac5f6df96..7ff023017 100644 --- a/bin/varnishtest/vtc_misc.c +++ b/bin/varnishtest/vtc_misc.c @@ -410,8 +410,6 @@ addr_no_randomize_works(void) * the test otherwise; or change the interpretation of the test, as * documented below. feature takes any number of arguments from this list: * - * SO_RCVTIMEO_WORKS - * The SO_RCVTIMEO socket option is working * 64bit * The environment is 64 bits * ipv4 @@ -508,12 +506,6 @@ static const unsigned with_persistent_storage = 1; static const unsigned with_persistent_storage = 0; #endif -#ifdef SO_RCVTIMEO_WORKS -static const unsigned so_rcvtimeo_works = 1; -#else -static const unsigned so_rcvtimeo_works = 0; -#endif - void v_matchproto_(cmd_f) cmd_feature(CMD_ARGS) { @@ -566,7 +558,6 @@ cmd_feature(CMD_ARGS) FEATURE("tsan", tsan); FEATURE("ubsan", ubsan); FEATURE("sanitizer", sanitizer); - FEATURE("SO_RCVTIMEO_WORKS", so_rcvtimeo_works); FEATURE("workspace_emulator", workspace_emulator); if (!strcmp(feat, "cmd")) { diff --git a/configure.ac b/configure.ac index 162a26d48..d9760807e 100644 --- a/configure.ac +++ b/configure.ac @@ -532,91 +532,24 @@ AC_CHECK_MEMBER([struct sockaddr.sa_len], AC_CHECK_DECL([SO_ACCEPTFILTER], AC_DEFINE(HAVE_ACCEPT_FILTERS,1,[Define to 1 if you have accept filters]), - , - [ -#include -#include - ] -) - -# Older Solaris versions define SO_{RCV,SND}TIMEO, but do not -# implement them. -# -# Varnish will build and run without these, but connections will not -# time out, which may leave Varnish vulnerable to denial-of-service -# attacks which would not be possible on other platforms. -# -# Newer Solaris releases with the Volo framework (Solaris 11, -# Opensolaris starting with onnv_106) do support SO_{RCV,SND}TIMEO -# (see PSARC 2007/587, initially committed into onnv-gate / -# OpenSolaris 8348:4137e18bfaf0 Thu Dec 11 20:04:13 2008) - -save_LIBS="${LIBS}" -LIBS="${LIBS} ${NET_LIBS}" -AC_CACHE_CHECK([whether SO_RCVTIMEO works], - [ac_cv_so_rcvtimeo_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include - ]],[[ -int s = socket(AF_INET, SOCK_STREAM, 0); -struct timeval tv = { 1, 0 }; -if (s < 0 && errno == EPROTONOSUPPORT) - s = socket(AF_INET6, SOCK_STREAM, 0); -if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) == 0) { - socklen_t l = sizeof tv; - if (getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, &l) == 0) { - return (l != sizeof tv); - } -} -return 1; - ]])], - [ac_cv_so_rcvtimeo_works=yes], - [ac_cv_so_rcvtimeo_works=no]) - ]) -if test "$ac_cv_so_rcvtimeo_works" = yes; then - AC_DEFINE([SO_RCVTIMEO_WORKS], [1], [Define if SO_RCVTIMEO works]) -fi -LIBS="${save_LIBS}" + [], [ + #include + #include + ]) -save_LIBS="${LIBS}" -LIBS="${LIBS} ${NET_LIBS}" -AC_CACHE_CHECK([whether SO_SNDTIMEO works], - [ac_cv_so_sndtimeo_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include - ]],[[ -int s = socket(AF_INET, SOCK_STREAM, 0); -struct timeval tv = { 1, 0 }; -if (s < 0 && errno == EPROTONOSUPPORT) - s = socket(AF_INET6, SOCK_STREAM, 0); -if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) == 0) { - socklen_t l = sizeof tv; - if (getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, &l) == 0) { - return (l != sizeof tv); - } -} -return 1; - ]])], - [ac_cv_so_sndtimeo_works=yes], - [ac_cv_so_sndtimeo_works=no]) - ]) -if test "$ac_cv_so_sndtimeo_works" = yes; then - AC_DEFINE([SO_SNDTIMEO_WORKS], [1], [Define if SO_SNDTIMEO works]) -fi +AC_CHECK_DECL([SO_RCVTIMEO], + [], + AC_MSG_ERROR([SO_RCVTIMEO is needed to build Varnish.]), [ + #include + #include + ]) -if test "$ac_cv_so_rcvtimeo_works" = no || - test "$ac_cv_so_sndtimeo_works" = no; then - AC_MSG_WARN([connection timeouts will not work]) -fi -LIBS="${save_LIBS}" +AC_CHECK_DECL([SO_SNDTIMEO], + [], + AC_MSG_ERROR([SO_SNDTIMEO is needed to build Varnish.]), [ + #include + #include + ]) # Check if the OS supports TCP_KEEP(CNT|IDLE|INTVL) socket options save_LIBS="${LIBS}" diff --git a/include/tbl/params.h b/include/tbl/params.h index 8f3eaf8d4..9a94e75c4 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -610,11 +610,6 @@ PARAM_SIMPLE( "of that the response is allowed to take up." ) -#if defined(SO_SNDTIMEO_WORKS) -# define PLATFORM_FLAGS DELAYED_EFFECT -#else -# define PLATFORM_FLAGS NOT_IMPLEMENTED -#endif PARAM_SIMPLE( /* name */ idle_send_timeout, /* type */ timeout, @@ -628,9 +623,8 @@ PARAM_SIMPLE( "When this timeout is hit, the session is closed.\n\n" "See the man page for `setsockopt(2)` or `socket(7)` under" " ``SO_SNDTIMEO`` for more information.", - /* flags */ PLATFORM_DEPENDENT | PLATFORM_FLAGS + /* flags */ DELAYED_EFFECT ) -#undef PLATFORM_FLAGS PARAM_SIMPLE( /* name */ listen_depth, @@ -781,11 +775,6 @@ PARAM_SIMPLE( /* flags */ EXPERIMENTAL ) -#if defined(SO_SNDTIMEO_WORKS) -# define PLATFORM_FLAGS DELAYED_EFFECT -#else -# define PLATFORM_FLAGS NOT_IMPLEMENTED -#endif PARAM_SIMPLE( /* name */ send_timeout, /* type */ timeout, @@ -800,9 +789,8 @@ PARAM_SIMPLE( " timeout is extended unless the total time already taken for sending" " the response in its entirety exceeds this many seconds.\n\n" "When this timeout is hit, the session is closed", - /* flags */ PLATFORM_DEPENDENT | PLATFORM_FLAGS + /* flags */ DELAYED_EFFECT ) -#undef PLATFORM_FLAGS PARAM_SIMPLE( /* name */ shortlived, @@ -914,11 +902,6 @@ PARAM_SIMPLE( ) #undef PLATFORM_FLAGS -#if defined(SO_RCVTIMEO_WORKS) -# define PLATFORM_FLAGS 0 -#else -# define PLATFORM_FLAGS NOT_IMPLEMENTED -#endif PARAM_SIMPLE( /* name */ timeout_idle, /* type */ timeout, @@ -932,10 +915,8 @@ PARAM_SIMPLE( " request headers.\n\n" "This parameter is particularly relevant for HTTP1 keepalive " " connections which are closed unless the next request is received" - " before this timeout is reached.", - /* flags */ PLATFORM_DEPENDENT | PLATFORM_FLAGS + " before this timeout is reached." ) -#undef PLATFORM_FLAGS PARAM_SIMPLE( /* name */ timeout_linger, diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index 9e43f5da0..6c1d154a2 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -349,8 +349,8 @@ VTCP_close(int *s) void VTCP_set_read_timeout(int s, vtim_dur seconds) { -#ifdef SO_RCVTIMEO_WORKS struct timeval timeout = VTIM_timeval(seconds); + /* * Solaris bug (present at least in snv_151 and older): If this fails * with EINVAL, the socket is half-closed (SS_CANTSENDMORE) and the @@ -359,10 +359,6 @@ VTCP_set_read_timeout(int s, vtim_dur seconds) */ VTCP_Assert(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); -#else - (void)s; - (void)seconds; -#endif } /*-------------------------------------------------------------------- From dridi.boukelmoune at gmail.com Tue Nov 23 12:31:12 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 12:31:12 +0000 (UTC) Subject: [master] d4f44004d Somebody forgot LIBUNWIND_CFLAGS Message-ID: <20211123123112.AF10D115E97@lists.varnish-cache.org> commit d4f44004d774daf5f8b30e3ffd915b7c5d3a6111 Author: Poul-Henning Kamp Date: Fri Nov 19 09:58:27 2021 +0000 Somebody forgot LIBUNWIND_CFLAGS diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index e70b43de9..93b7aa6b2 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -182,7 +182,7 @@ varnishd_LDADD = \ ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} if WITH_UNWIND -varnishd_CFLAGS += -DUNW_LOCAL_ONLY +varnishd_CFLAGS += -DUNW_LOCAL_ONLY ${LIBUNWIND_CFLAGS} varnishd_LDADD += ${LIBUNWIND_LIBS} endif From dridi.boukelmoune at gmail.com Tue Nov 23 12:31:12 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 12:31:12 +0000 (UTC) Subject: [master] b789480f2 mac: Polish Message-ID: <20211123123112.D5E90115EA6@lists.varnish-cache.org> commit b789480f2a37a76ce02a6f66b1810b1c3a69d0e9 Author: Dridi Boukelmoune Date: Mon Nov 15 12:44:19 2021 +0100 mac: Polish diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 6488c5b03..86c62683b 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -152,8 +152,7 @@ mk_listen_sock(const struct listen_arg *la, const struct suckaddr *sa) ls->sock = -1; ls->addr = VSA_Clone(sa); AN(ls->addr); - ls->endpoint = strdup(la->endpoint); - AN(ls->endpoint); + REPLACE(ls->endpoint, la->endpoint); ls->name = la->name; ls->transport = la->transport; ls->perms = la->perms; From dridi.boukelmoune at gmail.com Tue Nov 23 12:31:12 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 12:31:12 +0000 (UTC) Subject: [master] 492d910bf mac: Add brackets around IPv6 endpoints Message-ID: <20211123123113.00277115EB8@lists.varnish-cache.org> commit 492d910bf98e17a1427bfe7dd194211a96e6b702 Author: Dridi Boukelmoune Date: Mon Nov 15 12:44:59 2021 +0100 mac: Add brackets around IPv6 endpoints diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 86c62683b..454b91d30 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -202,7 +202,10 @@ mac_tcp(void *priv, const struct suckaddr *sa) ls->addr = VTCP_my_suckaddr(ls->sock); VTCP_myname(ls->sock, abuf, sizeof abuf, pbuf, sizeof pbuf); - bprintf(nbuf, "%s:%s", abuf, pbuf); + if (VSA_Get_Proto(sa) == AF_INET6) + bprintf(nbuf, "[%s]:%s", abuf, pbuf); + else + bprintf(nbuf, "%s:%s", abuf, pbuf); REPLACE(ls->endpoint, nbuf); } VTAILQ_INSERT_TAIL(&la->socks, ls, arglist); From dridi.boukelmoune at gmail.com Tue Nov 23 12:31:13 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 23 Nov 2021 12:31:13 +0000 (UTC) Subject: [master] ab2f26c20 vtc: Account for [braces] on IPv6-only systems Message-ID: <20211123123113.25A14115EC6@lists.varnish-cache.org> commit ab2f26c20738f98a288112fe3da5ac4773a10867 Author: Dridi Boukelmoune Date: Mon Nov 15 18:39:53 2021 +0100 vtc: Account for [braces] on IPv6-only systems diff --git a/bin/varnishtest/tests/v00025.vtc b/bin/varnishtest/tests/v00025.vtc index 790f24873..c6cdadd8f 100644 --- a/bin/varnishtest/tests/v00025.vtc +++ b/bin/varnishtest/tests/v00025.vtc @@ -174,8 +174,8 @@ client c1 { expect resp.http.C-Sess-XID ~ "^[0-9]+$" expect resp.http.B-Sess-XID ~ "^[0-9]+$" expect resp.http.C-Sess-XID == resp.http.B-Sess-XID - expect resp.http.C-Endpoint == "${v1_addr}:${v1_port}" - expect resp.http.B-Endpoint == "${v1_addr}:${v1_port}" + expect resp.http.C-Endpoint ~ ".?${v1_addr}.?:${v1_port}" + expect resp.http.B-Endpoint ~ ".?${v1_addr}.?:${v1_port}" expect resp.http.C-Socket == "a0" expect resp.http.B-Socket == "a0" } -run From martin at varnish-software.com Tue Nov 23 12:31:13 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:13 +0000 (UTC) Subject: [master] bec768df9 Hopefully fix u00006 on various platforms. Message-ID: <20211123123113.42293115ED7@lists.varnish-cache.org> commit bec768df97ca2a0b50b3ed5bd169ac40e5e1d830 Author: Poul-Henning Kamp Date: Fri Nov 19 18:51:03 2021 +0000 Hopefully fix u00006 on various platforms. Dont limit ourselves to a set number of VSL records to include the "0 CLI" we want, various platforms emit a number of Debug messages relating to sockopt Use the `process p%d -expect-text` mechanism to wait only as long as necessary for the "0 CLI" diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index e420aa18d..a79d592e8 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -7,9 +7,11 @@ server s1 -repeat 2 { varnish v1 -vcl+backend {} -start +# We use this to make sure we know there is a "0 CLI" in the binary log. process p1 { - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A + exec varnishlog -n ${v1_name} -g raw -u -A } -start + shell { exec varnishlog -n ${v1_name} -D -P ${tmpdir}/vlog.pid \ -w ${tmpdir}/vlog.bin -R 10/s \ @@ -119,8 +121,11 @@ shell -err -expect "-R: Syntax error: Invalid duration" \ shell -err -expect "-R: Syntax error" \ "varnishlog -R 1000000000/1000000000000000000000000000000s" -process p1 -wait -shell {grep -q "0 CLI" ${tmpdir}/vlog} +# Wait until the binary also (must) contain a "0 CLI" +process p1 -expect-text 0 0 "0 CLI" +process p1 -screen_dump +process p1 -stop + shell -match "0 CLI[ ]+- Wr 200 [0-9]+ PONG" \ {varnishlog -n ${v1_name} -d -g raw -X "Wr 200 [0-9]+ [^P]"} From martin at varnish-software.com Tue Nov 23 12:31:13 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:13 +0000 (UTC) Subject: [master] 885a9fd7f Changelog for 7.0.1 Message-ID: <20211123123113.5CB4C115EF3@lists.varnish-cache.org> commit 885a9fd7fb5b3bb84c8f024bd73fcce5c5d38916 Author: Martin Blix Grydeland Date: Tue Nov 23 10:31:40 2021 +0100 Changelog for 7.0.1 diff --git a/doc/changes.rst b/doc/changes.rst index c290a644c..b105f4717 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -31,6 +31,46 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via individual releases. These documents are updated as part of the release process. +================================ +Varnish Cache 7.0.1 (unreleased) +================================ + +* An assertion failure has been fixed which triggered when matching bans + on non-existing headers (3706_). + +* A VCL compilation issue has been fixed when calling builtin functions + directly (3719_). + +* It is now again possible to concatenate static strings to produce + combined strings of type VCL_REGEX (3721_). + +* An issue has been fixed that would cause the VCL dependency checker to + incorrectly flag VCLs as dependants of other VCLs when using labels, + preventing them from being discarded (3734_). + +* VCLs loaded through CLI or the use of startup CLI scripts (-I option to + `varnishd`) will, when no active VCL has previously been set, no longer + automatically set the first VCL loaded to the active VCL. This prevents + situations where it was possible to make a cold VCL the active VCL + (3737_). + +* There is now a `configure` build-time requirement on working SO_RCVTIMEO + and SO_SNDTIMEO socket options. + +* The socket option inheritance checks now correctly identifies situations + where UDS and TCP listening sockets behave differently, and are no + longer subject to the order the inheritance checks happens to be + executed (3732_). + +* IPv6 listen endpoint address strings are now printed using brackets. + +.. _3706: https://github.com/varnishcache/varnish-cache/issues/3706 +.. _3719: https://github.com/varnishcache/varnish-cache/issues/3719 +.. _3721: https://github.com/varnishcache/varnish-cache/issues/3726 +.. _3734: https://github.com/varnishcache/varnish-cache/issues/3734 +.. _3737: https://github.com/varnishcache/varnish-cache/pull/3737 +.. _3732: https://github.com/varnishcache/varnish-cache/pull/3732 + ================================ Varnish Cache 7.0.0 (2021-09-15) ================================ From martin at varnish-software.com Tue Nov 23 12:31:13 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:13 +0000 (UTC) Subject: [master] d454d0ed7 Prepare for 7.0.1 Message-ID: <20211123123113.79335115F05@lists.varnish-cache.org> commit d454d0ed759ce8ed2b5c7bf244090a73487e8021 Author: Martin Blix Grydeland Date: Tue Nov 23 10:39:47 2021 +0100 Prepare for 7.0.1 diff --git a/configure.ac b/configure.ac index d9760807e..f21a8f85c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.69) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2021 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [7.0.0], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [7.0.1], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index b105f4717..19af0b100 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -32,7 +32,7 @@ individual releases. These documents are updated as part of the release process. ================================ -Varnish Cache 7.0.1 (unreleased) +Varnish Cache 7.0.1 (2021-11-23) ================================ * An assertion failure has been fixed which triggered when matching bans From martin at varnish-software.com Tue Nov 23 12:31:13 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Tue, 23 Nov 2021 12:31:13 +0000 (UTC) Subject: [master] 539a6be9a Merge 7.0.1 release branch Message-ID: <20211123123113.A614A115F1D@lists.varnish-cache.org> commit 539a6be9ad41c21f93b40d392d01d76f615d7203 Merge: bdc1620cf d454d0ed7 Author: Martin Blix Grydeland Date: Tue Nov 23 13:26:54 2021 +0100 Merge 7.0.1 release branch diff --cc doc/changes.rst index 77eba21c0,19af0b100..caecc06fa --- a/doc/changes.rst +++ b/doc/changes.rst @@@ -31,20 -31,46 +31,60 @@@ http://varnish-cache.org/docs/trunk/wha individual releases. These documents are updated as part of the release process. +=============================== +Varnish Cache NEXT (2022-03-15) +=============================== + +* Added macros ``TOSTRAND(s)`` and ``TOSTRANDS(x, ...)`` to create a + ``struct strands *`` (intended to be used as a ``VCL_STANDS``) from + a single string ``s`` or ``x`` strings, respectively. + + Note that the macros create a local pointer value (on the stack), + which should only be used for local variables and parameters, but + never as a function return value (use ``VRT_AllocStrandsWS()`` for + that or just return a ``VCL_STRING`` result created with + ``VRT_StrandsWS()``). + + ================================ + Varnish Cache 7.0.1 (2021-11-23) + ================================ + + * An assertion failure has been fixed which triggered when matching bans + on non-existing headers (3706_). + + * A VCL compilation issue has been fixed when calling builtin functions + directly (3719_). + + * It is now again possible to concatenate static strings to produce + combined strings of type VCL_REGEX (3721_). + + * An issue has been fixed that would cause the VCL dependency checker to + incorrectly flag VCLs as dependants of other VCLs when using labels, + preventing them from being discarded (3734_). + + * VCLs loaded through CLI or the use of startup CLI scripts (-I option to + `varnishd`) will, when no active VCL has previously been set, no longer + automatically set the first VCL loaded to the active VCL. This prevents + situations where it was possible to make a cold VCL the active VCL + (3737_). + + * There is now a `configure` build-time requirement on working SO_RCVTIMEO + and SO_SNDTIMEO socket options. + + * The socket option inheritance checks now correctly identifies situations + where UDS and TCP listening sockets behave differently, and are no + longer subject to the order the inheritance checks happens to be + executed (3732_). + + * IPv6 listen endpoint address strings are now printed using brackets. + + .. _3706: https://github.com/varnishcache/varnish-cache/issues/3706 + .. _3719: https://github.com/varnishcache/varnish-cache/issues/3719 + .. _3721: https://github.com/varnishcache/varnish-cache/issues/3726 + .. _3734: https://github.com/varnishcache/varnish-cache/issues/3734 + .. _3737: https://github.com/varnishcache/varnish-cache/pull/3737 + .. _3732: https://github.com/varnishcache/varnish-cache/pull/3732 + ================================ Varnish Cache 7.0.0 (2021-09-15) ================================ From martin at varnish-software.com Wed Nov 24 10:08:09 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 24 Nov 2021 10:08:09 +0000 (UTC) Subject: [6.0] b486bf47d More changelog entries Message-ID: <20211124100809.70733116AE5@lists.varnish-cache.org> commit b486bf47d197153650d588246648be6be82222ae Author: Martin Blix Grydeland Date: Wed Nov 24 11:05:11 2021 +0100 More changelog entries diff --git a/doc/changes.rst b/doc/changes.rst index cf9e6bb75..4416bfdc5 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -49,11 +49,23 @@ Varnish Cache 6.0.9 (unreleased) * Add an option to `configure` to use `libunwind` for the stack backtrace in the panic output. (3717_) +* A bug in ``vmod_blob`` for base64 decoding with a ``length`` argument + and non-padding decoding has been fixed (3378_) + +* The socket option inheritance checks now correctly identifies situations + where UDS and TCP listening sockets behave differently, and are no + longer subject to the order the inheritance checks happens to be + executed (3732_). + +* IPv6 listen endpoint address strings are now printed using brackets. + .. _3617: https://github.com/varnishcache/varnish-cache/pull/3617 .. _3437: https://github.com/varnishcache/varnish-cache/issues/3437' .. _3564: https://github.com/varnishcache/varnish-cache/issues/3564' .. _3716: https://github.com/varnishcache/varnish-cache/pull/3716' .. _3717: https://github.com/varnishcache/varnish-cache/pull/3717' +.. _3378: https://github.com/varnishcache/varnish-cache/issues/3378' +.. _3732: https://github.com/varnishcache/varnish-cache/pull/3732 ================================ Varnish Cache 6.0.8 (2021-07-13) From martin at varnish-software.com Wed Nov 24 10:08:09 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 24 Nov 2021 10:08:09 +0000 (UTC) Subject: [6.0] be077d4af Hopefully fix u00006 on various platforms. Message-ID: <20211124100809.636D9116AE3@lists.varnish-cache.org> commit be077d4af9278d0a44e5d20c369a1f8c7d39128f Author: Poul-Henning Kamp Date: Fri Nov 19 18:51:03 2021 +0000 Hopefully fix u00006 on various platforms. Dont limit ourselves to a set number of VSL records to include the "0 CLI" we want, various platforms emit a number of Debug messages relating to sockopt Use the `process p%d -expect-text` mechanism to wait only as long as necessary for the "0 CLI" diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index 9ffb331e7..e80a35089 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -7,9 +7,11 @@ server s1 -repeat 2 { varnish v1 -vcl+backend {} -start +# We use this to make sure we know there is a "0 CLI" in the binary log. process p1 { - exec varnishlog -n ${v1_name} -g raw -k 3 -w ${tmpdir}/vlog -A + exec varnishlog -n ${v1_name} -g raw -A } -start + shell { exec varnishlog -n ${v1_name} -D -P ${tmpdir}/vlog.pid \ -w ${tmpdir}/vlog.bin -R 10/s @@ -98,8 +100,11 @@ shell -err -expect "-R: Syntax error: Invalid duration" \ shell -err -expect "-R: Syntax error" \ "varnishlog -R 1000000000/1000000000000000000000000000000s" -process p1 -wait -shell {grep -q "0 CLI" ${tmpdir}/vlog} +# Wait until the binary also (must) contain a "0 CLI" +process p1 -expect-text 0 0 "0 CLI" +process p1 -screen_dump +process p1 -stop + shell -match "0 CLI[ ]+- Wr 200 [0-9]+ PONG" \ {varnishlog -n ${v1_name} -d -g raw -X "Wr 200 [0-9]+ [^P]"} From martin at varnish-software.com Wed Nov 24 11:00:09 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 24 Nov 2021 11:00:09 +0000 (UTC) Subject: [6.0] 08eba5660 Update copyright Message-ID: <20211124110009.8A1291183A4@lists.varnish-cache.org> commit 08eba566087aa22ca11f35efd6f715ef9fd80a53 Author: Martin Blix Grydeland Date: Wed Nov 24 11:13:04 2021 +0100 Update copyright diff --git a/lib/libvarnish/version.c b/lib/libvarnish/version.c index 087289e51..194eb328e 100644 --- a/lib/libvarnish/version.c +++ b/lib/libvarnish/version.c @@ -44,5 +44,5 @@ VCS_Message(const char *progname) { fprintf(stderr, "%s (%s)\n", progname, VCS_version); fprintf(stderr, "Copyright (c) 2006 Verdens Gang AS\n"); - fprintf(stderr, "Copyright (c) 2006-2020 Varnish Software AS\n"); + fprintf(stderr, "Copyright (c) 2006-2021 Varnish Software\n"); } From martin at varnish-software.com Wed Nov 24 11:00:09 2021 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 24 Nov 2021 11:00:09 +0000 (UTC) Subject: [6.0] 3383d3d02 Prepare for 6.0.9 Message-ID: <20211124110009.A292C1183A7@lists.varnish-cache.org> commit 3383d3d02c6ee459f20e1f46cfcb9692726a6387 Author: Martin Blix Grydeland Date: Wed Nov 24 11:13:25 2021 +0100 Prepare for 6.0.9 diff --git a/configure.ac b/configure.ac index cc6ea4ae4..344b14c2a 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2020 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [6.0.8], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [6.0.9], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index 4416bfdc5..cdd80b28c 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -27,7 +27,7 @@ individual releases. These documents are updated as part of the release process. ================================ -Varnish Cache 6.0.9 (unreleased) +Varnish Cache 6.0.9 (2021-11-24) ================================ * Increase the default stack size to 64k. (3617_) From phk at FreeBSD.org Wed Nov 24 11:37:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 11:37:05 +0000 (UTC) Subject: [master] 0c69a758b Whitespace OCD (Too much python have ruined my TAB-reflex) Message-ID: <20211124113705.D9504119639@lists.varnish-cache.org> commit 0c69a758bd7f0d732259c11d2abc75240edef714 Author: Poul-Henning Kamp Date: Wed Nov 24 11:34:06 2021 +0000 Whitespace OCD (Too much python have ruined my TAB-reflex) diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index 29510e9e8..02a3d4c84 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -137,7 +137,7 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv) cs = cli->cls; CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC); - for (av += 2; av[0] != NULL && av[0][0] == '-'; av++) { + for (av += 2; av[0] != NULL && av[0][0] == '-'; av++) { if (!strcmp(av[0], "-a")) { filter = 3; } else if (!strcmp(av[0], "-d")) { From phk at FreeBSD.org Wed Nov 24 11:37:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 11:37:05 +0000 (UTC) Subject: [master] 0d68e21d1 Use trivial VRT_Assign_Backend() to assign VCL_BACKEND to variables. Message-ID: <20211124113705.F130511963C@lists.varnish-cache.org> commit 0d68e21d1c12984f0285c12d9898aa6bbba3198e Author: Poul-Henning Kamp Date: Wed Nov 24 11:36:21 2021 +0000 Use trivial VRT_Assign_Backend() to assign VCL_BACKEND to variables. (First part of #3599) diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index f3e41716f..9a5fe36d1 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -137,7 +137,7 @@ VBO_GetBusyObj(const struct worker *wrk, const struct req *req) XXXAN(bo->client_identity); } - bo->director_req = req->director_hint; + VRT_Assign_Backend(&bo->director_req, req->director_hint); bo->vcl = req->vcl; VCL_Ref(bo->vcl); @@ -180,6 +180,8 @@ VBO_ReleaseBusyObj(struct worker *wrk, struct busyobj **pbo) HSH_RUSH_POLICY); } + VRT_Assign_Backend(&bo->director_req, NULL); + VRT_Assign_Backend(&bo->director_resp, NULL); VCL_Rel(&bo->vcl); #ifdef ENABLE_WORKSPACE_EMULATOR WS_Rollback(bo->ws, 0); diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c index 173ad6604..5bb3ac7b7 100644 --- a/bin/varnishd/cache/cache_director.c +++ b/bin/varnishd/cache/cache_director.c @@ -140,7 +140,7 @@ VDI_GetHdr(struct busyobj *bo) d = VDI_Resolve(ctx); if (d != NULL) { - bo->director_resp = d; + VRT_Assign_Backend(&bo->director_resp, d); AN(d->vdir->methods->gethdrs); bo->director_state = DIR_S_HDRS; i = d->vdir->methods->gethdrs(ctx, d); @@ -214,7 +214,7 @@ VDI_Http1Pipe(struct req *req, struct busyobj *bo) VSLb(bo->vsl, SLT_VCL_Error, "Backend does not support pipe"); return (SC_TX_ERROR); } - bo->director_resp = d; + VRT_Assign_Backend(&bo->director_resp, d); return (d->vdir->methods->http1pipe(ctx, d)); } diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index e754014e7..0b383e594 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -876,7 +876,8 @@ cnt_recv_prep(struct req *req, const char *ci) http_CollectHdr(req->http, H_Cache_Control); /* By default we use the first backend */ - req->director_hint = VCL_DefaultDirector(req->vcl); + VRT_Assign_Backend(&req->director_hint, + VCL_DefaultDirector(req->vcl)); req->d_ttl = -1; req->d_grace = -1; @@ -1190,6 +1191,7 @@ CNT_Request(struct req *req) VCL_TaskLeave(ctx, req->privs); AN(req->vsl->wid); VRB_Free(req); + VRT_Assign_Backend(&req->director_hint, NULL); req->wrk = NULL; } assert(nxt == REQ_FSM_DISEMBARK || !WS_IsReserved(req->ws)); diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index c73c28385..1f0edca4d 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -504,13 +504,22 @@ VRT_r_req_##nm(VRT_CTX) \ return (ctx->req->elem); \ } -REQ_VAR_L(backend_hint, director_hint, VCL_BACKEND,) REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND) + REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;) REQ_VAR_R(ttl, d_ttl, VCL_DURATION) REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;) REQ_VAR_R(grace, d_grace, VCL_DURATION) +VCL_VOID +VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be) +{ + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); + VRT_Assign_Backend(&ctx->req->director_hint, be); +} + /*--------------------------------------------------------------------*/ VCL_VOID @@ -519,7 +528,7 @@ VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); - ctx->bo->director_req = be; + VRT_Assign_Backend(&ctx->bo->director_req, be); } VCL_BACKEND diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 3fd34e42e..194098c3f 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -251,6 +251,14 @@ VRT_DelDirector(VCL_BACKEND *bp) vcldir_free(vdir); } +void +VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src) +{ + + AN(dst); + *dst = src; +} + void VRT_DisableDirector(VCL_BACKEND d) { diff --git a/include/vrt.h b/include/vrt.h index a0d4f10ff..5e99b242d 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -53,6 +53,9 @@ * Whenever something is deleted or changed in a way which is not * binary/load-time compatible, increment MAJOR version * + * Next (2021-03-15) + * VRT_Assign_Backend added + * * 14.0 (2021-09-15) * VIN_n_Arg() no directly returns the directory name. * VSB_new() and VSB_delete() removed @@ -682,6 +685,7 @@ VCL_BACKEND VRT_AddDirector(VRT_CTX, const struct vdi_methods *, void VRT_DisableDirector(VCL_BACKEND); VCL_BACKEND VRT_LookupDirector(VRT_CTX, VCL_STRING); void VRT_DelDirector(VCL_BACKEND *); +void VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src); /*********************************************************************** * vmod_priv related diff --git a/vmod/vmod_directors.c b/vmod/vmod_directors.c index 09f18719e..2130c4b55 100644 --- a/vmod/vmod_directors.c +++ b/vmod/vmod_directors.c @@ -96,10 +96,13 @@ void vdir_delete(struct vdir **vdp) { struct vdir *vd; + unsigned u; TAKE_OBJ_NOTNULL(vd, vdp, VDIR_MAGIC); AZ(vd->dir); + for (u = 0; u < vd->n_backend; u++) + VRT_Assign_Backend(&vd->backend[u], NULL); free(vd->backend); free(vd->weight); AZ(pthread_rwlock_destroy(&vd->mtx)); @@ -147,7 +150,8 @@ vdir_add_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, double weight) vdir_expand(vd, vd->l_backend + 16); assert(vd->n_backend < vd->l_backend); u = vd->n_backend++; - vd->backend[u] = be; + vd->backend[u] = NULL; + VRT_Assign_Backend(&vd->backend[u], be); vd->weight[u] = weight; vdir_unlock(vd); } @@ -173,6 +177,7 @@ vdir_remove_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, unsigned *cur) vdir_unlock(vd); return; } + VRT_Assign_Backend(&vd->backend[u], NULL); n = (vd->n_backend - u) - 1; memmove(&vd->backend[u], &vd->backend[u+1], n * sizeof(vd->backend[0])); memmove(&vd->weight[u], &vd->weight[u+1], n * sizeof(vd->weight[0])); diff --git a/vmod/vmod_directors_shard_cfg.c b/vmod/vmod_directors_shard_cfg.c index 3d3c6de11..6df86b643 100644 --- a/vmod/vmod_directors_shard_cfg.c +++ b/vmod/vmod_directors_shard_cfg.c @@ -195,7 +195,8 @@ shard_change_task_backend(VRT_CTX, struct sharddir *shardd, return (NULL); } - b->backend = be; + b->backend = NULL; + VRT_Assign_Backend(&b->backend, be); b->ident = ident != NULL && *ident != '\0' ? ident : NULL; b->rampup = rampup; @@ -333,6 +334,7 @@ shardcfg_backend_free(struct shard_backend *f) { if (f->freeptr) free (f->freeptr); + VRT_Assign_Backend(&f->backend, NULL); memset(f, 0, sizeof(*f)); } @@ -466,8 +468,7 @@ shardcfg_backend_clear(struct sharddir *shardd) static void -shardcfg_backend_del(struct backend_reconfig *re, - const struct shard_backend *spec) +shardcfg_backend_del(struct backend_reconfig *re, struct shard_backend *spec) { unsigned i, max = re->shardd->n_backend + re->hole_n; struct shard_backend * const bb = re->shardd->backend; @@ -485,6 +486,7 @@ shardcfg_backend_del(struct backend_reconfig *re, re->hole_i = vmin(re->hole_i, i); } } + VRT_Assign_Backend(&spec->backend, NULL); } static void From phk at FreeBSD.org Wed Nov 24 12:33:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 12:33:05 +0000 (UTC) Subject: [master] 8941ae92d Reference count directors. Message-ID: <20211124123306.08C9111B075@lists.varnish-cache.org> commit 8941ae92dc95d6ff28833037077d5dd3a757feb1 Author: Poul-Henning Kamp Date: Wed Nov 24 11:49:55 2021 +0000 Reference count directors. (2nd part of #3599) diff --git a/bin/varnishd/cache/cache_director.h b/bin/varnishd/cache/cache_director.h index eefbd9335..31c41e27b 100644 --- a/bin/varnishd/cache/cache_director.h +++ b/bin/varnishd/cache/cache_director.h @@ -36,6 +36,7 @@ struct vcldir { unsigned magic; #define VCLDIR_MAGIC 0xbf726c7d + int refcnt; struct lock dlck; struct director *dir; struct vcl *vcl; diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 194098c3f..4144c13f2 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -197,6 +197,7 @@ VRT_AddDirector(VRT_CTX, const struct vdi_methods *m, void *priv, vdir->admin_health = VDI_AH_AUTO; vdir->health_changed = VTIM_real(); + vdir->refcnt++; Lck_New(&vdir->dlck, lck_director); vdir->dir->mtx = &vdir->dlck; @@ -238,6 +239,11 @@ VRT_DelDirector(VCL_BACKEND *bp) vcl = vdir->vcl; CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + Lck_Lock(d->mtx); + assert(vdir->refcnt == 1); + --vdir->refcnt; + Lck_Unlock(d->mtx); + Lck_Lock(&vcl_mtx); temp = vcl->temp; VTAILQ_REMOVE(&vcl->director_list, vdir, list); @@ -256,6 +262,22 @@ VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src) { AN(dst); + CHECK_OBJ_ORNULL((*dst), DIRECTOR_MAGIC); + CHECK_OBJ_ORNULL(src, DIRECTOR_MAGIC); + if (*dst != NULL) { + CHECK_OBJ_NOTNULL((*dst)->vdir, VCLDIR_MAGIC); + Lck_Lock((*dst)->mtx); + assert((*dst)->vdir->refcnt > 0); + --(*dst)->vdir->refcnt; + Lck_Unlock((*dst)->mtx); + } + if (src != NULL) { + CHECK_OBJ_NOTNULL(src->vdir, VCLDIR_MAGIC); + Lck_Lock(src->mtx); + assert(src->vdir->refcnt > 0); + src->vdir->refcnt++; + Lck_Unlock(src->mtx); + } *dst = src; } From phk at FreeBSD.org Wed Nov 24 12:33:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 12:33:06 +0000 (UTC) Subject: [master] 5ed9aece4 Teardown straggler backends by sending them DISCARD event Message-ID: <20211124123306.2574D11B078@lists.varnish-cache.org> commit 5ed9aece431e5f0d3a6c4cf337fc90ca2a52c1be Author: Poul-Henning Kamp Date: Wed Nov 24 11:57:35 2021 +0000 Teardown straggler backends by sending them DISCARD event (3rd part of #3599) diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 063048931..dada7f2b7 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -408,6 +408,8 @@ vbe_dir_event(const struct director *d, enum vcl_event_e ev) if (bp->probe != NULL) VBP_Control(bp, 0); VRT_VSC_Hide(bp->vsc_seg); + } else if (ev == VCL_EVENT_DISCARD) { + VRT_Assign_Backend(&bp->director, NULL); } } diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index c69e1e5c7..48ee357ba 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -447,24 +447,19 @@ vcl_BackendEvent(const struct vcl *vcl, enum vcl_event_e e) } static void -vcl_KillBackends(struct vcl *vcl) +vcl_KillBackends(const struct vcl *vcl) { - struct vcldir *vdir; + struct vcldir *vdir, *vdir2; CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - AZ(vcl->busy); - assert(VTAILQ_EMPTY(&vcl->ref_list)); - Lck_Lock(&vcl_mtx); - while (1) { - vdir = VTAILQ_FIRST(&vcl->director_list); - if (vdir == NULL) - break; - VTAILQ_REMOVE(&vcl->director_list, vdir, list); - AN(vdir->methods->destroy); - vdir->methods->destroy(vdir->dir); - vcldir_free(vdir); - } - Lck_Unlock(&vcl_mtx); + assert(vcl->temp == VCL_TEMP_COLD || vcl->temp == VCL_TEMP_INIT); + /* + * Unlocked because no further directors can be added, and the + * remaining ones need to be able to remove themselves. + */ + VTAILQ_FOREACH_SAFE(vdir, &vcl->director_list, list, vdir2) + VDI_Event(vdir->dir, VCL_EVENT_DISCARD); + assert(VTAILQ_EMPTY(&vcl->director_list)); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 4144c13f2..6e4592c06 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -146,6 +146,7 @@ vcldir_free(struct vcldir *vdir) CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC); CHECK_OBJ_NOTNULL(vdir->dir, DIRECTOR_MAGIC); + AZ(vdir->refcnt); Lck_Delete(&vdir->dlck); free(vdir->cli_name); FREE_OBJ(vdir->dir); @@ -225,10 +226,9 @@ VRT_AddDirector(VRT_CTX, const struct vdi_methods *m, void *priv, return (vdir->dir); } -void -VRT_DelDirector(VCL_BACKEND *bp) +static void +retire_backend(VCL_BACKEND *bp) { - struct vcl *vcl; struct vcldir *vdir; const struct vcltemp *temp; VCL_BACKEND d; @@ -236,17 +236,13 @@ VRT_DelDirector(VCL_BACKEND *bp) TAKE_OBJ_NOTNULL(d, bp, DIRECTOR_MAGIC); vdir = d->vdir; CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC); - vcl = vdir->vcl; - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - - Lck_Lock(d->mtx); - assert(vdir->refcnt == 1); - --vdir->refcnt; - Lck_Unlock(d->mtx); + assert(vdir->refcnt == 0); + assert (d == vdir->dir); + CHECK_OBJ_NOTNULL(vdir->vcl, VCL_MAGIC); Lck_Lock(&vcl_mtx); - temp = vcl->temp; - VTAILQ_REMOVE(&vcl->director_list, vdir, list); + temp = vdir->vcl->temp; + VTAILQ_REMOVE(&vdir->vcl->director_list, vdir, list); Lck_Unlock(&vcl_mtx); if (temp->is_warm) @@ -257,9 +253,25 @@ VRT_DelDirector(VCL_BACKEND *bp) vcldir_free(vdir); } +void +VRT_DelDirector(VCL_BACKEND *bp) +{ + struct vcldir *vdir; + + AN(bp); + vdir = (*bp)->vdir; + CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC); + Lck_Lock(&vdir->dlck); + assert(vdir->refcnt == 1); + vdir->refcnt = 0; + Lck_Unlock(&vdir->dlck); + retire_backend(bp); +} + void VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src) { + int busy; AN(dst); CHECK_OBJ_ORNULL((*dst), DIRECTOR_MAGIC); @@ -268,8 +280,10 @@ VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src) CHECK_OBJ_NOTNULL((*dst)->vdir, VCLDIR_MAGIC); Lck_Lock((*dst)->mtx); assert((*dst)->vdir->refcnt > 0); - --(*dst)->vdir->refcnt; + busy = --(*dst)->vdir->refcnt; Lck_Unlock((*dst)->mtx); + if (!busy) + retire_backend(dst); } if (src != NULL) { CHECK_OBJ_NOTNULL(src->vdir, VCLDIR_MAGIC); From phk at FreeBSD.org Wed Nov 24 12:33:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 12:33:06 +0000 (UTC) Subject: [master] b81e27708 Ditch the director cooling list and trust the refcounts. Message-ID: <20211124123306.4FB1D11B07C@lists.varnish-cache.org> commit b81e27708a792ce8168476f43b2a87c8beca50d5 Author: Poul-Henning Kamp Date: Wed Nov 24 12:06:44 2021 +0000 Ditch the director cooling list and trust the refcounts. (4th part of #3599) diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index dada7f2b7..ebf1b9e3c 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -54,9 +54,6 @@ static const char * const vbe_proto_ident = "HTTP Backend"; -static VTAILQ_HEAD(, backend) backends = VTAILQ_HEAD_INITIALIZER(backends); -static VTAILQ_HEAD(, backend) cool_backends = - VTAILQ_HEAD_INITIALIZER(cool_backends); static struct lock backends_mtx; /*--------------------------------------------------------------------*/ @@ -426,13 +423,9 @@ vbe_free(struct backend *be) VSC_vbe_Destroy(&be->vsc_seg); Lck_Lock(&backends_mtx); - if (be->cooled > 0) - VTAILQ_REMOVE(&cool_backends, be, list); - else - VTAILQ_REMOVE(&backends, be, list); VSC_C_main->n_backend--; - VCP_Rel(&be->conn_pool); Lck_Unlock(&backends_mtx); + VCP_Rel(&be->conn_pool); #define DA(x) do { if (be->x != NULL) free(be->x); } while (0) #define DN(x) /**/ @@ -630,21 +623,19 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, } Lck_Lock(&backends_mtx); - VTAILQ_INSERT_TAIL(&backends, be, list); VSC_C_main->n_backend++; Lck_Unlock(&backends_mtx); be->director = VRT_AddDirector(ctx, m, be, "%s", vrt->vcl_name); - if (be->director != NULL) { - /* for cold VCL, update initial director state */ - if (be->probe != NULL && ! vcl->temp->is_warm) - VBP_Update_Backend(be->probe); - return (be->director); + if (be->director == NULL) { + vbe_free(be); + return (NULL); } - - vbe_free(be); - return (NULL); + /* for cold VCL, update initial director state */ + if (be->probe != NULL) + VBP_Update_Backend(be->probe); + return (be->director); } VCL_BACKEND @@ -664,47 +655,11 @@ VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt) void VRT_delete_backend(VRT_CTX, VCL_BACKEND *dp) { - VCL_BACKEND d; - struct backend *be; - - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - TAKE_OBJ_NOTNULL(d, dp, DIRECTOR_MAGIC); - CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC); - Lck_Lock(be->director->mtx); - VRT_DisableDirector(be->director); - Lck_Unlock(be->director->mtx); - Lck_Lock(&backends_mtx); - AZ(be->cooled); - be->cooled = VTIM_real() + 60.; - VTAILQ_REMOVE(&backends, be, list); - VTAILQ_INSERT_TAIL(&cool_backends, be, list); - Lck_Unlock(&backends_mtx); - // NB. The backend is still usable for the ongoing transactions, - // this is why we don't bust the director's magic number. -} - -/*---------------------------------------------------------------------*/ - -void -VBE_Poll(void) -{ - struct backend *be, *be2; - vtim_real now = VTIM_real(); - - ASSERT_CLI(); - Lck_Lock(&backends_mtx); - VTAILQ_FOREACH_SAFE(be, &cool_backends, list, be2) { - CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC); - if (be->cooled > now) - break; - if (be->n_conn > 0) - continue; - Lck_Unlock(&backends_mtx); - VRT_DelDirector(&be->director); - Lck_Lock(&backends_mtx); - } - Lck_Unlock(&backends_mtx); + (void)ctx; + CHECK_OBJ_NOTNULL(*dp, DIRECTOR_MAGIC); + VRT_DisableDirector(*dp); + VRT_Assign_Backend(dp, NULL); } /*---------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index 536494f7b..76bc3c07c 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -54,8 +54,6 @@ struct backend { unsigned n_conn; - VTAILQ_ENTRY(backend) list; - struct vrt_endpoint *endpoint; VRT_BACKEND_FIELDS() @@ -71,8 +69,6 @@ struct backend { struct conn_pool *conn_pool; VCL_BACKEND director; - - vtim_real cooled; }; /*--------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c index 85a16a724..06b2e02e6 100644 --- a/bin/varnishd/cache/cache_cli.c +++ b/bin/varnishd/cache/cache_cli.c @@ -77,7 +77,6 @@ cli_cb_before(const struct cli *cli) ASSERT_CLI(); VSL(SLT_CLI, 0, "Rd %s", VSB_data(cli->cmd)); VCL_Poll(); - VBE_Poll(); Lck_Lock(&cli_mtx); } diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index a3e0b150a..aae9be794 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -256,7 +256,7 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) if (IS_TOPREQ(req)) AZ(req->top->vcl0); - req->director_hint = NULL; + AZ(req->director_hint); req->restarts = 0; if (req->vcl != NULL) diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 57294faa9..a4192018f 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -162,7 +162,6 @@ void VCA_Shutdown(void); /* cache_backend_cfg.c */ void VBE_InitCfg(void); -void VBE_Poll(void); void VBP_Init(void); diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h index 355cccf59..ac0d7aa75 100644 --- a/bin/varnishd/cache/cache_vcl.h +++ b/bin/varnishd/cache/cache_vcl.h @@ -71,7 +71,6 @@ extern struct lock vcl_mtx; extern struct vcl *vcl_active; /* protected by vcl_mtx */ struct vcl *vcl_find(const char *); void VCL_Update(struct vcl **, struct vcl *); -void vcldir_free(struct vcldir *); struct vcltemp { const char * const name; diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 6e4592c06..35e83f3df 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -140,7 +140,7 @@ VCL_Rel(struct vcl **vcc) /*--------------------------------------------------------------------*/ -void +static void vcldir_free(struct vcldir *vdir) { From phk at FreeBSD.org Wed Nov 24 12:33:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 12:33:06 +0000 (UTC) Subject: [master] 4c295286d Add VRT_StaticDirector() to disable refcounting. Message-ID: <20211124123306.6E1F911B084@lists.varnish-cache.org> commit 4c295286d89def5d70c80c98d0f002dba6d79efc Author: Poul-Henning Kamp Date: Wed Nov 24 12:23:25 2021 +0000 Add VRT_StaticDirector() to disable refcounting. (Last part of #3599) diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index ebf1b9e3c..9f286a55f 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -406,7 +406,7 @@ vbe_dir_event(const struct director *d, enum vcl_event_e ev) VBP_Control(bp, 0); VRT_VSC_Hide(bp->vsc_seg); } else if (ev == VCL_EVENT_DISCARD) { - VRT_Assign_Backend(&bp->director, NULL); + VRT_DelDirector(&bp->director); } } diff --git a/bin/varnishd/cache/cache_director.h b/bin/varnishd/cache/cache_director.h index 31c41e27b..9a12c6b3d 100644 --- a/bin/varnishd/cache/cache_director.h +++ b/bin/varnishd/cache/cache_director.h @@ -37,6 +37,8 @@ struct vcldir { unsigned magic; #define VCLDIR_MAGIC 0xbf726c7d int refcnt; + unsigned flags; +#define VDIR_FLG_NOREFCNT 1 struct lock dlck; struct director *dir; struct vcl *vcl; diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 35e83f3df..070822f36 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -226,6 +226,19 @@ VRT_AddDirector(VRT_CTX, const struct vdi_methods *m, void *priv, return (vdir->dir); } +void +VRT_StaticDirector(VCL_BACKEND b) +{ + struct vcldir *vdir; + + CHECK_OBJ_NOTNULL(b, DIRECTOR_MAGIC); + vdir = b->vdir; + CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC); + assert(vdir->refcnt == 1); + AZ(vdir->flags & VDIR_FLG_NOREFCNT); + vdir->flags |= VDIR_FLG_NOREFCNT; +} + static void retire_backend(VCL_BACKEND *bp) { @@ -278,19 +291,23 @@ VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src) CHECK_OBJ_ORNULL(src, DIRECTOR_MAGIC); if (*dst != NULL) { CHECK_OBJ_NOTNULL((*dst)->vdir, VCLDIR_MAGIC); - Lck_Lock((*dst)->mtx); - assert((*dst)->vdir->refcnt > 0); - busy = --(*dst)->vdir->refcnt; - Lck_Unlock((*dst)->mtx); - if (!busy) - retire_backend(dst); + if (!((*dst)->vdir->flags & VDIR_FLG_NOREFCNT)) { + Lck_Lock((*dst)->mtx); + assert((*dst)->vdir->refcnt > 0); + busy = --(*dst)->vdir->refcnt; + Lck_Unlock((*dst)->mtx); + if (!busy) + retire_backend(dst); + } } if (src != NULL) { CHECK_OBJ_NOTNULL(src->vdir, VCLDIR_MAGIC); - Lck_Lock(src->mtx); - assert(src->vdir->refcnt > 0); - src->vdir->refcnt++; - Lck_Unlock(src->mtx); + if (!(src->vdir->flags & VDIR_FLG_NOREFCNT)) { + Lck_Lock(src->mtx); + assert(src->vdir->refcnt > 0); + src->vdir->refcnt++; + Lck_Unlock(src->mtx); + } } *dst = src; } From phk at FreeBSD.org Wed Nov 24 12:35:07 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 24 Nov 2021 12:35:07 +0000 (UTC) Subject: [master] 651bff316 Oops, last commit missed these. Message-ID: <20211124123507.0CA6411B682@lists.varnish-cache.org> commit 651bff31609f4cdde1eadf1beac2e28212002976 Author: Poul-Henning Kamp Date: Wed Nov 24 12:34:18 2021 +0000 Oops, last commit missed these. diff --git a/include/vrt.h b/include/vrt.h index 5e99b242d..a47250255 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -55,6 +55,7 @@ * * Next (2021-03-15) * VRT_Assign_Backend added + * VRT_StaticDirector added * * 14.0 (2021-09-15) * VIN_n_Arg() no directly returns the directory name. @@ -683,6 +684,7 @@ VCL_VOID VRT_SetChanged(VCL_BACKEND, VCL_TIME); VCL_BACKEND VRT_AddDirector(VRT_CTX, const struct vdi_methods *, void *, const char *, ...) v_printflike_(4, 5); void VRT_DisableDirector(VCL_BACKEND); +void VRT_StaticDirector(VCL_BACKEND); VCL_BACKEND VRT_LookupDirector(VRT_CTX, VCL_STRING); void VRT_DelDirector(VCL_BACKEND *); void VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src); diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index 4fac23c20..8b357a58e 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -572,8 +572,10 @@ 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);", + "\t\t&vgc_dir_priv_%s);\n", vgcname, vgcname); + 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 dridi.boukelmoune at gmail.com Mon Nov 29 14:37:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 14:37:06 +0000 (UTC) Subject: [master] c0ff10a73 github actions: add CIFuzz integration Message-ID: <20211129143706.6C0D9106E16@lists.varnish-cache.org> commit c0ff10a7357c2b8085757dca3fe281cb747506db Author: David Korczynski Date: Fri Nov 26 18:39:22 2021 +0000 github actions: add CIFuzz integration diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 000000000..a18f1333c --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,26 @@ +name: CIFuzz +on: [pull_request] +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers at master + with: + oss-fuzz-project-name: 'varnish' + dry-run: false + language: c + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers at master + with: + oss-fuzz-project-name: 'varnish' + fuzz-seconds: 600 + dry-run: false + language: c + - name: Upload Crash + uses: actions/upload-artifact at v1 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts From nils.goroll at uplex.de Mon Nov 29 14:47:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 29 Nov 2021 14:47:06 +0000 (UTC) Subject: [master] ae6512a47 Add {req,req_top,resp,bereq,beresp,obj}.time Message-ID: <20211129144706.731F710741F@lists.varnish-cache.org> commit ae6512a47dbef775036d890a71cd9f87b18fa84d Author: Nils Goroll Date: Thu Mar 25 17:26:21 2021 +0100 Add {req,req_top,resp,bereq,beresp,obj}.time {req,bereq}.time remain constant across restarts/retries req_top.time remains constant across esi includes The other values represent the time when the respective object was created. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f35b0ab69..aeadda251 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -393,6 +393,7 @@ struct busyobj { /* Timers */ vtim_real t_first; /* First timestamp logged */ + vtim_real t_resp; /* response received */ vtim_real t_prev; /* Previous timestamp logged */ /* Acct */ @@ -484,6 +485,7 @@ struct req { vtim_real t_first; /* First timestamp logged */ vtim_real t_prev; /* Previous timestamp logged */ vtim_real t_req; /* Headers complete */ + vtim_real t_resp; /* Entry to last deliver/synth */ struct http_conn *htc; struct vfp_ctx *vfc; diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 76a3a2422..942a611f8 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -427,7 +427,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) VSLb_ts_busyobj(bo, "Fetch", W_TIM_real(wrk)); i = VDI_GetHdr(bo); - now = W_TIM_real(wrk); + bo->t_resp = now = W_TIM_real(wrk); VSLb_ts_busyobj(bo, "Beresp", now); if (i) { diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 0b383e594..3538c3e6c 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -231,7 +231,9 @@ cnt_deliver(struct worker *wrk, struct req *req) !(req->objcore->flags & OC_F_PRIVATE)) http_ForceHeader(req->resp, H_Accept_Ranges, "bytes"); + req->t_resp = W_TIM_real(wrk); VCL_deliver_method(req->vcl, wrk, req, NULL, NULL); + VSLb_ts_req(req, "Process", W_TIM_real(wrk)); assert(req->restarts <= cache_param->max_restarts); @@ -324,6 +326,7 @@ cnt_synth(struct worker *wrk, struct req *req) synth_body = VSB_new_auto(); AN(synth_body); + req->t_resp = W_TIM_real(wrk); VCL_synth_method(req->vcl, wrk, req, NULL, synth_body); AZ(VSB_finish(synth_body)); diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 1f0edca4d..64b7257d4 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -707,6 +707,25 @@ VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0) /*lint -restore */ +// XXX more assertions? +#define VRT_DO_TIME_R(which, where, field) \ + \ +VCL_TIME \ +VRT_r_##which##_time(VRT_CTX) \ +{ \ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ + AN((ctx)->where); \ + \ + return ((ctx)->where->field); \ +} + +VRT_DO_TIME_R(req, req, t_req) +VRT_DO_TIME_R(req_top, req->top->topreq, t_req) +VRT_DO_TIME_R(resp, req, t_resp) +VRT_DO_TIME_R(bereq, bo, t_first) +VRT_DO_TIME_R(beresp, bo, t_resp) +VRT_DO_TIME_R(obj, req->objcore, t_origin) + /*-------------------------------------------------------------------- */ diff --git a/bin/varnishtest/tests/b00030.vtc b/bin/varnishtest/tests/b00030.vtc index 626324755..ba6b7c9cb 100644 --- a/bin/varnishtest/tests/b00030.vtc +++ b/bin/varnishtest/tests/b00030.vtc @@ -7,68 +7,107 @@ varnishtest "Test timestamps" server s1 { rxreq txresp + rxreq + txresp } -start varnish v1 -vcl+backend { import vtc; + import std; sub recv_sub { - set req.http.recv_sub = now; + set req.http.now-recv_sub = now; } sub vcl_recv { - set req.http.recv = now; + if (req.restarts == 0) { + set req.http.req-time = req.time; + } else if (req.http.req-time != "" + req.time) { + return (fail); + } + set req.http.now-recv = now; vtc.sleep(1s); call recv_sub; - if (req.http.recv != req.http.recv_sub) { + if (req.http.now-recv != req.http.now-recv_sub) { return (fail); } } sub vcl_synth { - set resp.http.synth = now; + set resp.http.now-synth = now; + if (req.http.req-time != "" + req.time) { + return (fail); + } + set req.http.req-time = req.time; + set resp.http.resp-time = resp.time; } sub vcl_deliver { - set resp.http.deliver = now; - if (req.http.recv == req.http.deliver) { + if (req.http.req-time != "" + req.time) { + return (fail); + } + set resp.http.resp-time = resp.time; + set resp.http.obj-time = obj.time; + set resp.http.now-deliver = now; + if (req.http.now-recv == req.http.now-deliver) { return (fail); } vtc.sleep(1s); + if (req.restarts == 0) { + return (restart); + } return (synth(200)); } sub bf_sub { - set bereq.http.bf_sub = now; + set bereq.http.now-bf_sub = now; } sub vcl_backend_fetch { - set bereq.http.bf = now; + if (bereq.retries == 0) { + set bereq.http.bereq-time = bereq.time; + } else if (bereq.http.bereq-time != "" + bereq.time) { + # bereq.time is identical for all retries + return (fail); + } + if (bereq.time <= std.time(bereq.http.req-time)) { + return (fail); + } + set bereq.http.now-bf = now; vtc.sleep(1s); call bf_sub; - if (bereq.http.bf != bereq.http.bf_sub) { + # now remains constant during built-in vcl sub + if (bereq.http.now-bf != bereq.http.now-bf_sub) { return (fail); } } sub br_sub { - set beresp.http.br_sub = now; + set beresp.http.now-br_sub = now; } sub vcl_backend_response { - set beresp.http.br = now; + if (bereq.http.bereq-time != "" + bereq.time) { + return (fail); + } + set beresp.http.beresp-time = beresp.time; + set beresp.http.now-br = now; vtc.sleep(1s); call br_sub; - if (beresp.http.br != beresp.http.br_sub) { + if (beresp.http.now-br != beresp.http.now-br_sub) { return (fail); } - if (bereq.http.bf == beresp.http.br) { + if (bereq.http.now-bf == beresp.http.now-br) { return (fail); } + if (bereq.retries == 0) { + return (retry); + } + } + sub vcl_backend_error { + call vcl_backend_response; } - - } -start client c1 { txreq rxresp expect resp.status == 200 - expect resp.http.synth ~ "^..., .. ... .... ..:..:.. GMT" + expect resp.http.now-synth ~ "^..., .. ... .... ..:..:.. GMT" } -run diff --git a/bin/varnishtest/tests/e00030.vtc b/bin/varnishtest/tests/e00030.vtc index 0a529d1f9..ff2016fb9 100644 --- a/bin/varnishtest/tests/e00030.vtc +++ b/bin/varnishtest/tests/e00030.vtc @@ -56,7 +56,11 @@ varnish v1 -vcl+backend { sub vcl_recv { if (req.esi_level > 0) { set req.url = req.url + req.esi_level; + if (req_top.http.top-time != "" + req_top.time) { + return (fail); + } } else { + set req.http.top-time = req_top.time; set req.http.foo = "bar"; } diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 4271824ac..02f71001f 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -409,6 +409,15 @@ req.is_hitpass If this request resulted in a hitpass +req.time + + Type: TIME + + Readable from: client + + The time when the request was fully received, remains constant + across restarts. + req_top.method Type: STRING @@ -453,6 +462,14 @@ req_top.proto ESI requests. Identical to req.proto in non-ESI requests. +req_top.time + + Type: TIME + + Readable from: client + + The time when the top-level request was fully received, + remains constant across restarts. bereq ~~~~~ @@ -671,6 +688,15 @@ bereq.is_hitpass If this backend request was caused by a hitpass. +bereq.time + + Type: TIME + + Readable from: backend + + The time when we started preparing the first backend request, + remains constant across retries. + beresp ~~~~~~ @@ -1025,6 +1051,17 @@ beresp.filters After beresp.filters is set, using any of the beforementioned ``beresp.do_*`` switches is a VCL error. +beresp.time + + Type: TIME + + Readable from: vcl_backend_response, vcl_backend_error + + When the backend headers were fully received just before + ``vcl_backend_response {}`` was entered, or when + ``vcl_backend_error {}`` was entered. + + obj ~~~ @@ -1149,6 +1186,15 @@ obj.can_esi ``vcl_deliver {}`` would cause the response body to be ESI processed. +obj.time + + Type: TIME + + Readable from: vcl_hit, vcl_deliver + + The time the object was created from the perspective of the + server which generated it. This will roughly be equivalent to + ``now`` - ``obj.age``. resp ~~~~ @@ -1292,6 +1338,15 @@ resp.filters effiect. Using resp.do_esi is an error once resp.filters is set. +resp.time + + Type: TIME + + Readable from: vcl_deliver, vcl_synth + + The time when we started preparing the response, just before + entering ``vcl_synth {}`` or ``vcl_deliver {}``. + Special variables ~~~~~~~~~~~~~~~~~ From nils.goroll at uplex.de Mon Nov 29 14:47:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 29 Nov 2021 14:47:06 +0000 (UTC) Subject: [master] fb3a5bb1d Adjust vtc to account for another 8 bytes used in struct req Message-ID: <20211129144706.8B5C6107422@lists.varnish-cache.org> commit fb3a5bb1d1569f9ceee0a7f2cff5d9dcf11dd233 Author: Nils Goroll Date: Mon Nov 29 15:37:31 2021 +0100 Adjust vtc to account for another 8 bytes used in struct req diff --git a/bin/varnishtest/tests/r02219.vtc b/bin/varnishtest/tests/r02219.vtc index 3604392a0..599f2ced7 100644 --- a/bin/varnishtest/tests/r02219.vtc +++ b/bin/varnishtest/tests/r02219.vtc @@ -22,7 +22,7 @@ varnish v1 -arg "-p workspace_client=9k" \ } -start client c1 { - send "PROXY TCP4 127.0.0.1 127.0.0.1 1111 2222\r\nGET /${string,repeat,752,A} HTTP/1.1\r\n\r\n" + send "PROXY TCP4 127.0.0.1 127.0.0.1 1111 2222\r\nGET /${string,repeat,744,A} HTTP/1.1\r\n\r\n" rxresp } -run @@ -39,6 +39,6 @@ ${string,repeat,732,"42 "} } -run client c3 { - send "PROXY TCP4 127.0.0.1 127.0.0.1 1111 2222\r\nGET /${string,repeat,756,C} HTTP/1.1\r\n\r\n" + send "PROXY TCP4 127.0.0.1 127.0.0.1 1111 2222\r\nGET /${string,repeat,748,C} HTTP/1.1\r\n\r\n" rxresp } -run From dridi.boukelmoune at gmail.com Mon Nov 29 14:47:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 14:47:06 +0000 (UTC) Subject: [master] 3dd4d72df std.ip: Always provide some form of fallback Message-ID: <20211129144706.A7A40107426@lists.varnish-cache.org> commit 3dd4d72df82be40782374195225c79f6cb9424d9 Author: Dridi Boukelmoune Date: Fri Nov 26 12:56:10 2021 +0100 std.ip: Always provide some form of fallback Otherwise valid code can panic on workspace exhaustion: std.ip(req.http.X-Real-IP, std.ip(req.http.X-Client-IP, client.ip)) If the nested std.ip() call runs out of workspace, it will return a null ip instead of the fallback, and since the outer std.ip() call is getting a fallback argument, it will panic upon checking the suckaddr sanity. Refs a3b26d0ba7dd8763a4e34d9e18d92fc24f1c291c diff --git a/vmod/vmod_std_conversions.c b/vmod/vmod_std_conversions.c index 4ce88474b..c45410114 100644 --- a/vmod/vmod_std_conversions.c +++ b/vmod/vmod_std_conversions.c @@ -200,17 +200,23 @@ vmod_ip(VRT_CTX, struct VARGS(ip) *a) { uintptr_t sn; void *p; - VCL_IP retval = NULL; + VCL_IP retval = NULL, fb = bogo_ip; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - if (a->valid_fallback) - assert(VSA_Sane(a->fallback)); + + if (a->valid_fallback) { + if (a->fallback == NULL || !VSA_Sane(a->fallback)) { + VRT_fail(ctx, "std.ip: invalid fallback"); + return (fb); + } + fb = a->fallback; + } sn = WS_Snapshot(ctx->ws); p = WS_Alloc(ctx->ws, vsa_suckaddr_len); if (p == NULL) { VRT_fail(ctx, "std.ip: insufficient workspace"); - return (NULL); + return (fb); } if (a->s != NULL) @@ -224,11 +230,10 @@ vmod_ip(VRT_CTX, struct VARGS(ip) *a) WS_Reset(ctx->ws, sn); - if (a->valid_fallback) - return (a->fallback); + if (!a->valid_fallback) + VRT_fail(ctx, "std.ip: conversion failed"); - VRT_fail(ctx, "std.ip: conversion failed"); - return (NULL); + return (fb); } VCL_REAL v_matchproto_(td_std_real) From dridi.boukelmoune at gmail.com Mon Nov 29 14:48:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 14:48:07 +0000 (UTC) Subject: [master] 5810817d3 Fix unnecessary log buffer flushing Message-ID: <20211129144807.3BA0F1078D1@lists.varnish-cache.org> commit 5810817d37f134d23c0a1f56d9fac560d1a94c0b Author: Martin Blix Grydeland Date: Mon Oct 2 17:18:23 2017 +0200 Fix unnecessary log buffer flushing When vsl_reclen (maximum length of a record) is close to vsl_buffer, the vsl buffer is flushed to the main shared memory log for every record. This is because we test if there is space for vsl_reclen, not the actual size of the formatted log record (which likely is much smaller). Fix this by doing the formatting in up to two stages. If the first stage shows that we overflowed, but would not have overflown vcl_reclen if there was more room in the buffer, then flush and redo the formatting. This limits the extra work of formatting twice only to the one record that happened to overflow the buffer. diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index b301c5a2f..0db4d5284 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -409,6 +409,8 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap) const char *u, *f; unsigned n, mlen; txt t; + va_list ap2; + int first; vsl_sanity(vsl); AN(fmt); @@ -437,14 +439,38 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap) return; } - mlen = cache_param->vsl_reclen; + assert(vsl->wlp <= vsl->wle); - /* Flush if we cannot fit a full size record */ - if (VSL_END(vsl->wlp, mlen + 1) >= vsl->wle) + /* Flush if we can't fit any bytes */ + if (vsl->wle - vsl->wlp <= VSL_OVERHEAD) VSL_Flush(vsl, 1); - p = VSL_DATA(vsl->wlp); - n = vsnprintf(p, mlen, fmt, ap); + /* Do the vsnprintf formatting in one or two stages. If the first + stage shows that we overflowed, and the available space to work + with was less than vsl_reclen, flush and do the formatting + again. */ + first = 1; + while (1) { + assert(vsl->wle - vsl->wlp > VSL_OVERHEAD); + mlen = VSL_BYTES((vsl->wle - vsl->wlp) - VSL_OVERHEAD); + if (mlen > cache_param->vsl_reclen) + mlen = cache_param->vsl_reclen; + assert(mlen > 0); + assert(VSL_END(vsl->wlp, mlen) <= vsl->wle); + p = VSL_DATA(vsl->wlp); + va_copy(ap2, ap); + n = vsnprintf(p, mlen, fmt, ap2); + va_end(ap2); + + if (first && n >= mlen && mlen < cache_param->vsl_reclen) { + first = 0; + VSL_Flush(vsl, 1); + continue; + } + + break; + } + if (n > mlen - 1) n = mlen - 1; /* we truncate long fields */ p[n++] = '\0'; /* NUL-terminated */ diff --git a/include/vapi/vsl_int.h b/include/vapi/vsl_int.h index f4a0c86b8..dbd043908 100644 --- a/include/vapi/vsl_int.h +++ b/include/vapi/vsl_int.h @@ -67,19 +67,20 @@ #define VSL_IDENTMASK (~(3U<<30)) #define VSL_LENMASK 0xffff +#define VSL_OVERHEAD 2 #define VSL_WORDS(len) (((len) + 3) / 4) #define VSL_BYTES(words) ((words) * 4) -#define VSL_END(ptr, len) ((ptr) + 2 + VSL_WORDS(len)) +#define VSL_END(ptr, len) ((ptr) + VSL_OVERHEAD + VSL_WORDS(len)) #define VSL_NEXT(ptr) VSL_END(ptr, VSL_LEN(ptr)) #define VSL_LEN(ptr) ((ptr)[0] & VSL_LENMASK) #define VSL_TAG(ptr) ((enum VSL_tag_e)((ptr)[0] >> 24)) #define VSL_ID(ptr) (((ptr)[1]) & VSL_IDENTMASK) #define VSL_CLIENT(ptr) (((ptr)[1]) & VSL_CLIENTMARKER) #define VSL_BACKEND(ptr) (((ptr)[1]) & VSL_BACKENDMARKER) -#define VSL_DATA(ptr) ((char*)((ptr)+2)) -#define VSL_CDATA(ptr) ((const char*)((ptr)+2)) +#define VSL_DATA(ptr) ((char*)((ptr)+VSL_OVERHEAD)) +#define VSL_CDATA(ptr) ((const char*)((ptr)+VSL_OVERHEAD)) #define VSL_BATCHLEN(ptr) ((ptr)[1]) -#define VSL_BATCHID(ptr) (VSL_ID((ptr) + 2)) +#define VSL_BATCHID(ptr) (VSL_ID((ptr) + VSL_OVERHEAD)) #define VSL_ENDMARKER (((uint32_t)SLT__Reserved << 24) | 0x454545) /* "EEE" */ #define VSL_WRAPMARKER (((uint32_t)SLT__Reserved << 24) | 0x575757) /* "WWW" */ From dridi.boukelmoune at gmail.com Mon Nov 29 16:12:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 16:12:07 +0000 (UTC) Subject: [master] a19457ac1 vsl: Write to stdout when opening "-" Message-ID: <20211129161207.D8709109EBC@lists.varnish-cache.org> commit a19457ac1971a611cc5bb9d09af1fd5dd78e4dac Author: Dridi Boukelmoune Date: Tue Nov 23 09:41:29 2021 +0100 vsl: Write to stdout when opening "-" Just like the file cursor reads from stdin when opening "-". And in addition, teach varnishlog to also write to stdout when it is opening the file directly. Likewise, put varnishncsa on par with varnishlog in that regard. It is now possible to compress binary VSL on the fly without taking a detour to the file system, see u00019.vtc for an example. Considering how VUT daemonizes, a "-w -" option in daemon mode becomes an error as well. Refs #3740 diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index 0e049f003..2b3de1383 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -72,9 +72,12 @@ openout(int append) { AN(LOG.w_arg); - if (LOG.A_opt) - LOG.fo = fopen(LOG.w_arg, append ? "a" : "w"); - else + if (LOG.A_opt) { + if (!strcmp(LOG.w_arg, "-")) + LOG.fo = stdout; + else + LOG.fo = fopen(LOG.w_arg, append ? "a" : "w"); + } else LOG.fo = VSL_WriteOpen(vut->vsl, LOG.w_arg, append, LOG.u_opt); if (LOG.fo == NULL) VUT_Error(vut, 2, "Cannot open output file (%s)", @@ -148,6 +151,9 @@ main(int argc, char * const *argv) if (vut->D_opt && !LOG.w_arg) VUT_Error(vut, 1, "Missing -w option"); + if (vut->D_opt && !strcmp(LOG.w_arg, "-")) + VUT_Error(vut, 1, "Daemon cannot write to stdout"); + /* Setup output */ if (LOG.A_opt || !LOG.w_arg) { vut->dispatch_f = VSL_PrintTransactions; diff --git a/bin/varnishlog/varnishlog_options.h b/bin/varnishlog/varnishlog_options.h index 470023060..39d07b913 100644 --- a/bin/varnishlog/varnishlog_options.h +++ b/bin/varnishlog/varnishlog_options.h @@ -58,7 +58,9 @@ " reopened allowing the old one to be rotated away. The" \ " file can then be read by varnishlog and other tools with" \ " the -r option, unless the -A option was specified. This" \ - " option is required when running in daemon mode." \ + " option is required when running in daemon mode. If the" \ + " filename is -, varnishlog writes to the standard output" \ + " and cannot work as a daemon." \ ) LOG_OPT_a diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 9ae918b0e..7b1e4234e 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -167,7 +167,10 @@ openout(int append) { AN(CTX.w_arg); - CTX.fo = fopen(CTX.w_arg, append ? "a" : "w"); + if (!strcmp(CTX.w_arg, "-")) + CTX.fo = stdout; + else + CTX.fo = fopen(CTX.w_arg, append ? "a" : "w"); if (CTX.fo == NULL) VUT_Error(vut, 1, "Can't open output file (%s)", strerror(errno)); @@ -1217,6 +1220,9 @@ main(int argc, char * const *argv) if (vut->D_opt && !CTX.w_arg) VUT_Error(vut, 1, "Missing -w option"); + if (vut->D_opt && !strcmp(CTX.w_arg, "-")) + VUT_Error(vut, 1, "Daemon cannot write to stdout"); + /* Check for valid grouping mode */ assert(vut->g_arg < VSL_g__MAX); if (vut->g_arg != VSL_g_vxid && vut->g_arg != VSL_g_request) diff --git a/bin/varnishncsa/varnishncsa_options.h b/bin/varnishncsa/varnishncsa_options.h index fa2dd57d1..ccd2a3098 100644 --- a/bin/varnishncsa/varnishncsa_options.h +++ b/bin/varnishncsa/varnishncsa_options.h @@ -34,7 +34,8 @@ #define NCSA_OPT_a \ VOPT("a", "[-a]", "Append to file", \ "When writing output to a file, append to it rather than" \ - " overwrite it." \ + " overwrite it. This option has no effect without the -w" \ + " option." \ ) #define NCSA_OPT_F \ @@ -62,7 +63,9 @@ " unless the -a option was specified. If the application" \ " receives a SIGHUP in daemon mode the file will be" \ " reopened allowing the old one to be rotated away. This" \ - " option is required when running in daemon mode." \ + " option is required when running in daemon mode. If the" \ + " filename is -, varnishncsa writes to the standard output" \ + " and cannot work as a daemon." \ ) #define NCSA_OPT_b \ VOPT("b", "[-b]", "Backend mode", \ diff --git a/bin/varnishtest/tests/u00003.vtc b/bin/varnishtest/tests/u00003.vtc index e67962a28..65aadee41 100644 --- a/bin/varnishtest/tests/u00003.vtc +++ b/bin/varnishtest/tests/u00003.vtc @@ -69,6 +69,8 @@ shell -expect "Copyright (c) 2006 Verdens Gang AS" \ "varnishncsa -V" shell -err -expect "Missing -w option" \ {varnishncsa -D} +shell -err -expect "Daemon cannot write to stdout" \ + "varnishlog -D -w -" shell -err -expect "Unknown format specifier at: %{foo}A" \ {varnishncsa -F "%{foo}A"} shell -err -expect "Unknown format specifier at: %A" \ diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index a79d592e8..6fe729929 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -26,6 +26,8 @@ shell -err -match "Usage: .*varnishlog " \ "varnishlog extra" shell -err -expect "Missing -w option" \ "varnishlog -D" +shell -err -expect "Daemon cannot write to stdout" \ + "varnishlog -D -w -" shell -err -expect "Ambiguous grouping type: r" \ "varnishlog -g r" shell -err -expect "Unknown grouping type: foo" \ diff --git a/bin/varnishtest/tests/u00019.vtc b/bin/varnishtest/tests/u00019.vtc new file mode 100644 index 000000000..9683d6967 --- /dev/null +++ b/bin/varnishtest/tests/u00019.vtc @@ -0,0 +1,18 @@ +varnishtest "varnishlog write vsl to stdout" + +feature cmd "command -v gzip" +feature cmd "command -v zcat" + +varnish v1 -vcl { + backend be none; +} -start + +client c1 { + txreq + rxresp + expect resp.status == 503 +} -run + +shell {varnishlog -d -w - -n ${v1_name} | gzip >vsl.gz} +shell {ls -l} +shell -match "RespStatus +503" {zcat vsl.gz | varnishlog -r -} diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index 7fadba364..e5f2ddaf1 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -413,14 +413,17 @@ VSL_WriteOpen(struct VSL_data *vsl, const char *name, int append, int unbuf) { const char head[] = VSL_FILE_ID; FILE* f; - f = fopen(name, append ? "a" : "w"); + if (!strcmp(name, "-")) + f = stdout; + else + f = fopen(name, append ? "a" : "w"); if (f == NULL) { vsl_diag(vsl, "%s", strerror(errno)); return (NULL); } if (unbuf) setbuf(f, NULL); - if (0 == ftell(f)) { + if (ftell(f) == 0 || f == stdout) { if (fwrite(head, 1, sizeof head, f) != sizeof head) { vsl_diag(vsl, "%s", strerror(errno)); (void)fclose(f); From dridi.boukelmoune at gmail.com Mon Nov 29 16:12:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 16:12:07 +0000 (UTC) Subject: [master] 9853a629d varnishlog: Document impotent options without -w Message-ID: <20211129161208.0281B109EBF@lists.varnish-cache.org> commit 9853a629d512e9a4f513c8286787acb908db63e7 Author: Dridi Boukelmoune Date: Tue Nov 23 09:47:59 2021 +0100 varnishlog: Document impotent options without -w diff --git a/bin/varnishlog/varnishlog_options.h b/bin/varnishlog/varnishlog_options.h index 39d07b913..dabaffff0 100644 --- a/bin/varnishlog/varnishlog_options.h +++ b/bin/varnishlog/varnishlog_options.h @@ -32,22 +32,24 @@ #include "vapi/vapi_options.h" #include "vut_options.h" +#define LOG_NOTICE_w " This option has no effect without the -w option." + #define LOG_OPT_a \ VOPT("a", "[-a]", "Append to file", \ "When writing output to a file with the -w option, append" \ - " to it rather than overwrite it." \ + " to it rather than overwrite it." LOG_NOTICE_w \ ) #define LOG_OPT_A \ VOPT("A", "[-A]", "Text output", \ "When writing output to a file with the -w option, output" \ - " data in ascii format." \ + " data in ascii format." LOG_NOTICE_w \ ) #define LOG_OPT_u \ VOPT("u", "[-u]", "Unbuffered output", \ "When writing output to a file with the -w option, output" \ - " data is not buffered." \ + " data is not buffered." LOG_NOTICE_w \ ) #define LOG_OPT_w \ diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc index 6fe729929..7c4fcf706 100644 --- a/bin/varnishtest/tests/u00006.vtc +++ b/bin/varnishtest/tests/u00006.vtc @@ -9,7 +9,7 @@ varnish v1 -vcl+backend {} -start # We use this to make sure we know there is a "0 CLI" in the binary log. process p1 { - exec varnishlog -n ${v1_name} -g raw -u -A + exec varnishlog -n ${v1_name} -g raw -u -A -w - } -start shell { From dridi.boukelmoune at gmail.com Mon Nov 29 16:12:08 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 16:12:08 +0000 (UTC) Subject: [master] ed93bc55c vut: Don't read VSL from stdin in daemon mode Message-ID: <20211129161208.2649A109EC3@lists.varnish-cache.org> commit ed93bc55cc9ec69ecebb753104c747616b424e88 Author: Dridi Boukelmoune Date: Tue Nov 23 09:53:11 2021 +0100 vut: Don't read VSL from stdin in daemon mode diff --git a/include/vut_options.h b/include/vut_options.h index ad9e59a71..14eb0699e 100644 --- a/include/vut_options.h +++ b/include/vut_options.h @@ -93,7 +93,9 @@ #define VUT_OPT_r \ VOPT("r:", "[-r ]", "Binary file input", \ "Read log in binary file format from this file. The file" \ - " can be created with ``varnishlog -w filename``." \ + " can be created with ``varnishlog -w filename``. If the" \ + " filename is -, logs are read from the standard input." \ + " and cannot work as a daemon." \ ) #define VUT_OPT_t \ diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index 7c275102e..42839da0c 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -302,6 +302,9 @@ VUT_Setup(struct VUT *vut) (vut->r_arg == NULL ? 0 : 2) > 2) VUT_Error(vut, 1, "Only one of -n and -r options may be used"); + if (vut->r_arg != NULL && !strcmp(vut->r_arg, "-") && vut->D_opt) + VUT_Error(vut, 1, "Daemon cannot read from stdin"); + /* Create and validate the query expression */ vut->vslq = VSLQ_New(vut->vsl, NULL, (enum VSL_grouping_e)vut->g_arg, vut->q_arg); From phk at FreeBSD.org Mon Nov 29 21:16:10 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 29 Nov 2021 21:16:10 +0000 (UTC) Subject: [master] 19dba7e59 zcat(1) was originally, and still on OSX only for compress(1) files. Message-ID: <20211129211610.D2D2311459A@lists.varnish-cache.org> commit 19dba7e59b28b167dfeda647382c72c0d00eed25 Author: Poul-Henning Kamp Date: Mon Nov 29 21:14:56 2021 +0000 zcat(1) was originally, and still on OSX only for compress(1) files. diff --git a/bin/varnishtest/tests/u00019.vtc b/bin/varnishtest/tests/u00019.vtc index 9683d6967..4b4168ad2 100644 --- a/bin/varnishtest/tests/u00019.vtc +++ b/bin/varnishtest/tests/u00019.vtc @@ -15,4 +15,4 @@ client c1 { shell {varnishlog -d -w - -n ${v1_name} | gzip >vsl.gz} shell {ls -l} -shell -match "RespStatus +503" {zcat vsl.gz | varnishlog -r -} +shell -match "RespStatus +503" {gunzip < vsl.gz | varnishlog -r -} From dridi.boukelmoune at gmail.com Mon Nov 29 21:59:08 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 29 Nov 2021 21:59:08 +0000 (UTC) Subject: [master] a8ffd8745 vtc: Stop requiring zcat in u19 Message-ID: <20211129215908.754A71158EE@lists.varnish-cache.org> commit a8ffd8745dbb9fb26060173fb1f22483516d454d Author: Dridi Boukelmoune Date: Mon Nov 29 22:57:31 2021 +0100 vtc: Stop requiring zcat in u19 diff --git a/bin/varnishtest/tests/u00019.vtc b/bin/varnishtest/tests/u00019.vtc index 4b4168ad2..975f34807 100644 --- a/bin/varnishtest/tests/u00019.vtc +++ b/bin/varnishtest/tests/u00019.vtc @@ -1,7 +1,7 @@ varnishtest "varnishlog write vsl to stdout" feature cmd "command -v gzip" -feature cmd "command -v zcat" +feature cmd "command -v gunzip" varnish v1 -vcl { backend be none; From phk at FreeBSD.org Mon Nov 29 22:25:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 29 Nov 2021 22:25:05 +0000 (UTC) Subject: [master] f65fcaeae Dont treat `git pull` non-zero exit as fatal Message-ID: <20211129222506.108CB11652B@lists.varnish-cache.org> commit f65fcaeae09ff3fc7a32412c59cd8f27a9b7f244 Author: Poul-Henning Kamp Date: Mon Nov 29 22:24:12 2021 +0000 Dont treat `git pull` non-zero exit as fatal diff --git a/tools/vtest.sh b/tools/vtest.sh index bf46d894e..f695f1f56 100755 --- a/tools/vtest.sh +++ b/tools/vtest.sh @@ -226,7 +226,7 @@ do rm -rf varnish-trunk > /dev/null 2>&1 || true git reset --hard > /dev/null 2>&1 || true git clean -df > /dev/null 2>&1 || true - git pull > /dev/null 2>&1 + git pull > /dev/null 2>&1 || true ) rev=`cd "${SRCDIR}" && git show -s --pretty=format:%H` if [ "x${rev}" != "x${orev}" ] ; then From dridi.boukelmoune at gmail.com Tue Nov 30 17:44:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 30 Nov 2021 17:44:06 +0000 (UTC) Subject: [6.0] 3cd55a65e std.ip: Always provide some form of fallback Message-ID: <20211130174406.68712110E01@lists.varnish-cache.org> commit 3cd55a65ec2c58f819d84b61a819a30470796cb3 Author: Dridi Boukelmoune Date: Mon Nov 29 16:00:20 2021 +0100 std.ip: Always provide some form of fallback Otherwise valid code can panic on workspace exhaustion: std.ip(req.http.X-Real-IP, std.ip(req.http.X-Client-IP, client.ip)) If the nested std.ip() call runs out of workspace, it will return a null ip instead of the fallback, and the outer std.ip() call will panic upon checking the suckaddr sanity. Refs #3746 diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c index 0bfa0ad7f..89fe23160 100644 --- a/lib/libvmod_std/vmod_std_conversions.c +++ b/lib/libvmod_std/vmod_std_conversions.c @@ -90,7 +90,7 @@ vmod_ip(VRT_CTX, VCL_STRING s, VCL_IP d, VCL_BOOL n, VCL_STRING default_port) p = WS_Alloc(ctx->ws, vsa_suckaddr_len); if (p == NULL) { VRT_fail(ctx, "std.ip: insufficient workspace"); - return (NULL); + return (d); } if (s != NULL)