From dridi.boukelmoune at gmail.com Wed Dec 1 08:13:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 1 Dec 2021 08:13:06 +0000 (UTC) Subject: [master] e51208cb6 Rework HSH_Purge() Message-ID: <20211201081306.41486101B6D@lists.varnish-cache.org> commit e51208cb6486853f166fc9448ada94dbb7415085 Author: Martin Blix Grydeland Date: Thu Nov 4 18:25:25 2021 +0100 Rework HSH_Purge() HSH_Purge() suffers from a problem when there are more objcores on a given objhead than we can hold temporary references for on the available workspace, and multiple purges for the same objhead are issued at the same time. The previous algorithm would use a flag on the objcores (OC_F_PURGED) in order to keep track of how far in the list we had gotten. This becomes a problem when multiple threads are purging the same objhead at the same time. When a new purge is started, the flags would be reset, which would cause any existing purge thread to restart. If a steady stream of purges for a given objhead is issued and enough objcores are present, none would finish. This rework uses OC references in the list as bookmarks, in order to know how far into the list we were when releasing the mutex partway through and want to resume again. This relies on the list not being reordered while we are not holding the mutex. The only place where that happens is in HSH_Unbusy(), where an OC_F_BUSY OC is moved first in the list. This does not cause problems because we skip OC_F_BUSY OCs. The OC_F_PURGED flag is removed as it is no longer needed. The existing r02372.vtc test case exercises this code. diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 5d24e0479..0fcb05739 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -672,82 +672,101 @@ unsigned HSH_Purge(struct worker *wrk, struct objhead *oh, vtim_real ttl_now, vtim_dur ttl, vtim_dur grace, vtim_dur keep) { - struct objcore *oc, **ocp; - unsigned spc, ospc, nobj, n, n_tot = 0; - int more = 0; + struct objcore *oc, *oc_nows[2], **ocp; + unsigned i, j, n, n_max, total = 0; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); - ospc = WS_ReserveAll(wrk->aws); - assert(ospc >= sizeof *ocp); - /* - * Because of "soft" purges, there might be oc's in the list that has - * the OC_F_PURGED flag set. We do not want to let these slip through, - * so we need to clear the flag before entering the do..while loop. - */ - Lck_Lock(&oh->mtx); - assert(oh->refcnt > 0); - VTAILQ_FOREACH(oc, &oh->objcs, hsh_list) { - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - assert(oc->objhead == oh); - oc->flags &= ~OC_F_PURGED; - } - Lck_Unlock(&oh->mtx); - do { - more = 0; - spc = ospc; - nobj = 0; + n_max = WS_ReserveLumps(wrk->aws, sizeof *ocp); + if (n_max < 2) { + /* No space on the workspace. Give it a stack buffer of 2 + * elements, which is the minimum for the algorithm + * below. */ + ocp = oc_nows; + n_max = 2; + } else ocp = WS_Reservation(wrk->aws); - Lck_Lock(&oh->mtx); - assert(oh->refcnt > 0); - VTAILQ_FOREACH(oc, &oh->objcs, hsh_list) { + AN(ocp); + + /* Note: This algorithm uses OC references in the list as + * bookmarks, in order to know how far into the list we were when + * releasing the mutex partway through and want to resume + * again. This relies on the list not being reordered while we are + * not holding the mutex. The only place where that happens is in + * HSH_Unbusy(), where an OC_F_BUSY OC is moved first in the + * list. This does not cause problems because we skip OC_F_BUSY + * OCs. */ + + Lck_Lock(&oh->mtx); + oc = VTAILQ_FIRST(&oh->objcs); + n = 0; + while (1) { + for (; n < n_max && oc != NULL; oc = VTAILQ_NEXT(oc, hsh_list)) + { CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); assert(oc->objhead == oh); if (oc->flags & OC_F_BUSY) { - /* - * We cannot purge busy objects here, because + /* We cannot purge busy objects here, because * their owners have special rights to them, * and may nuke them without concern for the * refcount, which by definition always must - * be one, so they don't check. - */ + * be one, so they don't check. */ continue; } if (oc->flags & OC_F_DYING) continue; - if (oc->flags & OC_F_PURGED) { - /* - * We have already called EXP_Rearm on this - * object, and we do not want to do it - * again. Plus the space in the ocp array may - * be limited. - */ - continue; - } - if (spc < sizeof *ocp) { - /* Iterate if aws is not big enough */ - more = 1; - break; - } oc->refcnt++; - spc -= sizeof *ocp; - ocp[nobj++] = oc; - oc->flags |= OC_F_PURGED; + ocp[n++] = oc; } + Lck_Unlock(&oh->mtx); - for (n = 0; n < nobj; n++) { - oc = ocp[n]; - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - EXP_Rearm(oc, ttl_now, ttl, grace, keep); - (void)HSH_DerefObjCore(wrk, &oc, 0); + if (n == 0) { + /* No eligible objcores found. We are finished. */ + break; + } + + j = n; + if (oc != NULL) { + /* There are more objects on the objhead that we + * have not yet looked at, but no more space on + * the objcore reference list. Do not process the + * last one, it will be used as the bookmark into + * the objcore list for the next iteration of the + * outer loop. */ + j--; + assert(j >= 1); /* True because n_max >= 2 */ + } + for (i = 0; i < j; i++) { + CHECK_OBJ_NOTNULL(ocp[i], OBJCORE_MAGIC); + EXP_Rearm(ocp[i], ttl_now, ttl, grace, keep); + (void)HSH_DerefObjCore(wrk, &ocp[i], 0); + AZ(ocp[i]); + total++; } - n_tot += nobj; - } while (more); + + if (j == n) { + /* No bookmark set, that means we got to the end + * of the objcore list in the previous run and are + * finished. */ + break; + } + + Lck_Lock(&oh->mtx); + + /* Move the bookmark first and continue scanning the + * objcores */ + CHECK_OBJ_NOTNULL(ocp[j], OBJCORE_MAGIC); + ocp[0] = ocp[j]; + n = 1; + oc = VTAILQ_NEXT(ocp[0], hsh_list); + CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC); + } + WS_Release(wrk->aws, 0); - Pool_PurgeStat(n_tot); - return (n_tot); + Pool_PurgeStat(total); + return (total); } /*--------------------------------------------------------------------- diff --git a/include/tbl/oc_flags.h b/include/tbl/oc_flags.h index 9a37335f2..768962fda 100644 --- a/include/tbl/oc_flags.h +++ b/include/tbl/oc_flags.h @@ -30,8 +30,7 @@ /*lint -save -e525 -e539 */ -OC_FLAG(PURGED, purged, (1<<0)) //lint !e835 -OC_FLAG(BUSY, busy, (1<<1)) +OC_FLAG(BUSY, busy, (1<<1)) //lint !e835 OC_FLAG(HFM, hfm, (1<<2)) OC_FLAG(HFP, hfp, (1<<3)) OC_FLAG(CANCEL, cancel, (1<<4)) From phk at FreeBSD.org Wed Dec 1 10:10:09 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 1 Dec 2021 10:10:09 +0000 (UTC) Subject: [master] e8ce24cb9 Collapse the VFP and VDP filter repository lists to a single list. Message-ID: <20211201101009.7835F104C87@lists.varnish-cache.org> commit e8ce24cb942b5a3e207a96919927235a1ac27c06 Author: Poul-Henning Kamp Date: Wed Dec 1 08:54:42 2021 +0000 Collapse the VFP and VDP filter repository lists to a single list. diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 48ee357ba..50c1228ba 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -516,8 +516,7 @@ VCL_Close(struct vcl **vclp) struct vcl *vcl; TAKE_OBJ_NOTNULL(vcl, vclp, VCL_MAGIC); - assert(VTAILQ_EMPTY(&vcl->vfps)); - assert(VTAILQ_EMPTY(&vcl->vdps)); + assert(VTAILQ_EMPTY(&vcl->filters)); AZ(dlclose(vcl->dlh)); FREE_OBJ(vcl); } @@ -685,8 +684,7 @@ vcl_load(struct cli *cli, XXXAN(vcl->loaded_name); VTAILQ_INIT(&vcl->director_list); VTAILQ_INIT(&vcl->ref_list); - VTAILQ_INIT(&vcl->vfps); - VTAILQ_INIT(&vcl->vdps); + VTAILQ_INIT(&vcl->filters); vcl->temp = VCL_TEMP_INIT; diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h index ac0d7aa75..d8827b667 100644 --- a/bin/varnishd/cache/cache_vcl.h +++ b/bin/varnishd/cache/cache_vcl.h @@ -55,8 +55,7 @@ struct vcl { int nrefs; struct vcl *label; int nlabels; - struct vfilter_head vfps; - struct vfilter_head vdps; + struct vfilter_head filters; }; struct vclref { diff --git a/bin/varnishd/cache/cache_vrt_filter.c b/bin/varnishd/cache/cache_vrt_filter.c index cab61ea74..d5962c7c6 100644 --- a/bin/varnishd/cache/cache_vrt_filter.c +++ b/bin/varnishd/cache/cache_vrt_filter.c @@ -57,17 +57,14 @@ struct vfilter { VTAILQ_ENTRY(vfilter) list; }; -static struct vfilter_head vfp_filters = - VTAILQ_HEAD_INITIALIZER(vfp_filters); - -static struct vfilter_head vdp_filters = - VTAILQ_HEAD_INITIALIZER(vdp_filters); +static struct vfilter_head vrt_filters = + VTAILQ_HEAD_INITIALIZER(vrt_filters); void VRT_AddVFP(VRT_CTX, const struct vfp *filter) { struct vfilter *vp; - struct vfilter_head *hd = &vfp_filters; + struct vfilter_head *hd = &vrt_filters; CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC); AN(filter); @@ -75,14 +72,18 @@ VRT_AddVFP(VRT_CTX, const struct vfp *filter) AN(*filter->name); VTAILQ_FOREACH(vp, hd, list) { + if (vp->vfp == NULL) + continue; xxxassert(vp->vfp != filter); xxxassert(strcasecmp(vp->name, filter->name)); } if (ctx != NULL) { ASSERT_CLI(); CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - hd = &ctx->vcl->vfps; + hd = &ctx->vcl->filters; VTAILQ_FOREACH(vp, hd, list) { + if (vp->vfp == NULL) + continue; xxxassert(vp->vfp != filter); xxxassert(strcasecmp(vp->name, filter->name)); } @@ -99,7 +100,7 @@ void VRT_AddVDP(VRT_CTX, const struct vdp *filter) { struct vfilter *vp; - struct vfilter_head *hd = &vdp_filters; + struct vfilter_head *hd = &vrt_filters; CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC); AN(filter); @@ -107,14 +108,18 @@ VRT_AddVDP(VRT_CTX, const struct vdp *filter) AN(*filter->name); VTAILQ_FOREACH(vp, hd, list) { + if (vp->vdp == NULL) + continue; xxxassert(vp->vdp != filter); xxxassert(strcasecmp(vp->name, filter->name)); } if (ctx != NULL) { ASSERT_CLI(); CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - hd = &ctx->vcl->vdps; + hd = &ctx->vcl->filters; VTAILQ_FOREACH(vp, hd, list) { + if (vp->vdp == NULL) + continue; xxxassert(vp->vdp != filter); xxxassert(strcasecmp(vp->name, filter->name)); } @@ -135,7 +140,7 @@ VRT_RemoveVFP(VRT_CTX, const struct vfp *filter) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - hd = &ctx->vcl->vfps; + hd = &ctx->vcl->filters; AN(filter); AN(filter->name); AN(*filter->name); @@ -159,7 +164,7 @@ VRT_RemoveVDP(VRT_CTX, const struct vdp *filter) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - hd = &ctx->vcl->vdps; + hd = &ctx->vcl->filters; AN(filter); AN(filter->name); AN(*filter->name); @@ -179,7 +184,7 @@ static const struct vfilter vfilter_error[1]; // XXX: idea(fgs): Allow filters (...) arguments in the list static const struct vfilter * -vcl_filter_list_iter(const struct vfilter_head *h1, +vcl_filter_list_iter(int want_vfp, const struct vfilter_head *h1, const struct vfilter_head *h2, const char **flp) { const char *fl, *q; @@ -201,12 +206,22 @@ vcl_filter_list_iter(const struct vfilter_head *h1, for (q = fl; *q && !vct_isspace(*q); q++) continue; *flp = q; - VTAILQ_FOREACH(vp, h1, list) + VTAILQ_FOREACH(vp, h1, list) { + if (want_vfp && vp->vfp == NULL) + continue; + else if (!want_vfp && vp->vdp == NULL) + continue; if (vp->nlen == q - fl && !memcmp(fl, vp->name, vp->nlen)) return (vp); - VTAILQ_FOREACH(vp, h2, list) + } + VTAILQ_FOREACH(vp, h2, list) { + if (want_vfp && vp->vfp == NULL) + continue; + else if (!want_vfp && vp->vdp == NULL) + continue; if (vp->nlen == q - fl && !memcmp(fl, vp->name, vp->nlen)) return (vp); + } *flp = fl; return (vfilter_error); } @@ -220,7 +235,7 @@ VCL_StackVFP(struct vfp_ctx *vc, const struct vcl *vcl, const char *fl) VSLb(vc->wrk->vsl, SLT_Filters, "%s", fl); while (1) { - vp = vcl_filter_list_iter(&vfp_filters, &vcl->vfps, &fl); + vp = vcl_filter_list_iter(1, &vrt_filters, &vcl->filters, &fl); if (vp == NULL) return (0); if (vp == vfilter_error) @@ -238,7 +253,7 @@ VCL_StackVDP(struct req *req, const struct vcl *vcl, const char *fl) AN(fl); VSLb(req->vsl, SLT_Filters, "%s", fl); while (1) { - vp = vcl_filter_list_iter(&vdp_filters, &vcl->vdps, &fl); + vp = vcl_filter_list_iter(0, &vrt_filters, &vcl->filters, &fl); if (vp == NULL) return (0); if (vp == vfilter_error) { From phk at FreeBSD.org Wed Dec 1 10:10:09 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 1 Dec 2021 10:10:09 +0000 (UTC) Subject: [master] 19f77efe6 Rework VDP/VFP filter registry Message-ID: <20211201101009.89FF1104C89@lists.varnish-cache.org> commit 19f77efe69aceb78cc9e8a0d36a1dc9b8624cdc3 Author: Poul-Henning Kamp Date: Wed Dec 1 10:04:54 2021 +0000 Rework VDP/VFP filter registry The old VRT_AddV[DF]P() and VRT_RemoveV[DF]P() are "soft deprecated" and work the same as previous. (Hard deprecation after next major.) Replaced by: const char *VRT_AddFilter(VRT_CTX, const struct vfp *, const struct vdp * void VRT_RemoveFilter(VRT_CTX, const struct vfp *, const struct vdp *); VRT_CTX is mandatory. Both kinds of filters can be handled in one go, but the names must be identical. VRT_AddFilter returns NULL on success, and VRT_fail'ed error message otherwise. Supersedes #3287 diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 451c5715b..5d910e9c6 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -91,6 +91,8 @@ struct vfp_ctx { enum vfp_status VFP_Suck(struct vfp_ctx *, void *p, ssize_t *lp); enum vfp_status VFP_Error(struct vfp_ctx *, const char *fmt, ...) v_printflike_(2, 3); + +/* These two deprecated per 2021-12-01, add v_deprecated_ after next major */ void VRT_AddVFP(VRT_CTX, const struct vfp *); void VRT_RemoveVFP(VRT_CTX, const struct vfp *); @@ -147,5 +149,11 @@ struct vdp_ctx { }; int VDP_bytes(struct vdp_ctx *, enum vdp_action act, const void *, ssize_t); + +/* These two deprecated per 2021-12-01, add v_deprecated_ after next major */ void VRT_AddVDP(VRT_CTX, const struct vdp *); void VRT_RemoveVDP(VRT_CTX, const struct vdp *); + +/* Registry functions -------------------------------------------------*/ +const char *VRT_AddFilter(VRT_CTX, const struct vfp *, const struct vdp *); +void VRT_RemoveFilter(VRT_CTX, const struct vfp *, const struct vdp *); diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 31424c2ca..df7440ad8 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -664,6 +664,7 @@ VRT_fail(VRT_CTX, const char *fmt, ...) { va_list ap; + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); assert(ctx->vsl != NULL || ctx->msg != NULL); AN(ctx->handling); if (*ctx->handling == VCL_RET_FAIL) diff --git a/bin/varnishd/cache/cache_vrt_filter.c b/bin/varnishd/cache/cache_vrt_filter.c index d5962c7c6..b8e3b7c9a 100644 --- a/bin/varnishd/cache/cache_vrt_filter.c +++ b/bin/varnishd/cache/cache_vrt_filter.c @@ -60,104 +60,95 @@ struct vfilter { static struct vfilter_head vrt_filters = VTAILQ_HEAD_INITIALIZER(vrt_filters); -void -VRT_AddVFP(VRT_CTX, const struct vfp *filter) +static const char * +is_dup_filter(const struct vfilter_head *head, const struct vfp * vfp, + const struct vdp *vdp, const char *name) { struct vfilter *vp; - struct vfilter_head *hd = &vrt_filters; - - CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC); - AN(filter); - AN(filter->name); - AN(*filter->name); - - VTAILQ_FOREACH(vp, hd, list) { - if (vp->vfp == NULL) - continue; - xxxassert(vp->vfp != filter); - xxxassert(strcasecmp(vp->name, filter->name)); - } - if (ctx != NULL) { - ASSERT_CLI(); - CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - hd = &ctx->vcl->filters; - VTAILQ_FOREACH(vp, hd, list) { - if (vp->vfp == NULL) - continue; - xxxassert(vp->vfp != filter); - xxxassert(strcasecmp(vp->name, filter->name)); + VTAILQ_FOREACH(vp, head, list) { + if (vfp != NULL && vp->vfp != NULL) { + if (vp->vfp == vfp) + return ("VFP already registered"); + if (!strcasecmp(vp->name, name)) + return ("VFP name already used"); + } + if (vdp != NULL && vp->vdp != NULL) { + if (vp->vdp == vdp) + return ("VDP already registered"); + if (!strcasecmp(vp->name, name)) + return ("VDP name already used"); } } - ALLOC_OBJ(vp, VFILTER_MAGIC); - AN(vp); - vp->vfp = filter; - vp->name = filter->name; - vp->nlen = strlen(vp->name); - VTAILQ_INSERT_TAIL(hd, vp, list); + return (NULL); } -void -VRT_AddVDP(VRT_CTX, const struct vdp *filter) +static const char * +vrt_addfilter(VRT_CTX, const struct vfp *vfp, const struct vdp *vdp) { struct vfilter *vp; struct vfilter_head *hd = &vrt_filters; + const char *err, *name = NULL; CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC); - AN(filter); - AN(filter->name); - AN(*filter->name); - - VTAILQ_FOREACH(vp, hd, list) { - if (vp->vdp == NULL) - continue; - xxxassert(vp->vdp != filter); - xxxassert(strcasecmp(vp->name, filter->name)); + assert(vfp != NULL || vdp != NULL); + assert(vfp == NULL || vfp->name != NULL); + assert(vdp == NULL || vdp->name != NULL); + assert(vfp == NULL || vdp == NULL || !strcasecmp(vfp->name, vdp->name)); + if (vfp != NULL) + name = vfp->name; + else if (vdp != NULL) + name = vdp->name; + AN(name); + + err = is_dup_filter(hd, vfp, vdp, name); + if (err != NULL) { + if (ctx != NULL) + VRT_fail(ctx, "%s (global)", err); + return (err); } if (ctx != NULL) { ASSERT_CLI(); CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); hd = &ctx->vcl->filters; - VTAILQ_FOREACH(vp, hd, list) { - if (vp->vdp == NULL) - continue; - xxxassert(vp->vdp != filter); - xxxassert(strcasecmp(vp->name, filter->name)); + err = is_dup_filter(hd, vfp, vdp, name); + if (err != NULL) { + VRT_fail(ctx, "%s (per-vcl)", err); + return (err); } } + ALLOC_OBJ(vp, VFILTER_MAGIC); AN(vp); - vp->vdp = filter; - vp->name = filter->name; - vp->nlen = strlen(vp->name); + vp->vfp = vfp; + vp->vdp = vdp; + vp->name = name; + vp->nlen = strlen(name); VTAILQ_INSERT_TAIL(hd, vp, list); + return(err); } -void -VRT_RemoveVFP(VRT_CTX, const struct vfp *filter) +const char * +VRT_AddFilter(VRT_CTX, const struct vfp *vfp, const struct vdp *vdp) { - struct vfilter *vp; - struct vfilter_head *hd; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - hd = &ctx->vcl->filters; - AN(filter); - AN(filter->name); - AN(*filter->name); + return (vrt_addfilter(ctx, vfp, vdp)); +} - ASSERT_CLI(); - VTAILQ_FOREACH(vp, hd, list) { - CHECK_OBJ_NOTNULL(vp, VFILTER_MAGIC); - if (vp->vfp == filter) - break; - } - XXXAN(vp); - VTAILQ_REMOVE(hd, vp, list); - FREE_OBJ(vp); +void +VRT_AddVFP(VRT_CTX, const struct vfp *filter) +{ + AZ(VRT_AddFilter(ctx, filter, NULL)); } void -VRT_RemoveVDP(VRT_CTX, const struct vdp *filter) +VRT_AddVDP(VRT_CTX, const struct vdp *filter) +{ + AZ(VRT_AddFilter(ctx, NULL, filter)); +} + +void +VRT_RemoveFilter(VRT_CTX, const struct vfp *vfp, const struct vdp *vdp) { struct vfilter *vp; struct vfilter_head *hd; @@ -165,21 +156,38 @@ VRT_RemoveVDP(VRT_CTX, const struct vdp *filter) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); hd = &ctx->vcl->filters; - AN(filter); - AN(filter->name); - AN(*filter->name); + assert(vfp != NULL || vdp != NULL); + assert(vfp == NULL || vfp->name != NULL); + assert(vdp == NULL || vdp->name != NULL); + assert(vfp == NULL || vdp == NULL || !strcasecmp(vfp->name, vdp->name)); ASSERT_CLI(); VTAILQ_FOREACH(vp, hd, list) { CHECK_OBJ_NOTNULL(vp, VFILTER_MAGIC); - if (vp->vdp == filter) + if (vp->vfp == vfp && vp->vdp == vdp) break; } - XXXAN(vp); + AN(vp); + assert(vfp == NULL || !strcasecmp(vfp->name, vp->name)); + assert(vdp == NULL || !strcasecmp(vdp->name, vp->name)); VTAILQ_REMOVE(hd, vp, list); FREE_OBJ(vp); } +void +VRT_RemoveVFP(VRT_CTX, const struct vfp *filter) +{ + + VRT_RemoveFilter(ctx, filter, NULL); +} + +void +VRT_RemoveVDP(VRT_CTX, const struct vdp *filter) +{ + + VRT_RemoveFilter(ctx, NULL, filter); +} + static const struct vfilter vfilter_error[1]; // XXX: idea(fgs): Allow filters (...) arguments in the list @@ -269,14 +277,14 @@ VCL_StackVDP(struct req *req, const struct vcl *vcl, const char *fl) void VCL_VRT_Init(void) { - VRT_AddVFP(NULL, &VFP_testgunzip); - VRT_AddVFP(NULL, &VFP_gunzip); - VRT_AddVFP(NULL, &VFP_gzip); - VRT_AddVFP(NULL, &VFP_esi); - VRT_AddVFP(NULL, &VFP_esi_gzip); - VRT_AddVDP(NULL, &VDP_esi); - VRT_AddVDP(NULL, &VDP_gunzip); - VRT_AddVDP(NULL, &VDP_range); + AZ(vrt_addfilter(NULL, &VFP_testgunzip, NULL)); + AZ(vrt_addfilter(NULL, &VFP_gunzip, NULL)); + AZ(vrt_addfilter(NULL, &VFP_gzip, NULL)); + AZ(vrt_addfilter(NULL, &VFP_esi, NULL)); + AZ(vrt_addfilter(NULL, &VFP_esi_gzip, NULL)); + AZ(vrt_addfilter(NULL, NULL, &VDP_esi)); + AZ(vrt_addfilter(NULL, NULL, &VDP_gunzip)); + AZ(vrt_addfilter(NULL, NULL, &VDP_range)); } /*-------------------------------------------------------------------- From phk at FreeBSD.org Wed Dec 1 10:10:09 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 1 Dec 2021 10:10:09 +0000 (UTC) Subject: [master] ff8f8bff5 Exercise both the old and new V[DF]P registry functions Message-ID: <20211201101009.A5FD9104C8C@lists.varnish-cache.org> commit ff8f8bff5d4aaafd5c13dc12ed166573fe7ec6b9 Author: Poul-Henning Kamp Date: Wed Dec 1 10:09:20 2021 +0000 Exercise both the old and new V[DF]P registry functions diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index aee0a9350..b1c272d7e 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -70,7 +70,7 @@ extern void mylog(struct vsl_log *vsl, enum VSL_tag_e tag, /**********************************************************************/ static enum vfp_status v_matchproto_(vfp_pull_f) -xyzzy_rot13_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, +xyzzy_vfp_rot13_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { enum vfp_status vp; @@ -91,9 +91,9 @@ xyzzy_rot13_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, return (vp); } -static const struct vfp xyzzy_rot13 = { +static const struct vfp xyzzy_vfp_rot13 = { .name = "rot13", - .pull = xyzzy_rot13_pull, + .pull = xyzzy_vfp_rot13_pull, }; /**********************************************************************/ @@ -102,7 +102,7 @@ static const struct vfp xyzzy_rot13 = { #define ROT13_BUFSZ 8 static int v_matchproto_(vdp_init_f) -xyzzy_rot13_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc) +xyzzy_vfp_rot13_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc) { (void)vdc; (void)oc; @@ -114,7 +114,7 @@ xyzzy_rot13_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc) } static int v_matchproto_(vdp_bytes_f) -xyzzy_rot13_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, +xyzzy_vfp_rot13_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { char *q; @@ -152,7 +152,7 @@ xyzzy_rot13_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, } static int v_matchproto_(vdp_fini_f) -xyzzy_rot13_fini(struct vdp_ctx *vdc, void **priv) +xyzzy_vfp_rot13_fini(struct vdp_ctx *vdc, void **priv) { (void)vdc; AN(priv); @@ -163,9 +163,9 @@ xyzzy_rot13_fini(struct vdp_ctx *vdc, void **priv) static const struct vdp xyzzy_vdp_rot13 = { .name = "rot13", - .init = xyzzy_rot13_init, - .bytes = xyzzy_rot13_bytes, - .fini = xyzzy_rot13_fini, + .init = xyzzy_vfp_rot13_init, + .bytes = xyzzy_vfp_rot13_bytes, + .fini = xyzzy_vfp_rot13_fini, }; /********************************************************************** @@ -451,9 +451,19 @@ event_load(VRT_CTX, struct vmod_priv *priv) priv->priv = priv_vcl; priv->methods = priv_vcl_methods; - VRT_AddVFP(ctx, &xyzzy_rot13); - + VRT_AddVFP(ctx, &xyzzy_vfp_rot13); VRT_AddVDP(ctx, &xyzzy_vdp_rot13); + + // This should fail + AN(VRT_AddFilter(ctx, &xyzzy_vfp_rot13, &xyzzy_vdp_rot13)); + // Reset the error, we know what we're doing. + *ctx->handling = 0; + + VRT_RemoveVFP(ctx, &xyzzy_vfp_rot13); + VRT_RemoveVDP(ctx, &xyzzy_vdp_rot13); + + AZ(VRT_AddFilter(ctx, &xyzzy_vfp_rot13, &xyzzy_vdp_rot13)); + VRT_AddVDP(ctx, &xyzzy_vdp_pedantic); return (0); } @@ -616,8 +626,7 @@ event_discard(VRT_CTX, void *priv) AZ(ctx->msg); - VRT_RemoveVFP(ctx, &xyzzy_rot13); - VRT_RemoveVDP(ctx, &xyzzy_vdp_rot13); + VRT_RemoveFilter(ctx, &xyzzy_vfp_rot13, &xyzzy_vdp_rot13); VRT_RemoveVDP(ctx, &xyzzy_vdp_pedantic); if (--loads) From nils.goroll at uplex.de Wed Dec 1 11:44:04 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 1 Dec 2021 11:44:04 +0000 (UTC) Subject: [master] e3cfeb558 Learn something new every day Message-ID: <20211201114404.EB4E510773D@lists.varnish-cache.org> commit e3cfeb5586b263605a5118d70b42c9e9dcce2d2d Author: Nils Goroll Date: Wed Dec 1 12:38:41 2021 +0100 Learn something new every day today: VRBT_REMOVE returns the element argument no matter if it was present in the tree or not, so it can not sensibly be used for assertions. diff --git a/lib/libvarnishapi/vsl_dispatch.c b/lib/libvarnishapi/vsl_dispatch.c index 5474d8ca9..75d5be180 100644 --- a/lib/libvarnishapi/vsl_dispatch.c +++ b/lib/libvarnishapi/vsl_dispatch.c @@ -562,7 +562,8 @@ vtx_retire(struct VSLQ *vslq, struct vtx **pvtx) AZ(vtx->n_child); AZ(vtx->n_descend); vtx->n_childready = 0; - AN(VRBT_REMOVE(vtx_tree, &vslq->tree, &vtx->key)); + // remove rval is no way to check if element was present + (void)VRBT_REMOVE(vtx_tree, &vslq->tree, &vtx->key); vtx->key.vxid = 0; vtx->flags = 0; From dridi.boukelmoune at gmail.com Wed Dec 1 15:04:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 1 Dec 2021 15:04:05 +0000 (UTC) Subject: [master] f9f2a8655 wrk: Opportunistic logging in a worker's VSL buffer Message-ID: <20211201150405.8B92A10F187@lists.varnish-cache.org> commit f9f2a8655211412937cf161802b490bf9735f78b Author: Dridi Boukelmoune Date: Wed Sep 8 10:21:26 2021 +0200 wrk: Opportunistic logging in a worker's VSL buffer Since its primary usage will be workspace logs, workers can be initialized earlier to offer even more opportunity for logging. diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 095279dc3..2a102940e 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -408,6 +408,8 @@ child_main(int sigmagic, size_t altstksz) ObjInit(); + WRK_Init(); + VCL_Init(); VCL_VRT_Init(); @@ -432,8 +434,6 @@ child_main(int sigmagic, size_t altstksz) VMOD_Init(); - WRK_Init(); - BAN_Compile(); VRND_SeedAll(); diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index a4192018f..59ea9b1cb 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -524,6 +524,7 @@ void VMOD_Panic(struct vsb *); /* cache_wrk.c */ void WRK_Init(void); void WRK_AddStat(const struct worker *); +void WRK_Log(enum VSL_tag_e, const char *, ...); /* cache_ws.c */ void WS_Panic(struct vsb *, const struct ws *); @@ -577,3 +578,9 @@ void SMP_Ready(void); if (DO_DEBUG(debug_bit)) \ VSL(SLT_Debug, (id), __VA_ARGS__); \ } while (0) + +#define DSLb(debug_bit, ...) \ + do { \ + if (DO_DEBUG(debug_bit)) \ + WRK_Log(SLT_Debug, __VA_ARGS__); \ + } while (0) diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 3cbb99fe2..e8e6f6154 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -738,6 +738,25 @@ static struct cli_proto debug_cmds[] = { { NULL } }; +void +WRK_Log(enum VSL_tag_e tag, const char *fmt, ...) +{ + struct worker *wrk; + va_list ap; + + AN(fmt); + + wrk = THR_GetWorker(); + CHECK_OBJ_ORNULL(wrk, WORKER_MAGIC); + + va_start(ap, fmt); + if (wrk != NULL && wrk->vsl != NULL) + VSLbv(wrk->vsl, tag, fmt, ap); + else + VSLv(tag, 0, fmt, ap); + va_end(ap); +} + /*-------------------------------------------------------------------- * */ From dridi.boukelmoune at gmail.com Wed Dec 1 15:04:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 1 Dec 2021 15:04:05 +0000 (UTC) Subject: [master] 588d5c45b ws: Tie workspace logs to their transactions Message-ID: <20211201150405.AFF6710F18A@lists.varnish-cache.org> commit 588d5c45bd94792f6bd5d113b1fc27efdc1e6d63 Author: Dridi Boukelmoune Date: Mon Apr 6 20:36:41 2020 +0200 ws: Tie workspace logs to their transactions That is, when it's a request or backend transaction, otherwise it's still logged with VXID 0. The goal is to allow a correlation between VCL statements and their workspace footprint by sharing the same transaction instead of being split between raw and vxid scopes. That kind of debugging becomes possible when the workspace debug flag is used and VCL_trace records are not masked. Given the verbosity of both workspace and trace logs, we would need new tools to process transactions for this purpose and until we can link everything we have a chicken-egg problem. This change does not go all the way and relies on the thread-local worker reference to opportunistically log into its VSL buffer when it has one. When the workspace is initialized, the buffer may not be ready yet, so some logs may still end up raw. What's likely going to be missing is workspace early initialization and teardown: in other words before and after VCL execution, which should be good enough for the purpose of debugging workspace operations in VCL tasks. diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c index c709817e1..4f7d5f4f2 100644 --- a/bin/varnishd/cache/cache_ws.c +++ b/bin/varnishd/cache/cache_ws.c @@ -44,7 +44,7 @@ WS_Assert(const struct ws *ws) { CHECK_OBJ_NOTNULL(ws, WS_MAGIC); - DSL(DBG_WORKSPACE, 0, "WS(%p) = (%s, %p %zu %zu %zu)", + DSLb(DBG_WORKSPACE, "WS(%p) = (%s, %p %zu %zu %zu)", ws, ws->id, ws->s, pdiff(ws->s, ws->f), ws->r == NULL ? 0 : pdiff(ws->f, ws->r), pdiff(ws->s, ws->e)); @@ -84,7 +84,7 @@ WS_Init(struct ws *ws, const char *id, void *space, unsigned len) { unsigned l; - DSL(DBG_WORKSPACE, 0, + DSLb(DBG_WORKSPACE, "WS_Init(%p, \"%s\", %p, %u)", ws, id, space, len); assert(space != NULL); INIT_OBJ(ws, WS_MAGIC); @@ -116,12 +116,12 @@ WS_Reset(struct ws *ws, uintptr_t pp) WS_Assert(ws); AN(pp); if (pp == snap_overflowed) { - DSL(DBG_WORKSPACE, 0, "WS_Reset(%p, overflowed)", ws); + DSLb(DBG_WORKSPACE, "WS_Reset(%p, overflowed)", ws); AN(WS_Overflowed(ws)); return; } p = (char *)pp; - DSL(DBG_WORKSPACE, 0, "WS_Reset(%p, %p)", ws, p); + DSLb(DBG_WORKSPACE, "WS_Reset(%p, %p)", ws, p); assert(ws->r == NULL); assert(p >= ws->s); assert(p <= ws->e); @@ -176,7 +176,7 @@ WS_Alloc(struct ws *ws, unsigned bytes) } r = ws->f; ws->f += bytes; - DSL(DBG_WORKSPACE, 0, "WS_Alloc(%p, %u) = %p", ws, bytes, r); + DSLb(DBG_WORKSPACE, "WS_Alloc(%p, %u) = %p", ws, bytes, r); WS_Assert(ws); return (r); } @@ -202,7 +202,7 @@ WS_Copy(struct ws *ws, const void *str, int len) r = ws->f; ws->f += bytes; memcpy(r, str, len); - DSL(DBG_WORKSPACE, 0, "WS_Copy(%p, %d) = %p", ws, len, r); + DSLb(DBG_WORKSPACE, "WS_Copy(%p, %d) = %p", ws, len, r); WS_Assert(ws); return (r); } @@ -214,10 +214,10 @@ WS_Snapshot(struct ws *ws) WS_Assert(ws); assert(ws->r == NULL); if (WS_Overflowed(ws)) { - DSL(DBG_WORKSPACE, 0, "WS_Snapshot(%p) = overflowed", ws); + DSLb(DBG_WORKSPACE, "WS_Snapshot(%p) = overflowed", ws); return (snap_overflowed); } - DSL(DBG_WORKSPACE, 0, "WS_Snapshot(%p) = %p", ws, ws->f); + DSLb(DBG_WORKSPACE, "WS_Snapshot(%p) = %p", ws, ws->f); return ((uintptr_t)ws->f); } @@ -236,7 +236,7 @@ WS_ReserveAll(struct ws *ws) b = pdiff(ws->f, ws->r); WS_Assert(ws); - DSL(DBG_WORKSPACE, 0, "WS_ReserveAll(%p) = %u", ws, b); + DSLb(DBG_WORKSPACE, "WS_ReserveAll(%p) = %u", ws, b); return (b); } @@ -259,7 +259,7 @@ WS_ReserveSize(struct ws *ws, unsigned bytes) return (0); } ws->r = ws->f + bytes; - DSL(DBG_WORKSPACE, 0, "WS_ReserveSize(%p, %u/%u) = %u", + DSLb(DBG_WORKSPACE, "WS_ReserveSize(%p, %u/%u) = %u", ws, bytes, l, bytes); WS_Assert(ws); return (bytes); @@ -270,7 +270,7 @@ WS_Release(struct ws *ws, unsigned bytes) { WS_Assert(ws); assert(bytes <= ws->e - ws->f); - DSL(DBG_WORKSPACE, 0, "WS_Release(%p, %u)", ws, bytes); + DSLb(DBG_WORKSPACE, "WS_Release(%p, %u)", ws, bytes); assert(ws->r != NULL); assert(ws->f + bytes <= ws->r); ws->f += PRNDUP(bytes); @@ -282,7 +282,7 @@ void WS_ReleaseP(struct ws *ws, const char *ptr) { WS_Assert(ws); - DSL(DBG_WORKSPACE, 0, "WS_ReleaseP(%p, %p (%zd))", ws, ptr, ptr - ws->f); + DSLb(DBG_WORKSPACE, "WS_ReleaseP(%p, %p (%zd))", ws, ptr, ptr - ws->f); assert(ws->r != NULL); assert(ptr >= ws->f); assert(ptr <= ws->r); diff --git a/bin/varnishd/cache/cache_ws_emu.c b/bin/varnishd/cache/cache_ws_emu.c index f3d74150e..22e85870c 100644 --- a/bin/varnishd/cache/cache_ws_emu.c +++ b/bin/varnishd/cache/cache_ws_emu.c @@ -118,7 +118,7 @@ WS_Assert(const struct ws *ws) AZ(ws->r); } - DSL(DBG_WORKSPACE, 0, "WS(%p) = (%s, %p %zu %zu %zu)", + DSLb(DBG_WORKSPACE, "WS(%p) = (%s, %p %zu %zu %zu)", ws, ws->id, ws->s, wa2 == NULL ? 0 : wa2->off + PRNDUP(wa2->len), ws->r == NULL ? 0 : pdiff(ws->f, ws->r), pdiff(ws->s, ws->e)); @@ -159,7 +159,7 @@ WS_Init(struct ws *ws, const char *id, void *space, unsigned len) { struct ws_emu *we; - DSL(DBG_WORKSPACE, 0, + DSLb(DBG_WORKSPACE, "WS_Init(%p, \"%s\", %p, %u)", ws, id, space, len); assert(space != NULL); assert(PAOK(space)); @@ -203,12 +203,12 @@ WS_Reset(struct ws *ws, uintptr_t pp) WS_Assert(ws); AN(pp); if (pp == snap_overflowed) { - DSL(DBG_WORKSPACE, 0, "WS_Reset(%p, overflowed)", ws); + DSLb(DBG_WORKSPACE, "WS_Reset(%p, overflowed)", ws); AN(WS_Overflowed(ws)); return; } p = (char *)pp; - DSL(DBG_WORKSPACE, 0, "WS_Reset(%p, %p)", ws, p); + DSLb(DBG_WORKSPACE, "WS_Reset(%p, %p)", ws, p); AZ(ws->r); we = ws_emu(ws); @@ -308,7 +308,7 @@ WS_Alloc(struct ws *ws, unsigned bytes) WS_Assert(ws); if (wa != NULL) { AN(wa->ptr); - DSL(DBG_WORKSPACE, 0, "WS_Alloc(%p, %u) = %p", + DSLb(DBG_WORKSPACE, "WS_Alloc(%p, %u) = %p", ws, bytes, wa->ptr); return (wa->ptr); } @@ -329,7 +329,7 @@ WS_Copy(struct ws *ws, const void *str, int len) if (wa != NULL) { AN(wa->ptr); memcpy(wa->ptr, str, len); - DSL(DBG_WORKSPACE, 0, "WS_Copy(%p, %d) = %p", + DSLb(DBG_WORKSPACE, "WS_Copy(%p, %d) = %p", ws, len, wa->ptr); return (wa->ptr); } @@ -346,7 +346,7 @@ WS_Snapshot(struct ws *ws) WS_Assert(ws); assert(ws->r == NULL); if (WS_Overflowed(ws)) { - DSL(DBG_WORKSPACE, 0, "WS_Snapshot(%p) = overflowed", ws); + DSLb(DBG_WORKSPACE, "WS_Snapshot(%p) = overflowed", ws); return (snap_overflowed); } @@ -354,7 +354,7 @@ WS_Snapshot(struct ws *ws) wa = VTAILQ_LAST(&we->head, ws_alloc_head); CHECK_OBJ_ORNULL(wa, WS_ALLOC_MAGIC); p = (wa == NULL ? ws->s : wa->ptr); - DSL(DBG_WORKSPACE, 0, "WS_Snapshot(%p) = %p", ws, p); + DSLb(DBG_WORKSPACE, "WS_Snapshot(%p) = %p", ws, p); return ((uintptr_t)p); } @@ -376,7 +376,7 @@ WS_ReserveAll(struct ws *ws) } b = pdiff(ws->f, ws->r); - DSL(DBG_WORKSPACE, 0, "WS_ReserveAll(%p) = %u", ws, b); + DSLb(DBG_WORKSPACE, "WS_ReserveAll(%p) = %u", ws, b); WS_Assert(ws); return (b); } @@ -397,7 +397,7 @@ WS_ReserveSize(struct ws *ws, unsigned bytes) ws->f = wa->ptr; ws->r = ws->f + bytes; we = ws_emu(ws); - DSL(DBG_WORKSPACE, 0, "WS_ReserveSize(%p, %u/%u) = %u", + DSLb(DBG_WORKSPACE, "WS_ReserveSize(%p, %u/%u) = %u", ws, bytes, we->len - wa->off, bytes); WS_Assert(ws); return (bytes); @@ -436,7 +436,7 @@ WS_Release(struct ws *ws, unsigned bytes) { ws_release(ws, bytes); - DSL(DBG_WORKSPACE, 0, "WS_Release(%p, %u)", ws, bytes); + DSLb(DBG_WORKSPACE, "WS_Release(%p, %u)", ws, bytes); } void @@ -450,7 +450,7 @@ WS_ReleaseP(struct ws *ws, const char *ptr) assert(ptr <= ws->r); l = pdiff(ws->f, ptr); ws_release(ws, l); - DSL(DBG_WORKSPACE, 0, "WS_ReleaseP(%p, %p (%u))", ws, ptr, l); + DSLb(DBG_WORKSPACE, "WS_ReleaseP(%p, %p (%u))", ws, ptr, l); } void * diff --git a/bin/varnishd/fuzzers/esi_parse_fuzzer.c b/bin/varnishd/fuzzers/esi_parse_fuzzer.c index 5cdb2f449..8d2ff3caa 100644 --- a/bin/varnishd/fuzzers/esi_parse_fuzzer.c +++ b/bin/varnishd/fuzzers/esi_parse_fuzzer.c @@ -89,6 +89,14 @@ VSLb_ts(struct vsl_log *l, const char *event, vtim_real first, vtim_real *pprev, (void)now; } +void +WRK_Log(enum VSL_tag_e tag, const char *fmt, ...) +{ + + (void)tag; + (void)fmt; +} + int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/bin/varnishtest/tests/c00071.vtc b/bin/varnishtest/tests/c00071.vtc index b7f8d12fc..09e5ccf8b 100644 --- a/bin/varnishtest/tests/c00071.vtc +++ b/bin/varnishtest/tests/c00071.vtc @@ -46,17 +46,14 @@ varnish v1 -vsl_catchup logexpect l1 -v v1 -g vxid -q "vxid == 1006" { expect * 1006 VCL_call {^DELIVER$} - expect 0 = LostHeader {^x-foo:$} + expect * = LostHeader {^x-foo:$} # std.log does not need workspace expect 0 = VCL_Log {^dummy$} + expect * = Debug {^WS_Snapshot.* = overflowed} + expect * = Debug {^WS_Reset.*, overflowed} # the workspace is overflowed, but still has space - expect 0 = RespHeader {^x-of: true$} - expect 6 = Error {^workspace_client overflow} -} -start - -logexpect l2 -v v1 -g raw -i Debug { - expect * 0 Debug {^WS_Snapshot.* = overflowed} - expect 24 0 Debug {^WS_Reset.*, overflowed} + expect * = RespHeader {^x-of: true$} + expect * = Error {^workspace_client overflow} } -start client c2 { @@ -67,7 +64,6 @@ client c2 { } -run logexpect l1 -wait -logexpect l2 -wait varnish v1 -expect client_resp_500 == 2 varnish v1 -expect ws_client_overflow == 2 From phk at FreeBSD.org Wed Dec 1 20:29:12 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 1 Dec 2021 20:29:12 +0000 (UTC) Subject: [master] 10749ffe2 Off by one error Message-ID: <20211201202912.947BF117E6E@lists.varnish-cache.org> commit 10749ffe2dacd7744ea94265cf751e5a341d3110 Author: Poul-Henning Kamp Date: Wed Dec 1 20:28:01 2021 +0000 Off by one error diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 0db4d5284..60187bc33 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -475,7 +475,7 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap) n = mlen - 1; /* we truncate long fields */ p[n++] = '\0'; /* NUL-terminated */ vsl->wlp = vsl_hdr(tag, vsl->wlp, n, vsl->wid); - assert(vsl->wlp < vsl->wle); + assert(vsl->wlp <= vsl->wle); vsl->wlr++; if (DO_DEBUG(DBG_SYNCVSL)) From phk at FreeBSD.org Wed Dec 1 20:29:12 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 1 Dec 2021 20:29:12 +0000 (UTC) Subject: [master] 5ba919d7f If there is an unexpected panic, show it. Message-ID: <20211201202912.88441117E62@lists.varnish-cache.org> commit 5ba919d7f9b392e5b6b4d2a179db28316ca8c098 Author: Poul-Henning Kamp Date: Wed Dec 1 20:27:40 2021 +0000 If there is an unexpected panic, show it. diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 15ca52016..a6fff9d25 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -699,7 +699,7 @@ varnish_wait(struct varnish *v) /* Then stop it */ varnish_stop(v); - if (varnish_ask_cli(v, "panic.clear", NULL) != CLIS_CANT) + if (varnish_ask_cli(v, "panic.show", NULL) != CLIS_CANT) vtc_fatal(v->vl, "Unexpected panic"); varnish_cleanup(v); From dridi.boukelmoune at gmail.com Thu Dec 2 06:15:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 2 Dec 2021 06:15:06 +0000 (UTC) Subject: [master] 8df302401 Allow using the whole per thread log buffer Message-ID: <20211202061506.BD18F101769@lists.varnish-cache.org> commit 8df30240174b190db2601f4d64c28ee313eae486 Author: Martin Blix Grydeland Date: Wed Oct 4 15:24:10 2017 +0200 Allow using the whole per thread log buffer The logics were off by one in the available buffer space checks, causing us to loose one word of per thread log buffer space, and making reasoning about available space tricky. Fix this. Refs 10749ffe2dacd7744ea94265cf751e5a341d3110 Refs #3745 diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 60187bc33..2e67bbd05 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -347,17 +347,17 @@ VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t) if (l > mlen - 1) l = mlen - 1; - assert(vsl->wlp < vsl->wle); + assert(vsl->wlp <= vsl->wle); /* Flush if necessary */ - if (VSL_END(vsl->wlp, l + 1) >= vsl->wle) + if (VSL_END(vsl->wlp, l + 1) > vsl->wle) VSL_Flush(vsl, 1); - assert(VSL_END(vsl->wlp, l + 1) < vsl->wle); + assert(VSL_END(vsl->wlp, l + 1) <= vsl->wle); p = VSL_DATA(vsl->wlp); memcpy(p, t.b, l); p[l++] = '\0'; /* NUL-terminated */ vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid); - assert(vsl->wlp < vsl->wle); + assert(vsl->wlp <= vsl->wle); vsl->wlr++; if (DO_DEBUG(DBG_SYNCVSL)) @@ -531,16 +531,16 @@ VSLb_bin(struct vsl_log *vsl, enum VSL_tag_e tag, ssize_t len, const void *ptr) /* Truncate */ len = vmin_t(ssize_t, len, mlen); - assert(vsl->wlp < vsl->wle); + assert(vsl->wlp <= vsl->wle); /* Flush if necessary */ - if (VSL_END(vsl->wlp, len) >= vsl->wle) + if (VSL_END(vsl->wlp, len) > vsl->wle) VSL_Flush(vsl, 1); - assert(VSL_END(vsl->wlp, len) < vsl->wle); + assert(VSL_END(vsl->wlp, len) <= vsl->wle); p = VSL_DATA(vsl->wlp); memcpy(p, ptr, len); vsl->wlp = vsl_hdr(tag, vsl->wlp, len, vsl->wid); - assert(vsl->wlp < vsl->wle); + assert(vsl->wlp <= vsl->wle); vsl->wlr++; if (DO_DEBUG(DBG_SYNCVSL)) From dridi.boukelmoune at gmail.com Thu Dec 2 20:05:12 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 2 Dec 2021 20:05:12 +0000 (UTC) Subject: [master] b5d314a60 logexpect: Stop waiting after seeing an End tag Message-ID: <20211202200512.AF6EF119982@lists.varnish-cache.org> commit b5d314a60fd102f453d215a7fec44c28c6747e9b Author: Dridi Boukelmoune Date: Thu Dec 2 20:50:34 2021 +0100 logexpect: Stop waiting after seeing an End tag When a transaction ends, there will be nothing left to match for the transaction's VXID. Instead of timing the whole test case out, fail immediately. diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index 5a018cf89..ad7b85180 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -370,7 +370,7 @@ logexp_match(const struct logexp *le, struct logexp_test *test, const char *data, int vxid, int tag, int type, int len) { const char *legend; - int ok = 1, skip = 0, alt, fail; + int ok = 1, skip = 0, alt, fail, vxid_ok = 0; AN(le); AN(test); @@ -380,9 +380,11 @@ logexp_match(const struct logexp *le, struct logexp_test *test, if (test->vxid == LE_LAST) { if (le->vxid_last != vxid) ok = 0; + vxid_ok = ok; } else if (test->vxid >= 0) { if (test->vxid != vxid) ok = 0; + vxid_ok = ok; } if (test->tag == LE_LAST) { if (le->tag_last != tag) @@ -404,9 +406,14 @@ logexp_match(const struct logexp *le, struct logexp_test *test, test->skip_max > le->skip_cnt)) skip = 1; + if (skip && vxid_ok && tag == SLT_End) + fail = 1; + if (fail) { if (ok) legend = "fail"; + else if (skip) + legend = "end"; else if (le->m_arg) legend = "fmiss"; else @@ -438,7 +445,7 @@ logexp_match(const struct logexp *le, struct logexp_test *test, vtc_log(le->vl, 3, "alt | %s", VSB_data(test->str)); return (logexp_match(le, test, data, vxid, tag, type, len)); } - if (skip) + if (skip && !fail) return (LEM_SKIP); return (LEM_FAIL); } From dridi.boukelmoune at gmail.com Fri Dec 3 15:01:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 3 Dec 2021 15:01:07 +0000 (UTC) Subject: [master] 7ead21cb5 logexpect: Make all legends fit into 5 characters Message-ID: <20211203150107.30C36115567@lists.varnish-cache.org> commit 7ead21cb5c71bcf721dc1774584b96a3340d88c7 Author: Dridi Boukelmoune Date: Fri Dec 3 15:09:18 2021 +0100 logexpect: Make all legends fit into 5 characters This way they can all nicely align in the VTC output. The recently added "end" legend that denotes the end of a transaction before a match happened for the given VXID conflicted with the end of the logexpect spec. The latter was renamed to "done". diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index ad7b85180..ac8c7bdf2 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -345,17 +345,17 @@ logexp_next(struct logexp *le) logexp_next(le); return; case LE_CLEAR: - vtc_log(le->vl, 3, "condition| fail clear"); + vtc_log(le->vl, 3, "cond | fail clear"); VTAILQ_INIT(&le->fail); logexp_next(le); return; case LE_FAIL: - vtc_log(le->vl, 3, "condition| %s", VSB_data(le->test->str)); + vtc_log(le->vl, 3, "cond | %s", VSB_data(le->test->str)); VTAILQ_INSERT_TAIL(&le->fail, le->test, faillist); logexp_next(le); return; default: - vtc_log(le->vl, 3, "expecting| %s", VSB_data(le->test->str)); + vtc_log(le->vl, 3, "test | %s", VSB_data(le->test->str)); } } @@ -413,7 +413,7 @@ logexp_match(const struct logexp *le, struct logexp_test *test, if (ok) legend = "fail"; else if (skip) - legend = "end"; + legend = "end", skip = 0; else if (le->m_arg) legend = "fmiss"; else @@ -442,10 +442,10 @@ logexp_match(const struct logexp *le, struct logexp_test *test, test = logexp_alt(test); if (test == NULL) return (LEM_FAIL); - vtc_log(le->vl, 3, "alt | %s", VSB_data(test->str)); + vtc_log(le->vl, 3, "alt | %s", VSB_data(test->str)); return (logexp_match(le, test, data, vxid, tag, type, len)); } - if (skip && !fail) + if (skip) return (LEM_SKIP); return (LEM_FAIL); } @@ -549,24 +549,24 @@ logexp_thread(void *priv) AZ(le->test); vtc_log(le->vl, 4, "begin|"); if (le->query != NULL) - vtc_log(le->vl, 4, "qry| %s", le->query); + vtc_log(le->vl, 4, "qry | %s", le->query); logexp_next(le); while (!logexp_done(le) && !vtc_stop && !vtc_error) { i = VSLQ_Dispatch(le->vslq, logexp_dispatch, le); if (i == 2 && le->err_arg) { - vtc_log(le->vl, 4, "end| failed as expected"); + vtc_log(le->vl, 4, "done | failed as expected"); return (NULL); } if (i == 2) - vtc_fatal(le->vl, "bad| expectation failed"); + vtc_fatal(le->vl, "bad | expectation failed"); else if (i < 0) - vtc_fatal(le->vl, "bad| dispatch failed (%d)", i); + vtc_fatal(le->vl, "bad | dispatch failed (%d)", i); else if (i == 0 && ! logexp_done(le)) VTIM_sleep(0.01); } if (!logexp_done(le)) - vtc_fatal(le->vl, "bad| outstanding expectations"); - vtc_log(le->vl, 4, "end|"); + vtc_fatal(le->vl, "bad | outstanding expectations"); + vtc_log(le->vl, 4, "done |"); return (NULL); } From dridi.boukelmoune at gmail.com Fri Dec 3 15:01:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 3 Dec 2021 15:01:07 +0000 (UTC) Subject: [master] b93a741f8 vcc: Better format TOSTRANDS() C code Message-ID: <20211203150107.477C911556A@lists.varnish-cache.org> commit b93a741f872fc5b2f622233984d494d810c8e431 Author: Dridi Boukelmoune Date: Tue Nov 30 11:26:52 2021 +0100 vcc: Better format TOSTRANDS() C code diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index dcc0c07c9..bc9864d29 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -148,6 +148,19 @@ vcc_delete_expr(struct expr *e) * XXX: check line lengths in edit, should pass indent in for this */ +static void +vcc_strands_edit(struct expr *e1, struct expr *e2) +{ + + if (e2->nstr == 1) { + VSB_printf(e1->vsb, "TOSTRAND(%s)", VSB_data(e2->vsb)); + return; + } + + VSB_printf(e1->vsb, "TOSTRANDS(%d,\v+\n%s\v-)", + e2->nstr, VSB_data(e2->vsb)); +} + static struct expr * vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1, struct expr *e2) @@ -179,9 +192,7 @@ vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1, if (e3->nstr > 1) { VSB_cat(e->vsb, "\nVRT_STRANDS_string(ctx,\v+\n"); - VSB_printf(e->vsb, - "TOSTRANDS(%d,%s)", - e3->nstr, VSB_data(e3->vsb)); + vcc_strands_edit(e, e3); VSB_cat(e->vsb, "\v-\n)\n"); } else { @@ -192,8 +203,7 @@ 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, "TOSTRANDS(%d,%s)", - e3->nstr, VSB_data(e3->vsb)); + vcc_strands_edit(e, e3); break; case '1': VSB_cat(e->vsb, VSB_data(e1->vsb)); From phk at FreeBSD.org Mon Dec 6 14:07:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 6 Dec 2021 14:07:06 +0000 (UTC) Subject: [master] c5676a866 vcl.show no param defaults to active vcl Message-ID: <20211206140706.7003F107B57@lists.varnish-cache.org> commit c5676a866ce59f7796859477201967c286ba728a Author: Lachlan Abbott Date: Wed Dec 1 10:58:51 2021 +1100 vcl.show no param defaults to active vcl diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 50c1228ba..18d820fe4 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -946,28 +946,33 @@ vcl_cli_show(struct cli *cli, const char * const *av, void *priv) { struct vcl *vcl; int verbose = 0; - int i; + int i = 2; ASSERT_CLI(); ASSERT_VCL_ACTIVE(); AZ(priv); - if (!strcmp(av[2], "-v") && av[3] == NULL) { - VCLI_Out(cli, "Too few parameters"); - VCLI_SetResult(cli, CLIS_TOOFEW); - return; - } else if (strcmp(av[2], "-v") && av[3] != NULL) { - VCLI_Out(cli, "Unknown options '%s'", av[2]); + + if (av[i] != NULL && !strcmp(av[i], "-v")) { + verbose = 1; + i++; + } + + if (av[i] == NULL) { + vcl = vcl_active; + AN(vcl); + } else { + vcl = vcl_find(av[i]); + i++; + } + + if (av[i] != NULL) { + VCLI_Out(cli, "Too many parameters: '%s'", av[i]); VCLI_SetResult(cli, CLIS_PARAM); return; - } else if (av[3] != NULL) { - verbose = 1; - vcl = vcl_find(av[3]); - } else - vcl = vcl_find(av[2]); + } if (vcl == NULL) { - VCLI_Out(cli, "No VCL named '%s'", - av[3] == NULL ? av[2] : av[3]); + VCLI_Out(cli, "No VCL named '%s'", av[i - 1]); VCLI_SetResult(cli, CLIS_PARAM); return; } diff --git a/bin/varnishtest/tests/c00015.vtc b/bin/varnishtest/tests/c00015.vtc index 1acbbd297..1f1e1a479 100644 --- a/bin/varnishtest/tests/c00015.vtc +++ b/bin/varnishtest/tests/c00015.vtc @@ -53,7 +53,8 @@ varnish v1 -cli "vcl.show vcl2" varnish v1 -cli "vcl.show -v vcl2" varnish v1 -cli "vcl.discard vcl2" varnish v1 -cli "vcl.list" -varnish v1 -clierr 104 "vcl.show -v" +varnish v1 -cli "vcl.show" +varnish v1 -cli "vcl.show -v" varnish v1 -clierr 106 "vcl.show -x nowhere" varnish v1 -clierr 106 "vcl.show nothere" varnish v1 -clierr 106 "vcl.use nothere" diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h index 3814a1615..7b989e2ca 100644 --- a/include/tbl/cli_cmds.h +++ b/include/tbl/cli_cmds.h @@ -146,10 +146,10 @@ CLI_CMD(VCL_DEPS, CLI_CMD(VCL_SHOW, "vcl.show", - "vcl.show [-v] ", + "vcl.show [-v] []", "Display the source code for the specified configuration.", "", - 1, 2 + 0, 2 ) CLI_CMD(VCL_USE, From dridi.boukelmoune at gmail.com Tue Dec 7 06:51:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 7 Dec 2021 06:51:06 +0000 (UTC) Subject: [master] cb446a38d vcc: set BODY [+]= STRINGS|BLOB Message-ID: <20211207065106.30C4F6475E@lists.varnish-cache.org> commit cb446a38d75c7768b5c5f7b4330f45d69375ba4a Author: Dridi Boukelmoune Date: Mon Nov 29 18:35:57 2021 +0100 vcc: set BODY [+]= STRINGS|BLOB This reuses the stringform concept and introduces a similar bodyform flag for STRINGS and BLOB types. We can now assign either a STRING or a BLOB to [be]resp.body, without breaking the VRT ABI and API. In fact, the VRT API now uses a void* C type for the BODY VCL type and finds which type to use based on enum lbody_e. The enum completely changed but macros were added to maintain the API, and because of this change, enum lbody_e literals are formatted in two steps. As a result the BODY type grew another noindent flag. It prevents the insertion of white space between the LBODY_{ADD,SET}_ prefix and the type name suffix (BLOB or STRANDS). diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 64b7257d4..d80b96526 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -965,17 +965,29 @@ VRT_r_resp_do_esi(VRT_CTX) #define VRT_BODY_L(which) \ VCL_VOID \ VRT_l_##which##_body(VRT_CTX, enum lbody_e type, \ - const char *str, VCL_STRANDS s) \ + const char *str, VCL_BODY body) \ { \ int n; \ struct vsb *vsb; \ + VCL_STRANDS s; \ + VCL_BLOB b; \ \ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ + AN(body); \ CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC); \ - assert(type == LBODY_SET || type == LBODY_ADD); \ - if (type == LBODY_SET) \ + if (type == LBODY_SET_STRING || type == LBODY_SET_BLOB) \ VSB_clear(vsb); \ + if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) { \ + AZ(str); \ + b = body; \ + VSB_bcat(vsb, b->blob, b->len); \ + return; \ + } \ if (str != NULL) \ VSB_cat(vsb, str); \ + assert(type == LBODY_SET_STRING || \ + type == LBODY_ADD_STRING); \ + s = body; \ for (n = 0; s != NULL && n < s->n; n++) \ if (s->p[n] != NULL) \ VSB_cat(vsb, s->p[n]); \ diff --git a/bin/varnishtest/tests/r03079.vtc b/bin/varnishtest/tests/r03079.vtc index 3b2f57204..22da633ac 100644 --- a/bin/varnishtest/tests/r03079.vtc +++ b/bin/varnishtest/tests/r03079.vtc @@ -26,7 +26,7 @@ client c1 { expect resp.http.x-powered-by == varnishtest1002 } -run -# set BODY [+]= STRINGS; +# set BODY [+]= STRINGS|BLOB; varnish v1 -vcl { import blob; @@ -50,11 +50,20 @@ varnish v1 -vcl { set resp.body += "world"; } } + if (req.url ~ "blob") { + set resp.body = blob.decode(HEX, encoded="1100"); + if (req.url ~ "reset") { + set resp.body = blob.decode(HEX, encoded="221100"); + } + if (req.url ~ "add") { + set resp.body += blob.decode(HEX, encoded="221100"); + } + } return (deliver); } } -client c1 { +client c2 { txreq -url "/synth" rxresp expect resp.body == hello @@ -74,4 +83,16 @@ client c1 { txreq -url "/string/add" rxresp expect resp.body == helloworld + + txreq -url "/blob" + rxresp + expect resp.bodylen == 2 + + txreq -url "/blob/reset" + rxresp + expect resp.bodylen == 3 + + txreq -url "/blob/add" + rxresp + expect resp.bodylen == 5 } -run diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index 84283745f..10460cd7b 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -302,6 +302,13 @@ BLOB An opaque type to pass random bits of memory between VMOD functions. +BODY + C-type: ``const void *`` + + A type only used on the LHS of an assignment that can take + either a blob or an expression that can be converted to a + string. + BOOL C-type: ``unsigned`` diff --git a/include/vrt.h b/include/vrt.h index a47250255..f7a1d31e1 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -56,6 +56,14 @@ * Next (2021-03-15) * VRT_Assign_Backend added * VRT_StaticDirector added + * enum lbody_e changed + * - previous enum lbody_e values are defined as macros + * The following functions changed to take `const char *, BODY`: + * - VRT_l_beresp_body() + * - VRT_l_resp_body() + * BODY can either be a BLOB or a STRANDS, but only a STRANDS + * can take a non-NULL const char * prefix. The changes to BODY + * assignments doesn't break the ABI or the API. * * 14.0 (2021-09-15) * VIN_n_Arg() no directly returns the directory name. @@ -328,7 +336,7 @@ extern const struct vrt_blob *vrt_null_blob; typedef const struct vrt_acl * VCL_ACL; typedef const struct director * VCL_BACKEND; typedef const struct vrt_blob * VCL_BLOB; -typedef const char * VCL_BODY; +typedef const void * VCL_BODY; typedef unsigned VCL_BOOL; typedef int64_t VCL_BYTES; typedef vtim_dur VCL_DURATION; @@ -615,10 +623,15 @@ VCL_STRING VRT_GetHdr(VRT_CTX, VCL_HEADER); */ enum lbody_e { - LBODY_SET, - LBODY_ADD, + LBODY_SET_STRING, + LBODY_ADD_STRING, + LBODY_SET_BLOB, + LBODY_ADD_BLOB, }; +#define LBODY_SET LBODY_SET_STRING +#define LBODY_ADD LBODY_ADD_STRING + VCL_BYTES VRT_CacheReqBody(VRT_CTX, VCL_BYTES maxsize); VCL_STRING VRT_ban_string(VRT_CTX, VCL_STRING); diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index a2b318ba8..c50194348 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -219,7 +219,7 @@ class vardef(object): if self.typ == "STRING": s += ctyp.c + ", VCL_STRANDS)" elif self.typ == "BODY": - s += "enum lbody_e, " + ctyp.c + ", VCL_STRANDS)" + s += "enum lbody_e, const char *, " + ctyp.c + ")" else: s += "VCL_" + self.typ + ")" varproto(s) diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c index 0ed675da6..f7c2ce29f 100644 --- a/lib/libvcc/vcc_action.c +++ b/lib/libvcc/vcc_action.c @@ -121,8 +121,8 @@ static const struct assign { { STRING, '=', STRANDS, "0,\n" }, { HEADER, T_INCR, STRANDS, "VRT_GetHdr(ctx, \v),\n" }, { HEADER, '=', STRANDS, "0,\n" }, - { BODY, '=', STRANDS, "LBODY_SET, 0,\n" }, - { BODY, T_INCR, STRANDS, "LBODY_ADD, 0,\n" }, + { BODY, '=', BODY, "LBODY_SET_" }, + { BODY, T_INCR, BODY, "LBODY_ADD_" }, { VOID, '=', VOID } }; diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 6ce150c4c..76b2cab73 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -119,6 +119,8 @@ struct type { const char *tostring; vcc_type_t multype; int stringform; + int bodyform; + int noindent; }; #define VCC_TYPE(UC, lc) extern const struct type UC[1]; diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index bc9864d29..0805f9340 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -237,8 +237,10 @@ vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1) char *p; int i; - for (i = 0; i < ind; i++) - VSB_cat(d, " "); + if (!e1->fmt->noindent) { + for (i = 0; i < ind; i++) + VSB_putc(d, ' '); + } p = VSB_data(e1->vsb); while (*p != '\0') { if (*p == '\n') { @@ -246,7 +248,7 @@ vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1) if (*++p == '\0') break; for (i = 0; i < ind; i++) - VSB_cat(d, " "); + VSB_putc(d, ' '); } else if (*p != '\v') { VSB_putc(d, *p++); } else { @@ -1417,6 +1419,8 @@ vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt) vcc_expr_cor(tl, e, fmt); ERRCHK(tl); + assert((*e)->fmt != BODY); + if ((*e)->fmt == fmt) return; @@ -1431,6 +1435,18 @@ vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt) return; } + if (fmt == BODY && !(*e)->fmt->bodyform) + vcc_expr_tostring(tl, e, STRINGS); + + if (fmt == BODY && (*e)->fmt->bodyform) { + if ((*e)->fmt == STRINGS) + *e = vcc_expr_edit(tl, BODY, "STRING, 0, \vT", *e, NULL); + else if ((*e)->fmt == BLOB) + *e = vcc_expr_edit(tl, BODY, "BLOB, 0, \v1", *e, NULL); + else + WRONG("Unhandled bodyform"); + } + if ((*e)->fmt == STRINGS && fmt->stringform) { if (fmt == STRING) *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL); diff --git a/lib/libvcc/vcc_types.c b/lib/libvcc/vcc_types.c index 829bb2c2e..cfa6714b3 100644 --- a/lib/libvcc/vcc_types.c +++ b/lib/libvcc/vcc_types.c @@ -78,12 +78,14 @@ const struct type BACKEND[1] = {{ const struct type BLOB[1] = {{ .magic = TYPE_MAGIC, .name = "BLOB", + .bodyform = 1, .tostring = "VRT_BLOB_string(ctx, \v1)", }}; const struct type BODY[1] = {{ .magic = TYPE_MAGIC, .name = "BODY", + .noindent = 1, }}; const struct type BOOL[1] = {{ @@ -199,6 +201,7 @@ const struct type STRINGS[1] = {{ .magic = TYPE_MAGIC, .name = "STRINGS", .methods = strings_methods, + .bodyform = 1, .tostring = "", }}; From dridi.boukelmoune at gmail.com Wed Dec 8 11:37:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 8 Dec 2021 11:37:09 +0000 (UTC) Subject: [6.0] ff364a31e Polish Message-ID: <20211208113709.4DCF8106F9E@lists.varnish-cache.org> commit ff364a31ed6c9d698dd7c0a80c692c95194b7d43 Author: Poul-Henning Kamp Date: Wed Jan 16 22:32:56 2019 +0000 Polish Conflicts: bin/varnishd/cache/cache_esi_deliver.c This fixes a potential out-of-workspace panic. diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 405bcaaf5..42d090e9e 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -576,7 +576,7 @@ struct ved_foo { ssize_t start, last, stop, lpad; ssize_t ll; uint64_t olen; - uint8_t *dbits; + uint8_t dbits[8]; uint8_t tailbuf[8]; }; @@ -726,18 +726,17 @@ ved_stripgzip(struct req *req, const struct boc *boc) const char *p; uint32_t icrc; uint32_t ilen; - uint8_t *dbits; struct ecx *ecx; - struct ved_foo foo; + struct ved_foo foo[1]; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); CAST_OBJ_NOTNULL(ecx, req->transport_priv, ECX_MAGIC); - INIT_OBJ(&foo, VED_FOO_MAGIC); - foo.req = req; - foo.preq = ecx->preq; - memset(foo.tailbuf, 0xdd, sizeof foo.tailbuf); + INIT_OBJ(foo, VED_FOO_MAGIC); + foo->req = req; + foo->preq = ecx->preq; + memset(foo->tailbuf, 0xdd, sizeof foo->tailbuf); /* OA_GZIPBITS is not valid until BOS_FINISHED */ if (boc != NULL) @@ -759,28 +758,25 @@ ved_stripgzip(struct req *req, const struct boc *boc) p = ObjGetAttr(req->wrk, req->objcore, OA_GZIPBITS, &l); AN(p); assert(l == 32); - foo.start = vbe64dec(p); - foo.last = vbe64dec(p + 8); - foo.stop = vbe64dec(p + 16); - foo.olen = ObjGetLen(req->wrk, req->objcore); - assert(foo.start > 0 && foo.start < foo.olen * 8); - assert(foo.last > 0 && foo.last < foo.olen * 8); - assert(foo.stop > 0 && foo.stop < foo.olen * 8); - assert(foo.last >= foo.start); - assert(foo.last < foo.stop); + foo->start = vbe64dec(p); + foo->last = vbe64dec(p + 8); + foo->stop = vbe64dec(p + 16); + foo->olen = ObjGetLen(req->wrk, req->objcore); + assert(foo->start > 0 && foo->start < foo->olen * 8); + assert(foo->last > 0 && foo->last < foo->olen * 8); + assert(foo->stop > 0 && foo->stop < foo->olen * 8); + assert(foo->last >= foo->start); + assert(foo->last < foo->stop); /* The start bit must be byte aligned. */ - AZ(foo.start & 7); + AZ(foo->start & 7); - dbits = WS_Alloc(req->ws, 8); - AN(dbits); - foo.dbits = dbits; (void)ObjIterate(req->wrk, req->objcore, &foo, ved_objiterate, 0); /* XXX: error check ?? */ - (void)ved_bytes(req, foo.preq, VDP_FLUSH, NULL, 0); + (void)ved_bytes(req, foo->preq, VDP_FLUSH, NULL, 0); - icrc = vle32dec(foo.tailbuf); - ilen = vle32dec(foo.tailbuf + 4); + icrc = vle32dec(foo->tailbuf); + ilen = vle32dec(foo->tailbuf + 4); ecx->crc = crc32_combine(ecx->crc, icrc, ilen); ecx->l_crc += ilen; From nils.goroll at uplex.de Fri Dec 10 16:18:09 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 10 Dec 2021 16:18:09 +0000 (UTC) Subject: [master] 91f998e47 Improve VCF coverage Message-ID: <20211210161809.DB36A114A81@lists.varnish-cache.org> commit 91f998e47e970ebef09d0d23eb5dd83be6bdbe13 Author: Nils Goroll Date: Fri Dec 10 17:17:13 2021 +0100 Improve VCF coverage diff --git a/bin/varnishtest/tests/m00051.vtc b/bin/varnishtest/tests/m00051.vtc index a5231894a..8d2ed69aa 100644 --- a/bin/varnishtest/tests/m00051.vtc +++ b/bin/varnishtest/tests/m00051.vtc @@ -12,6 +12,9 @@ varnish v1 -vcl { debug.catflap(first); } else if (req.http.get == "last") { debug.catflap(last); + } else if (req.http.novcf) { + set req.http.consume = "some workspace"; + return (pass); } else { return (fail); } @@ -19,6 +22,10 @@ varnish v1 -vcl { } sub vcl_backend_error { + if (bereq.http.novcf) { + set beresp.status = 206; + return (deliver); + } if (! bereq.http.id) { return (deliver); } @@ -27,18 +34,36 @@ varnish v1 -vcl { set beresp.grace = 1m; set beresp.http.id = bereq.http.id; } + + sub vcl_deliver { + if (req.http.restart) { + unset req.http.restart; + unset req.http.id; + set req.http.novcf = "yes"; + return (restart); + } + } } -start client c1 { txreq -hdr "id: 1" rxresp expect resp.status == 200 + txreq -hdr "novcf: yes" + rxresp + expect resp.status == 206 txreq -hdr "id: 2" rxresp expect resp.status == 200 + txreq -hdr "id: 2" -hdr "restart: yes" + rxresp + expect resp.status == 206 txreq -hdr "id: 3" rxresp expect resp.status == 200 + txreq -hdr "novcf: yes" + rxresp + expect resp.status == 206 # the first object is the one which went into cache last @@ -46,9 +71,15 @@ client c1 { rxresp expect resp.status == 200 expect resp.http.id == "3" + txreq -hdr "novcf: yes" + rxresp + expect resp.status == 206 txreq -hdr "get: last" rxresp expect resp.status == 200 expect resp.http.id == "1" + txreq -hdr "novcf: yes" + rxresp + expect resp.status == 206 } -run From nils.goroll at uplex.de Fri Dec 10 17:12:07 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 10 Dec 2021 17:12:07 +0000 (UTC) Subject: [master] f4e7c9674 Clear catflap when rolling back Message-ID: <20211210171207.4778A116424@lists.varnish-cache.org> commit f4e7c9674cd22249f64544b021fe681a341c7cb6 Author: Nils Goroll Date: Fri Dec 10 18:10:32 2021 +0100 Clear catflap when rolling back Fixes #3752 diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index aae9be794..c827a0dec 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -235,6 +235,7 @@ Req_Rollback(VRT_CTX) VCL_TaskEnter(req->top->privs); HTTP_Clone(req->http, req->http0); req->filter_list = NULL; + req->vcf = NULL; if (WS_Overflowed(req->ws)) req->wrk->stats->ws_client_overflow++; AN(req->ws_req); diff --git a/bin/varnishtest/tests/m00051.vtc b/bin/varnishtest/tests/m00051.vtc index 8d2ed69aa..2768e9504 100644 --- a/bin/varnishtest/tests/m00051.vtc +++ b/bin/varnishtest/tests/m00051.vtc @@ -2,6 +2,7 @@ varnishtest "catflap" varnish v1 -vcl { import debug; + import std; backend dummy { .host = "${bad_backend}"; } @@ -15,6 +16,11 @@ varnish v1 -vcl { } else if (req.http.novcf) { set req.http.consume = "some workspace"; return (pass); + } else if (req.http.rollback) { + debug.catflap(first); + std.rollback(req); + set req.http.consume = "some workspace"; + set req.http.consume = "some workspace"; } else { return (fail); } @@ -71,6 +77,10 @@ client c1 { rxresp expect resp.status == 200 expect resp.http.id == "3" + txreq -hdr "rollback: yes" + rxresp + expect resp.status == 200 + expect resp.http.id == "3" txreq -hdr "novcf: yes" rxresp expect resp.status == 206 From dridi.boukelmoune at gmail.com Mon Dec 13 17:08:08 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 13 Dec 2021 17:08:08 +0000 (UTC) Subject: [master] 95b10d1ba param: Consistent formatting of flag notices Message-ID: <20211213170809.0CE3B11BD6A@lists.varnish-cache.org> commit 95b10d1baaf6768de827e67cc6b9c228fb7fd0e7 Author: Dridi Boukelmoune Date: Mon Dec 13 08:40:56 2021 +0100 param: Consistent formatting of flag notices diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 308015ced..dff2ea78d 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -101,10 +101,12 @@ static const char ONLY_ROOT_TEXT[] = "NB: This parameter only works if varnishd is run as root."; static const char NOT_IMPLEMENTED_TEXT[] = - "This parameter depends on a feature which is not available" + "\n\n" + "NB: This parameter depends on a feature which is not available" " on this platform."; static const char PLATFORM_DEPENDENT_TEXT[] = + "\n\n" "NB: This parameter depends on a feature which is not available" " on all platforms."; From dridi.boukelmoune at gmail.com Mon Dec 13 17:08:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 13 Dec 2021 17:08:09 +0000 (UTC) Subject: [master] 66ecc8369 param: Comment OCD Message-ID: <20211213170809.2C07611BD6D@lists.varnish-cache.org> commit 66ecc83692d55d7c4f14b5b3ab1e6b2c9e90b383 Author: Dridi Boukelmoune Date: Mon Dec 13 08:41:53 2021 +0100 param: Comment OCD diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index 2971eaa1b..776439959 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -492,7 +492,6 @@ tweak_thread_pool_max(struct vsb *vsb, const struct parspec *par, /*-------------------------------------------------------------------- * Tweak storage - * */ int v_matchproto_(tweak_t) diff --git a/include/tbl/params.h b/include/tbl/params.h index 270cec0de..e316a4eab 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -37,8 +37,8 @@ /*lint -save -e525 -e539 -e835 */ /*-------------------------------------------------------------------- - * * Simple parameters - * */ + * Simple parameters + */ #define PARAM_SIMPLE(nm, typ, ...) \ PARAM(typ, nm, nm, tweak_##typ, &mgt_param.nm, __VA_ARGS__) @@ -1167,7 +1167,8 @@ PARAM_SIMPLE( /* We have a strict min at the protocol default here. This is because we * don't have the 'use settings only after peer ack' in place yet. If the * value is lower than the protocol default, the very first stream could - * get a flow control error. */ + * get a flow control error. + */ PARAM_SIMPLE( /* name */ h2_initial_window_size, /* type */ bytes_u, From dridi.boukelmoune at gmail.com Mon Dec 13 17:08:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 13 Dec 2021 17:08:09 +0000 (UTC) Subject: [master] c6e3d6b5b param: Infrastructure for deprecated aliases Message-ID: <20211213170809.51DF911BD70@lists.varnish-cache.org> commit c6e3d6b5b91c81ff075112c3008940d15b201ad1 Author: Dridi Boukelmoune Date: Mon Dec 13 08:47:48 2021 +0100 param: Infrastructure for deprecated aliases With this change, we can formalize the renaming of a parameter while maintaining the old name temporarily for compatibility. A deprecated alias can be set with either param.set or the -p option, but won't be listed by: - param.show [-j] - param.show [-j] changed - param.show -l Only an explicit param.show for the name of the alias will provide a minimal documentation with a deprecation notice and the current value. In the manual, there is only a deprecation notice. The rationale is that administration tools shouldn't pick them up when enumerating the parameters. Since we currently don't have deprecated parameters, this can only be tested manually, for example: PARAM_ALIAS(vcl_dir, vcl_path) To ensure that we don't break this, we could consider having a perpetual deprecated parameter. diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index dff2ea78d..3502e2820 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -262,6 +262,10 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) pp = pl->spec; if (lfmt && strcmp(pp->name, av[2]) && strcmp("-l", av[2])) continue; + if (pp->func == tweak_alias && !lfmt) + continue; + if (pp->func == tweak_alias && strcmp(pp->name, av[2])) + continue; n++; VSB_clear(vsb); @@ -383,6 +387,10 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) pp = pl->spec; if (show != NULL && strcmp(pp->name, show) != 0) continue; + if (pp->func == tweak_alias && show == NULL) + continue; + if (pp->func == tweak_alias && strcmp(pp->name, show)) + continue; n++; VSB_clear(vsb); @@ -622,6 +630,13 @@ mcf_wash_param(struct cli *cli, struct parspec *pp, enum mcf_which_e which, } AN(val); + if (pp->func == tweak_alias) { + assert(which == MCF_DEFAULT); + pp->priv = mcf_findpar(pp->def); + pp->def = NULL; + return; + } + VSB_clear(vsb); VSB_printf(vsb, "FAILED to set %s for param %s: %s\n", name, pp->name, val); diff --git a/bin/varnishd/mgt/mgt_param.h b/bin/varnishd/mgt/mgt_param.h index f31fc1078..f3af67df5 100644 --- a/bin/varnishd/mgt/mgt_param.h +++ b/bin/varnishd/mgt/mgt_param.h @@ -66,6 +66,7 @@ struct parspec { char *dyn_def; }; +tweak_t tweak_alias; tweak_t tweak_boolean; tweak_t tweak_bytes; tweak_t tweak_bytes_u; diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index 776439959..526fcf64e 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -527,3 +527,15 @@ tweak_storage(struct vsb *vsb, const struct parspec *par, const char *arg) } return (tweak_string(vsb, par, arg)); } + +/*-------------------------------------------------------------------- + * Tweak alias + */ + +int v_matchproto_(tweak_t) +tweak_alias(struct vsb *vsb, const struct parspec *par, const char *arg) +{ + + par = TRUST_ME(par->priv); + return (par->func(vsb, par, arg)); +} diff --git a/include/tbl/params.h b/include/tbl/params.h index e316a4eab..48b89aa76 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -1641,6 +1641,21 @@ PARAM_PCRE2( " messages." ) +/*-------------------------------------------------------------------- + * Parameter deprecated aliases + * + * When a parameter is renamed, but the a deprecated alias is kept for + * compatibility, its documentation is minimal: only a description in + * manual pages, a description and current value in the CLI. + */ + +#define PARAM_ALIAS(al, nm) \ + PARAM(, , al, tweak_alias, NULL, NULL, NULL, #nm, NULL, \ + "Deprecated alias for the " #nm " parameter.") + +/* PARAM_ALIAS(old, new) */ + +# undef PARAM_ALIAS # undef PARAM_ALL # undef PARAM_PCRE2 # undef PARAM_STRING From dridi.boukelmoune at gmail.com Mon Dec 13 17:08:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 13 Dec 2021 17:08:09 +0000 (UTC) Subject: [master] 6613cca62 param: Add a hidden deprecated alias for coverage Message-ID: <20211213170809.7C48B11BD75@lists.varnish-cache.org> commit 6613cca62e5bf7193cb9717e476d47ab74a2e2a5 Author: Dridi Boukelmoune Date: Mon Dec 13 16:02:00 2021 +0100 param: Add a hidden deprecated alias for coverage diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 3502e2820..4a4ecbfcc 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -778,6 +778,8 @@ MCF_DumpRstParam(void) "output from varnishd -x parameter\n\n"); VTAILQ_FOREACH(pl, &phead, list) { pp = pl->spec; + if (!strcmp("deprecated_dummy", pp->name)) + continue; printf(".. _ref_param_%s:\n\n", pp->name); printf("%s\n", pp->name); for (z = 0; z < strlen(pp->name); z++) diff --git a/bin/varnishtest/tests/b00078.vtc b/bin/varnishtest/tests/b00078.vtc new file mode 100644 index 000000000..e732f1d2f --- /dev/null +++ b/bin/varnishtest/tests/b00078.vtc @@ -0,0 +1,23 @@ +varnishtest "deprecated parameters" + +varnish v1 -cliok "param.set debug +syncvsl" + +shell -expect "+syncvsl" { + varnishadm -n ${v1_name} "param.show deprecated_dummy" +} + +shell -expect "+syncvsl" { + varnishadm -n ${v1_name} "param.show -j deprecated_dummy" +} + +shell -err { + varnishadm -n ${v1_name} "param.show" | grep deprecated_dummy +} + +shell -err { + varnishadm -n ${v1_name} "param.show -l" | grep deprecated_dummy +} + +shell -err { + varnishadm -n ${v1_name} "param.show -j" | grep deprecated_dummy +} diff --git a/include/tbl/params.h b/include/tbl/params.h index 48b89aa76..964c2d255 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -1647,13 +1647,15 @@ PARAM_PCRE2( * When a parameter is renamed, but the a deprecated alias is kept for * compatibility, its documentation is minimal: only a description in * manual pages, a description and current value in the CLI. + * + * The deprecated_dummy alias is here for test coverage. */ #define PARAM_ALIAS(al, nm) \ PARAM(, , al, tweak_alias, NULL, NULL, NULL, #nm, NULL, \ "Deprecated alias for the " #nm " parameter.") -/* PARAM_ALIAS(old, new) */ +PARAM_ALIAS(deprecated_dummy, debug) # undef PARAM_ALIAS # undef PARAM_ALL From nils.goroll at uplex.de Tue Dec 14 07:46:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 14 Dec 2021 07:46:05 +0000 (UTC) Subject: [master] 01ed6eb63 Use workspace_reserve() in the catflap test Message-ID: <20211214074605.B184A10EC2D@lists.varnish-cache.org> commit 01ed6eb639dda8b7db3bfe923bed60bbf4f0a3be Author: Nils Goroll Date: Tue Dec 14 08:10:52 2021 +0100 Use workspace_reserve() in the catflap test I have checked that this catches #3752 too diff --git a/bin/varnishtest/tests/m00051.vtc b/bin/varnishtest/tests/m00051.vtc index 2768e9504..cc2e87eb7 100644 --- a/bin/varnishtest/tests/m00051.vtc +++ b/bin/varnishtest/tests/m00051.vtc @@ -3,6 +3,7 @@ varnishtest "catflap" varnish v1 -vcl { import debug; import std; + import vtc; backend dummy { .host = "${bad_backend}"; } @@ -14,13 +15,12 @@ varnish v1 -vcl { } else if (req.http.get == "last") { debug.catflap(last); } else if (req.http.novcf) { - set req.http.consume = "some workspace"; + vtc.workspace_reserve(client, -1); return (pass); } else if (req.http.rollback) { debug.catflap(first); std.rollback(req); - set req.http.consume = "some workspace"; - set req.http.consume = "some workspace"; + vtc.workspace_reserve(client, -1); } else { return (fail); } From nils.goroll at uplex.de Tue Dec 14 07:46:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 14 Dec 2021 07:46:05 +0000 (UTC) Subject: [master] 2b4ed68c8 vtc.workspace_reserve() zero memory like vtc.workspace_alloc() Message-ID: <20211214074605.A3A4B10EC2B@lists.varnish-cache.org> commit 2b4ed68c847d03e5c337933131d9bd972069b3b2 Author: Nils Goroll Date: Tue Dec 14 08:07:26 2021 +0100 vtc.workspace_reserve() zero memory like vtc.workspace_alloc() This is useful to ensure that workspace does not, by chance or accident, contain data and, in particular, magic numbers from previous workspace use. diff --git a/vmod/vmod_vtc.c b/vmod/vmod_vtc.c index 7c09e79c3..31412c06c 100644 --- a/vmod/vmod_vtc.c +++ b/vmod/vmod_vtc.c @@ -194,6 +194,7 @@ vmod_workspace_reserve(VRT_CTX, VCL_ENUM which, VCL_INT size) r = WS_ReserveSize(ws, size); if (r == 0) return (0); + memset(WS_Reservation(ws), 0, r); WS_Release(ws, 0); return (r); } diff --git a/vmod/vmod_vtc.vcc b/vmod/vmod_vtc.vcc index 17a823f2c..833a163a4 100644 --- a/vmod/vmod_vtc.vcc +++ b/vmod/vmod_vtc.vcc @@ -101,8 +101,8 @@ architecture. A failed allocation fails the transaction. $Function BYTES workspace_reserve(ENUM { client, backend, session, thread }, INT size) -Attempt to reserve *size* bytes and release the reservation right -away. Return the size of the reservation. +Attempt to reserve *size* bytes, zero out that memory and release the +reservation right away. Return the size of the reservation. See `vtc.workspace_alloc()`_ for semantics of the *size* argument. From nils.goroll at uplex.de Tue Dec 14 07:46:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 14 Dec 2021 07:46:05 +0000 (UTC) Subject: [master] 5897f401f catflap test: rename for clarity Message-ID: <20211214074605.CC0E410EC30@lists.varnish-cache.org> commit 5897f401f22c335e9484fb1971287c7139ea6430 Author: Nils Goroll Date: Tue Dec 14 08:19:11 2021 +0100 catflap test: rename for clarity diff --git a/bin/varnishtest/tests/m00051.vtc b/bin/varnishtest/tests/m00051.vtc index cc2e87eb7..5be0b4d79 100644 --- a/bin/varnishtest/tests/m00051.vtc +++ b/bin/varnishtest/tests/m00051.vtc @@ -14,7 +14,7 @@ varnish v1 -vcl { debug.catflap(first); } else if (req.http.get == "last") { debug.catflap(last); - } else if (req.http.novcf) { + } else if (req.http.novcfpass) { vtc.workspace_reserve(client, -1); return (pass); } else if (req.http.rollback) { @@ -28,7 +28,7 @@ varnish v1 -vcl { } sub vcl_backend_error { - if (bereq.http.novcf) { + if (bereq.http.novcfpass) { set beresp.status = 206; return (deliver); } @@ -45,7 +45,7 @@ varnish v1 -vcl { if (req.http.restart) { unset req.http.restart; unset req.http.id; - set req.http.novcf = "yes"; + set req.http.novcfpass = "yes"; return (restart); } } @@ -55,7 +55,7 @@ client c1 { txreq -hdr "id: 1" rxresp expect resp.status == 200 - txreq -hdr "novcf: yes" + txreq -hdr "novcfpass: yes" rxresp expect resp.status == 206 txreq -hdr "id: 2" @@ -67,7 +67,7 @@ client c1 { txreq -hdr "id: 3" rxresp expect resp.status == 200 - txreq -hdr "novcf: yes" + txreq -hdr "novcfpass: yes" rxresp expect resp.status == 206 @@ -81,7 +81,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.http.id == "3" - txreq -hdr "novcf: yes" + txreq -hdr "novcfpass: yes" rxresp expect resp.status == 206 @@ -89,7 +89,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.http.id == "1" - txreq -hdr "novcf: yes" + txreq -hdr "novcfpass: yes" rxresp expect resp.status == 206 } -run From nils.goroll at uplex.de Tue Dec 14 07:46:05 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 14 Dec 2021 07:46:05 +0000 (UTC) Subject: [master] e296eea75 Clear the vcf pointer inbetween requests Message-ID: <20211214074605.E57B410EC35@lists.varnish-cache.org> commit e296eea75e61f2525b6801c000440eb2bb0b5541 Author: Nils Goroll Date: Tue Dec 14 08:26:04 2021 +0100 Clear the vcf pointer inbetween requests Fixes #3755 diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index c827a0dec..cf456c98f 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -288,6 +288,7 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) req->esi_level = 0; req->is_hit = 0; req->req_step = R_STP_TRANSPORT; + req->vcf = NULL; if (WS_Overflowed(req->ws)) wrk->stats->ws_client_overflow++; diff --git a/bin/varnishtest/tests/m00051.vtc b/bin/varnishtest/tests/m00051.vtc index 5be0b4d79..ac596feb4 100644 --- a/bin/varnishtest/tests/m00051.vtc +++ b/bin/varnishtest/tests/m00051.vtc @@ -17,6 +17,11 @@ varnish v1 -vcl { } else if (req.http.novcfpass) { vtc.workspace_reserve(client, -1); return (pass); + } else if (req.http.novcfmiss) { + vtc.workspace_reserve(client, -1); + } else if (req.http.vcfpass) { + debug.catflap(first); + return (pass); } else if (req.http.rollback) { debug.catflap(first); std.rollback(req); @@ -28,7 +33,7 @@ varnish v1 -vcl { } sub vcl_backend_error { - if (bereq.http.novcfpass) { + if (bereq.http.novcfpass || bereq.http.vcfpass) { set beresp.status = 206; return (deliver); } @@ -92,4 +97,16 @@ client c1 { txreq -hdr "novcfpass: yes" rxresp expect resp.status == 206 + + # VCF with return(pass) must not leave the VCF dangling on the + # workspace for a subsequent plain miss + + txreq -hdr "vcfpass: yes" + rxresp + expect resp.status == 206 + + txreq -hdr "novcfmiss: yes" + rxresp + expect resp.status == 200 + expect resp.http.id == "3" } -run From nils.goroll at uplex.de Tue Dec 14 07:46:06 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 14 Dec 2021 07:46:06 +0000 (UTC) Subject: [master] 5dde9ff33 Clear seen_methods bitmask inbetween requests Message-ID: <20211214074606.0A14710EC38@lists.varnish-cache.org> commit 5dde9ff334216ca53b1055b5c676955909242876 Author: Nils Goroll Date: Tue Dec 14 08:39:52 2021 +0100 Clear seen_methods bitmask inbetween requests Confusing panic output was generated when a worker ran multiple requests before returning to the pool. Noticed when debugging #3755 : VCL::methods = {RECV, PASS, HASH, MISS, HIT, DELIVER}, Same panic with this fix: VCL::methods = {RECV, HASH}, diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index cf456c98f..27cfe3034 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -292,6 +292,8 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) if (WS_Overflowed(req->ws)) wrk->stats->ws_client_overflow++; + + wrk->seen_methods = 0; } /*---------------------------------------------------------------------- From dridi.boukelmoune at gmail.com Tue Dec 14 08:38:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 14 Dec 2021 08:38:06 +0000 (UTC) Subject: [master] 563df677c param: Parse param.show like param.show -j Message-ID: <20211214083806.526AA110907@lists.varnish-cache.org> commit 563df677cdd1836cf391ce824f683230d20de8ff Author: Dridi Boukelmoune Date: Tue Dec 14 09:25:41 2021 +0100 param: Parse param.show like param.show -j And complain when two parameters are passed instead of one parameter and one option. diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 4a4ecbfcc..4070ddb42 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -242,29 +242,42 @@ mcf_wrap(struct cli *cli, const char *text) static void v_matchproto_(cli_func_t) mcf_param_show(struct cli *cli, const char * const *av, void *priv) { - int n; struct plist *pl; const struct parspec *pp; - int lfmt = 0, chg = 0; + int n, lfmt = 0, chg = 0; struct vsb *vsb; + const char *show = NULL; vsb = VSB_new_auto(); AN(vsb); (void)priv; - if (av[2] != NULL && !strcmp(av[2], "changed")) - chg = 1; - else if (av[2] != NULL) + for (n = 2; av[n] != NULL; n++) { + if (strcmp(av[n], "-l") == 0) { + lfmt = 1; + continue; + } + if (strcmp(av[n], "changed") == 0) { + chg = 1; + continue; + } + if (show != NULL) { + VCLI_SetResult(cli, CLIS_TOOMANY); + VCLI_Out(cli, "Too many parameters"); + return; + } + show = av[n]; lfmt = 1; + } n = 0; VTAILQ_FOREACH(pl, &phead, list) { pp = pl->spec; - if (lfmt && strcmp(pp->name, av[2]) && strcmp("-l", av[2])) + if (lfmt && show != NULL && strcmp(pp->name, show)) continue; - if (pp->func == tweak_alias && !lfmt) + if (pp->func == tweak_alias && show == NULL) continue; - if (pp->func == tweak_alias && strcmp(pp->name, av[2])) + if (pp->func == tweak_alias && strcmp(pp->name, show)) continue; n++; @@ -333,9 +346,9 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "\n\n"); } } - if (av[2] != NULL && lfmt && strcmp(av[2], "-l") && n == 0) { + if (show != NULL && n == 0) { VCLI_SetResult(cli, CLIS_PARAM); - VCLI_Out(cli, "Unknown parameter \"%s\".", av[2]); + VCLI_Out(cli, "Unknown parameter \"%s\".", show); } VSB_destroy(&vsb); } @@ -372,6 +385,11 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) } if (strcmp(av[i], "-j") == 0) continue; + if (show != NULL) { + VCLI_SetResult(cli, CLIS_TOOMANY); + VCLI_Out(cli, "Too many parameters"); + return; + } show = av[i]; } diff --git a/bin/varnishtest/tests/b00042.vtc b/bin/varnishtest/tests/b00042.vtc index 6c338ae51..02a969082 100644 --- a/bin/varnishtest/tests/b00042.vtc +++ b/bin/varnishtest/tests/b00042.vtc @@ -40,3 +40,5 @@ varnish v1 -clijson "param.show -j changed" varnish v1 -clijson "param.show -j" varnish v1 -clierr "106" "param.show -j -l" varnish v1 -clierr "106" "param.show -j fofofofo" +varnish v1 -clierr "105" "param.show debug debug" +varnish v1 -clierr "105" "param.show -j debug debug" diff --git a/bin/varnishtest/tests/u00017.vtc b/bin/varnishtest/tests/u00017.vtc index a7fa82598..86e6e018b 100644 --- a/bin/varnishtest/tests/u00017.vtc +++ b/bin/varnishtest/tests/u00017.vtc @@ -13,7 +13,7 @@ varnish v1 -vcl+backend { } } -start -varnish v1 -cliok "param.show vsl_mask +Debug" +varnish v1 -cliok "param.set vsl_mask +Debug" client c1 { txreq From dridi.boukelmoune at gmail.com Tue Dec 14 13:08:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 14 Dec 2021 13:08:07 +0000 (UTC) Subject: [master] d4e54f925 varnishtest: Polish includes Message-ID: <20211214130808.12AEF117EB1@lists.varnish-cache.org> commit d4e54f9250e393a8c3405a635fd9b574f477908d Author: Dridi Boukelmoune Date: Tue Dec 14 14:06:41 2021 +0100 varnishtest: Polish includes diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 9dccb70bb..dc05e2eaa 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -31,6 +31,7 @@ #include "config.h" #include +#include #include #include @@ -41,8 +42,6 @@ #include #include #include -#include -#include #include "vtc.h" From dridi.boukelmoune at gmail.com Tue Dec 14 14:45:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 14 Dec 2021 14:45:07 +0000 (UTC) Subject: [master] 370ca28c3 param: We have a generic string tweak Message-ID: <20211214144507.51F0E11A948@lists.varnish-cache.org> commit 370ca28c36b7271ead7b23609f4b3de929a4a842 Author: Dridi Boukelmoune Date: Tue Dec 14 15:41:56 2021 +0100 param: We have a generic string tweak I checked the git history to understand this comment. diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index 526fcf64e..a385263c6 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -378,7 +378,6 @@ tweak_string(struct vsb *vsb, const struct parspec *par, const char *arg) char **p = TRUST_ME(par->priv); AN(p); - /* XXX should have tweak_generic_string */ if (arg == NULL) { VSB_quote(vsb, *p, -1, 0); } else if (arg == JSON_FMT) { From dridi.boukelmoune at gmail.com Tue Dec 14 16:02:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 14 Dec 2021 16:02:06 +0000 (UTC) Subject: [master] 82be6f46a param: Plug leak spotted by lsan Message-ID: <20211214160206.B71FB11CBAD@lists.varnish-cache.org> commit 82be6f46a73a99bff56e51140e138c569f34ff36 Author: Dridi Boukelmoune Date: Tue Dec 14 17:01:03 2021 +0100 param: Plug leak spotted by lsan diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 4070ddb42..d023b6e72 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -264,6 +264,7 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) if (show != NULL) { VCLI_SetResult(cli, CLIS_TOOMANY); VCLI_Out(cli, "Too many parameters"); + VSB_destroy(&vsb); return; } show = av[n]; @@ -388,6 +389,7 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) if (show != NULL) { VCLI_SetResult(cli, CLIS_TOOMANY); VCLI_Out(cli, "Too many parameters"); + VSB_destroy(&vsb); return; } show = av[i]; From dridi.boukelmoune at gmail.com Tue Dec 14 16:20:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 14 Dec 2021 16:20:07 +0000 (UTC) Subject: [master] f9a802fa2 Revert "param: Plug leak spotted by lsan" Message-ID: <20211214162007.9C0A545D6@lists.varnish-cache.org> commit f9a802fa26e143175bcf253212c3284299e83d4d Author: Dridi Boukelmoune Date: Tue Dec 14 17:17:24 2021 +0100 Revert "param: Plug leak spotted by lsan" This reverts commit 82be6f46a73a99bff56e51140e138c569f34ff36. diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index d023b6e72..4070ddb42 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -264,7 +264,6 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) if (show != NULL) { VCLI_SetResult(cli, CLIS_TOOMANY); VCLI_Out(cli, "Too many parameters"); - VSB_destroy(&vsb); return; } show = av[n]; @@ -389,7 +388,6 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) if (show != NULL) { VCLI_SetResult(cli, CLIS_TOOMANY); VCLI_Out(cli, "Too many parameters"); - VSB_destroy(&vsb); return; } show = av[i]; From dridi.boukelmoune at gmail.com Tue Dec 14 16:20:07 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 14 Dec 2021 16:20:07 +0000 (UTC) Subject: [master] 4706fc1b9 param: Plug leak spotted by lsan, take 2 Message-ID: <20211214162007.AEE2F45DA@lists.varnish-cache.org> commit 4706fc1b9406c4ae1425b82c636863b8db89b218 Author: Dridi Boukelmoune Date: Tue Dec 14 17:18:07 2021 +0100 param: Plug leak spotted by lsan, take 2 diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 4070ddb42..7cfebcc20 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -248,8 +248,6 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) struct vsb *vsb; const char *show = NULL; - vsb = VSB_new_auto(); - AN(vsb); (void)priv; for (n = 2; av[n] != NULL; n++) { @@ -270,6 +268,9 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) lfmt = 1; } + vsb = VSB_new_auto(); + AN(vsb); + n = 0; VTAILQ_FOREACH(pl, &phead, list) { pp = pl->spec; From dridi.boukelmoune at gmail.com Wed Dec 15 16:45:09 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 15 Dec 2021 16:45:09 +0000 (UTC) Subject: [master] 948cf26de doc: Sort VCL variables alphabetically Message-ID: <20211215164509.C781B6F01@lists.varnish-cache.org> commit 948cf26deb09848aade89d7f0c1f7e7a669f592a Author: Dridi Boukelmoune Date: Wed Dec 15 17:17:07 2021 +0100 doc: Sort VCL variables alphabetically They are grouped by categories and that hasn't changed, and the order of groups haven't changed. All occurrences of foo.* variables are sorted alphabetically instead of approximately by relationship between each other. Inside the first group, variables are now ordered based on the PROXY protocol diagram: - client - server - remote - local A note was added and is hopefully visible enough to maintain this order. You can verify that nothing changed: $ COMMIT= $ git show $COMMIT~:doc/sphinx/reference/vcl_var.rst | sed '/^$/d' | sort | sha1sum 3400130e88c0456b3bc779b9dfeeff09e130efa3 $ git show ${COMMIT}:doc/sphinx/reference/vcl_var.rst | sed '/^$/d ; /.. NOTE:/d' | sort | sha1sum 3400130e88c0456b3bc779b9dfeeff09e130efa3 Use whatever alternative to sha1sum your system may provide. diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 02f71001f..049c1f3cf 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -3,6 +3,8 @@ SPDX-License-Identifier: BSD-2-Clause See LICENSE file for full text of license +.. NOTE: please maintain lexicographic order of foo.* variable names + .. _vcl_variables: @@ -27,65 +29,6 @@ With PROXY protocol:: CLIENT ------------ PROXY ------------ VARNISHD -local.ip - - Type: IP - - Readable from: client, backend - - The IP address (and port number) of the local end of the - TCP connection, for instance ``192.168.1.1:81`` - - If the connection is a UNIX domain socket, the value - will be ``0.0.0.0:0`` - -local.endpoint ``VCL >= 4.1`` - - Type: STRING - - Readable from: client, backend - - The address of the '-a' socket the session was accepted on. - - If the argument was ``-a foo=:81`` this would be ":81" - - -local.socket ``VCL >= 4.1`` - - Type: STRING - - Readable from: client, backend - - The name of the '-a' socket the session was accepted on. - - If the argument was ``-a foo=:81`` this would be "foo". - - Note that all '-a' gets a default name on the form ``a%d`` - if no name is provided. - -remote.ip - - Type: IP - - Readable from: client, backend - - The IP address of the other end of the TCP connection. - This can either be the clients IP, or the outgoing IP - of a proxy server. - - If the connection is a UNIX domain socket, the value - will be ``0.0.0.0:0`` - -client.ip - - Type: IP - - Readable from: client, backend - - - The client's IP address, either the same as ``remote.ip`` - or what the PROXY protocol told us. - client.identity Type: STRING @@ -103,15 +46,14 @@ client.identity header. -server.ip +client.ip Type: IP Readable from: client, backend - The IP address of the socket on which the client - connection was received, either the same as ``server.ip`` + The client's IP address, either the same as ``remote.ip`` or what the PROXY protocol told us. @@ -136,126 +78,127 @@ server.identity If an ``-i`` parameter is not passed to varnishd, the return value from `gethostname(3)` system function will be used. -req and req_top -~~~~~~~~~~~~~~~ -These variables describe the present request, and when ESI:include -requests are being processed, req_top points to the request received -from the client. +server.ip -req + Type: IP - Type: HTTP + Readable from: client, backend - Readable from: client + The IP address of the socket on which the client + connection was received, either the same as ``server.ip`` + or what the PROXY protocol told us. - The entire request HTTP data structure. - Mostly useful for passing to VMODs. +remote.ip -req.method + Type: IP - Type: STRING + Readable from: client, backend - Readable from: client + The IP address of the other end of the TCP connection. + This can either be the clients IP, or the outgoing IP + of a proxy server. - Writable from: client + If the connection is a UNIX domain socket, the value + will be ``0.0.0.0:0`` - The request method (e.g. "GET", "HEAD", ...) +local.endpoint ``VCL >= 4.1`` + Type: STRING -req.hash + Readable from: client, backend - Type: BLOB + The address of the '-a' socket the session was accepted on. - Readable from: vcl_hit, vcl_miss, vcl_pass, vcl_purge, vcl_deliver + If the argument was ``-a foo=:81`` this would be ":81" - The hash key of this request. - Mostly useful for passing to VMODs, but can also be useful - for debugging hit/miss status. +local.ip + Type: IP -req.url + Readable from: client, backend - Type: STRING + The IP address (and port number) of the local end of the + TCP connection, for instance ``192.168.1.1:81`` - Readable from: client + If the connection is a UNIX domain socket, the value + will be ``0.0.0.0:0`` - Writable from: client +local.socket ``VCL >= 4.1`` - The requested URL, for instance "/robots.txt". + Type: STRING + Readable from: client, backend -req.proto ``VCL <= 4.0`` + The name of the '-a' socket the session was accepted on. - Type: STRING + If the argument was ``-a foo=:81`` this would be "foo". - Readable from: client + Note that all '-a' gets a default name on the form ``a%d`` + if no name is provided. - Writable from: client - The HTTP protocol version used by the client, usually "HTTP/1.1" - or "HTTP/2.0". +req and req_top +~~~~~~~~~~~~~~~ -req.proto ``VCL >= 4.1`` +These variables describe the present request, and when ESI:include +requests are being processed, req_top points to the request received +from the client. - Type: STRING +req + + Type: HTTP Readable from: client - The HTTP protocol version used by the client, usually "HTTP/1.1" - or "HTTP/2.0". + + The entire request HTTP data structure. + Mostly useful for passing to VMODs. -req.http.* +req.backend_hint - Type: HEADER + Type: BACKEND Readable from: client Writable from: client - Unsetable from: client - - - The headers of request, things like ``req.http.date``. - - The RFCs allow multiple headers with the same name, and both - ``set`` and ``unset`` will remove *all* headers with the name - given. - - The header name ``*`` is a VCL symbol and as such cannot, for - example, start with a numeral. To work with valid header that - can't be represented as VCL symbols it is possible to quote the - name, like ``req.http."grammatically.valid"``. None of the HTTP - headers present in IANA registries need to be quoted, so the - quoted syntax is discouraged but available for interoperability. + Set bereq.backend to this if we attempt to fetch. + When set to a director, reading this variable returns + an actual backend if the director has resolved immediately, + or the director otherwise. + When used in string context, returns the name of the director + or backend, respectively. -req.restarts +req.can_gzip - Type: INT + Type: BOOL Readable from: client - - A count of how many times this request has been restarted. + True if the client provided ``gzip`` or ``x-gzip`` in the + ``Accept-Encoding`` header. -req.storage +req.esi ``VCL <= 4.0`` - Type: STEVEDORE + Type: BOOL Readable from: client Writable from: client - - The storage backend to use to save this request body. + Set to ``false`` to disable ESI processing + regardless of any value in beresp.do_esi. Defaults + to ``true``. This variable is replaced by ``resp.do_esi`` + in VCL 4.1. req.esi_level @@ -266,17 +209,6 @@ req.esi_level A count of how many levels of ESI requests we're currently at. -req.ttl - - Type: DURATION - - Readable from: client - - Writable from: client - - - Upper limit on the object age for cache lookups to return hit. - req.grace @@ -293,51 +225,33 @@ req.grace grace value will be used as the object's grace. -req.xid - - Type: STRING - - Readable from: client - - Unique ID of this request. +req.hash -req.esi ``VCL <= 4.0`` + Type: BLOB - Type: BOOL + Readable from: vcl_hit, vcl_miss, vcl_pass, vcl_purge, vcl_deliver - Readable from: client - Writable from: client + The hash key of this request. + Mostly useful for passing to VMODs, but can also be useful + for debugging hit/miss status. - Set to ``false`` to disable ESI processing - regardless of any value in beresp.do_esi. Defaults - to ``true``. This variable is replaced by ``resp.do_esi`` - in VCL 4.1. -req.can_gzip +req.hash_always_miss Type: BOOL Readable from: client - True if the client provided ``gzip`` or ``x-gzip`` in the - ``Accept-Encoding`` header. - - -req.backend_hint - - Type: BACKEND + Writable from: client - Readable from: client + Default: ``false``. - Writable from: client + Force a cache miss for this request, even if perfectly + good matching objects are in the cache. - Set bereq.backend to this if we attempt to fetch. - When set to a director, reading this variable returns - an actual backend if the director has resolved immediately, - or the director otherwise. - When used in string context, returns the name of the director - or backend, respectively. + This is useful to force-update the cache without invalidating + existing entries in case the fetch fails. req.hash_ignore_busy @@ -377,23 +291,32 @@ req.hash_ignore_vary Use with caution. -req.hash_always_miss +req.http.* - Type: BOOL + Type: HEADER Readable from: client Writable from: client - Default: ``false``. - - Force a cache miss for this request, even if perfectly - good matching objects are in the cache. + Unsetable from: client - This is useful to force-update the cache without invalidating - existing entries in case the fetch fails. -req.is_hitmiss + The headers of request, things like ``req.http.date``. + + The RFCs allow multiple headers with the same name, and both + ``set`` and ``unset`` will remove *all* headers with the name + given. + + The header name ``*`` is a VCL symbol and as such cannot, for + example, start with a numeral. To work with valid header that + can't be represented as VCL symbols it is possible to quote the + name, like ``req.http."grammatically.valid"``. None of the HTTP + headers present in IANA registries need to be quoted, so the + quoted syntax is discouraged but available for interoperability. + + +req.is_hitmiss Type: BOOL @@ -401,6 +324,7 @@ req.is_hitmiss If this request resulted in a hitmiss + req.is_hitpass Type: BOOL @@ -409,210 +333,221 @@ req.is_hitpass If this request resulted in a hitpass -req.time - Type: TIME +req.method + + Type: STRING Readable from: client - The time when the request was fully received, remains constant - across restarts. + Writable from: client -req_top.method + + The request method (e.g. "GET", "HEAD", ...) + + +req.proto ``VCL <= 4.0`` Type: STRING Readable from: client - The request method of the top-level request in a tree - of ESI requests. (e.g. "GET", "HEAD"). - Identical to req.method in non-ESI requests. + Writable from: client + The HTTP protocol version used by the client, usually "HTTP/1.1" + or "HTTP/2.0". -req_top.url +req.proto ``VCL >= 4.1`` Type: STRING Readable from: client - The requested URL of the top-level request in a tree - of ESI requests. - Identical to req.url in non-ESI requests. + The HTTP protocol version used by the client, usually "HTTP/1.1" + or "HTTP/2.0". -req_top.http.* +req.restarts - Type: HEADER + Type: INT Readable from: client - HTTP headers of the top-level request in a tree of ESI requests. - Identical to req.http. in non-ESI requests. - See ``req.http.*`` for general notes. + A count of how many times this request has been restarted. -req_top.proto +req.storage - Type: STRING + Type: STEVEDORE Readable from: client - HTTP protocol version of the top-level request in a tree of - ESI requests. - Identical to req.proto in non-ESI requests. + Writable from: client -req_top.time + + The storage backend to use to save this request body. + + +req.time Type: TIME Readable from: client - The time when the top-level request was fully received, - remains constant across restarts. + The time when the request was fully received, remains constant + across restarts. -bereq -~~~~~ -This is the request we send to the backend, it is built from the -clients ``req.*`` fields by filtering out "per-hop" fields which -should not be passed along (``Connection:``, ``Range:`` and similar). +req.ttl -Slightly more fields are allowed through for ``pass` fetches -than for `miss` fetches, for instance ``Range``. + Type: DURATION -bereq + Readable from: client - Type: HTTP + Writable from: client - Readable from: backend - The entire backend request HTTP data structure. - Mostly useful as argument to VMODs. + Upper limit on the object age for cache lookups to return hit. -bereq.xid +req.url Type: STRING - Readable from: vcl_pipe, backend + Readable from: client - Unique ID of this request. + Writable from: client -bereq.retries + The requested URL, for instance "/robots.txt". - Type: INT - Readable from: backend +req.xid - A count of how many times this request has been retried. + Type: STRING + Readable from: client -bereq.backend + Unique ID of this request. - Type: BACKEND - Readable from: vcl_pipe, backend +req_top.http.* - Writable from: vcl_pipe, backend + Type: HEADER - This is the backend or director we attempt to fetch from. - When set to a director, reading this variable returns - an actual backend if the director has resolved immediately, - or the director otherwise. - When used in string context, returns the name of the director - or backend, respectively. + Readable from: client + HTTP headers of the top-level request in a tree of ESI requests. + Identical to req.http. in non-ESI requests. -bereq.body + See ``req.http.*`` for general notes. - Type: BODY - Unsetable from: vcl_backend_fetch +req_top.method - The request body. + Type: STRING - Unset will also remove ``bereq.http.Content-Length``. + Readable from: client -bereq.hash + The request method of the top-level request in a tree + of ESI requests. (e.g. "GET", "HEAD"). + Identical to req.method in non-ESI requests. - Type: BLOB - Readable from: vcl_pipe, backend +req_top.proto - The hash key of this request, a copy of ``req.hash``. + Type: STRING + Readable from: client -bereq.method + HTTP protocol version of the top-level request in a tree of + ESI requests. + Identical to req.proto in non-ESI requests. - Type: STRING - Readable from: vcl_pipe, backend +req_top.time - Writable from: vcl_pipe, backend + Type: TIME - The request type (e.g. "GET", "HEAD"). + Readable from: client - Regular (non-pipe, non-pass) fetches are always "GET" + The time when the top-level request was fully received, + remains constant across restarts. -bereq.url +req_top.url Type: STRING - Readable from: vcl_pipe, backend + Readable from: client - Writable from: vcl_pipe, backend + The requested URL of the top-level request in a tree + of ESI requests. + Identical to req.url in non-ESI requests. - The requested URL, copied from ``req.url`` +bereq +~~~~~ -bereq.proto ``VCL <= 4.0`` +This is the request we send to the backend, it is built from the +clients ``req.*`` fields by filtering out "per-hop" fields which +should not be passed along (``Connection:``, ``Range:`` and similar). - Type: STRING +Slightly more fields are allowed through for ``pass` fetches +than for `miss` fetches, for instance ``Range``. - Readable from: vcl_pipe, backend +bereq - Writable from: vcl_pipe, backend + Type: HTTP - The HTTP protocol version, "HTTP/1.1" unless a pass or pipe - request has "HTTP/1.0" in ``req.proto`` + Readable from: backend -bereq.proto ``VCL >= 4.1`` + The entire backend request HTTP data structure. + Mostly useful as argument to VMODs. - Type: STRING + +bereq.backend + + Type: BACKEND Readable from: vcl_pipe, backend - The HTTP protocol version, "HTTP/1.1" unless a pass or pipe - request has "HTTP/1.0" in ``req.proto`` + Writable from: vcl_pipe, backend + This is the backend or director we attempt to fetch from. + When set to a director, reading this variable returns + an actual backend if the director has resolved immediately, + or the director otherwise. + When used in string context, returns the name of the director + or backend, respectively. -bereq.http.* - Type: HEADER +bereq.between_bytes_timeout - Readable from: vcl_pipe, backend + Type: DURATION - Writable from: vcl_pipe, backend + Readable from: backend - Unsetable from: vcl_pipe, backend + Writable from: backend - The headers to be sent to the backend. + Default: ``.between_bytes_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)`. - See ``req.http.*`` for general notes. + The time in seconds to wait between each received byte from the + backend. Not available in pipe mode. -bereq.uncacheable - Type: BOOL +bereq.body - Readable from: backend + Type: BODY + Unsetable from: vcl_backend_fetch - Indicates whether this request is uncacheable due to a - `pass` in the client side or a hit on an hit-for-pass object. + The request body. + Unset will also remove ``bereq.http.Content-Length``. bereq.connect_timeout @@ -646,20 +581,28 @@ bereq.first_byte_timeout from the backend. Not available in pipe mode. -bereq.between_bytes_timeout +bereq.hash - Type: DURATION + Type: BLOB - Readable from: backend + Readable from: vcl_pipe, backend - Writable from: backend + The hash key of this request, a copy of ``req.hash``. - Default: ``.between_bytes_timeout`` attribute from the - :ref:`backend_definition`, which defaults to the - ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)`. - The time in seconds to wait between each received byte from the - backend. Not available in pipe mode. +bereq.http.* + + Type: HEADER + + Readable from: vcl_pipe, backend + + Writable from: vcl_pipe, backend + + Unsetable from: vcl_pipe, backend + + The headers to be sent to the backend. + + See ``req.http.*`` for general notes. bereq.is_bgfetch @@ -672,6 +615,7 @@ bereq.is_bgfetch grace, and this fetch was kicked of in the background to get a fresh copy. + bereq.is_hitmiss Type: BOOL @@ -680,6 +624,7 @@ bereq.is_hitmiss If this backend request was caused by a hitmiss. + bereq.is_hitpass Type: BOOL @@ -688,92 +633,156 @@ bereq.is_hitpass If this backend request was caused by a hitpass. -bereq.time - Type: TIME +bereq.method - Readable from: backend + Type: STRING - The time when we started preparing the first backend request, - remains constant across retries. + Readable from: vcl_pipe, backend -beresp -~~~~~~ + Writable from: vcl_pipe, backend -The response received from the backend, one cache misses, the -store object is built from ``beresp``. + The request type (e.g. "GET", "HEAD"). -beresp + Regular (non-pipe, non-pass) fetches are always "GET" - Type: HTTP - Readable from: vcl_backend_response, vcl_backend_error +bereq.proto ``VCL <= 4.0`` - The entire backend response HTTP data structure, useful as - argument to VMOD functions. + Type: STRING -beresp.body + Readable from: vcl_pipe, backend - Type: BODY + Writable from: vcl_pipe, backend - Writable from: vcl_backend_error + The HTTP protocol version, "HTTP/1.1" unless a pass or pipe + request has "HTTP/1.0" in ``req.proto`` - For producing a synthetic body. +bereq.proto ``VCL >= 4.1`` -beresp.proto ``VCL <= 4.0`` + Type: STRING + + Readable from: vcl_pipe, backend + + The HTTP protocol version, "HTTP/1.1" unless a pass or pipe + request has "HTTP/1.0" in ``req.proto`` + + +bereq.retries + + Type: INT + + Readable from: backend + + A count of how many times this request has been retried. + + +bereq.time + + Type: TIME + + Readable from: backend + + The time when we started preparing the first backend request, + remains constant across retries. + + +bereq.uncacheable + + Type: BOOL + + Readable from: backend + + + Indicates whether this request is uncacheable due to a + `pass` in the client side or a hit on an hit-for-pass object. + + +bereq.url Type: STRING - Readable from: vcl_backend_response, vcl_backend_error + Readable from: vcl_pipe, backend - Writable from: vcl_backend_response, vcl_backend_error + Writable from: vcl_pipe, backend - The HTTP protocol version the backend replied with. + The requested URL, copied from ``req.url`` -beresp.proto ``VCL >= 4.1`` + +bereq.xid Type: STRING - Readable from: vcl_backend_response, vcl_backend_error + Readable from: vcl_pipe, backend - The HTTP protocol version the backend replied with. + Unique ID of this request. -beresp.status +beresp +~~~~~~ - Type: INT +The response received from the backend, one cache misses, the +store object is built from ``beresp``. + +beresp + + Type: HTTP Readable from: vcl_backend_response, vcl_backend_error - Writable from: vcl_backend_response, vcl_backend_error + The entire backend response HTTP data structure, useful as + argument to VMOD functions. - The HTTP status code returned by the server. +beresp.age - More information in the `HTTP response status`_ section. + Type: DURATION -beresp.reason + Readable from: vcl_backend_response, vcl_backend_error - Type: STRING + Default: Age header, or zero. + + The age of the object. + + +beresp.backend + + Type: BACKEND Readable from: vcl_backend_response, vcl_backend_error - Writable from: vcl_backend_response, vcl_backend_error + This is the backend we fetched from. If bereq.backend + was set to a director, this will be the backend selected + by the director. + When used in string context, returns its name. - The HTTP status message returned by the server. -beresp.http.* +beresp.backend.ip ``VCL <= 4.0`` - Type: HEADER + Type: IP + + Readable from: vcl_backend_response + + IP of the backend this response was fetched from. + + +beresp.backend.name + + Type: STRING Readable from: vcl_backend_response, vcl_backend_error - Writable from: vcl_backend_response, vcl_backend_error + Name of the backend this response was fetched from. + Same as beresp.backend. - Unsetable from: vcl_backend_response, vcl_backend_error - The HTTP headers returned from the server. +beresp.body + + Type: BODY + + Writable from: vcl_backend_error + + For producing a synthetic body. - See ``req.http.*`` for general notes. beresp.do_esi @@ -793,7 +802,8 @@ beresp.do_esi It is a VCL error to use beresp.do_esi after setting beresp.filters. -beresp.do_stream + +beresp.do_gunzip Type: BOOL @@ -801,17 +811,16 @@ beresp.do_stream Writable from: vcl_backend_response, vcl_backend_error - Default: ``true``. + Default: ``false``. - Deliver the object to the client while fetching the whole - object into varnish. + Set to ``true`` to gunzip the object while storing it in the + cache. - For uncacheable objects, storage for parts of the body which - have been sent to the client may get freed early, depending - on the storage engine used. + If ``http_gzip_support`` is disabled, setting this variable + has no effect. + + It is a VCL error to use beresp.do_gunzip after setting beresp.filters. - This variable has no effect if beresp.do_esi is true or when - the response body is empty. beresp.do_gzip @@ -830,7 +839,8 @@ beresp.do_gzip It is a VCL error to use beresp.do_gzip after setting beresp.filters. -beresp.do_gunzip + +beresp.do_stream Type: BOOL @@ -838,83 +848,106 @@ beresp.do_gunzip Writable from: vcl_backend_response, vcl_backend_error - Default: ``false``. + Default: ``true``. - Set to ``true`` to gunzip the object while storing it in the - cache. + Deliver the object to the client while fetching the whole + object into varnish. - If ``http_gzip_support`` is disabled, setting this variable - has no effect. + For uncacheable objects, storage for parts of the body which + have been sent to the client may get freed early, depending + on the storage engine used. - It is a VCL error to use beresp.do_gunzip after setting beresp.filters. + This variable has no effect if beresp.do_esi is true or when + the response body is empty. -beresp.was_304 - Type: BOOL +beresp.filters - Readable from: vcl_backend_response, vcl_backend_error + Type: STRING + Readable from: vcl_backend_response - When ``true`` this indicates that we got a 304 response - to our conditional fetch from the backend and turned - that into ``beresp.status = 200`` + Writable from: vcl_backend_response -beresp.uncacheable + List of Varnish Fetch Processor (VFP) filters the beresp.body + will be pulled through. The order left to right signifies + processing from backend to cache, iow the leftmost filter is + run first on the body as received from the backend after + decoding of any transfer encodings. - Type: BOOL + VFP Filters change the body before going into the cache and/or + being handed to the client side, where it may get processed + again by resp.filters. - Readable from: vcl_backend_response, vcl_backend_error + The following VFP filters exist in varnish-cache: - Writable from: vcl_backend_response, vcl_backend_error + * ``gzip``: compress a body using gzip - Inherited from bereq.uncacheable, see there. + * ``testgunzip``: Test if a body is valid gzip and refuse it + otherwise - Setting this variable makes the object uncacheable. + * ``gunzip``: Uncompress gzip content - This may may produce a hit-for-miss object in the cache. + * ``esi``: ESI-process plain text content - Clearing the variable has no effect and will log the warning - "Ignoring attempt to reset beresp.uncacheable". + * ``esi_gzip``: Save gzipped snippets for efficient + ESI-processing + This filter enables stitching together ESI from individually + gzipped fragments, saving processing power for + re-compression on the client side at the expense of some + compression efficiency. -beresp.ttl + Additional VFP filters are available from VMODs. - Type: DURATION + By default, beresp.filters is constructed as follows: - Readable from: vcl_backend_response, vcl_backend_error + * ``gunzip`` gets added for gzipped content if + ``beresp.do_gunzip`` or ``beresp.do_esi`` are true. - Writable from: vcl_backend_response, vcl_backend_error + * ``esi_gzip`` gets added if ``beresp.do_esi`` is true + together with ``beresp.do_gzip`` or content is already + compressed. - Default: Cache-Control ``s-maxage`` or ``max-age`` directives, - or a value computed from the Expires header's deadline, or the - ``default_ttl`` parameter. + * ``esi`` gets added if ``beresp.do_esi`` is true - The object's remaining time to live, in seconds. + * ``gzip`` gets added for uncompressed content if + ``beresp.do_gzip`` is true + * ``testgunzip`` gets added for compressed content if + ``beresp.do_gunzip`` is false. + + After beresp.filters is set, using any of the beforementioned + ``beresp.do_*`` switches is a VCL error. -beresp.age + +beresp.grace Type: DURATION Readable from: vcl_backend_response, vcl_backend_error - Default: Age header, or zero. + Writable from: vcl_backend_response, vcl_backend_error - The age of the object. + Default: Cache-Control ``stale-while-revalidate`` directive, + or ``default_grace`` parameter. + Set to a period to enable grace. -beresp.grace - Type: DURATION +beresp.http.* + + Type: HEADER Readable from: vcl_backend_response, vcl_backend_error Writable from: vcl_backend_response, vcl_backend_error - Default: Cache-Control ``stale-while-revalidate`` directive, - or ``default_grace`` parameter. + Unsetable from: vcl_backend_response, vcl_backend_error - Set to a period to enable grace. + The HTTP headers returned from the server. + + See ``req.http.*`` for general notes. beresp.keep @@ -936,35 +969,49 @@ beresp.keep requests to the backend to refresh them. -beresp.backend +beresp.proto ``VCL <= 4.0`` - Type: BACKEND + Type: STRING Readable from: vcl_backend_response, vcl_backend_error - This is the backend we fetched from. If bereq.backend - was set to a director, this will be the backend selected - by the director. - When used in string context, returns its name. + Writable from: vcl_backend_response, vcl_backend_error + The HTTP protocol version the backend replied with. -beresp.backend.name + +beresp.proto ``VCL >= 4.1`` Type: STRING Readable from: vcl_backend_response, vcl_backend_error - Name of the backend this response was fetched from. - Same as beresp.backend. + The HTTP protocol version the backend replied with. -beresp.backend.ip ``VCL <= 4.0`` +beresp.reason - Type: IP + Type: STRING - Readable from: vcl_backend_response + Readable from: vcl_backend_response, vcl_backend_error + + Writable from: vcl_backend_response, vcl_backend_error + + The HTTP status message returned by the server. + + +beresp.status + + Type: INT + + Readable from: vcl_backend_response, vcl_backend_error + + Writable from: vcl_backend_response, vcl_backend_error + + The HTTP status code returned by the server. + + More information in the `HTTP response status`_ section. - IP of the backend this response was fetched from. beresp.storage @@ -992,74 +1039,61 @@ beresp.storage_hint ``VCL <= 4.0`` Hint to Varnish that you want to save this object to a particular storage backend. -beresp.filters - Type: STRING +beresp.time - Readable from: vcl_backend_response + Type: TIME - Writable from: vcl_backend_response + Readable from: vcl_backend_response, vcl_backend_error - List of Varnish Fetch Processor (VFP) filters the beresp.body - will be pulled through. The order left to right signifies - processing from backend to cache, iow the leftmost filter is - run first on the body as received from the backend after - decoding of any transfer encodings. + When the backend headers were fully received just before + ``vcl_backend_response {}`` was entered, or when + ``vcl_backend_error {}`` was entered. - VFP Filters change the body before going into the cache and/or - being handed to the client side, where it may get processed - again by resp.filters. - The following VFP filters exist in varnish-cache: +beresp.ttl - * ``gzip``: compress a body using gzip + Type: DURATION - * ``testgunzip``: Test if a body is valid gzip and refuse it - otherwise + Readable from: vcl_backend_response, vcl_backend_error - * ``gunzip``: Uncompress gzip content + Writable from: vcl_backend_response, vcl_backend_error - * ``esi``: ESI-process plain text content + Default: Cache-Control ``s-maxage`` or ``max-age`` directives, + or a value computed from the Expires header's deadline, or the + ``default_ttl`` parameter. - * ``esi_gzip``: Save gzipped snippets for efficient - ESI-processing + The object's remaining time to live, in seconds. - This filter enables stitching together ESI from individually - gzipped fragments, saving processing power for - re-compression on the client side at the expense of some - compression efficiency. - Additional VFP filters are available from VMODs. +beresp.uncacheable - By default, beresp.filters is constructed as follows: + Type: BOOL - * ``gunzip`` gets added for gzipped content if - ``beresp.do_gunzip`` or ``beresp.do_esi`` are true. + Readable from: vcl_backend_response, vcl_backend_error - * ``esi_gzip`` gets added if ``beresp.do_esi`` is true - together with ``beresp.do_gzip`` or content is already - compressed. + Writable from: vcl_backend_response, vcl_backend_error - * ``esi`` gets added if ``beresp.do_esi`` is true + Inherited from bereq.uncacheable, see there. - * ``gzip`` gets added for uncompressed content if - ``beresp.do_gzip`` is true + Setting this variable makes the object uncacheable. - * ``testgunzip`` gets added for compressed content if - ``beresp.do_gunzip`` is false. + This may may produce a hit-for-miss object in the cache. - After beresp.filters is set, using any of the beforementioned - ``beresp.do_*`` switches is a VCL error. + Clearing the variable has no effect and will log the warning + "Ignoring attempt to reset beresp.uncacheable". -beresp.time - Type: TIME +beresp.was_304 + + Type: BOOL 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. + + When ``true`` this indicates that we got a 304 response + to our conditional fetch from the backend and turned + that into ``beresp.status = 200`` obj @@ -1067,35 +1101,34 @@ obj This is the object we found in cache. It cannot be modified. -obj.proto - - Type: STRING - - Readable from: vcl_hit - - The HTTP protocol version stored in the object. +obj.age + Type: DURATION -obj.status + Readable from: vcl_hit, vcl_deliver - Type: INT + The age of the object. - Readable from: vcl_hit +obj.can_esi - The HTTP status code stored in the object. + Type: BOOL - More information in the `HTTP response status`_ section. + Readable from: vcl_hit, vcl_deliver + If the object can be ESI processed, that is if setting + ``resp.do_esi`` or adding ``esi`` to ``resp.filters`` in + ``vcl_deliver {}`` would cause the response body to be ESI + processed. -obj.reason - Type: STRING +obj.grace - Readable from: vcl_hit + Type: DURATION + Readable from: vcl_hit, vcl_deliver - The HTTP reason phrase stored in the object. + The object's grace period in seconds. obj.hits @@ -1120,50 +1153,45 @@ obj.http.* See ``req.http.*`` for general notes. -obj.ttl + +obj.keep Type: DURATION Readable from: vcl_hit, vcl_deliver - The object's remaining time to live, in seconds. - - -obj.age + The object's keep period in seconds. - Type: DURATION - Readable from: vcl_hit, vcl_deliver +obj.proto - The age of the object. + Type: STRING + Readable from: vcl_hit -obj.grace + The HTTP protocol version stored in the object. - Type: DURATION - Readable from: vcl_hit, vcl_deliver +obj.reason - The object's grace period in seconds. + Type: STRING + Readable from: vcl_hit -obj.keep - Type: DURATION + The HTTP reason phrase stored in the object. - Readable from: vcl_hit, vcl_deliver - The object's keep period in seconds. +obj.status + Type: INT -obj.uncacheable + Readable from: vcl_hit - Type: BOOL - Readable from: vcl_deliver + The HTTP status code stored in the object. - Whether the object is uncacheable (pass, hit-for-pass or - hit-for-miss). + More information in the `HTTP response status`_ section. obj.storage @@ -1175,17 +1203,6 @@ obj.storage The storage backend where this object is stored. -obj.can_esi - - Type: BOOL - - Readable from: vcl_hit, vcl_deliver - - If the object can be ESI processed, that is if setting - ``resp.do_esi`` or adding ``esi`` to ``resp.filters`` in - ``vcl_deliver {}`` would cause the response body to be ESI - processed. - obj.time Type: TIME @@ -1196,6 +1213,26 @@ obj.time server which generated it. This will roughly be equivalent to ``now`` - ``obj.age``. + +obj.ttl + + Type: DURATION + + Readable from: vcl_hit, vcl_deliver + + The object's remaining time to live, in seconds. + + +obj.uncacheable + + Type: BOOL + + Readable from: vcl_deliver + + Whether the object is uncacheable (pass, hit-for-pass or + hit-for-miss). + + resp ~~~~ @@ -1214,6 +1251,7 @@ resp The entire response HTTP data structure, useful as argument to VMODs. + resp.body Type: BODY @@ -1222,53 +1260,25 @@ resp.body To produce a synthetic response body, for instance for errors. -resp.proto ``VCL <= 4.0`` - - Type: STRING - - Readable from: vcl_deliver, vcl_synth - - Writable from: vcl_deliver, vcl_synth - - The HTTP protocol version to use for the response. - -resp.proto ``VCL >= 4.1`` - - Type: STRING - - Readable from: vcl_deliver, vcl_synth - - The HTTP protocol version to use for the response. -resp.status +resp.do_esi ``VCL >= 4.1`` - Type: INT + Type: BOOL Readable from: vcl_deliver, vcl_synth Writable from: vcl_deliver, vcl_synth - The HTTP status code that will be returned. - - More information in the `HTTP response status`_ section. + Default: obj.can_esi - resp.status 200 will get changed into 304 by core code after - a return(deliver) from vcl_deliver for conditional requests - to cached content if validation succeeds. + This can be used to selectively disable ESI processing, even + though ESI parsing happened during fetch (see beresp.do_esi). + This is useful when Varnish caches peer with each other. - For the validation, first ``req.http.If-None-Match`` is - compared against ``resp.http.Etag``. If they compare equal - according to the rules for weak validation (see RFC7232), a - 304 is sent. + It is a VCL error to use resp.do_esi after setting resp.filters. - Secondly, ``req.http.If-Modified-Since`` is compared against - ``resp.http.Last-Modified`` or, if it is unset, against the - point in time when the object was last modified based on the - ``Date`` and ``Age`` headers received with the backend - response which created the object. If the object has not been - modified based on that comparison, a 304 is sent. -resp.reason +resp.filters Type: STRING @@ -1276,7 +1286,16 @@ resp.reason Writable from: vcl_deliver, vcl_synth - The HTTP status message that will be returned. + List of VDP filters the resp.body will be pushed through. + + Before resp.filters is set, the value read will be the default + filter list as determined by varnish based on resp.do_esi and + request headers. + + After resp.filters is set, changing any of the conditions + which otherwise determine the filter selection will have no + effiect. Using resp.do_esi is an error once resp.filters is + set. resp.http.* @@ -1293,33 +1312,38 @@ resp.http.* See ``req.http.*`` for general notes. -resp.do_esi ``VCL >= 4.1`` + +resp.is_streaming Type: BOOL Readable from: vcl_deliver, vcl_synth - Writable from: vcl_deliver, vcl_synth + Returns true when the response will be streamed + while being fetched from the backend. - Default: obj.can_esi - This can be used to selectively disable ESI processing, even - though ESI parsing happened during fetch (see beresp.do_esi). - This is useful when Varnish caches peer with each other. +resp.proto ``VCL <= 4.0`` - It is a VCL error to use resp.do_esi after setting resp.filters. + Type: STRING + Readable from: vcl_deliver, vcl_synth -resp.is_streaming + Writable from: vcl_deliver, vcl_synth - Type: BOOL + The HTTP protocol version to use for the response. + + +resp.proto ``VCL >= 4.1`` + + Type: STRING Readable from: vcl_deliver, vcl_synth - Returns true when the response will be streamed - while being fetched from the backend. + The HTTP protocol version to use for the response. -resp.filters + +resp.reason Type: STRING @@ -1327,16 +1351,37 @@ resp.filters Writable from: vcl_deliver, vcl_synth - List of VDP filters the resp.body will be pushed through. + The HTTP status message that will be returned. - Before resp.filters is set, the value read will be the default - filter list as determined by varnish based on resp.do_esi and - request headers. - After resp.filters is set, changing any of the conditions - which otherwise determine the filter selection will have no - effiect. Using resp.do_esi is an error once resp.filters is - set. +resp.status + + Type: INT + + Readable from: vcl_deliver, vcl_synth + + Writable from: vcl_deliver, vcl_synth + + The HTTP status code that will be returned. + + More information in the `HTTP response status`_ section. + + resp.status 200 will get changed into 304 by core code after + a return(deliver) from vcl_deliver for conditional requests + to cached content if validation succeeds. + + For the validation, first ``req.http.If-None-Match`` is + compared against ``resp.http.Etag``. If they compare equal + according to the rules for weak validation (see RFC7232), a + 304 is sent. + + Secondly, ``req.http.If-Modified-Since`` is compared against + ``resp.http.Last-Modified`` or, if it is unset, against the + point in time when the object was last modified based on the + ``Date`` and ``Age`` headers received with the backend + response which created the object. If the object has not been + modified based on that comparison, a 304 is sent. + resp.time @@ -1347,6 +1392,7 @@ resp.time The time when we started preparing the response, just before entering ``vcl_synth {}`` or ``vcl_deliver {}``. + Special variables ~~~~~~~~~~~~~~~~~ @@ -1362,6 +1408,7 @@ now When converted to STRING in expressions it returns a formatted timestamp like ``Tue, 20 Feb 2018 09:30:31 GMT`` + sess ~~~~ @@ -1371,15 +1418,20 @@ transactions may take place. It may comprise the traffic over an HTTP/1 keep-alive connection, or the multiplexed traffic over an HTTP/2 connection. -sess.xid ``VCL >= 4.1`` +sess.idle_send_timeout - Type: STRING + Type: DURATION - Readable from: client, backend + Readable from: client - Unique ID of this session. + Writable from: client + + Send timeout for individual pieces of data on client + connections, defaults to the ``idle_send_timeout`` parameter, + see :ref:`varnishd(1)` -sess.timeout_idle + +sess.send_timeout Type: DURATION @@ -1387,10 +1439,11 @@ sess.timeout_idle Writable from: client - Idle timeout for this session, defaults to the - ``timeout_idle`` parameter, see :ref:`varnishd(1)` + Total timeout for ordinary HTTP1 responses, defaults to the + ``send_timeout`` parameter, see :ref:`varnishd(1)` -sess.timeout_linger + +sess.timeout_idle Type: DURATION @@ -1398,10 +1451,11 @@ sess.timeout_linger Writable from: client - Linger timeout for this session, defaults to the - ``timeout_linger`` parameter, see :ref:`varnishd(1)` + Idle timeout for this session, defaults to the + ``timeout_idle`` parameter, see :ref:`varnishd(1)` -sess.send_timeout + +sess.timeout_linger Type: DURATION @@ -1409,20 +1463,18 @@ sess.send_timeout Writable from: client - Total timeout for ordinary HTTP1 responses, defaults to the - ``send_timeout`` parameter, see :ref:`varnishd(1)` + Linger timeout for this session, defaults to the + ``timeout_linger`` parameter, see :ref:`varnishd(1)` -sess.idle_send_timeout - Type: DURATION +sess.xid ``VCL >= 4.1`` - Readable from: client + Type: STRING - Writable from: client + Readable from: client, backend + + Unique ID of this session. - Send timeout for individual pieces of data on client - connections, defaults to the ``idle_send_timeout`` parameter, - see :ref:`varnishd(1)` storage ~~~~~~~ @@ -1438,24 +1490,24 @@ storage..free_space the malloc stevedore. -storage..used_space +storage..happy - Type: BYTES + Type: BOOL Readable from: client, backend - Used space in the named stevedore. Only available for the malloc - stevedore. + Health status for the named stevedore. Not available in any of the + current stevedores. -storage..happy +storage..used_space - Type: BOOL + Type: BYTES Readable from: client, backend - Health status for the named stevedore. Not available in any of the - current stevedores. + Used space in the named stevedore. Only available for the malloc + stevedore. From dridi.boukelmoune at gmail.com Thu Dec 16 07:13:05 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Dec 2021 07:13:05 +0000 (UTC) Subject: [master] b2914a121 vrt: Polish changelog Message-ID: <20211216071305.75D3511302D@lists.varnish-cache.org> commit b2914a1217169383da4b4b68c00377ec80d0ccaa Author: Dridi Boukelmoune Date: Thu Dec 16 07:40:38 2021 +0100 vrt: Polish changelog diff --git a/include/vrt.h b/include/vrt.h index f7a1d31e1..f57398280 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -54,8 +54,8 @@ * binary/load-time compatible, increment MAJOR version * * Next (2021-03-15) - * VRT_Assign_Backend added - * VRT_StaticDirector added + * VRT_Assign_Backend() added + * VRT_StaticDirector() added * enum lbody_e changed * - previous enum lbody_e values are defined as macros * The following functions changed to take `const char *, BODY`: From nils.goroll at uplex.de Sat Dec 18 14:02:08 2021 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 18 Dec 2021 14:02:08 +0000 (UTC) Subject: [master] 473ca493c fix sml_iterator prototype Message-ID: <20211218140208.7AF32106A01@lists.varnish-cache.org> commit 473ca493c9ccd034c144bf1aa4aed3a8e5c2a100 Author: Nils Goroll Date: Sat Dec 18 15:01:20 2021 +0100 fix sml_iterator prototype diff --git a/bin/varnishd/storage/storage_simple.c b/bin/varnishd/storage/storage_simple.c index c5c335848..429ef4f96 100644 --- a/bin/varnishd/storage/storage_simple.c +++ b/bin/varnishd/storage/storage_simple.c @@ -273,7 +273,7 @@ sml_objfree(struct worker *wrk, struct objcore *oc) wrk->stats->n_object--; } -static int v_matchproto_(objiterate_f) +static int v_matchproto_(objiterator_f) sml_iterator(struct worker *wrk, struct objcore *oc, void *priv, objiterate_f *func, int final) { From phk at FreeBSD.org Sun Dec 19 16:18:06 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Sun, 19 Dec 2021 16:18:06 +0000 (UTC) Subject: [master] a8f1e0bf6 typo Message-ID: <20211219161806.C93E310DD38@lists.varnish-cache.org> commit a8f1e0bf678abfa4e3e379e5819dc4f105a6d439 Author: Guillaume Quintard Date: Sat Dec 18 20:06:25 2021 -0800 typo diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index a6fff9d25..c1739c45b 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -1076,7 +1076,7 @@ vsl_catchup(struct varnish *v) * * \-errvcl STRING1 STRING2 * Load STRING2 as VCL, expecting it to fail, and Varnish to send an - * error string matching STRING2 + * error string matching STRING1 * * \-jail STRING * Look at ``man varnishd`` (-j) for more information. From phk at FreeBSD.org Sun Dec 19 18:14:04 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Sun, 19 Dec 2021 18:14:04 +0000 (UTC) Subject: [master] 7cd22d4a7 Add `req.transport` which returns "HTTP/1" or "HTTP/2" as appropriate. Message-ID: <20211219181404.DCF4311109D@lists.varnish-cache.org> commit 7cd22d4a769e8b4d7f4b12fe584c85b0afd92c7a Author: Poul-Henning Kamp Date: Sun Dec 19 17:40:23 2021 +0000 Add `req.transport` which returns "HTTP/1" or "HTTP/2" as appropriate. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index fd86f4835..5232f2a7a 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -800,9 +800,9 @@ XPORT_Init(void) ASSERT_MGT(); - XPORT_Register(&PROXY_transport); - XPORT_Register(&HTTP1_transport); - XPORT_Register(&H2_transport); +#define TRANSPORT_MACRO(name) XPORT_Register(&name##_transport); + TRANSPORTS +#undef TRANSPORT_MACRO } const struct transport * diff --git a/bin/varnishd/cache/cache_transport.h b/bin/varnishd/cache/cache_transport.h index 36502911a..6815ce446 100644 --- a/bin/varnishd/cache/cache_transport.h +++ b/bin/varnishd/cache/cache_transport.h @@ -69,9 +69,15 @@ struct transport { VTAILQ_ENTRY(transport) list; }; -extern struct transport PROXY_transport; -extern struct transport HTTP1_transport; -extern struct transport H2_transport; +#define TRANSPORTS \ + TRANSPORT_MACRO(PROXY) \ + TRANSPORT_MACRO(HTTP1) \ + TRANSPORT_MACRO(HTTP2) + +#define TRANSPORT_MACRO(name) extern struct transport name##_transport; +TRANSPORTS +#undef TRANSPORT_MACRO + htc_complete_f H2_prism_complete; void H2_PU_Sess(struct worker *, struct sess *, struct req *); void H2_OU_Sess(struct worker *, struct sess *, struct req *); diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index d80b96526..8d2da90ca 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -35,6 +35,7 @@ #include #include "cache_varnishd.h" +#include "cache_transport.h" #include "common/heritage.h" #include "vcl.h" @@ -634,6 +635,18 @@ VRT_r_bereq_retries(VRT_CTX) return (ctx->bo->retries); } +/*--------------------------------------------------------------------*/ + +VCL_STRING +VRT_r_req_transport(VRT_CTX) +{ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + + CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(ctx->req->transport, TRANSPORT_MAGIC); + return (ctx->req->transport->name); +} + /*-------------------------------------------------------------------- * In exp.*: * t_origin is absolute diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index df5d4bc2e..f2d238769 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -677,7 +677,7 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) h2->new_req = req; req->sp = h2->sess; - req->transport = &H2_transport; + req->transport = &HTTP2_transport; req->t_first = VTIM_real(); req->t_req = VTIM_real(); diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index b260ffc59..1740d2a0a 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -278,7 +278,7 @@ h2_ou_session(struct worker *wrk, struct h2_sess *h2, /* Start req thread */ r2 = h2_new_req(h2, 1, req); - req->transport = &H2_transport; + req->transport = &HTTP2_transport; assert(req->req_step == R_STP_TRANSPORT); req->task->func = h2_do_req; req->task->priv = req; @@ -317,7 +317,7 @@ H2_PU_Sess(struct worker *wrk, struct sess *sp, struct req *req) { VSLb(req->vsl, SLT_Debug, "H2 Prior Knowledge Upgrade"); req->err_code = H2_PU_MARKER; - SES_SetTransport(wrk, sp, req, &H2_transport); + SES_SetTransport(wrk, sp, req, &HTTP2_transport); } void @@ -325,7 +325,7 @@ H2_OU_Sess(struct worker *wrk, struct sess *sp, struct req *req) { VSLb(req->vsl, SLT_Debug, "H2 Optimistic Upgrade"); req->err_code = H2_OU_MARKER; - SES_SetTransport(wrk, sp, req, &H2_transport); + SES_SetTransport(wrk, sp, req, &HTTP2_transport); } static void v_matchproto_(task_func_t) @@ -349,7 +349,7 @@ h2_new_session(struct worker *wrk, void *arg) if (wrk->wpriv->vcl) VCL_Rel(&wrk->wpriv->vcl); - assert(req->transport == &H2_transport); + assert(req->transport == &HTTP2_transport); assert (req->err_code == H2_PU_MARKER || req->err_code == H2_OU_MARKER); @@ -438,8 +438,8 @@ h2_new_session(struct worker *wrk, void *arg) wrk->vsl = NULL; } -struct transport H2_transport = { - .name = "H2", +struct transport HTTP2_transport = { + .name = "HTTP/2", .magic = TRANSPORT_MAGIC, .deliver = h2_deliver, .minimal_response = h2_minimal_response, diff --git a/bin/varnishtest/tests/b00002.vtc b/bin/varnishtest/tests/b00002.vtc index ade1169d3..c3feb0722 100644 --- a/bin/varnishtest/tests/b00002.vtc +++ b/bin/varnishtest/tests/b00002.vtc @@ -15,6 +15,7 @@ varnish v1 -arg "-sTransient=default,1m" -vcl+backend { } sub vcl_deliver { set resp.http.o_uncacheable = obj.uncacheable; + set resp.http.xport = req.transport; } } -start @@ -36,6 +37,7 @@ client c1 { expect resp.http.connection == close expect resp.http.x-ttl == 0.000 expect resp.http.o_uncacheable == true + expect resp.http.xport == HTTP/1 } -run varnish v1 -expect n_object == 0 diff --git a/bin/varnishtest/tests/o00001.vtc b/bin/varnishtest/tests/o00001.vtc index ebe38bcb9..03c898996 100644 --- a/bin/varnishtest/tests/o00001.vtc +++ b/bin/varnishtest/tests/o00001.vtc @@ -61,6 +61,7 @@ varnish v1 -proto "PROXY" -vcl+backend { set resp.http.sp = std.port(server.ip); set resp.http.fc = (client.ip ~ fwd_client); set resp.http.fs = (server.ip ~ fwd_server); + set resp.http.xport = req.transport; } } -start @@ -87,6 +88,8 @@ client c1 { expect resp.http.si == "${v1_addr}" expect resp.http.sp == "${v1_port}" expect resp.http.ci == "${localhost}" + # Transport is HTTP/1, even though proxy is used + expect resp.http.xport == HTTP/1 } -run delay .1 diff --git a/bin/varnishtest/tests/t02000.vtc b/bin/varnishtest/tests/t02000.vtc index 789b5d822..a139cc33a 100644 --- a/bin/varnishtest/tests/t02000.vtc +++ b/bin/varnishtest/tests/t02000.vtc @@ -82,6 +82,7 @@ varnish v1 -syntax 4.1 -vcl+backend { sub vcl_deliver { set resp.http.C-Sess-XID = sess.xid; + set resp.http.xport = req.transport; } } @@ -93,6 +94,7 @@ 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.xport == HTTP/2 } -run stream 9 { txreq -url "/still_not_cached" diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 049c1f3cf..153d52d33 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -399,6 +399,15 @@ req.time across restarts. +req.transport + + Type: STRING + + Readable from: client + + The transport protocol which brought this request. + + req.ttl Type: DURATION diff --git a/include/vrt.h b/include/vrt.h index f57398280..1a47ac8ba 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -54,6 +54,7 @@ * binary/load-time compatible, increment MAJOR version * * Next (2021-03-15) + * VRT_r_req_transport() added * VRT_Assign_Backend() added * VRT_StaticDirector() added * enum lbody_e changed From phk at FreeBSD.org Sun Dec 19 18:14:04 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Sun, 19 Dec 2021 18:14:04 +0000 (UTC) Subject: [master] 523aa3c75 Dont ignore errors when unwinding stacks, the process is far too fickle for that, and misleading information wastes oceans of time. Message-ID: <20211219181404.F3F3C1110A0@lists.varnish-cache.org> commit 523aa3c75eed63352fb3f91ee72d57fbc2a31c93 Author: Poul-Henning Kamp Date: Sun Dec 19 18:00:22 2021 +0000 Dont ignore errors when unwinding stacks, the process is far too fickle for that, and misleading information wastes oceans of time. diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 9123f1ce8..58933d00a 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -601,12 +601,13 @@ pan_backtrace(struct vsb *vsb) } 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 : "", (long)offp); + if (!unw_get_reg(&cursor, UNW_REG_IP, &ip)) + VSB_printf(vsb, "ip=0x%lx", (long) ip); + if (!unw_get_reg(&cursor, UNW_REG_SP, &sp)) + VSB_printf(vsb, " sp=0x%lx", (long) sp); + if (!unw_get_proc_name(&cursor, fname, sizeof(fname), &offp)) + VSB_printf(vsb, " <%s+0x%lx>\n", + fname[0] ? fname : "", (long)offp); } VSB_indent(vsb, -2); From phk at FreeBSD.org Sun Dec 19 18:14:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Sun, 19 Dec 2021 18:14:05 +0000 (UTC) Subject: [master] 5e6c7075e Restructure to make it easier to understand for FlexeLint Message-ID: <20211219181405.197AC1110A3@lists.varnish-cache.org> commit 5e6c7075e2545a03d2606fa2707a87d5ba98d4b1 Author: Poul-Henning Kamp Date: Sun Dec 19 18:01:05 2021 +0000 Restructure to make it easier to understand for FlexeLint diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 7cfebcc20..176f0432b 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -276,9 +276,8 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) pp = pl->spec; if (lfmt && show != NULL && strcmp(pp->name, show)) continue; - if (pp->func == tweak_alias && show == NULL) - continue; - if (pp->func == tweak_alias && strcmp(pp->name, show)) + if (pp->func == tweak_alias && + (show == NULL || strcmp(pp->name, show))) continue; n++; @@ -406,9 +405,8 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) pp = pl->spec; if (show != NULL && strcmp(pp->name, show) != 0) continue; - if (pp->func == tweak_alias && show == NULL) - continue; - if (pp->func == tweak_alias && strcmp(pp->name, show)) + if (pp->func == tweak_alias && + (show == NULL || strcmp(pp->name, show))) continue; n++; From phk at FreeBSD.org Sun Dec 19 18:14:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Sun, 19 Dec 2021 18:14:05 +0000 (UTC) Subject: [master] 40a4f4623 Constification Message-ID: <20211219181405.33FDE1110A8@lists.varnish-cache.org> commit 40a4f4623bd41db3f4621d84579bd216aaf17a47 Author: Poul-Henning Kamp Date: Sun Dec 19 18:01:28 2021 +0000 Constification diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 0805f9340..1b5926499 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -149,7 +149,7 @@ vcc_delete_expr(struct expr *e) */ static void -vcc_strands_edit(struct expr *e1, struct expr *e2) +vcc_strands_edit(const struct expr *e1, const struct expr *e2) { if (e2->nstr == 1) { From phk at FreeBSD.org Mon Dec 20 13:18:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Dec 2021 13:18:05 +0000 (UTC) Subject: [master] 3404553b3 Expose http_IsHdr(), it is useful to iterate over particular headers. Message-ID: <20211220131805.E7ACB10A144@lists.varnish-cache.org> commit 3404553b34a968a74ae5ccf53b89de2ff377c694 Author: Poul-Henning Kamp Date: Mon Dec 20 13:17:35 2021 +0000 Expose http_IsHdr(), it is useful to iterate over particular headers. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index aeadda251..0f528d9a2 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -585,6 +585,7 @@ void HTTP_Clone(struct http *to, const struct http * const fm); void HTTP_Dup(struct http *to, const struct http * const fm); struct http *HTTP_create(void *p, uint16_t nhttp, unsigned); const char *http_Status2Reason(unsigned, const char **); +int http_IsHdr(const txt *hh, hdr_t hdr); unsigned http_EstimateWS(const struct http *fm, unsigned how); void http_PutResponse(struct http *to, const char *proto, uint16_t status, const char *response); diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index c30d21ee6..516e09648 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -423,7 +423,7 @@ http_PutField(struct http *to, int field, const char *string) /*--------------------------------------------------------------------*/ -static int +int http_IsHdr(const txt *hh, hdr_t hdr) { unsigned l; From phk at FreeBSD.org Mon Dec 20 13:18:05 2021 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 20 Dec 2021 13:18:05 +0000 (UTC) Subject: [master] 473b37a35 Make sure backtrace entries always have a newline. Message-ID: <20211220131805.D81D210A142@lists.varnish-cache.org> commit 473b37a35dd4adafe0827d13a989c64dd7a014c1 Author: Poul-Henning Kamp Date: Mon Dec 20 13:14:54 2021 +0000 Make sure backtrace entries always have a newline. diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 58933d00a..3ac6af736 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -606,8 +606,9 @@ pan_backtrace(struct vsb *vsb) if (!unw_get_reg(&cursor, UNW_REG_SP, &sp)) VSB_printf(vsb, " sp=0x%lx", (long) sp); if (!unw_get_proc_name(&cursor, fname, sizeof(fname), &offp)) - VSB_printf(vsb, " <%s+0x%lx>\n", + VSB_printf(vsb, " <%s+0x%lx>", fname[0] ? fname : "", (long)offp); + VSB_putc(vsb, '\n'); } VSB_indent(vsb, -2); From dridi.boukelmoune at gmail.com Tue Dec 21 13:35:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 21 Dec 2021 13:35:06 +0000 (UTC) Subject: [master] 389d7ba28 pipe: Add missing Start and Process timestamps Message-ID: <20211221133507.0CDC510F3BB@lists.varnish-cache.org> commit 389d7ba28e0d0e3a2d5c30a959aa517e5166b246 Author: Dridi Boukelmoune Date: Thu Dec 16 08:19:28 2021 +0100 pipe: Add missing Start and Process timestamps And expose bereq.time in vcl_pipe now that we have some. Refs #3562 diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 3538c3e6c..86a74b0cb 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -766,6 +766,7 @@ cnt_pipe(struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); VSLb(bo->vsl, SLT_Begin, "bereq %u pipe", VXID(req->vsl->wid)); VSLb(req->vsl, SLT_Link, "bereq %u pipe", VXID(bo->vsl->wid)); + VSLb_ts_busyobj(bo, "Start", W_TIM_real(wrk)); THR_SetBusyobj(bo); bo->sp = req->sp; SES_Ref(bo->sp); @@ -792,6 +793,8 @@ cnt_pipe(struct worker *wrk, struct req *req) nxt = REQ_FSM_MORE; break; case VCL_RET_PIPE: + VSLb_ts_req(req, "Process", W_TIM_real(wrk)); + VSLb_ts_busyobj(bo, "Process", wrk->lastused); if (V1P_Enter() == 0) { AZ(bo->req); bo->req = req; diff --git a/bin/varnishtest/tests/b00030.vtc b/bin/varnishtest/tests/b00030.vtc index ba6b7c9cb..72abee7da 100644 --- a/bin/varnishtest/tests/b00030.vtc +++ b/bin/varnishtest/tests/b00030.vtc @@ -7,7 +7,14 @@ varnishtest "Test timestamps" server s1 { rxreq txresp + + rxreq + txresp + rxreq + expect req.method == PIPE + expect req.http.req-time != + expect req.http.bereq-time != txresp } -start @@ -31,6 +38,10 @@ varnish v1 -vcl+backend { return (fail); } } + sub vcl_pipe { + set bereq.http.req-time = req.time; + set bereq.http.bereq-time = bereq.time; + } sub vcl_synth { set resp.http.now-synth = now; if (req.http.req-time != "" + req.time) { @@ -110,4 +121,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.http.now-synth ~ "^..., .. ... .... ..:..:.. GMT" + + txreq -method PIPE + rxresp } -run diff --git a/bin/varnishtest/tests/v00051.vtc b/bin/varnishtest/tests/v00051.vtc index 8f5ffd606..e13dae04b 100644 --- a/bin/varnishtest/tests/v00051.vtc +++ b/bin/varnishtest/tests/v00051.vtc @@ -182,6 +182,7 @@ varnish v1 -expect sc_vcl_failure == 4 logexpect l1012 -v v1 -g vxid -q "vxid == 1012" { expect 0 1012 Begin {^bereq 1011 pipe} + expect 0 = Timestamp {^Start:} expect 0 = BereqMethod {^GET} expect 0 = BereqURL {^/} expect 0 = BereqProtocol {^HTTP/1.1} diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 153d52d33..be15b6448 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -690,7 +690,7 @@ bereq.time Type: TIME - Readable from: backend + Readable from: vcl_pipe, backend The time when we started preparing the first backend request, remains constant across retries. diff --git a/doc/sphinx/reference/vsl.rst b/doc/sphinx/reference/vsl.rst index 3e174a979..e8ea7a36d 100644 --- a/doc/sphinx/reference/vsl.rst +++ b/doc/sphinx/reference/vsl.rst @@ -79,12 +79,19 @@ Restart Pipe handling timestamps ~~~~~~~~~~~~~~~~~~~~~~~~ +The following timestamps are client timestamps specific to pipe transactions: + Pipe Opened a pipe to the backend and forwarded the request. PipeSess The pipe session has finished. +The following timestamps change meaning in a pipe transaction: + +Process + Processing finished, ready to begin the pipe delivery. + Backend fetch timestamps ~~~~~~~~~~~~~~~~~~~~~~~~ From dridi.boukelmoune at gmail.com Thu Dec 30 05:48:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 30 Dec 2021 05:48:06 +0000 (UTC) Subject: [master] 529137322 vtc_http2: Avoid header encoding allocation churn Message-ID: <20211230054806.915FD11581B@lists.varnish-cache.org> commit 5291373223feae667517bf8b33758426eddcb862 Author: Dridi Boukelmoune Date: Wed Dec 29 10:32:21 2021 +0100 vtc_http2: Avoid header encoding allocation churn diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c index 1ee37b95a..7a437eb84 100644 --- a/bin/varnishtest/vtc_http2.c +++ b/bin/varnishtest/vtc_http2.c @@ -1275,16 +1275,12 @@ cmd_sendhex(CMD_ARGS) #define ENC(hdr, k, v) \ { \ AN(k); \ - hdr.key.ptr = strdup(k); \ - AN(hdr.key.ptr); \ + hdr.key.ptr = TRUST_ME(k); \ hdr.key.len = strlen(k); \ AN(v); \ - hdr.value.ptr = strdup(v); \ - AN(hdr.value.ptr); \ + hdr.value.ptr = TRUST_ME(v); \ hdr.value.len = strlen(v); \ assert(HPK_EncHdr(iter, &hdr) != hpk_err); \ - free(hdr.key.ptr); \ - free(hdr.value.ptr); \ } #define STR_ENC(av, field, str) \ From dridi.boukelmoune at gmail.com Thu Dec 30 07:32:06 2021 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 30 Dec 2021 07:32:06 +0000 (UTC) Subject: [master] 92a4d5155 param: Fix indentation of param.show -j Message-ID: <20211230073206.0A35A118813@lists.varnish-cache.org> commit 92a4d5155c2b610bc4d034a3e6007aad228be9fb Author: Dridi Boukelmoune Date: Thu Dec 30 08:11:18 2021 +0100 param: Fix indentation of param.show -j diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 176f0432b..3b160dcf9 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -364,12 +364,11 @@ mcf_json_key_valstr(struct cli *cli, const char *key, const char *val) static void v_matchproto_(cli_func_t) mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) { - int n, comma = 0; + int n, comma = 0, chg = 0; struct plist *pl; const struct parspec *pp; - int chg = 0, flags; struct vsb *vsb, *def; - const char *show = NULL; + const char *show = NULL, *sep; (void)priv; @@ -445,16 +444,15 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) mcf_json_key_valstr(cli, "maximum", pp->max); mcf_json_key_valstr(cli, "description", pp->descr); - flags = 0; - VCLI_Out(cli, "\"flags\": [\n"); + VCLI_Out(cli, "\"flags\": ["); VSB_indent(cli->sb, 2); + sep = ""; #define flag_out(flag, string) do { \ if (pp->flags & flag) { \ - if (flags) \ - VCLI_Out(cli, ",\n"); \ + VCLI_Out(cli, "%s\n", sep); \ VCLI_Out(cli, "\"%s\"", #string); \ - flags++; \ + sep = ","; \ } \ } while(0) @@ -469,10 +467,12 @@ mcf_param_show_json(struct cli *cli, const char * const *av, void *priv) #undef flag_out + if (pp->flags) + VCLI_Out(cli, "\n"); VSB_indent(cli->sb, -2); - VCLI_Out(cli, "\n]"); + VCLI_Out(cli, "]\n"); VSB_indent(cli->sb, -2); - VCLI_Out(cli, "\n}"); + VCLI_Out(cli, "}"); } VCLI_JSON_end(cli); if (show != NULL && n == 0) {