From dridi.boukelmoune at gmail.com Fri Apr 4 14:50:07 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 4 Apr 2025 14:50:07 +0000 (UTC) Subject: [master] f0a4d995c http: Delay zero-length range check Message-ID: <20250404145007.8E57810EF0D@lists.varnish-cache.org> commit f0a4d995cfdfefb97a13ddc970b1136489ae8bc7 Author: Dridi Boukelmoune Date: Fri Apr 4 16:16:41 2025 +0200 http: Delay zero-length range check The check is delayed until after low and high indices are adjusted, to avoid a scenario where the low index is zero for a content length of zero, and seen as a valid range. Spotted by Asad Sajjad Ahmed. diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 37f54e2ac..26ec4d054 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -1007,9 +1007,6 @@ http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi, ssize_t len) assert(*lo >= -1); assert(*hi >= -1); - if (len <= 0) - return (NULL); // Allow 200 response - if (*lo < 0) { assert(*hi > 0); *lo = len - *hi; @@ -1020,6 +1017,9 @@ http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi, ssize_t len) *hi = len - 1; } + if (len <= 0) + return (NULL); // Allow 200 response + if (*lo >= len) return ("low range beyond object"); diff --git a/bin/varnishtest/tests/c00135.vtc b/bin/varnishtest/tests/c00135.vtc new file mode 100644 index 000000000..76d877ec3 --- /dev/null +++ b/bin/varnishtest/tests/c00135.vtc @@ -0,0 +1,20 @@ +varnishtest "Range 0-0 (1B) on empty response" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend {} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.content-length == 0 + + txreq -hdr "range: bytes=0-0" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 0 +} -run From dridi.boukelmoune at gmail.com Fri Apr 4 14:50:07 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Fri, 4 Apr 2025 14:50:07 +0000 (UTC) Subject: [master] 0b91fc754 vtc-bisect: Pass build options via the environment Message-ID: <20250404145007.7C15210EF0B@lists.varnish-cache.org> commit 0b91fc75436eb288b6e446d9d5fcf7368c1723c7 Author: Dridi Boukelmoune Date: Fri Apr 4 11:17:19 2025 +0200 vtc-bisect: Pass build options via the environment The first and foremost goal is to disable developer warnings for compiler warnings that didn't trigger several releases ago. diff --git a/tools/vtc-bisect.sh b/tools/vtc-bisect.sh index e0f2e8b92..7a085a08d 100755 --- a/tools/vtc-bisect.sh +++ b/tools/vtc-bisect.sh @@ -51,6 +51,11 @@ usage() { -i : inverted mode, look for a bug fix instead -j : number of jobs for make invocations (defaults to 8) + Environment variables: + + CONFIGURE_OPTS : additional options for the configure script + MAKE_OPTS : additional options for make(1) executions + When is empty or missing, bisect.vtc is expected to be found at the root of the git repository. The current source tree is used and VPATH setups are not supported. @@ -66,9 +71,9 @@ usage() { } build() { - make -s -j"$MAKE_JOBS" all || { - ./autogen.des - make -s -j"$MAKE_JOBS" all + make -s -j"$MAKE_JOBS" ${MAKE_OPTS:-} all || { + ./autogen.des ${CONFIGURE_OPTS:-} + make -s -j"$MAKE_JOBS" ${MAKE_OPTS:-} all } } From dridi.boukelmoune at gmail.com Mon Apr 7 08:34:07 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 7 Apr 2025 08:34:07 +0000 (UTC) Subject: [master] ff600bc76 coverity: Run 'apt update' before installing packages Message-ID: <20250407083407.B4463654DE@lists.varnish-cache.org> commit ff600bc763e58254027ec32113b9b6afce385476 Author: Dridi Boukelmoune Date: Mon Apr 7 10:32:02 2025 +0200 coverity: Run 'apt update' before installing packages A job failed because of a stale index. diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index c86322600..308502df6 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - run: | + sudo apt-get update sudo apt-get install -y \ autoconf \ automake \ From walid.boudebouda at gmail.com Mon Apr 7 10:28:05 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Mon, 7 Apr 2025 10:28:05 +0000 (UTC) Subject: [master] a80160a0c vcp: Check found pool just once in VCP_Ref() Message-ID: <20250407102805.DF765104093@lists.varnish-cache.org> commit a80160a0c5e5390ae9c81d790b157b5a7c05eb88 Author: Dridi Boukelmoune Date: Fri Mar 14 16:15:43 2025 +0100 vcp: Check found pool just once in VCP_Ref() Testing cp2 nullity twice somehow resulted in multiple obj checks for both cp and cp2. In the cp case, there doesn't seem to be a point since the pool is created by the same function. Better diff with the --ignore-all-space option. diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c index bca79783c..7e8519fbe 100644 --- a/bin/varnishd/cache/cache_conn_pool.c +++ b/bin/varnishd/cache/cache_conn_pool.c @@ -811,28 +811,23 @@ VCP_Ref(const struct vrt_endpoint *vep, const char *ident) Lck_New(&cp->mtx, lck_conn_pool); VTAILQ_INIT(&cp->connlist); - CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); Lck_Lock(&conn_pools_mtx); cp2 = VRBT_FIND(vrb, &conn_pools, cp); - if (cp2 == NULL) - AZ(VRBT_INSERT(vrb, &conn_pools, cp)); - else { - CHECK_OBJ(cp2, CONN_POOL_MAGIC); - assert(cp2->refcnt > 0); - cp2->refcnt++; - } - Lck_Unlock(&conn_pools_mtx); - if (cp2 == NULL) { - CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); + AZ(VRBT_INSERT(vrb, &conn_pools, cp)); + Lck_Unlock(&conn_pools_mtx); return (cp); } + CHECK_OBJ(cp2, CONN_POOL_MAGIC); + assert(cp2->refcnt > 0); + cp2->refcnt++; + Lck_Unlock(&conn_pools_mtx); + Lck_Delete(&cp->mtx); AZ(cp->n_conn); AZ(cp->n_kill); FREE_OBJ(cp->endpoint); FREE_OBJ(cp); - CHECK_OBJ_NOTNULL(cp2, CONN_POOL_MAGIC); return (cp2); } From walid.boudebouda at gmail.com Mon Apr 7 10:28:05 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Mon, 7 Apr 2025 10:28:05 +0000 (UTC) Subject: [master] e70297446 vcp: Destroy unused VCP_Ref() pool with vcp_destroy() Message-ID: <20250407102806.0035D104097@lists.varnish-cache.org> commit e702974463c886329a0d77267a916e0dc7aba867 Author: Dridi Boukelmoune Date: Fri Mar 14 16:32:30 2025 +0100 vcp: Destroy unused VCP_Ref() pool with vcp_destroy() diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c index 7e8519fbe..9aba217b2 100644 --- a/bin/varnishd/cache/cache_conn_pool.c +++ b/bin/varnishd/cache/cache_conn_pool.c @@ -235,7 +235,7 @@ vcp_destroy(struct conn_pool **cpp) AZ(cp->n_conn); AZ(cp->n_kill); Lck_Delete(&cp->mtx); - free(cp->endpoint); + FREE_OBJ(cp->endpoint); FREE_OBJ(cp); } @@ -824,10 +824,6 @@ VCP_Ref(const struct vrt_endpoint *vep, const char *ident) cp2->refcnt++; Lck_Unlock(&conn_pools_mtx); - Lck_Delete(&cp->mtx); - AZ(cp->n_conn); - AZ(cp->n_kill); - FREE_OBJ(cp->endpoint); - FREE_OBJ(cp); + vcp_destroy(&cp); return (cp2); } From walid.boudebouda at gmail.com Mon Apr 7 10:28:06 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Mon, 7 Apr 2025 10:28:06 +0000 (UTC) Subject: [master] 7d1ffef3a vcp: More accurate description of VCP_Rel() Message-ID: <20250407102806.1B96F10409A@lists.varnish-cache.org> commit 7d1ffef3a3e7943e3292db5bd766557b5c3a41fd Author: Dridi Boukelmoune Date: Fri Mar 14 16:39:03 2025 +0100 vcp: More accurate description of VCP_Rel() diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c index 9aba217b2..d947cbfcd 100644 --- a/bin/varnishd/cache/cache_conn_pool.c +++ b/bin/varnishd/cache/cache_conn_pool.c @@ -240,7 +240,8 @@ vcp_destroy(struct conn_pool **cpp) } /*-------------------------------------------------------------------- - * Release Conn pool, destroy if last reference. + * Release Conn pool, destroy or stash for future destruction if last + * reference. */ void From nils.goroll at uplex.de Wed Apr 9 14:26:07 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 9 Apr 2025 14:26:07 +0000 (UTC) Subject: [master] 35bc77071 VMOD_Panic: avoid double panic with NULL vcs/version Message-ID: <20250409142607.9951A65B76@lists.varnish-cache.org> commit 35bc77071a16430cafcdb7ef1e89bc6e43f5539a Author: Nils Goroll Date: Wed Apr 9 16:15:52 2025 +0200 VMOD_Panic: avoid double panic with NULL vcs/version seen: ?5 0x000055a60d249491 in VAS_Fail (func=0x55a60d2b6456 "VSB_quote_pfx", file=0x55a60d2b6372 "vsb.c", line=545, cond=0x55a60d27e06d "p != NULL", kind=VAS_ASSERT) at vas.c:67 ?6 0x000055a60d2587d5 in VSB_quote_pfx (s=0x55a60d2f4d78 , pfx=0x55a60d2b192e "", v=0x0, len=-1, how=8) at vsb.c:545 ?7 0x000055a60d258d41 in VSB_quote (s=0x55a60d2f4d78 , v=0x0, len=-1, how=8) at vsb.c:652 ?8 0x000055a60d1cb946 in VMOD_Panic (vsb=0x55a60d2f4d78 ) at cache/cache_vrt_vmod.c:214 diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c index 3b5e7c564..ca5e37c65 100644 --- a/bin/varnishd/cache/cache_vrt_vmod.c +++ b/bin/varnishd/cache/cache_vrt_vmod.c @@ -198,6 +198,8 @@ VPI_Vmod_Unload(VRT_CTX, struct vmod **hdl) FREE_OBJ(v); } +#define nvl(x, y) ((x) ? (x) : (y)) + void VMOD_Panic(struct vsb *vsb) { @@ -211,9 +213,9 @@ VMOD_Panic(struct vsb *vsb) VSB_printf(vsb, "p=%p, abi=\"%s\", vrt=%u.%u,\n", v, v->abi, v->vrt_major, v->vrt_minor); VSB_bcat(vsb, "vcs=", 4); - VSB_quote(vsb, v->vcs, -1, VSB_QUOTE_CSTR); + VSB_quote(vsb, nvl(v->vcs, ""), -1, VSB_QUOTE_CSTR); VSB_bcat(vsb, ", version=", 10); - VSB_quote(vsb, v->version, -1, VSB_QUOTE_CSTR); + VSB_quote(vsb, nvl(v->version, ""), -1, VSB_QUOTE_CSTR); VSB_indent(vsb, -2); VSB_bcat(vsb, "},\n", 3); } From nils.goroll at uplex.de Thu Apr 10 06:47:06 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 10 Apr 2025 06:47:06 +0000 (UTC) Subject: [master] 7e2475da4 vcp: polish Message-ID: <20250410064706.9BB4661766@lists.varnish-cache.org> commit 7e2475da44d1f8165dfe412702b7923857bdb99b Author: Nils Goroll Date: Thu Apr 10 08:42:11 2025 +0200 vcp: polish A recent polish of VCP_Ref() in a80160a0c5e5390ae9c81d790b157b5a7c05eb88 made me notice that VRBT_FIND + optional VRBT_INSERT is just duplicating tree traversal for the insert case. Only use VRBT_INSERT - it already returns an existing element and is only marginally less efficient (the comparison function dominates). Using an additional VRBT_FIND would make sense if we did not create the element to be inserted upfront. diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c index d947cbfcd..fafb41b96 100644 --- a/bin/varnishd/cache/cache_conn_pool.c +++ b/bin/varnishd/cache/cache_conn_pool.c @@ -110,7 +110,6 @@ static struct lock dead_pools_mtx; VRBT_HEAD(vrb, conn_pool); VRBT_GENERATE_REMOVE_COLOR(vrb, conn_pool, entry, static) VRBT_GENERATE_REMOVE(vrb, conn_pool, entry, static) -VRBT_GENERATE_FIND(vrb, conn_pool, entry, vcp_cmp, static) VRBT_GENERATE_INSERT_COLOR(vrb, conn_pool, entry, static) VRBT_GENERATE_INSERT_FINISH(vrb, conn_pool, entry, static) VRBT_GENERATE_INSERT(vrb, conn_pool, entry, vcp_cmp, static) @@ -813,9 +812,8 @@ VCP_Ref(const struct vrt_endpoint *vep, const char *ident) VTAILQ_INIT(&cp->connlist); Lck_Lock(&conn_pools_mtx); - cp2 = VRBT_FIND(vrb, &conn_pools, cp); + cp2 = VRBT_INSERT(vrb, &conn_pools, cp); if (cp2 == NULL) { - AZ(VRBT_INSERT(vrb, &conn_pools, cp)); Lck_Unlock(&conn_pools_mtx); return (cp); } From nils.goroll at uplex.de Fri Apr 11 10:52:09 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 11 Apr 2025 10:52:09 +0000 (UTC) Subject: [master] 54e569239 debug storage: Clarify single instance use and document why Message-ID: <20250411105209.A8B3510E8D9@lists.varnish-cache.org> commit 54e569239d3751c3c81e1eefeebd92cfabf9fb2f Author: Nils Goroll Date: Fri Apr 11 11:27:22 2025 +0200 debug storage: Clarify single instance use and document why diff --git a/bin/varnishd/storage/storage_debug.c b/bin/varnishd/storage/storage_debug.c index f2500d8ed..bf4a01a43 100644 --- a/bin/varnishd/storage/storage_debug.c +++ b/bin/varnishd/storage/storage_debug.c @@ -34,6 +34,7 @@ #include "cache/cache_varnishd.h" #include "cache/cache_obj.h" +#include "common/heritage.h" #include #include @@ -44,12 +45,13 @@ #include "vtim.h" #include "vnum.h" -/* we cheat and make the open delay a static to avoid - * having to wrap all callbacks to unpack the priv - * pointer. Consequence: last dopen applies to all - * debug stevedores +/* + * if smd was to have its own configuration, we would have to wrap all function + * pointers from the actual storage implementation (sma). To avoid these + * complications, we limit to one smd instance and use statics. */ static vtim_dur dopen = 0.0; +static unsigned count = 0; /* returns one byte less than requested */ static int v_matchproto_(objgetspace_f) @@ -85,6 +87,9 @@ smd_init(struct stevedore *parent, int aac, char * const *aav) char **av; //lint -e429 char *a; + if (count++ > 0) + ARGV_ERR("Only one -s%s instance supported\n", smd_stevedore.name); + ident = parent->ident; memcpy(parent, &sma_stevedore, sizeof *parent); parent->ident = ident; diff --git a/bin/varnishtest/tests/c00030.vtc b/bin/varnishtest/tests/c00030.vtc new file mode 100644 index 000000000..912337dbf --- /dev/null +++ b/bin/varnishtest/tests/c00030.vtc @@ -0,0 +1,4 @@ +varnishtest "debug storage" + +shell -err -expect {Error: Only one -sdebug instance supported} \ + "varnishd -b none -a ${tmpdir}/vtc.sock -sdebug -sdebug" From nils.goroll at uplex.de Fri Apr 11 10:52:09 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 11 Apr 2025 10:52:09 +0000 (UTC) Subject: [master] 916473552 debug stoage: Add support for maxsize= Message-ID: <20250411105209.DEAA710E8DC@lists.varnish-cache.org> commit 9164735521989e54d8a8599828498797bc271107 Author: Nils Goroll Date: Fri Apr 11 12:45:21 2025 +0200 debug stoage: Add support for maxsize= If the maximum is reached, allocations fail. diff --git a/bin/varnishd/storage/storage_debug.c b/bin/varnishd/storage/storage_debug.c index bf4a01a43..e144f9648 100644 --- a/bin/varnishd/storage/storage_debug.c +++ b/bin/varnishd/storage/storage_debug.c @@ -52,6 +52,7 @@ */ static vtim_dur dopen = 0.0; static unsigned count = 0; +static ssize_t max_size = 0; /* returns one byte less than requested */ static int v_matchproto_(objgetspace_f) @@ -64,10 +65,61 @@ smd_lsp_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz, return (SML_methods.objgetspace(wrk, oc, sz, ptr)); } +/* + * returns max_size at most, then fails + * + * relies on the actual storage implementation to not use priv2 + */ +static int v_matchproto_(objgetspace_f) +smd_max_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz, + uint8_t **ptr) +{ + ssize_t used; + int r; + + AN(sz); + used = (ssize_t)oc->stobj->priv2; + + VSLb(wrk->vsl, SLT_Debug, "-sdebug: %zd/%zd", used, max_size); + + if (used >= max_size) { + VSLb(wrk->vsl, SLT_Storage, "-sdebug: max_size=%zd reached", max_size); + return (0); + } + + assert(used < max_size); + *sz = vmin_t(ssize_t, *sz, max_size - used); + + r = SML_methods.objgetspace(wrk, oc, sz, ptr); + if (r != 0) + oc->stobj->priv2 = (uint64_t)(used + *sz); + return (r); +} + #define dur_arg(a, s, d) \ (! strncmp((a), (s), strlen(s)) \ && (d = VNUM_duration(a + strlen(s))) != nan("")) +static int +bytes_arg(char *a, const char *s, ssize_t *sz) +{ + const char *err; + uintmax_t bytes; + + AN(sz); + if (strncmp(a, s, strlen(s))) + return (0); + a += strlen(s); + err = VNUM_2bytes(a, &bytes, 0); + if (err != NULL) + ARGV_ERR("%s\n", err); + assert(bytes <= SSIZE_MAX); + *sz = (ssize_t)bytes; + + return (1); +} + + static void smd_open(struct stevedore *stv) { sma_stevedore.open(stv); @@ -80,6 +132,7 @@ static void v_matchproto_(storage_init_f) smd_init(struct stevedore *parent, int aac, char * const *aav) { struct obj_methods *methods; + objgetspace_f *getspace = NULL; const char *ident; int i, ac = 0; size_t nac; @@ -109,7 +162,19 @@ smd_init(struct stevedore *parent, int aac, char * const *aav) a = aav[i]; if (a != NULL) { if (! strcmp(a, "lessspace")) { - methods->objgetspace = smd_lsp_getspace; + if (getspace != NULL) { + ARGV_ERR("-s%s conflicting options\n", + smd_stevedore.name); + } + getspace = smd_lsp_getspace; + continue; + } + if (bytes_arg(a, "maxspace=", &max_size)) { + if (getspace != NULL) { + ARGV_ERR("-s%s conflicting options\n", + smd_stevedore.name); + } + getspace = smd_max_getspace; continue; } if (dur_arg(a, "dinit=", d)) { @@ -128,6 +193,9 @@ smd_init(struct stevedore *parent, int aac, char * const *aav) assert(ac < (int)nac); AZ(av[ac]); + if (getspace != NULL) + methods->objgetspace = getspace; + sma_stevedore.init(parent, ac, av); free(av); fprintf(stderr, "-sdebug init delay %fs\n", dinit); diff --git a/bin/varnishtest/tests/c00030.vtc b/bin/varnishtest/tests/c00030.vtc index 912337dbf..b0eb4945a 100644 --- a/bin/varnishtest/tests/c00030.vtc +++ b/bin/varnishtest/tests/c00030.vtc @@ -2,3 +2,50 @@ varnishtest "debug storage" shell -err -expect {Error: Only one -sdebug instance supported} \ "varnishd -b none -a ${tmpdir}/vtc.sock -sdebug -sdebug" + +shell -err -expect {Error: -sdebug conflicting options} \ + "varnishd -b none -a ${tmpdir}/vtc.sock -sdebug,lessspace,maxspace=1KB" + +shell -err -expect {Error: Unknown BYTES} \ + "varnishd -b none -a ${tmpdir}/vtc.sock -sdebug,maxspace=1DJT" + +# lessspace is implicitly tested in b00017.vtc + +server s1 { + rxreq + txresp -bodylen 1024 + + rxreq + txresp -bodylen 1025 +} -start + + +varnish v1 -arg "-sTransient=debug,maxspace=1KB" -vcl+backend { + sub vcl_recv { + return(pass); + } +} -start + +logexpect l1 -v v1 -q "BerespHeader:Content-Length eq 1025" { + fail add * End + expect * * Storage {^-sdebug: max_size=1024 reached} + expect 0 = FetchError {^Could not get storage} + expect 0 = BackendClose {close RX_BODY} + fail clear +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 1024 + + txreq + rxresphdrs + expect resp.status == 200 + expect resp.http.Content-Length == 1025 + rxrespbody -max 1024 + expect_close + expect resp.bodylen == 1024 +} -run + +logexpect l1 -wait From nils.goroll at uplex.de Fri Apr 11 12:21:06 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 11 Apr 2025 12:21:06 +0000 (UTC) Subject: [master] 9177521b2 debug storage: Stabilize test Message-ID: <20250411122106.A317B111981@lists.varnish-cache.org> commit 9177521b2ce1bbf862c75130e491fc1140573062 Author: Nils Goroll Date: Fri Apr 11 14:19:16 2025 +0200 debug storage: Stabilize test Ensure we reach streaming mode using barriers diff --git a/bin/varnishtest/tests/c00030.vtc b/bin/varnishtest/tests/c00030.vtc index b0eb4945a..97fa9a4e6 100644 --- a/bin/varnishtest/tests/c00030.vtc +++ b/bin/varnishtest/tests/c00030.vtc @@ -11,12 +11,17 @@ shell -err -expect {Error: Unknown BYTES} \ # lessspace is implicitly tested in b00017.vtc +barrier b1 cond 2 + server s1 { rxreq txresp -bodylen 1024 rxreq - txresp -bodylen 1025 + txresp -nolen -hdr "Content-Length: 1025" + barrier b1 sync + send_n 32 "0123456789abcdef0123456789abcdef" + send "X" } -start @@ -43,6 +48,7 @@ client c1 { rxresphdrs expect resp.status == 200 expect resp.http.Content-Length == 1025 + barrier b1 sync rxrespbody -max 1024 expect_close expect resp.bodylen == 1024 From nils.goroll at uplex.de Fri Apr 11 14:35:08 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 11 Apr 2025 14:35:08 +0000 (UTC) Subject: [master] f5e92fe31 debug storage: Stabilize the test for real Message-ID: <20250411143508.48477116093@lists.varnish-cache.org> commit f5e92fe311d83e497fc2bdd094e914bec0c8b511 Author: Nils Goroll Date: Fri Apr 11 16:31:32 2025 +0200 debug storage: Stabilize the test for real As soon as we finished writing 1024 bytes on the server side, the client read of 1024 could end with EOF. diff --git a/bin/varnishtest/tests/c00030.vtc b/bin/varnishtest/tests/c00030.vtc index 97fa9a4e6..852a02013 100644 --- a/bin/varnishtest/tests/c00030.vtc +++ b/bin/varnishtest/tests/c00030.vtc @@ -12,6 +12,7 @@ shell -err -expect {Error: Unknown BYTES} \ # lessspace is implicitly tested in b00017.vtc barrier b1 cond 2 +barrier b2 cond 2 server s1 { rxreq @@ -20,7 +21,10 @@ server s1 { rxreq txresp -nolen -hdr "Content-Length: 1025" barrier b1 sync - send_n 32 "0123456789abcdef0123456789abcdef" + send_n 31 0123456789abcdef0123456789abcdef + send_n 1 0123456789abcdef0123456789abcde + barrier b2 sync + non_fatal send "X" } -start @@ -49,9 +53,11 @@ client c1 { expect resp.status == 200 expect resp.http.Content-Length == 1025 barrier b1 sync - rxrespbody -max 1024 + rxrespbody -max 1023 + barrier b2 sync + non_fatal + rxrespbody -max 1 expect_close - expect resp.bodylen == 1024 } -run logexpect l1 -wait From nils.goroll at uplex.de Fri Apr 11 14:35:08 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Fri, 11 Apr 2025 14:35:08 +0000 (UTC) Subject: [master] 9d6a0e02f debug storage: We need to wrap the extend function, too Message-ID: <20250411143508.2714D116090@lists.varnish-cache.org> commit 9d6a0e02f158f82e401d8c131e1f12aff8b124cf Author: Nils Goroll Date: Fri Apr 11 16:29:42 2025 +0200 debug storage: We need to wrap the extend function, too diff --git a/bin/varnishd/storage/storage_debug.c b/bin/varnishd/storage/storage_debug.c index e144f9648..7689f2849 100644 --- a/bin/varnishd/storage/storage_debug.c +++ b/bin/varnishd/storage/storage_debug.c @@ -80,7 +80,7 @@ smd_max_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz, AN(sz); used = (ssize_t)oc->stobj->priv2; - VSLb(wrk->vsl, SLT_Debug, "-sdebug: %zd/%zd", used, max_size); + VSLb(wrk->vsl, SLT_Debug, "-sdebug getspace: %zd/%zd", used, max_size); if (used >= max_size) { VSLb(wrk->vsl, SLT_Storage, "-sdebug: max_size=%zd reached", max_size); @@ -91,11 +91,19 @@ smd_max_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz, *sz = vmin_t(ssize_t, *sz, max_size - used); r = SML_methods.objgetspace(wrk, oc, sz, ptr); - if (r != 0) - oc->stobj->priv2 = (uint64_t)(used + *sz); return (r); } +static void v_matchproto_(objextend_f) +smd_max_extend(struct worker *wrk, struct objcore *oc, ssize_t l) +{ + + assert(l > 0); + oc->stobj->priv2 += (uint64_t)l; + VSLb(wrk->vsl, SLT_Debug, "-sdebug extend: %zd/%zd", (ssize_t)oc->stobj->priv2, max_size); + SML_methods.objextend(wrk, oc, l); +} + #define dur_arg(a, s, d) \ (! strncmp((a), (s), strlen(s)) \ && (d = VNUM_duration(a + strlen(s))) != nan("")) @@ -175,6 +183,7 @@ smd_init(struct stevedore *parent, int aac, char * const *aav) smd_stevedore.name); } getspace = smd_max_getspace; + methods->objextend = smd_max_extend; continue; } if (dur_arg(a, "dinit=", d)) { From nils.goroll at uplex.de Sat Apr 12 09:05:06 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 12 Apr 2025 09:05:06 +0000 (UTC) Subject: [master] 1678f98fa cache_fetch: Fail if storage allocation for synthetic body fails Message-ID: <20250412090506.F124B114883@lists.varnish-cache.org> commit 1678f98fab599100ebee57328774da9ad8f96460 Author: Nils Goroll Date: Fri Apr 11 14:07:51 2025 +0200 cache_fetch: Fail if storage allocation for synthetic body fails Fixes #4313 diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 2f67446b6..f5a1a1d6a 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -1020,14 +1020,17 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo) o = 0; while (ll > 0) { l = ll; - if (VFP_GetStorage(bo->vfc, &l, &ptr) != VFP_OK) - break; + if (VFP_GetStorage(bo->vfc, &l, &ptr) != VFP_OK) { + VSB_destroy(&synth_body); + return (F_STP_FAIL); + } l = vmin(l, ll); memcpy(ptr, VSB_data(synth_body) + o, l); VFP_Extend(bo->vfc, l, l == ll ? VFP_END : VFP_OK); ll -= l; o += l; } + assert(o == VSB_len(synth_body)); AZ(ObjSetU64(wrk, oc, OA_LEN, o)); VSB_destroy(&synth_body); ObjSetState(wrk, oc, BOS_PREP_STREAM); diff --git a/bin/varnishtest/tests/r04313.vtc b/bin/varnishtest/tests/r04313.vtc new file mode 100644 index 000000000..3a43deff9 --- /dev/null +++ b/bin/varnishtest/tests/r04313.vtc @@ -0,0 +1,43 @@ +varnishtest "storage failure with synthetic body" + +varnish v1 -arg "-sTransient=debug,maxspace=32B" -vcl { + backend none none; + + sub vcl_recv { + return(pass); + } + + # avoid the client side running into the same storage failure + sub vcl_synth { + set resp.body = resp.reason; + return(deliver); + } + + sub vcl_recv { + return(pass); + } + + sub vcl_backend_error { + set beresp.status = 200; + set beresp.body = + "0123456789abcdef" + + "0123456789abcdef" + + "X"; + return (deliver); + } +} -start + +logexpect l1 -v v1 -q "vxid == 1002" { + fail add * End + expect * * Storage {^-sdebug: max_size=32 reached} + expect 0 = FetchError {^Could not get storage} + fail clear +} -start + +client c1 { + txreq + rxresp + expect resp.status == 503 +} -run + +logexpect l1 -wait From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:05 +0000 (UTC) Subject: [master] 5651267d4 vrt: Harmonize regexp error messages Message-ID: <20250414154705.DF8A010D9DA@lists.varnish-cache.org> commit 5651267d4aa5fd9258d7385b7f6fd3e28a008d8c Author: Dridi Boukelmoune Date: Wed Apr 9 17:19:02 2025 +0200 vrt: Harmonize regexp error messages Better diff with the --patience option. diff --git a/bin/varnishd/cache/cache_vrt_re.c b/bin/varnishd/cache/cache_vrt_re.c index 58d980d1b..5ad281f1d 100644 --- a/bin/varnishd/cache/cache_vrt_re.c +++ b/bin/varnishd/cache/cache_vrt_re.c @@ -61,11 +61,23 @@ VPI_re_fini(vre_t *rep) VRE_free(&vv); } -VCL_BOOL -VRT_re_match(VRT_CTX, const char *s, VCL_REGEX re) +static void +re_fail(VRT_CTX, const char *pfx, int res) { struct vsb vsb[1]; char errbuf[VRE_ERROR_LEN]; + + assert(res < VRE_ERROR_NOMATCH); + AN(VSB_init(vsb, errbuf, sizeof errbuf)); + AZ(VRE_error(vsb, res)); + AZ(VSB_finish(vsb)); + VSB_fini(vsb); + VRT_fail(ctx, "%sRegexp matching failed: %s", pfx, errbuf); +} + +VCL_BOOL +VRT_re_match(VRT_CTX, const char *s, VCL_REGEX re) +{ int i; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); @@ -75,13 +87,8 @@ VRT_re_match(VRT_CTX, const char *s, VCL_REGEX re) i = VRE_match(re, s, 0, 0, &cache_param->vre_limits); if (i >= 0) return (1); - if (i < VRE_ERROR_NOMATCH ) { - AN(VSB_init(vsb, errbuf, sizeof errbuf)); - AZ(VRE_error(vsb, i)); - AZ(VSB_finish(vsb)); - VSB_fini(vsb); - VRT_fail(ctx, "Regexp matching failed: %s", errbuf); - } + if (i < VRE_ERROR_NOMATCH) + re_fail(ctx, "", i); return (0); } @@ -106,7 +113,7 @@ VRT_regsub(VRT_CTX, int all, VCL_STRING str, VCL_REGEX re, VCL_STRING sub) res = WS_VSB_finish(vsb, ctx->ws, NULL); if (i < VRE_ERROR_NOMATCH) - VRT_fail(ctx, "regsub: Regexp matching returned %d", i); + re_fail(ctx, "regsub: ", i); else if (res == NULL) VRT_fail(ctx, "regsub: Out of workspace"); else if (i > 0) From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] 2399d524a http: Polish using pdiff() macro Message-ID: <20250414154706.0702E10D9DD@lists.varnish-cache.org> commit 2399d524a686eb86e202464dcd02d7e2ce87cd41 Author: Dridi Boukelmoune Date: Tue Apr 1 15:21:38 2025 +0200 http: Polish using pdiff() macro diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 26ec4d054..31c533f30 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -187,9 +187,7 @@ http_hdr_flags(const char *b, const char *e) if (b == NULL || e == NULL) return (NULL); - assert(b <= e); - u = (unsigned)(e - b); - assert(b + u == e); + u = pdiff(b, e); if (u < GPERF_MIN_WORD_LENGTH || u > GPERF_MAX_WORD_LENGTH) return (NULL); u += http_asso_values[(uint8_t)(e[-1])] + From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] ef0a26f2c http: Expose H_Header symbols as char pointers Message-ID: <20250414154706.2B4FA10D9E1@lists.varnish-cache.org> commit ef0a26f2ca6a82127547047b88f2296ce4fe1295 Author: Dridi Boukelmoune Date: Tue Apr 1 17:23:34 2025 +0200 http: Expose H_Header symbols as char pointers It poses two problems alleviated by the previous char[] type: - assigning a "string literal" that is considered const - referencing a pointer in a static lookup table The const problem is temporarily avoided with a char[] _H_Header static variable only used to store the string the actual H_Header symbol will point to. The static table limitation is worked around, storing pointers to the offending symbols. This workaround is permanent, because headers should eventually take a new structured type that will pose the same problem. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 82bede0f4..d062de071 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -673,12 +673,12 @@ int http_IsFiltered(const struct http *hp, unsigned u, unsigned how); #define HTTPH_A_PASS (1 << 3) /* Response (b->o) for pass */ #define HTTPH_C_SPECIFIC (1 << 4) /* Connection-specific */ -#define HTTPH(a, b, c) extern char b[]; +#define HTTPH(a, b, c) extern char *b; #include "tbl/http_headers.h" -extern const char H__Status[]; -extern const char H__Proto[]; -extern const char H__Reason[]; +extern const char *H__Status; +extern const char *H__Proto; +extern const char *H__Reason; // rfc7233,l,1207,1208 #define http_tok_eq(s1, s2) (!vct_casecmp(s1, s2)) diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 31c533f30..514bdc77f 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -54,12 +54,14 @@ #include "tbl/body_status.h" -#define HTTPH(a, b, c) char b[] = "*" a ":"; +#define HTTPH(a, b, c) \ +static char _##b[] = "*" a ":"; \ +char *b = _##b; #include "tbl/http_headers.h" -const char H__Status[] = "\010:status:"; -const char H__Proto[] = "\007:proto:"; -const char H__Reason[] = "\010:reason:"; +const char *H__Status = "\010:status:"; +const char *H__Proto = "\007:proto:"; +const char *H__Reason = "\010:reason:"; static char * via_hdr; @@ -109,74 +111,74 @@ static const unsigned char http_asso_values[256] = { }; static struct http_hdrflg { - char *hdr; + char **hdr; unsigned flag; } http_hdrflg[GPERF_MAX_HASH_VALUE + 1] = { { NULL }, { NULL }, { NULL }, { NULL }, - { H_Date }, - { H_Range }, + { &H_Date }, + { &H_Range }, { NULL }, - { H_Referer }, - { H_Age }, - { H_From }, - { H_Keep_Alive }, - { H_Retry_After }, - { H_TE }, - { H_If_Range }, - { H_ETag }, - { H_X_Forwarded_For }, - { H_Expect }, - { H_Trailer }, - { H_If_Match }, - { H_Host }, - { H_Accept_Language }, - { H_Accept }, - { H_If_Modified_Since }, - { H_If_None_Match }, - { H_If_Unmodified_Since }, + { &H_Referer }, + { &H_Age }, + { &H_From }, + { &H_Keep_Alive }, + { &H_Retry_After }, + { &H_TE }, + { &H_If_Range }, + { &H_ETag }, + { &H_X_Forwarded_For }, + { &H_Expect }, + { &H_Trailer }, + { &H_If_Match }, + { &H_Host }, + { &H_Accept_Language }, + { &H_Accept }, + { &H_If_Modified_Since }, + { &H_If_None_Match }, + { &H_If_Unmodified_Since }, { NULL }, - { H_Cookie }, - { H_Upgrade }, - { H_Last_Modified }, - { H_Accept_Charset }, - { H_Accept_Encoding }, - { H_Content_MD5 }, - { H_Content_Type }, - { H_Content_Range }, + { &H_Cookie }, + { &H_Upgrade }, + { &H_Last_Modified }, + { &H_Accept_Charset }, + { &H_Accept_Encoding }, + { &H_Content_MD5 }, + { &H_Content_Type }, + { &H_Content_Range }, { NULL }, { NULL }, - { H_Content_Language }, - { H_Transfer_Encoding }, - { H_Authorization }, - { H_Content_Length }, - { H_User_Agent }, - { H_Server }, - { H_Expires }, - { H_Location }, + { &H_Content_Language }, + { &H_Transfer_Encoding }, + { &H_Authorization }, + { &H_Content_Length }, + { &H_User_Agent }, + { &H_Server }, + { &H_Expires }, + { &H_Location }, { NULL }, - { H_Set_Cookie }, - { H_Content_Encoding }, - { H_Max_Forwards }, - { H_Cache_Control }, + { &H_Set_Cookie }, + { &H_Content_Encoding }, + { &H_Max_Forwards }, + { &H_Cache_Control }, { NULL }, - { H_Connection }, - { H_Pragma }, + { &H_Connection }, + { &H_Pragma }, { NULL }, - { H_Accept_Ranges }, - { H_HTTP2_Settings }, - { H_Allow }, - { H_Content_Location }, + { &H_Accept_Ranges }, + { &H_HTTP2_Settings }, + { &H_Allow }, + { &H_Content_Location }, { NULL }, - { H_Proxy_Authenticate }, - { H_Vary }, + { &H_Proxy_Authenticate }, + { &H_Vary }, { NULL }, - { H_WWW_Authenticate }, - { H_Warning }, - { H_Via }, + { &H_WWW_Authenticate }, + { &H_Warning }, + { &H_Via }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, - { H_Proxy_Authorization } + { &H_Proxy_Authorization } }; static struct http_hdrflg * @@ -197,7 +199,8 @@ http_hdr_flags(const char *b, const char *e) retval = &http_hdrflg[u]; if (retval->hdr == NULL) return (NULL); - if (!http_hdr_at(retval->hdr + 1, b, e - b)) + AN(*retval->hdr); + if (!http_hdr_at(*retval->hdr + 1, b, e - b)) return (NULL); return (retval); } @@ -212,7 +215,7 @@ http_init_hdr(char *hdr, int flg) hdr[0] = strlen(hdr + 1); f = http_hdr_flags(hdr + 1, hdr + hdr[0]); AN(f); - assert(f->hdr == hdr); + assert(*f->hdr == hdr); f->flag = flg; } From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] 98d2e2a69 http: Constify H_Header symbols Message-ID: <20250414154706.451CF10D9E5@lists.varnish-cache.org> commit 98d2e2a69e95bd96927177641740250f024d9261 Author: Dridi Boukelmoune Date: Tue Apr 1 17:43:07 2025 +0200 http: Constify H_Header symbols Using the established hdr_t type definition. Solves #4304 diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index d062de071..a9b81db5b 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -673,12 +673,12 @@ int http_IsFiltered(const struct http *hp, unsigned u, unsigned how); #define HTTPH_A_PASS (1 << 3) /* Response (b->o) for pass */ #define HTTPH_C_SPECIFIC (1 << 4) /* Connection-specific */ -#define HTTPH(a, b, c) extern char *b; +#define HTTPH(a, b, c) extern hdr_t b; #include "tbl/http_headers.h" -extern const char *H__Status; -extern const char *H__Proto; -extern const char *H__Reason; +extern hdr_t H__Status; +extern hdr_t H__Proto; +extern hdr_t H__Reason; // rfc7233,l,1207,1208 #define http_tok_eq(s1, s2) (!vct_casecmp(s1, s2)) diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 514bdc77f..f11263b2e 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -56,12 +56,12 @@ #define HTTPH(a, b, c) \ static char _##b[] = "*" a ":"; \ -char *b = _##b; +hdr_t b = _##b; #include "tbl/http_headers.h" -const char *H__Status = "\010:status:"; -const char *H__Proto = "\007:proto:"; -const char *H__Reason = "\010:reason:"; +hdr_t H__Status = "\010:status:"; +hdr_t H__Proto = "\007:proto:"; +hdr_t H__Reason = "\010:reason:"; static char * via_hdr; @@ -111,7 +111,7 @@ static const unsigned char http_asso_values[256] = { }; static struct http_hdrflg { - char **hdr; + hdr_t *hdr; unsigned flag; } http_hdrflg[GPERF_MAX_HASH_VALUE + 1] = { { NULL }, { NULL }, { NULL }, { NULL }, @@ -224,7 +224,7 @@ HTTP_Init(void) { struct vsb *vsb; -#define HTTPH(a, b, c) http_init_hdr(b, c); +#define HTTPH(a, b, c) http_init_hdr(TRUST_ME(b), c); #include "tbl/http_headers.h" vsb = VSB_new_auto(); From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] b811258ea fetch: Make up an X-Varnish header variable Message-ID: <20250414154706.5F6A110D9EE@lists.varnish-cache.org> commit b811258ead70da834a38a0b1d91a5ee27d6e6387 Author: Dridi Boukelmoune Date: Tue Apr 1 17:51:09 2025 +0200 fetch: Make up an X-Varnish header variable It could be part of the well-known headers table, along with the h2 pseudo-header fields, but that would require an update of the perfect hash lookup table. The main goal so far is to formalize the hdr_t nature of this string. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index f5a1a1d6a..84db8e947 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -64,6 +64,8 @@ struct fetch_step { FETCH_STEPS #undef FETCH_STEP +static hdr_t const H_X_Varnish = "\012X-Varnish:"; + /*-------------------------------------------------------------------- * Allocate an object, with fall-back to Transient. * XXX: This somewhat overlaps the stuff in stevedore.c @@ -405,7 +407,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) bo->storage = bo->uncacheable ? stv_transient : STV_next(); if (bo->retries > 0) - http_Unset(bo->bereq, "\012X-Varnish:"); + http_Unset(bo->bereq, H_X_Varnish); http_PrintfHeader(bo->bereq, "X-Varnish: %ju", VXID(bo->vsl->wid)); From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] 6d32a53d3 vrt: Move hdr_t definition to vrt.h Message-ID: <20250414154706.8205F10DA09@lists.varnish-cache.org> commit 6d32a53d33e6948cd7c1e9561df09250cbe1621c Author: Dridi Boukelmoune Date: Tue Apr 1 18:10:14 2025 +0200 vrt: Move hdr_t definition to vrt.h diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index a9b81db5b..3b01a7ac7 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -83,8 +83,6 @@ struct body_status { typedef const struct body_status *body_status_t; -typedef const char *hdr_t; - /*--------------------------------------------------------------------*/ struct stream_close { diff --git a/include/vrt.h b/include/vrt.h index 49e3f5960..1a126e3e1 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -693,9 +693,11 @@ enum gethdr_e { HDR_BERESP }; +typedef const char *hdr_t; + struct gethdr_s { enum gethdr_e where; - const char *what; + hdr_t what; }; VCL_HTTP VRT_selecthttp(VRT_CTX, enum gethdr_e); From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] c7ea3dc90 vrt: Group hdr_t checks in new CHECK_HDR() macro Message-ID: <20250414154706.A175610DA25@lists.varnish-cache.org> commit c7ea3dc9039b555a6bcc46b89bdff079105a65b4 Author: Dridi Boukelmoune Date: Tue Apr 1 18:11:09 2025 +0200 vrt: Group hdr_t checks in new CHECK_HDR() macro It's a clunky macro, but its current shape is only a transition towards something structured. diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index f11263b2e..0cc17d572 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -482,10 +482,8 @@ http_IsHdr(const txt *hh, hdr_t hdr) unsigned l; Tcheck(*hh); - AN(hdr); + CHECK_HDR(hdr); l = hdr[0]; - assert(l == strlen(hdr + 1)); - assert(hdr[l] == ':'); hdr++; return (http_hdr_at(hdr, hh->b, l)); } @@ -556,6 +554,8 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) const char *v; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + CHECK_HDR(hdr); + if (WS_Overflowed(hp->ws)) return; @@ -564,8 +564,6 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) lsep = strlen(sep); l = hdr[0]; - assert(l == strlen(hdr + 1)); - assert(hdr[l] == ':'); f = http_findhdr(hp, l - 1, hdr + 1); if (f == 0) return; @@ -638,9 +636,8 @@ http_GetHdr(const struct http *hp, hdr_t hdr, const char **ptr) unsigned u, l; const char *p; + CHECK_HDR(hdr); l = hdr[0]; - assert(l == strlen(hdr + 1)); - assert(hdr[l] == ':'); hdr++; u = http_findhdr(hp, l - 1, hdr); if (u == 0) { @@ -1373,12 +1370,9 @@ HTTP_GetHdrPack(struct worker *wrk, struct objcore *oc, hdr_t hdr) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - AN(hdr); + CHECK_HDR(hdr); l = hdr[0]; - assert(l > 0); - assert(l == strlen(hdr + 1)); - assert(hdr[l] == ':'); hdr++; if (hdr[0] == ':') { diff --git a/include/vrt.h b/include/vrt.h index 1a126e3e1..326611273 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -695,6 +695,15 @@ enum gethdr_e { typedef const char *hdr_t; +#define CHECK_HDR(hdr) \ + do { \ + AN(hdr); \ + unsigned _l = hdr[0]; \ + assert(_l > 0); \ + assert(_l == strlen(hdr + 1)); \ + assert(hdr[_l] == ':'); \ + } while (0) + struct gethdr_s { enum gethdr_e where; hdr_t what; From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:06 +0000 (UTC) Subject: [master] 5d788a8c0 vrt: Turn hdr_t into a structured type Message-ID: <20250414154706.E2A9910DA3C@lists.varnish-cache.org> commit 5d788a8c081e3d0f626807773588b640582fc786 Author: Dridi Boukelmoune Date: Wed Apr 2 13:49:27 2025 +0200 vrt: Turn hdr_t into a structured type Without changing the memory layout of our pseudo-pascal-string for header names, this structured alternative clarifies the semantics and removes error-prone pointer arithmetics spread out everywhere. The new structure adds type safety to this specific use case. It comes with a new static analyzer with the HDR() macro, and a CAST_HDR() macro that includes a check with the CHECK_HDR() macro that was already present. Closes #3215 diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index ce54c5c3d..04468a547 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -495,6 +495,7 @@ ban_evaluate(struct worker *wrk, const uint8_t *bsarg, struct objcore *oc, const char *p; const char *arg1; double darg1, darg2; + hdr_t hdr; int rv; /* @@ -521,11 +522,13 @@ ban_evaluate(struct worker *wrk, const uint8_t *bsarg, struct objcore *oc, break; case BANS_ARG_REQHTTP: AN(reqhttp); - (void)http_GetHdr(reqhttp, bt.arg1_spec, &p); + CAST_HDR(hdr, bt.arg1_spec); + (void)http_GetHdr(reqhttp, hdr, &p); arg1 = p; break; case BANS_ARG_OBJHTTP: - arg1 = HTTP_GetHdrPack(wrk, oc, bt.arg1_spec); + CAST_HDR(hdr, bt.arg1_spec); + arg1 = HTTP_GetHdrPack(wrk, oc, hdr); break; case BANS_ARG_OBJSTATUS: arg1 = HTTP_GetHdrPack(wrk, oc, H__Status); diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 84db8e947..0521d0314 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -64,7 +64,7 @@ struct fetch_step { FETCH_STEPS #undef FETCH_STEP -static hdr_t const H_X_Varnish = "\012X-Varnish:"; +static hdr_t const H_X_Varnish = HDR("X-Varnish"); /*-------------------------------------------------------------------- * Allocate an object, with fall-back to Transient. diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 0cc17d572..f8402458f 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -54,14 +54,12 @@ #include "tbl/body_status.h" -#define HTTPH(a, b, c) \ -static char _##b[] = "*" a ":"; \ -hdr_t b = _##b; +#define HTTPH(a, b, c) hdr_t b = HDR(a); #include "tbl/http_headers.h" -hdr_t H__Status = "\010:status:"; -hdr_t H__Proto = "\007:proto:"; -hdr_t H__Reason = "\010:reason:"; +hdr_t H__Status = HDR(":status"); +hdr_t H__Proto = HDR(":proto"); +hdr_t H__Reason = HDR(":reason"); static char * via_hdr; @@ -208,12 +206,11 @@ http_hdr_flags(const char *b, const char *e) /*--------------------------------------------------------------------*/ static void -http_init_hdr(char *hdr, int flg) +http_init_hdr(hdr_t hdr, int flg) { struct http_hdrflg *f; - hdr[0] = strlen(hdr + 1); - f = http_hdr_flags(hdr + 1, hdr + hdr[0]); + f = http_hdr_flags(hdr->str, hdr->str + hdr->len - 1); AN(f); assert(*f->hdr == hdr); f->flag = flg; @@ -224,7 +221,7 @@ HTTP_Init(void) { struct vsb *vsb; -#define HTTPH(a, b, c) http_init_hdr(TRUST_ME(b), c); +#define HTTPH(a, b, c) http_init_hdr(b, c); #include "tbl/http_headers.h" vsb = VSB_new_auto(); @@ -479,13 +476,10 @@ http_PutField(struct http *to, int field, const char *string) int http_IsHdr(const txt *hh, hdr_t hdr) { - unsigned l; Tcheck(*hh); CHECK_HDR(hdr); - l = hdr[0]; - hdr++; - return (http_hdr_at(hdr, hh->b, l)); + return (http_hdr_at(hdr->str, hh->b, hdr->len)); } /*--------------------------------------------------------------------*/ @@ -549,7 +543,7 @@ http_CollectHdr(struct http *hp, hdr_t hdr) void http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) { - unsigned u, l, lsep, ml, f, x, d; + unsigned u, lsep, ml, f, x, d; char *b = NULL, *e = NULL; const char *v; @@ -563,8 +557,7 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) sep = ", "; lsep = strlen(sep); - l = hdr[0]; - f = http_findhdr(hp, l - 1, hdr + 1); + f = http_findhdr(hp, hdr->len - 1, hdr->str); if (f == 0) return; @@ -587,7 +580,7 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) if (b + x >= e) { http_fail(hp); VSLbs(hp->vsl, SLT_LostHeader, - TOSTRAND(hdr + 1)); + TOSTRAND(hdr->str)); WS_Release(hp->ws, 0); return; } @@ -599,9 +592,9 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) AN(e); /* Append the Nth header we found */ - x = Tlen(hp->hd[u]) - l; + x = Tlen(hp->hd[u]) - hdr->len; - v = hp->hd[u].b + *hdr; + v = hp->hd[u].b + hdr->len; while (vct_issp(*v)) { v++; x--; @@ -609,7 +602,7 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) if (b + lsep + x >= e) { http_fail(hp); - VSLbs(hp->vsl, SLT_LostHeader, TOSTRAND(hdr + 1)); + VSLbs(hp->vsl, SLT_LostHeader, TOSTRAND(hdr->str)); WS_Release(hp->ws, 0); return; } @@ -633,20 +626,18 @@ http_CollectHdrSep(struct http *hp, hdr_t hdr, const char *sep) int http_GetHdr(const struct http *hp, hdr_t hdr, const char **ptr) { - unsigned u, l; + unsigned u; const char *p; CHECK_HDR(hdr); - l = hdr[0]; - hdr++; - u = http_findhdr(hp, l - 1, hdr); + u = http_findhdr(hp, hdr->len - 1, hdr->str); if (u == 0) { if (ptr != NULL) *ptr = NULL; return (0); } if (ptr != NULL) { - p = hp->hd[u].b + l; + p = hp->hd[u].b + hdr->len; while (vct_issp(*p)) p++; *ptr = p; @@ -1366,36 +1357,32 @@ const char * HTTP_GetHdrPack(struct worker *wrk, struct objcore *oc, hdr_t hdr) { const char *ptr; - unsigned l; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_HDR(hdr); - l = hdr[0]; - hdr++; - - if (hdr[0] == ':') { + if (hdr->str[0] == ':') { /* Special cases */ ptr = ObjGetAttr(wrk, oc, OA_HEADERS, NULL); AN(ptr); ptr += 4; /* Skip nhd and status */ /* XXX: should we also have h2_hdr_eq() ? */ - if (!strcmp(hdr, ":proto:")) + if (!strcmp(hdr->str, ":proto:")) return (ptr); ptr = strchr(ptr, '\0') + 1; - if (!strcmp(hdr, ":status:")) + if (!strcmp(hdr->str, ":status:")) return (ptr); ptr = strchr(ptr, '\0') + 1; - if (!strcmp(hdr, ":reason:")) + if (!strcmp(hdr->str, ":reason:")) return (ptr); WRONG("Unknown magic packed header"); } HTTP_FOREACH_PACK(wrk, oc, ptr) { - if (http_hdr_at(ptr, hdr, l)) { - ptr += l; + if (http_hdr_at(ptr, hdr->str, hdr->len)) { + ptr += hdr->len; while (vct_islws(*ptr)) ptr++; return (ptr); @@ -1544,7 +1531,7 @@ http_ForceHeader(struct http *to, hdr_t hdr, const char *val) if (http_HdrIs(to, hdr, val)) return; http_Unset(to, hdr); - http_PrintfHeader(to, "%s %s", hdr + 1, val); + http_PrintfHeader(to, "%s %s", hdr->str, val); } void @@ -1555,9 +1542,9 @@ http_AppendHeader(struct http *to, hdr_t hdr, const char *val) http_CollectHdr(to, hdr); if (http_GetHdr(to, hdr, &old)) { http_Unset(to, hdr); - http_PrintfHeader(to, "%s %s, %s", hdr + 1, old, val); + http_PrintfHeader(to, "%s %s, %s", hdr->str, old, val); } else { - http_PrintfHeader(to, "%s %s", hdr + 1, val); + http_PrintfHeader(to, "%s %s", hdr->str, val); } } diff --git a/bin/varnishd/cache/cache_vary.c b/bin/varnishd/cache/cache_vary.c index fa9053966..c9c46231b 100644 --- a/bin/varnishd/cache/cache_vary.c +++ b/bin/varnishd/cache/cache_vary.c @@ -81,6 +81,7 @@ VRY_Create(struct busyobj *bo, struct vsb **psb) { const char *v, *p, *q, *h, *e; struct vsb *sb, *sbh; + hdr_t hdr; unsigned l; int error = 0; @@ -122,8 +123,9 @@ VRY_Create(struct busyobj *bo, struct vsb **psb) AZ(VSB_printf(sbh, "%c%.*s:%c", (char)(1 + (q - p)), (int)(q - p), p, 0)); AZ(VSB_finish(sbh)); + CAST_HDR(hdr, VSB_data(sbh)); - if (http_GetHdr(bo->bereq, VSB_data(sbh), &h)) { + if (http_GetHdr(bo->bereq, hdr, &h)) { AZ(vct_issp(*h)); /* Trim trailing space */ e = strchr(h, '\0'); @@ -292,6 +294,7 @@ VRY_Match(const struct req *req, const uint8_t *vary) const char *h, *e; unsigned lh, ln; int i, oflo = 0; + hdr_t hdr; AN(vsp); AN(vary); @@ -310,8 +313,9 @@ VRY_Match(const struct req *req, const uint8_t *vary) * then compare again with that new entry. */ + CAST_HDR(hdr, vary + 2); ln = 2 + vary[2] + 2; - i = http_GetHdr(req->http, (const char*)(vary+2), &h); + i = http_GetHdr(req->http, hdr, &h); if (i) { /* Trim trailing space */ e = strchr(h, '\0'); diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 39c8ef53c..fce89425d 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -604,11 +604,11 @@ VRT_SetHdr(VRT_CTX, VCL_HEADER hs, const char *pfx, VCL_STRANDS s) u = WS_ReserveAll(hp->ws); pl = (pfx == NULL) ? 0 : strlen(pfx); - l = hs->what[0] + 1 + pl; + l = hs->what->len + 1 + pl; if (u <= l) { WS_Release(hp->ws, 0); WS_MarkOverflow(hp->ws); - VSLbs(ctx->vsl, SLT_LostHeader, TOSTRAND(hs->what + 1)); + VSLbs(ctx->vsl, SLT_LostHeader, TOSTRAND(hs->what->str)); return; } b = WS_Reservation(hp->ws); @@ -618,15 +618,15 @@ VRT_SetHdr(VRT_CTX, VCL_HEADER hs, const char *pfx, VCL_STRANDS s) WS_Release(hp->ws, 0); WS_MarkOverflow(hp->ws); VSLbs(ctx->vsl, SLT_LostHeader, - TOSTRAND(hs->what + 1)); + TOSTRAND(hs->what->str)); return; } } else { b[l] = '\0'; } p = b; - memcpy(p, hs->what + 1, hs->what[0]); - p += hs->what[0]; + memcpy(p, hs->what->str, hs->what->len); + p += hs->what->len; *p++ = ' '; if (pfx != NULL) memcpy(p, pfx, pl); diff --git a/bin/varnishtest/tests/r01406.vtc b/bin/varnishtest/tests/r01406.vtc index 1d090201b..76af91952 100644 --- a/bin/varnishtest/tests/r01406.vtc +++ b/bin/varnishtest/tests/r01406.vtc @@ -10,7 +10,7 @@ varnish v1 -arg "-p vcc_feature=+allow_inline_c" -vcl+backend { C{ static const struct gethdr_s VGC_HDR_REQ_foo = - { HDR_REQ, "\020X-CUSTOM-HEADER:"}; + { HDR_REQ, HDR("X-CUSTOM-HEADER")}; }C sub vcl_recv { diff --git a/include/vrt.h b/include/vrt.h index 326611273..59d461087 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -57,6 +57,9 @@ * Whenever something is deleted or changed in a way which is not * binary/load-time compatible, increment MAJOR version * + * XX.X (unreleased) + * typedef hdr_t added + * struct gethdr_s.what changed to hdr_t * 21.0 (2025-03-17) * VRT_u_req_grace() added * VRT_u_req_ttl() added @@ -693,15 +696,29 @@ enum gethdr_e { HDR_BERESP }; -typedef const char *hdr_t; +typedef const struct { + unsigned char len; + const char str[]; +} *hdr_t; + +#define HDR(name) \ + ((hdr_t)&(const struct { \ + unsigned char _l; \ + char _s[sizeof(name ":")]; \ + }){ sizeof(name), name ":" }) + +#define CHECK_HDR(hdr) \ + do { \ + AN(hdr); \ + assert((hdr)->len > 0); \ + assert((hdr)->len == strlen((hdr)->str)); \ + assert((hdr)->str[(hdr)->len - 1] == ':'); \ + } while (0) -#define CHECK_HDR(hdr) \ - do { \ - AN(hdr); \ - unsigned _l = hdr[0]; \ - assert(_l > 0); \ - assert(_l == strlen(hdr + 1)); \ - assert(hdr[_l] == ':'); \ +#define CAST_HDR(hdr, str) \ + do { \ + hdr = (hdr_t)(str); \ + CHECK_HDR(hdr); \ } while (0) struct gethdr_s { diff --git a/lib/libvcc/vcc_var.c b/lib/libvcc/vcc_var.c index 643af2f1e..8f0892e05 100644 --- a/lib/libvcc/vcc_var.c +++ b/lib/libvcc/vcc_var.c @@ -57,8 +57,7 @@ vcc_Header_Fh(const struct vcc *tl, const struct symbol *sym) /* Create the static identifier */ Fh(tl, 0, "static const struct gethdr_s %s =\n", sym->rname + 1); - Fh(tl, 0, " { %s, \"\\%03o%s:\"};\n", - parent->rname, (unsigned int)strlen(sym->name) + 1, sym->name); + Fh(tl, 0, " { %s, HDR(\"%s\")};\n", parent->rname, sym->name); } /*--------------------------------------------------------------------*/ diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index 7b22d87df..73155871a 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -685,10 +685,10 @@ xyzzy_sethdr(VRT_CTX, VCL_HEADER hdr, VCL_STRANDS s) if (s->n == 0) { http_Unset(hp, hdr->what); } else { - b = VRT_StrandsWS(hp->ws, hdr->what + 1, s); + b = VRT_StrandsWS(hp->ws, hdr->what->str, s); if (b == NULL) { VSLbs(ctx->vsl, SLT_LostHeader, - TOSTRAND(hdr->what + 1)); + TOSTRAND(hdr->what->str)); } else { if (*b != '\0') AN(WS_Allocated(hp->ws, b, strlen(b) + 1)); From dridi.boukelmoune at gmail.com Mon Apr 14 15:47:07 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:47:07 +0000 (UTC) Subject: [master] e509aace2 Flexelint silencing for new HDR() macro Message-ID: <20250414154707.0E57710DA48@lists.varnish-cache.org> commit e509aace226eec1f3bd31df91ddd5a3b649da90e Author: Nils Goroll Date: Mon Apr 14 12:31:26 2025 +0200 Flexelint silencing for new HDR() macro The "local struct member ... not referenced" warning can only be suppressed using name::member. Because our struct used for the compound literal is anonymous, we have no name:: component and any silencing on member names will apply globally to any other anonymous struct with the same name. To avoid accidental silencing, we use the _hdr_ prefix. diff --git a/include/vrt.h b/include/vrt.h index 59d461087..2252cdc74 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -701,10 +701,12 @@ typedef const struct { const char str[]; } *hdr_t; +//lint -esym(754, _hdr_s, _hdr_l) local struct member ... not referenced +//lint -emacro(740, HDR) unusual cast #define HDR(name) \ ((hdr_t)&(const struct { \ - unsigned char _l; \ - char _s[sizeof(name ":")]; \ + unsigned char _hdr_l; \ + char _hdr_s[sizeof(name ":")]; \ }){ sizeof(name), name ":" }) #define CHECK_HDR(hdr) \ From dridi.boukelmoune at gmail.com Mon Apr 14 15:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:49:05 +0000 (UTC) Subject: [master] a6dded724 gzip: Remove unnecessary output buffer TRUST_ME() Message-ID: <20250414154905.B0F4A10E6C7@lists.varnish-cache.org> commit a6dded7248e95e95d9bae037ccc8e1b125c3cacf Author: Dridi Boukelmoune Date: Thu Mar 13 09:47:22 2025 +0100 gzip: Remove unnecessary output buffer TRUST_ME() Unlike the input buffer, the output buffer must be writable to be usable. The pointer used to be const, but the restriction was lifted without touching the macro. Refs e633a7f885660ee76d075098810c31bdad4e5571 diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 74a7f4e0f..1bc717bf5 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -197,7 +197,7 @@ VGZ_Obuf(struct vgz *vg, void *ptr, ssize_t len) CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - vg->vz.next_out = TRUST_ME(ptr); + vg->vz.next_out = ptr; vg->vz.avail_out = len; } From dridi.boukelmoune at gmail.com Mon Apr 14 15:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:49:05 +0000 (UTC) Subject: [master] 5036291c7 gzip: Check buffers arguments Message-ID: <20250414154905.DF39A10E6CC@lists.varnish-cache.org> commit 5036291c75fcc0d4c6292d90192cea6469a233ba Author: Dridi Boukelmoune Date: Thu Mar 13 09:54:21 2025 +0100 gzip: Check buffers arguments diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 1bc717bf5..06eb692ec 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -175,8 +175,11 @@ VGZ_Ibuf(struct vgz *vg, const void *ptr, ssize_t len) { CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - AZ(vg->vz.avail_in); + assert(len >= 0); + if (len > 0) + AN(ptr); + vg->vz.next_in = TRUST_ME(ptr); vg->vz.avail_in = len; } @@ -196,6 +199,8 @@ VGZ_Obuf(struct vgz *vg, void *ptr, ssize_t len) { CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); + AN(ptr); + assert(len > 0); vg->vz.next_out = ptr; vg->vz.avail_out = len; From dridi.boukelmoune at gmail.com Mon Apr 14 15:49:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 14 Apr 2025 15:49:06 +0000 (UTC) Subject: [master] f778ad5b9 gzip: Allocate gzip buffers from storage Message-ID: <20250414154906.09D9C10E6CF@lists.varnish-cache.org> commit f778ad5b986fadaa22dbec3a0ac49cab3076c81b Author: Dridi Boukelmoune Date: Thu Mar 13 10:35:20 2025 +0100 gzip: Allocate gzip buffers from storage Arbitrary allocation from storage was introduced to solve the h2 head-of-line blocking caused by early DATA frames, allowed by the initial control flow window of new streams. The decision could have been made then to allocate the window buffer from the heap, but it was tied to storage instead, offering better control over the global memory footprint of the cache process. The gzip buffer is tied to a task, but too large to allocate from workspace without posing a risk. Even worse, there may be multiple concurrent gzip operations in a single task. For example a gunzip needed to parse ESI followed by a gzip to store a compressed body. For a similar reason, it was not opportune to allocate the h2 stream window buffer from workspace, despite being tied to the task. Following the same logic, the gzip allocation can be performed from storage to remove one wild card in our heap consumption. Another possibility could have been the addition of a mempool, and it could also have been an alternative for the h2 stream window, but transient storage seemed more appropriate and it matches the on-demand malloc behavior. The gzip buffer logic could have been better encapsulated, but the amount of direct access to the m_buf field would have resulted in a lot of noise. Most of the noise here is caused by the two function signatures changed to take a worker argument. diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 465b432bd..74771b7d3 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -146,7 +146,7 @@ vfp_esi_end(struct vfp_ctx *vc, struct vef_priv *vef, if (vef->vgz != NULL) { if (retval == VFP_END) VGZ_UpdateObj(vc, vef->vgz, VGZ_END); - if (VGZ_Destroy(&vef->vgz) != VGZ_END) + if (VGZ_Destroy(vc->wrk, &vef->vgz) != VGZ_END) retval = VFP_Error(vc, "ESI+Gzip Failed at the very end"); } diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 06eb692ec..4f7205c92 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -46,6 +46,9 @@ #include "cache_filter.h" #include "cache_objhead.h" #include "cache_vgz.h" + +#include "storage/storage.h" + #include "vend.h" #include "vgz.h" @@ -59,6 +62,7 @@ struct vgz { int last_i; enum vgz_flag flag; + struct stv_buffer *stvbuf; char *m_buf; ssize_t m_sz; ssize_t m_len; @@ -151,20 +155,24 @@ VGZ_NewGzip(struct vsl_log *vsl, const char *id) */ static int -vgz_getmbuf(struct vgz *vg) +vgz_getmbuf(struct worker *wrk, struct vgz *vg) { + size_t sz; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->m_sz); AZ(vg->m_len); AZ(vg->m_buf); + AZ(vg->stvbuf); - vg->m_sz = cache_param->gzip_buffer; - vg->m_buf = malloc(vg->m_sz); - if (vg->m_buf == NULL) { - vg->m_sz = 0; + vg->stvbuf = STV_AllocBuf(wrk, stv_transient, cache_param->gzip_buffer); + if (vg->stvbuf == NULL) return (-1); - } + vg->m_buf = STV_GetBufPtr(vg->stvbuf, &sz); + vg->m_sz = sz; + AN(vg->m_buf); + assert(vg->m_sz > 0); return (0); } @@ -311,8 +319,8 @@ vdp_gunzip_init(VRT_CTX, struct vdp_ctx *vdc, void **priv) vg = VGZ_NewGunzip(vdc->vsl, "U D -"); AN(vg); - if (vgz_getmbuf(vg)) { - (void)VGZ_Destroy(&vg); + if (vgz_getmbuf(vdc->wrk, vg)) { + (void)VGZ_Destroy(vdc->wrk, &vg); return (-1); } @@ -352,7 +360,7 @@ vdp_gunzip_fini(struct vdp_ctx *vdc, void **priv) (void)vdc; TAKE_OBJ_NOTNULL(vg, priv, VGZ_MAGIC); AN(vg->m_buf); - (void)VGZ_Destroy(&vg); + (void)VGZ_Destroy(vdc->wrk, &vg); return (0); } @@ -439,12 +447,13 @@ VGZ_UpdateObj(const struct vfp_ctx *vc, struct vgz *vg, enum vgzret_e e) */ enum vgzret_e -VGZ_Destroy(struct vgz **vgp) +VGZ_Destroy(struct worker *wrk, struct vgz **vgp) { struct vgz *vg; enum vgzret_e vr; int i; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); TAKE_OBJ_NOTNULL(vg, vgp, VGZ_MAGIC); AN(vg->id); VSLb(vg->vsl, SLT_Gzip, "%s %jd %jd %jd %jd %jd", @@ -460,8 +469,11 @@ VGZ_Destroy(struct vgz **vgp) i = inflateEnd(&vg->vz); if (vg->last_i == Z_STREAM_END && i == Z_OK) i = Z_STREAM_END; - if (vg->m_buf) - free(vg->m_buf); + if (vg->m_buf != NULL) { + AN(vg->stvbuf); + STV_FreeBuf(wrk, &vg->stvbuf); + } + AZ(vg->stvbuf); if (i == Z_OK) vr = VGZ_OK; else if (i == Z_STREAM_END) @@ -514,7 +526,7 @@ vfp_gzip_init(VRT_CTX, struct vfp_ctx *vc, struct vfp_entry *vfe) } AN(vg); vfe->priv1 = vg; - if (vgz_getmbuf(vg)) + if (vgz_getmbuf(vc->wrk, vg)) return (VFP_ERROR); VGZ_Ibuf(vg, vg->m_buf, 0); AZ(vg->m_len); @@ -699,7 +711,7 @@ vfp_gzip_fini(struct vfp_ctx *vc, struct vfp_entry *vfe) if (vfe->priv1 != NULL) { TAKE_OBJ_NOTNULL(vg, &vfe->priv1, VGZ_MAGIC); - (void)VGZ_Destroy(&vg); + (void)VGZ_Destroy(vc->wrk, &vg); } } diff --git a/bin/varnishd/cache/cache_vgz.h b/bin/varnishd/cache/cache_vgz.h index 0464bc7f1..386d31bb6 100644 --- a/bin/varnishd/cache/cache_vgz.h +++ b/bin/varnishd/cache/cache_vgz.h @@ -53,6 +53,6 @@ int VGZ_ObufFull(const struct vgz *vg); enum vgzret_e VGZ_Gzip(struct vgz *, const void **, ssize_t *len, enum vgz_flag); // enum vgzret_e VGZ_Gunzip(struct vgz *, const void **, ssize_t *len); -enum vgzret_e VGZ_Destroy(struct vgz **); +enum vgzret_e VGZ_Destroy(struct worker *wrk, struct vgz **); void VGZ_UpdateObj(const struct vfp_ctx *, struct vgz*, enum vgzret_e); diff --git a/include/tbl/params.h b/include/tbl/params.h index 7c2c7a667..c66c3e8f4 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -538,10 +538,12 @@ PARAM_SIMPLE( /* units */ "bytes", /* descr */ "Size of malloc buffer used for gzip processing.\n" + "Size of buffer used for gzip processing.\n" "These buffers are used for in-transit data, for instance " - "gunzip'ed data being sent to a client.Making this space to small " + "gunzip'ed data being sent to a client. Making this space to small " "results in more overhead, writes to sockets etc, making it too " - "big is probably just a waste of memory.", + "big is probably just a waste of memory.\n" + "Gzip buffers are allocated from Transient storage.", /* flags */ EXPERIMENTAL ) From nils.goroll at uplex.de Tue Apr 15 06:36:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 15 Apr 2025 06:36:05 +0000 (UTC) Subject: [master] f8d611fb5 cache_ban: Add BANIDX facility to speed up BAN loading Message-ID: <20250415063605.B78B6102F9E@lists.varnish-cache.org> commit f8d611fb54f936006faefba07d54b20300ead611 Author: Nils Goroll Date: Wed Feb 5 19:57:07 2025 +0100 cache_ban: Add BANIDX facility to speed up BAN loading When loading a cache with a relevant number of BANs from a persistent storage, BAN_FindBan() needs to called for every object to determine the struct ban which the in-core object is to point to based on the persisted ban time. This is highly inefficient because BAN_FindBAN() conducts a linear search of the ban list, for which we would expect about half the bans to need inspection if objects were distributed equally across all bans. But for a long BAN list, most objects will hang near the bottom, so chances are high that we actually need to traverse nearly _all_ of the ban list for each loaded object. So this screams for turning the ban list into a different data structure, like a binary tree. Yet once loading of objects is complete, the ban list as we have it is optimal: All operations on the ban list need to traverse it anyway and in many cases this traversal can happen unlocked. So we really would not want to change the structure of the ban list. This patch suggests to add a search tree as an _additional_ data structure, which only exists during cache load (while there are ban_holds). In particular, the interface is made such that the only relevant change to the ban code is to provide a hint for the linear search to start at: VTAILQ_FOREACH(ban, ...) gets turned into ban = BANIDX_lookup(timestamp); VTAILQ_FOREACH_FROM(ban, ...); and that's it. In particular, this patch implies no change at all to setups which do not use persistent storage, so the risk is considered very low. The speed up is impressive: The following tests were conducted with a SLASH/fellow storage with 7689 bans. For each test round, the storage (residing on a ZFS volume) was rolled back to the same state, basically like so: zfs rollback int21/slash/10g at reproduce varnishd ... -sfellow=fellow,/dev/zvol/int21/slash/10g,10GB,1g,32k ... When the cache was loaded, varnishd was terminated and the test repeated. Six runs were conducted with Varnish-Cache master as of 749a2c3fcb417563fe3c1e076f6c78349e869aa1, resulting in load times in the order of 21 seconds: 0 Storage - fellow fellow: 289627 resurrected in 28.477966s (10235.386784/s), 1856 already expired 0 Storage - fellow fellow: 289627 resurrected in 26.170669s (11137.774192/s), 1856 already expired 0 Storage - fellow fellow: 289627 resurrected in 24.331572s (11979.620642/s), 1856 already expired 0 Storage - fellow fellow: 289626 resurrected in 21.455001s (13585.783644/s), 1857 already expired 0 Storage - fellow fellow: 289626 resurrected in 21.340564s (13658.635888/s), 1857 already expired 0 Storage - fellow fellow: 289626 resurrected in 21.568622s (13514.215014/s), 1857 already expired (note: the change of the number of cache objects is because wall clock time has passed the expiry time of one object) With this patch, load times were reduced by a factor >15 0 Storage - fellow fellow: 289625 resurrected in 1.293932s (225269.103288/s), 1858 already expired 0 Storage - fellow fellow: 289625 resurrected in 1.416040s (205843.804318/s), 1858 already expired 0 Storage - fellow fellow: 289625 resurrected in 1.341485s (217283.788555/s), 1858 already expired Naturally, the benefits are even more relevant with a higher number of bans. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index ae4414b52..0d60f1b18 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -20,6 +20,7 @@ varnishd_SOURCES = \ cache/cache_backend_probe.c \ cache/cache_ban.c \ cache/cache_ban_build.c \ + cache/cache_ban_idx.c \ cache/cache_ban_lurker.c \ cache/cache_busyobj.c \ cache/cache_cli.c \ diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 04468a547..77d7ed96f 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -124,8 +124,10 @@ BAN_Release(void) assert(ban_holds > 0); ban_holds--; Lck_Unlock(&ban_mtx); - if (ban_holds == 0) + if (ban_holds == 0) { + BANIDX_fini(); WRK_BgThread(&ban_thread, "ban-lurker", ban_lurker, NULL); + } } /*-------------------------------------------------------------------- @@ -294,7 +296,8 @@ BAN_FindBan(vtim_real t0) vtim_real t1; assert(ban_holds > 0); - VTAILQ_FOREACH(b, &ban_head, list) { + b = BANIDX_lookup(t0); + VTAILQ_FOREACH_FROM(b, &ban_head, list) { t1 = ban_time(b->spec); if (t1 == t0) return (b); @@ -392,11 +395,13 @@ ban_reload(const uint8_t *ban, unsigned len) vtim_real t0, t1, t2 = 9e99; ASSERT_CLI(); Lck_AssertHeld(&ban_mtx); + assert(ban_holds > 0); t0 = ban_time(ban); assert(len == ban_len(ban)); - VTAILQ_FOREACH(b, &ban_head, list) { + b = BANIDX_lookup(t0); + VTAILQ_FOREACH_FROM(b, &ban_head, list) { t1 = ban_time(b->spec); assert(t1 < t2); t2 = t1; diff --git a/bin/varnishd/cache/cache_ban.h b/bin/varnishd/cache/cache_ban.h index 468c54747..e2bce0113 100644 --- a/bin/varnishd/cache/cache_ban.h +++ b/bin/varnishd/cache/cache_ban.h @@ -156,3 +156,7 @@ vtim_real ban_time(const uint8_t *banspec); int ban_equal(const uint8_t *bs1, const uint8_t *bs2); void BAN_Free(struct ban *b); void ban_kick_lurker(void); + +// cache_ban_idx.c +struct ban * BANIDX_lookup(vtim_real); +void BANIDX_fini(void); diff --git a/bin/varnishd/cache/cache_ban_idx.c b/bin/varnishd/cache/cache_ban_idx.c new file mode 100644 index 000000000..11a5886a0 --- /dev/null +++ b/bin/varnishd/cache/cache_ban_idx.c @@ -0,0 +1,135 @@ +/*- + * Copyright 2025 UPLEX - Nils Goroll Systemoptimierung + * All rights reserved. + * + * Author: Nils Goroll + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This code creates an index on top of the ban list to speed up lookup during + * cache load (while ban_holds > 0). Its only assumption is that bans do not + * vanish (as guaranteed by ban_holds), and it does not change any functions + * called _after_ cache reload by constructing the additional index during + * lookup only. + * + * The lookup function returns a ban for VTAILQ_FOREACH_FROM() to start from, + * such that changes to the ban code remain minimal. + * + */ + +#include "config.h" + +#include + +#include "cache_varnishd.h" +#include "cache_ban.h" +#include "cache_objhead.h" + +#include "vtree.h" + +struct metaban { + unsigned magic; +#define BANIDX_MAGIC 0x39b799f8 + VRBT_ENTRY(metaban) tree; + // duplicate the ban time for efficiency + vtim_real time; + struct ban *ban; +}; + +static inline int +metaban_cmp(const struct metaban *i1, struct metaban *i2) +{ + if (i1->time < i2->time) + return (-1); + if (i1->time > i2->time) + return (1); + return (0); +} + +VRBT_HEAD(banidx_s, metaban); +VRBT_GENERATE_REMOVE_COLOR(banidx_s, metaban, tree, static) +VRBT_GENERATE_REMOVE(banidx_s, metaban, tree, static) +VRBT_GENERATE_NFIND(banidx_s, metaban, tree, metaban_cmp, static) +VRBT_GENERATE_INSERT_COLOR(banidx_s, metaban, tree, static) +VRBT_GENERATE_INSERT_FINISH(banidx_s, metaban, tree, static) +VRBT_GENERATE_INSERT(banidx_s, metaban, tree, metaban_cmp, static) +VRBT_GENERATE_NEXT(banidx_s, metaban, tree, static) +VRBT_GENERATE_MINMAX(banidx_s, metaban, tree, static) + +static struct banidx_s banidx = VRBT_INITIALIZER(banidx); +static pthread_mutex_t banidxmtx = PTHREAD_MUTEX_INITIALIZER; + +struct ban * +BANIDX_lookup(vtim_real t0) +{ + struct metaban *m, needle = {0, .time = t0}; + struct ban *best = NULL, *b = NULL; + vtim_real t1; + + PTOK(pthread_mutex_lock(&banidxmtx)); + m = VRBT_NFIND(banidx_s, &banidx, &needle); + if (m != NULL && ! (m->time > t0)) { + PTOK(pthread_mutex_unlock(&banidxmtx)); + return (m->ban); + } + /* + * if we have m, it is later than t0, which is higher up the list. + * check if there is a better match and create missing elements + * along the way + * if VRBT_NFIND did not return anything, it means it has no index for + * elements higher up the list and we can index from the top (implicit + * in VTAILQ_FOREACH_FROM()) + */ + if (m != NULL) { + best = m->ban; + b = VTAILQ_NEXT(best, list); + if (b == NULL) { + PTOK(pthread_mutex_unlock(&banidxmtx)); + return (best); + } + } + VTAILQ_FOREACH_FROM(b, &ban_head, list) { + t1 = ban_time(b->spec); + if (t1 < t0) + break; + ALLOC_OBJ(m, BANIDX_MAGIC); + m->time = t1; + m->ban = b; + AZ(VRBT_INSERT(banidx_s, &banidx, m)); + best = b; + } + PTOK(pthread_mutex_unlock(&banidxmtx)); + return (best); +} + +void +BANIDX_fini(void) +{ + struct metaban *m, *mm; + + VRBT_FOREACH_SAFE(m, banidx_s, &banidx, mm) { + VRBT_REMOVE(banidx_s, &banidx, m); + FREE_OBJ(m); + } +} From nils.goroll at uplex.de Tue Apr 15 08:03:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 15 Apr 2025 08:03:05 +0000 (UTC) Subject: [master] 48cf8867c vmod_debug: Add a length checking VDP Message-ID: <20250415080305.ABC92105DD2@lists.varnish-cache.org> commit 48cf8867c201976ccc1b2ac08ae43690420ad2fa Author: Nils Goroll Date: Tue Apr 15 09:48:22 2025 +0200 vmod_debug: Add a length checking VDP diff --git a/bin/varnishtest/tests/m00059.vtc b/bin/varnishtest/tests/m00059.vtc index 596bf87c6..19eb8ce35 100644 --- a/bin/varnishtest/tests/m00059.vtc +++ b/bin/varnishtest/tests/m00059.vtc @@ -1,4 +1,4 @@ -varnishtest "VMOD debug.chksha256" +varnishtest "VMOD debug.chk*" server s1 { rxreq @@ -6,6 +6,7 @@ server s1 { txresp \ -hdr "sha256: 9cbca99698fee7cefd93bc6db1c53226fdecae730197fd793a54e170a30af045" \ -hdr "crc32: 3177021206" \ + -hdr "len: 28" \ -hdr "Transfer-Encoding: chunked" -nolen chunked "Ponto Facto, " delay 1 @@ -17,6 +18,7 @@ server s1 { txresp \ -hdr "sha256: 9cbca99698fee7cefd93bc6db1c53226fdecae730197fd793a54e170a30af045" \ -hdr "crc32: 3177021206" \ + -hdr "len: 0" \ -body "" } -start @@ -32,12 +34,14 @@ varnish v1 \ debug.chksha256(blob.decode(HEX, encoded=resp.http.sha256), panic); debug.chkcrc32(std.integer(resp.http.crc32), panic); + debug.chklen(std.bytes(resp.http.len), panic); } else { debug.chksha256(blob.decode(HEX, encoded=resp.http.sha256), log); debug.chkcrc32(std.integer(resp.http.crc32), log); + debug.chklen(std.bytes(resp.http.len), log); } - set resp.filters += " debug.chksha256 debug.chkcrc32"; + set resp.filters += " debug.chksha256 debug.chkcrc32 debug.chklen"; } } -start diff --git a/vmod/vmod_debug.vcc b/vmod/vmod_debug.vcc index 1d531cc8c..fcf7cca27 100644 --- a/vmod/vmod_debug.vcc +++ b/vmod/vmod_debug.vcc @@ -440,6 +440,12 @@ be hanged to zero. Any larger value will be taken modulo UINT32_MAX. The *mode* argument behaves as for `debug.chksha256()`_. +$Function VOID chklen(BYTES expected, ENUM {log, panic, panic_unless_error} mode) + +Configure the expected length for the debug.chklen VDP. This function does not +push the VDP. + +The *mode* argument behaves as for `debug.chksha256()`_. $Function VOID use_reembarking_http1() $Restrict vcl_deliver diff --git a/vmod/vmod_debug_filters.c b/vmod/vmod_debug_filters.c index 464e95458..cb1dd2bd0 100644 --- a/vmod/vmod_debug_filters.c +++ b/vmod/vmod_debug_filters.c @@ -347,8 +347,9 @@ static const struct vdp xyzzy_vdp_slow = { }; /* - * checksum VDP: - * test that the stream of bytes has a certain checksum and either log + * check VDPs: + * + * test that the stream of bytes has a certain checksum or length and either log * or panic * * The sha256 and crc32 variants are basically identical, but the amount of @@ -377,6 +378,13 @@ struct vdp_chkcrc32_cfg_s { uint32_t expected; }; +struct vdp_chklen_cfg_s { + unsigned magic; +#define VDP_CHKLEN_CFG_MAGIC 0x08cf3426 + enum vdp_chk_mode_e mode; + size_t expected; +}; + struct vdp_chksha256_s { unsigned magic; #define VDP_CHKSHA256_MAGIC 0x6856e913 @@ -395,8 +403,17 @@ struct vdp_chkcrc32_s { struct vdp_chkcrc32_cfg_s *cfg; }; +struct vdp_chklen_s { + unsigned magic; +#define VDP_CHKLEN_MAGIC 0x029811f5 + unsigned called; + size_t bytes; + struct vdp_chklen_cfg_s *cfg; +}; + static const void * const chksha256_priv_id = &chksha256_priv_id; static const void * const chkcrc32_priv_id = &chkcrc32_priv_id; +static const void * const chklen_priv_id = &chklen_priv_id; static int v_matchproto_(vdp_init_f) xyzzy_chksha256_init(VRT_CTX, struct vdp_ctx *vdc, void **priv) @@ -456,6 +473,35 @@ xyzzy_chkcrc32_init(VRT_CTX, struct vdp_ctx *vdc, void **priv) return (0); } +static int v_matchproto_(vdp_init_f) +xyzzy_chklen_init(VRT_CTX, struct vdp_ctx *vdc, void **priv) +{ + struct vdp_chklen_s *vdps; + struct vmod_priv *p; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC); + CHECK_OBJ_ORNULL(vdc->oc, OBJCORE_MAGIC); + CHECK_OBJ_NOTNULL(vdc->hp, HTTP_MAGIC); + AN(vdc->clen); + AN(priv); + + WS_TASK_ALLOC_OBJ(ctx, vdps, VDP_CHKLEN_MAGIC); + if (vdps == NULL) + return (-1); + AZ(vdps->bytes); + + p = VRT_priv_task_get(ctx, chklen_priv_id); + if (p == NULL) + return (-1); + + assert(p->len == sizeof(struct vdp_chklen_cfg_s)); + CAST_OBJ_NOTNULL(vdps->cfg, p->priv, VDP_CHKLEN_CFG_MAGIC); + *priv = vdps; + + return (0); +} + static int v_matchproto_(vdp_bytes_f) xyzzy_chksha256_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv, const void *ptr, ssize_t len) @@ -484,6 +530,18 @@ xyzzy_chkcrc32_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv, return (VDP_bytes(vdc, act, ptr, len)); } +static int v_matchproto_(vdp_bytes_f) +xyzzy_chklen_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv, + const void *ptr, ssize_t len) +{ + struct vdp_chklen_s *vdps; + + CAST_OBJ_NOTNULL(vdps, *priv, VDP_CHKLEN_MAGIC); + vdps->called++; + vdps->bytes += len; + return (VDP_bytes(vdc, act, ptr, len)); +} + static int v_matchproto_(vdp_fini_f) xyzzy_chksha256_fini(struct vdp_ctx *vdc, void **priv) { @@ -563,6 +621,38 @@ xyzzy_chkcrc32_fini(struct vdp_ctx *vdc, void **priv) return (0); } +static int v_matchproto_(vdp_fini_f) +xyzzy_chklen_fini(struct vdp_ctx *vdc, void **priv) +{ + enum vdp_chk_mode_e mode; + struct vdp_chklen_s *vdps; + + (void) vdc; + AN(priv); + if (*priv == NULL) + return (0); + TAKE_OBJ_NOTNULL(vdps, priv, VDP_CHKLEN_MAGIC); + + if (vdps->bytes == vdps->cfg->expected) + return (0); + + mode = vdps->cfg->mode; + if (mode == VDP_CHK_PANIC_UNLESS_ERROR) + mode = (vdps->called == 0 || vdc->retval != 0) ? VDP_CHK_LOG : VDP_CHK_PANIC; + + if (mode == VDP_CHK_LOG) { + VSLb(vdc->vsl, SLT_Debug, "length mismatch"); + VSLb(vdc->vsl, SLT_Debug, "got: %zd", vdps->bytes); + VSLb(vdc->vsl, SLT_Debug, "exp: %zd", vdps->cfg->expected); + } + else if (mode == VDP_CHK_PANIC) + WRONG("body length"); + else + WRONG("mode"); + + return (0); +} + static const struct vdp xyzzy_vdp_chksha256 = { .name = "debug.chksha256", .init = xyzzy_chksha256_init, @@ -577,6 +667,13 @@ static const struct vdp xyzzy_vdp_chkcrc32 = { .fini = xyzzy_chkcrc32_fini, }; +static const struct vdp xyzzy_vdp_chklen = { + .name = "debug.chklen", + .init = xyzzy_chklen_init, + .bytes = xyzzy_chklen_bytes, + .fini = xyzzy_chklen_fini, +}; + #define chkcfg(ws, cfg, magic, id, mode_e) do { \ struct vmod_priv *p = VRT_priv_task(ctx, id); \ \ @@ -632,6 +729,18 @@ xyzzy_chkcrc32(VRT_CTX, VCL_INT expected, VCL_ENUM mode_e) cfg->expected = (uintmax_t)expected % UINT32_MAX; } +VCL_VOID v_matchproto_(td_xyzzy_debug_chklen) +xyzzy_chklen(VRT_CTX, VCL_BYTES expected, VCL_ENUM mode_e) +{ + struct vdp_chklen_cfg_s *cfg; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + + chkcfg(ctx->ws, cfg, VDP_CHKLEN_CFG_MAGIC, chklen_priv_id, mode_e); + + cfg->expected = expected; +} + /********************************************************************** * reserve thread_workspace */ @@ -676,6 +785,7 @@ debug_add_filters(VRT_CTX) AZ(VRT_AddFilter(ctx, &xyzzy_vfp_slow, &xyzzy_vdp_slow)); AZ(VRT_AddFilter(ctx, NULL, &xyzzy_vdp_chksha256)); AZ(VRT_AddFilter(ctx, NULL, &xyzzy_vdp_chkcrc32)); + AZ(VRT_AddFilter(ctx, NULL, &xyzzy_vdp_chklen)); AZ(VRT_AddFilter(ctx, NULL, &xyzzy_vdp_awshog)); } @@ -688,5 +798,6 @@ debug_remove_filters(VRT_CTX) VRT_RemoveFilter(ctx, NULL, &xyzzy_vdp_chunked); VRT_RemoveFilter(ctx, NULL, &xyzzy_vdp_chksha256); VRT_RemoveFilter(ctx, NULL, &xyzzy_vdp_chkcrc32); + VRT_RemoveFilter(ctx, NULL, &xyzzy_vdp_chklen); VRT_RemoveFilter(ctx, NULL, &xyzzy_vdp_awshog); } From dridi.boukelmoune at gmail.com Tue Apr 15 10:34:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 15 Apr 2025 10:34:05 +0000 (UTC) Subject: [master] d4cad81f9 param: Bump maximum http_req_overflow_status to 500 Message-ID: <20250415103405.93E4E10DD2D@lists.varnish-cache.org> commit d4cad81f97e6d214d4326d99e39dbca7a56e362b Author: Dridi Boukelmoune Date: Mon Mar 31 11:46:43 2025 +0200 param: Bump maximum http_req_overflow_status to 500 There are only two hard things in Computer Science^W^WVarnish: - cache invalidation - naming parameters - off by one error status codes diff --git a/include/tbl/params.h b/include/tbl/params.h index c66c3e8f4..9f0f581b2 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -655,7 +655,7 @@ PARAM_SIMPLE( /* name */ http_req_overflow_status, /* type */ uint_orzero, /* min */ "400", - /* max */ "499", + /* max */ "500", /* def */ "0", /* units */ "HTTP status code or 0 to disable", /* descr */ @@ -665,7 +665,9 @@ PARAM_SIMPLE( "Note that there is no standard HTTP status which exactly matches " "the implementation of http_req_size. 414 applies to the URL only, " "while 413 applies to the request body. 400 is probably the least " - "incorrect alternative value to sending no response at all (0)." + "incorrect alternative value to sending no response at all (0). It " + "can also be seen as an internal error on the Varnish side due to " + "configured limits, so 500 is also allowed." ) PARAM_SIMPLE( From walid.boudebouda at gmail.com Tue Apr 15 12:53:05 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Tue, 15 Apr 2025 12:53:05 +0000 (UTC) Subject: [master] 393040a3b vtc: Correctly indent u00020 with tabs Message-ID: <20250415125305.66A31112653@lists.varnish-cache.org> commit 393040a3b89316e5e7b5683ac92c491fd8022c9e Author: Walid Boudebouda Date: Tue Apr 15 14:47:39 2025 +0200 vtc: Correctly indent u00020 with tabs This caused the last shell block to always succeed because the EOF was taken as part of the file content, along with the diff command, which was therefore never executed diff --git a/bin/varnishtest/tests/u00020.vtc b/bin/varnishtest/tests/u00020.vtc index 84a8c71c3..795ad4e2d 100644 --- a/bin/varnishtest/tests/u00020.vtc +++ b/bin/varnishtest/tests/u00020.vtc @@ -48,24 +48,24 @@ varnish v1 -stop # Test things we receive from the backend server s1 { - rxreq - txresp -status 202 -hdr "beresp: origin" -hdr "unset: origin" + rxreq + txresp -status 202 -hdr "beresp: origin" -hdr "unset: origin" } -start varnish v1 -vcl+backend { - sub vcl_backend_response { + sub vcl_backend_response { set beresp.http.beresp = "vbr-updated"; set beresp.status = 200; unset beresp.http.unset; - } + } } -start client c1 { - txreq - rxresp + txreq + rxresp } -run @@ -110,9 +110,9 @@ client c1 { } -run shell { - varnishncsa -n ${v1_name} -d -c -F '%s %{resp}o %{unset}o %{added}o' > ncsa_sc.txt + varnishncsa -n ${v1_name} -d -c -F '%s %{resp}o %{unset}o %{added}o' > ncsa_sc.txt - cat >expected_sc.txt <<-EOF + cat >expected_sc.txt <<-EOF 201 deliver-updated - deliver EOF diff -u expected_sc.txt ncsa_sc.txt @@ -159,10 +159,10 @@ client c1 { shell { - varnishncsa -n ${v1_name} -d -c -F '%H %{reqhdr}i %{notreceived}i %{unset}i %m %q %U %u' > ncsa_rc.txt + varnishncsa -n ${v1_name} -d -c -F '%H %{reqhdr}i %{notreceived}i %{unset}i %m %q %U %u' > ncsa_rc.txt - cat >expected_rc.txt <<-EOF + cat >expected_rc.txt <<-EOF HTTP/1.1 client-header - client POST ?q=clientQuerry /client-url client - EOF - diff -u expected_rc.txt ncsa_rc.txt + EOF + diff -u expected_rc.txt ncsa_rc.txt } From walid.boudebouda at gmail.com Wed Apr 16 08:35:05 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Wed, 16 Apr 2025 08:35:05 +0000 (UTC) Subject: [master] 184c8980e VRT_VSC_Alloc() renamed to VRT_VSC_Allocv() Message-ID: <20250416083505.8B2ED11237F@lists.varnish-cache.org> commit 184c8980ed45d5940d4bbc2dd6121cfc4b43846c Author: Guillaume Quintard Date: Fri Apr 11 09:22:28 2025 -0700 VRT_VSC_Alloc() renamed to VRT_VSC_Allocv() diff --git a/bin/varnishd/common/common_vsc.c b/bin/varnishd/common/common_vsc.c index 8455e4d95..6c6cc9de3 100644 --- a/bin/varnishd/common/common_vsc.c +++ b/bin/varnishd/common/common_vsc.c @@ -135,7 +135,7 @@ VRT_VSC_Reveal(const struct vsc_seg *vsg) } void * -VRT_VSC_Alloc(struct vsmw_cluster *vc, struct vsc_seg **sg, +VRT_VSC_Allocv(struct vsmw_cluster *vc, struct vsc_seg **sg, const char *nm, size_t sd, const unsigned char *jp, size_t sj, const char *fmt, va_list va) { diff --git a/include/vrt.h b/include/vrt.h index 2252cdc74..0dd5a064d 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -60,6 +60,7 @@ * XX.X (unreleased) * typedef hdr_t added * struct gethdr_s.what changed to hdr_t + * VRT_VSC_Alloc() renamed to VRT_VSC_Allocv() * 21.0 (2025-03-17) * VRT_u_req_grace() added * VRT_u_req_ttl() added @@ -852,7 +853,7 @@ struct vsmw_cluster *VRT_VSM_Cluster_New(VRT_CTX, size_t); void VRT_VSM_Cluster_Destroy(VRT_CTX, struct vsmw_cluster **); #ifdef va_start // XXX: hackish -void *VRT_VSC_Alloc(struct vsmw_cluster *, struct vsc_seg **, +void *VRT_VSC_Allocv(struct vsmw_cluster *, struct vsc_seg **, const char *, size_t, const unsigned char *, size_t, const char *, va_list); #endif void VRT_VSC_Destroy(const char *, struct vsc_seg *); diff --git a/lib/libvsc/vsctool.py b/lib/libvsc/vsctool.py index db2a396dc..85e2b07c3 100755 --- a/lib/libvsc/vsctool.py +++ b/lib/libvsc/vsctool.py @@ -270,7 +270,7 @@ class CounterSet(object): fo.write("\t" + self.struct + " *retval;\n") fo.write("\n") fo.write("\tva_start(ap, fmt);\n") - fo.write("\tretval = VRT_VSC_Alloc") + fo.write("\tretval = VRT_VSC_Allocv") fo.write("(vc, sg, vsc_" + self.name + "_name, ") fo.write("VSC_" + self.name + "_size,\n") fo.write("\t vsc_" + self.name + "_json, ") From walid.boudebouda at gmail.com Wed Apr 16 08:35:05 2025 From: walid.boudebouda at gmail.com (Walid Boudebouda) Date: Wed, 16 Apr 2025 08:35:05 +0000 (UTC) Subject: [master] 9350950e5 new VRT_VSC_Alloc() added Message-ID: <20250416083505.A277B112382@lists.varnish-cache.org> commit 9350950e557b5bf152c979db2b550cd90b866000 Author: Guillaume Quintard Date: Thu Mar 27 14:50:37 2025 -0700 new VRT_VSC_Alloc() added diff --git a/bin/varnishd/common/common_vsc.c b/bin/varnishd/common/common_vsc.c index 6c6cc9de3..1918ff4d5 100644 --- a/bin/varnishd/common/common_vsc.c +++ b/bin/varnishd/common/common_vsc.c @@ -183,6 +183,20 @@ VRT_VSC_Allocv(struct vsmw_cluster *vc, struct vsc_seg **sg, return (vsg->ptr); } +void * +VRT_VSC_Alloc(struct vsmw_cluster *vc, struct vsc_seg **sg, + const char *nm, size_t sd, + const unsigned char *jp, size_t sj, const char *fmt, ...) +{ + va_list ap; + void *retval; + + va_start(ap, fmt); + retval = VRT_VSC_Allocv(vc, sg, nm, sd, jp, sj, fmt, ap); + va_end(ap); + return(retval); +} + void VRT_VSC_Destroy(const char *nm, struct vsc_seg *vsg) { diff --git a/include/vrt.h b/include/vrt.h index 0dd5a064d..712735b1d 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -61,6 +61,7 @@ * typedef hdr_t added * struct gethdr_s.what changed to hdr_t * VRT_VSC_Alloc() renamed to VRT_VSC_Allocv() + * new VRT_VSC_Alloc() added * 21.0 (2025-03-17) * VRT_u_req_grace() added * VRT_u_req_ttl() added @@ -855,6 +856,8 @@ void VRT_VSM_Cluster_Destroy(VRT_CTX, struct vsmw_cluster **); #ifdef va_start // XXX: hackish void *VRT_VSC_Allocv(struct vsmw_cluster *, struct vsc_seg **, const char *, size_t, const unsigned char *, size_t, const char *, va_list); +void *VRT_VSC_Alloc(struct vsmw_cluster *, struct vsc_seg **, + const char *, size_t, const unsigned char *, size_t, const char *, ...); #endif void VRT_VSC_Destroy(const char *, struct vsc_seg *); void VRT_VSC_Hide(const struct vsc_seg *); From nils.goroll at uplex.de Thu Apr 17 09:08:06 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 17 Apr 2025 09:08:06 +0000 (UTC) Subject: [master] 30fca975e cache_ban: Flexelint banidx Message-ID: <20250417090806.20D2C11BCAE@lists.varnish-cache.org> commit 30fca975e4e596a541106997f5cf5f282da164ac Author: Nils Goroll Date: Thu Apr 17 11:06:28 2025 +0200 cache_ban: Flexelint banidx Ref f8d611fb54f936006faefba07d54b20300ead611 diff --git a/bin/varnishd/cache/cache_ban_idx.c b/bin/varnishd/cache/cache_ban_idx.c index 11a5886a0..7857ffb20 100644 --- a/bin/varnishd/cache/cache_ban_idx.c +++ b/bin/varnishd/cache/cache_ban_idx.c @@ -44,9 +44,6 @@ #include "cache_varnishd.h" #include "cache_ban.h" -#include "cache_objhead.h" - -#include "vtree.h" struct metaban { unsigned magic; @@ -58,7 +55,7 @@ struct metaban { }; static inline int -metaban_cmp(const struct metaban *i1, struct metaban *i2) +metaban_cmp(const struct metaban *i1, const struct metaban *i2) { if (i1->time < i2->time) return (-1); @@ -67,10 +64,33 @@ metaban_cmp(const struct metaban *i1, struct metaban *i2) return (0); } +/* why does vtree.h not declare name and elm const ? */ +#define VRBT_GENERATE_NFINDc(name, type, field, cmp, attr) \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_VRBT_NFIND(const struct name *head, const struct type *elm) \ +{ \ + struct type *tmp = VRBT_ROOT(head); \ + struct type *res = NULL; \ + __typeof(cmp(NULL, NULL)) comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = VRBT_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = VRBT_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} + VRBT_HEAD(banidx_s, metaban); VRBT_GENERATE_REMOVE_COLOR(banidx_s, metaban, tree, static) VRBT_GENERATE_REMOVE(banidx_s, metaban, tree, static) -VRBT_GENERATE_NFIND(banidx_s, metaban, tree, metaban_cmp, static) +VRBT_GENERATE_NFINDc(banidx_s, metaban, tree, metaban_cmp, static) VRBT_GENERATE_INSERT_COLOR(banidx_s, metaban, tree, static) VRBT_GENERATE_INSERT_FINISH(banidx_s, metaban, tree, static) VRBT_GENERATE_INSERT(banidx_s, metaban, tree, metaban_cmp, static) @@ -83,7 +103,8 @@ static pthread_mutex_t banidxmtx = PTHREAD_MUTEX_INITIALIZER; struct ban * BANIDX_lookup(vtim_real t0) { - struct metaban *m, needle = {0, .time = t0}; + struct metaban *m; //lint -e429 not freed or returned + struct metaban needle = {0, .time = t0}; struct ban *best = NULL, *b = NULL; vtim_real t1; @@ -114,6 +135,7 @@ BANIDX_lookup(vtim_real t0) if (t1 < t0) break; ALLOC_OBJ(m, BANIDX_MAGIC); + AN(m); m->time = t1; m->ban = b; AZ(VRBT_INSERT(banidx_s, &banidx, m)); From dridi at varni.sh Thu Apr 17 10:03:08 2025 From: dridi at varni.sh (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 10:03:08 +0000 Subject: [master] 30fca975e cache_ban: Flexelint banidx In-Reply-To: <20250417090806.20D2C11BCAE@lists.varnish-cache.org> References: <20250417090806.20D2C11BCAE@lists.varnish-cache.org> Message-ID: On Thu, Apr 17, 2025 at 9:08?AM Nils Goroll wrote: > > > commit 30fca975e4e596a541106997f5cf5f282da164ac > Author: Nils Goroll > Date: Thu Apr 17 11:06:28 2025 +0200 > > cache_ban: Flexelint banidx > > Ref f8d611fb54f936006faefba07d54b20300ead611 > > diff --git a/bin/varnishd/cache/cache_ban_idx.c b/bin/varnishd/cache/cache_ban_idx.c > index 11a5886a0..7857ffb20 100644 > --- a/bin/varnishd/cache/cache_ban_idx.c > +++ b/bin/varnishd/cache/cache_ban_idx.c > @@ -44,9 +44,6 @@ > > #include "cache_varnishd.h" > #include "cache_ban.h" > -#include "cache_objhead.h" > - > -#include "vtree.h" > > struct metaban { > unsigned magic; > @@ -58,7 +55,7 @@ struct metaban { > }; > > static inline int > -metaban_cmp(const struct metaban *i1, struct metaban *i2) > +metaban_cmp(const struct metaban *i1, const struct metaban *i2) > { > if (i1->time < i2->time) > return (-1); > @@ -67,10 +64,33 @@ metaban_cmp(const struct metaban *i1, struct metaban *i2) > return (0); > } > > +/* why does vtree.h not declare name and elm const ? */ > +#define VRBT_GENERATE_NFINDc(name, type, field, cmp, attr) \ Why not patch vtree.h to align NFIND with FIND regarding const arguments? (and maybe try to report the lack of const upstream) Adding a specific generator here just to remove a flexlint complaint is a bit extreme, especially since it appears that we already patch FIND to constify arguments when we import it. See the lack of const for both at least here: https://github.com/freebsd/freebsd-src/blob/main/sys/sys/tree.h It's probably just that we never used NFIND before so flexelint didn't have a reason to complain until now. Dridi > +/* Finds the first node greater than or equal to the search key */ \ > +attr struct type * \ > +name##_VRBT_NFIND(const struct name *head, const struct type *elm) \ > +{ \ > + struct type *tmp = VRBT_ROOT(head); \ > + struct type *res = NULL; \ > + __typeof(cmp(NULL, NULL)) comp; \ > + while (tmp) { \ > + comp = cmp(elm, tmp); \ > + if (comp < 0) { \ > + res = tmp; \ > + tmp = VRBT_LEFT(tmp, field); \ > + } \ > + else if (comp > 0) \ > + tmp = VRBT_RIGHT(tmp, field); \ > + else \ > + return (tmp); \ > + } \ > + return (res); \ > +} > + > VRBT_HEAD(banidx_s, metaban); > VRBT_GENERATE_REMOVE_COLOR(banidx_s, metaban, tree, static) > VRBT_GENERATE_REMOVE(banidx_s, metaban, tree, static) > -VRBT_GENERATE_NFIND(banidx_s, metaban, tree, metaban_cmp, static) > +VRBT_GENERATE_NFINDc(banidx_s, metaban, tree, metaban_cmp, static) > VRBT_GENERATE_INSERT_COLOR(banidx_s, metaban, tree, static) > VRBT_GENERATE_INSERT_FINISH(banidx_s, metaban, tree, static) > VRBT_GENERATE_INSERT(banidx_s, metaban, tree, metaban_cmp, static) > @@ -83,7 +103,8 @@ static pthread_mutex_t banidxmtx = PTHREAD_MUTEX_INITIALIZER; > struct ban * > BANIDX_lookup(vtim_real t0) > { > - struct metaban *m, needle = {0, .time = t0}; > + struct metaban *m; //lint -e429 not freed or returned > + struct metaban needle = {0, .time = t0}; > struct ban *best = NULL, *b = NULL; > vtim_real t1; > > @@ -114,6 +135,7 @@ BANIDX_lookup(vtim_real t0) > if (t1 < t0) > break; > ALLOC_OBJ(m, BANIDX_MAGIC); > + AN(m); > m->time = t1; > m->ban = b; > AZ(VRBT_INSERT(banidx_s, &banidx, m)); > _______________________________________________ > varnish-commit mailing list > varnish-commit at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit From dridi at varni.sh Thu Apr 17 10:06:46 2025 From: dridi at varni.sh (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 10:06:46 +0000 Subject: [master] 30fca975e cache_ban: Flexelint banidx In-Reply-To: References: <20250417090806.20D2C11BCAE@lists.varnish-cache.org> Message-ID: > It's probably just that we never used NFIND before so flexelint didn't > have a reason to complain until now. I was very wrong, we mean to constify them! See tools/import_vtree_from_freebsd.sh: /(VRBT_FIND|VRBT_NFIND|VRBT_MINMAX)/{ s/struct name [*]/const struct name */ s/, struct type [*]/, const struct type */ } I'm not sure what went wrong last time it got imported. Dridi From nils.goroll at uplex.de Thu Apr 17 10:13:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 17 Apr 2025 10:13:05 +0000 (UTC) Subject: [master] 6aeb824f1 doc: Document how vmodtool.py generates C symbol names Message-ID: <20250417101305.41D7211E06B@lists.varnish-cache.org> commit 6aeb824f115a5c9693484cec4021b13964a664d0 Author: Nils Goroll Date: Thu Apr 17 12:11:33 2025 +0200 doc: Document how vmodtool.py generates C symbol names in preparation of the changes from #4240 "write the documentation first" did not always apply in the past... diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index cf28deac0..781929383 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -121,7 +121,7 @@ For the std VMOD, the compiled vcc_if.h file looks like this:: vmod_event_f event_function; Those are your C prototypes. Notice the ``vmod_`` prefix on the -function names. +function names, more on that in :ref:`ref-vmod-symbols`. Named arguments and default values ---------------------------------- @@ -512,6 +512,51 @@ VOID Can only be used for return-value, which makes the function a VCL procedure. +.. _ref-vmod-symbols: + +C symbols +========= + +Through generation of ``vcc_if.h``, ``vmodtool.py`` pre-defines the names of +most symbols on the C side of the vmod interface, namely: + +* function names as *_* + +* event handler names as *_* + +* method names as *__*, with two special methods named + + * ``_init`` for the constructor and + * ``_fini`` for the destructor + +* class struct names as *__* + +* argument struct names for support of optional arguments as + *arg___* for functions and + *arg____* for methods, with member names + + * *valid_* for the flag of optional arguments being present and + * ** for the argument name + +* enum values as *enum___* + +For the above, the ** placeholders are defined as: + +** + The ``$Prefix`` stanza value, if defined in the ``.vcc`` file, or + ``vmod`` by default. + +** + The vmod name fro the ``$Module`` stanza of the ``.vcc`` file. + +** + The function or method argument name + +The other placeholders should be self-explanatory as the name of the respective +function, class, method or handler name. + +In summary, only some symbol names (those with **) can be influenced by +the vmod author. .. _ref-vmod-private-pointers: From dridi.boukelmoune at gmail.com Thu Apr 17 11:03:04 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 11:03:04 +0000 (UTC) Subject: [master] ac41f195b Revert "cache_ban: Flexelint banidx" Message-ID: <20250417110305.0E9CE4CAB@lists.varnish-cache.org> commit ac41f195b83df7a6db5df3e7c6f97a0af469f668 Author: Dridi Boukelmoune Date: Thu Apr 17 12:55:46 2025 +0200 Revert "cache_ban: Flexelint banidx" This reverts commit 30fca975e4e596a541106997f5cf5f282da164ac. diff --git a/bin/varnishd/cache/cache_ban_idx.c b/bin/varnishd/cache/cache_ban_idx.c index 7857ffb20..11a5886a0 100644 --- a/bin/varnishd/cache/cache_ban_idx.c +++ b/bin/varnishd/cache/cache_ban_idx.c @@ -44,6 +44,9 @@ #include "cache_varnishd.h" #include "cache_ban.h" +#include "cache_objhead.h" + +#include "vtree.h" struct metaban { unsigned magic; @@ -55,7 +58,7 @@ struct metaban { }; static inline int -metaban_cmp(const struct metaban *i1, const struct metaban *i2) +metaban_cmp(const struct metaban *i1, struct metaban *i2) { if (i1->time < i2->time) return (-1); @@ -64,33 +67,10 @@ metaban_cmp(const struct metaban *i1, const struct metaban *i2) return (0); } -/* why does vtree.h not declare name and elm const ? */ -#define VRBT_GENERATE_NFINDc(name, type, field, cmp, attr) \ -/* Finds the first node greater than or equal to the search key */ \ -attr struct type * \ -name##_VRBT_NFIND(const struct name *head, const struct type *elm) \ -{ \ - struct type *tmp = VRBT_ROOT(head); \ - struct type *res = NULL; \ - __typeof(cmp(NULL, NULL)) comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) { \ - res = tmp; \ - tmp = VRBT_LEFT(tmp, field); \ - } \ - else if (comp > 0) \ - tmp = VRBT_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (res); \ -} - VRBT_HEAD(banidx_s, metaban); VRBT_GENERATE_REMOVE_COLOR(banidx_s, metaban, tree, static) VRBT_GENERATE_REMOVE(banidx_s, metaban, tree, static) -VRBT_GENERATE_NFINDc(banidx_s, metaban, tree, metaban_cmp, static) +VRBT_GENERATE_NFIND(banidx_s, metaban, tree, metaban_cmp, static) VRBT_GENERATE_INSERT_COLOR(banidx_s, metaban, tree, static) VRBT_GENERATE_INSERT_FINISH(banidx_s, metaban, tree, static) VRBT_GENERATE_INSERT(banidx_s, metaban, tree, metaban_cmp, static) @@ -103,8 +83,7 @@ static pthread_mutex_t banidxmtx = PTHREAD_MUTEX_INITIALIZER; struct ban * BANIDX_lookup(vtim_real t0) { - struct metaban *m; //lint -e429 not freed or returned - struct metaban needle = {0, .time = t0}; + struct metaban *m, needle = {0, .time = t0}; struct ban *best = NULL, *b = NULL; vtim_real t1; @@ -135,7 +114,6 @@ BANIDX_lookup(vtim_real t0) if (t1 < t0) break; ALLOC_OBJ(m, BANIDX_MAGIC); - AN(m); m->time = t1; m->ban = b; AZ(VRBT_INSERT(banidx_s, &banidx, m)); From dridi.boukelmoune at gmail.com Thu Apr 17 11:03:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 11:03:05 +0000 (UTC) Subject: [master] 956d529fb vtree: Constify generated NFIND arguments Message-ID: <20250417110305.21CF64CAD@lists.varnish-cache.org> commit 956d529fb8236596e3bd2c01e78e4dac9ec13b27 Author: Dridi Boukelmoune Date: Thu Apr 17 12:58:29 2025 +0200 vtree: Constify generated NFIND arguments I expected the tools/import_vtree_from_freebsd.sh script to take care of it when it was last updated. diff --git a/include/vtree.h b/include/vtree.h index d36233137..2d9cdf9cd 100644 --- a/include/vtree.h +++ b/include/vtree.h @@ -450,7 +450,7 @@ struct { \ #define VRBT_PROTOTYPE_FIND(name, type, attr) \ attr struct type *name##_VRBT_FIND(const struct name *, const struct type *) #define VRBT_PROTOTYPE_NFIND(name, type, attr) \ - attr struct type *name##_VRBT_NFIND(struct name *, struct type *) + attr struct type *name##_VRBT_NFIND(const struct name *, const struct type *) #define VRBT_PROTOTYPE_NEXT(name, type, attr) \ attr struct type *name##_VRBT_NEXT(struct type *) #define VRBT_PROTOTYPE_INSERT_NEXT(name, type, attr) \ From dridi.boukelmoune at gmail.com Thu Apr 17 11:03:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 11:03:05 +0000 (UTC) Subject: [master] ec2ec1355 ban: Restore banidx flexelint Message-ID: <20250417110305.494D74CB2@lists.varnish-cache.org> commit ec2ec1355c255131781ba945077fcc8262144a56 Author: Dridi Boukelmoune Date: Thu Apr 17 13:01:58 2025 +0200 ban: Restore banidx flexelint Refs 30fca975e4e596a541106997f5cf5f282da164ac diff --git a/bin/varnishd/cache/cache_ban_idx.c b/bin/varnishd/cache/cache_ban_idx.c index 11a5886a0..de1b7899a 100644 --- a/bin/varnishd/cache/cache_ban_idx.c +++ b/bin/varnishd/cache/cache_ban_idx.c @@ -44,9 +44,6 @@ #include "cache_varnishd.h" #include "cache_ban.h" -#include "cache_objhead.h" - -#include "vtree.h" struct metaban { unsigned magic; @@ -58,7 +55,7 @@ struct metaban { }; static inline int -metaban_cmp(const struct metaban *i1, struct metaban *i2) +metaban_cmp(const struct metaban *i1, const struct metaban *i2) { if (i1->time < i2->time) return (-1); @@ -83,7 +80,8 @@ static pthread_mutex_t banidxmtx = PTHREAD_MUTEX_INITIALIZER; struct ban * BANIDX_lookup(vtim_real t0) { - struct metaban *m, needle = {0, .time = t0}; + struct metaban *m; //lint -e429 not freed or returned + struct metaban needle = {0, .time = t0}; struct ban *best = NULL, *b = NULL; vtim_real t1; @@ -114,6 +112,7 @@ BANIDX_lookup(vtim_real t0) if (t1 < t0) break; ALLOC_OBJ(m, BANIDX_MAGIC); + AN(m); m->time = t1; m->ban = b; AZ(VRBT_INSERT(banidx_s, &banidx, m)); From dridi at varni.sh Thu Apr 17 11:35:13 2025 From: dridi at varni.sh (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 11:35:13 +0000 Subject: [master] 30fca975e cache_ban: Flexelint banidx In-Reply-To: References: <20250417090806.20D2C11BCAE@lists.varnish-cache.org> Message-ID: > I'm not sure what went wrong last time it got imported. It ain't the script's fault at least. I reverted this change and submitted a patch: https://github.com/varnishcache/varnish-cache/pull/4317 Dridi From nils.goroll at uplex.de Thu Apr 17 13:35:15 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 17 Apr 2025 15:35:15 +0200 Subject: [master] 956d529fb vtree: Constify generated NFIND arguments In-Reply-To: <20250417110305.21CF64CAD@lists.varnish-cache.org> References: <20250417110305.21CF64CAD@lists.varnish-cache.org> Message-ID: <97b9e516-7499-444e-a341-cb742eccd1f9@uplex.de> You only patched VRBT_PROTOTYPE_NFIND, not VRBT_GENERATE_NFIND On 17.04.25 13:03, Dridi Boukelmoune wrote: > > commit 956d529fb8236596e3bd2c01e78e4dac9ec13b27 > Author: Dridi Boukelmoune > Date: Thu Apr 17 12:58:29 2025 +0200 > > vtree: Constify generated NFIND arguments > > I expected the tools/import_vtree_from_freebsd.sh script to take care of > it when it was last updated. > > diff --git a/include/vtree.h b/include/vtree.h > index d36233137..2d9cdf9cd 100644 > --- a/include/vtree.h > +++ b/include/vtree.h > @@ -450,7 +450,7 @@ struct { \ > #define VRBT_PROTOTYPE_FIND(name, type, attr) \ > attr struct type *name##_VRBT_FIND(const struct name *, const struct type *) > #define VRBT_PROTOTYPE_NFIND(name, type, attr) \ > - attr struct type *name##_VRBT_NFIND(struct name *, struct type *) > + attr struct type *name##_VRBT_NFIND(const struct name *, const struct type *) > #define VRBT_PROTOTYPE_NEXT(name, type, attr) \ > attr struct type *name##_VRBT_NEXT(struct type *) > #define VRBT_PROTOTYPE_INSERT_NEXT(name, type, attr) \ > _______________________________________________ > varnish-commit mailing list > varnish-commit at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit -- Nils Goroll (he/him) ** * * UPLEX - Nils Goroll Systemoptimierung Scheffelstra?e 32 22301 Hamburg tel +49 40 28805731 mob +49 170 2723133 fax +49 40 42949753 xmpp://slink at jabber.int.uplex.de/ http://uplex.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_0x1DCD8F57A3868BD7.asc Type: application/pgp-keys Size: 3943 bytes Desc: OpenPGP public key URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From nils.goroll at uplex.de Thu Apr 17 13:37:04 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 17 Apr 2025 13:37:04 +0000 (UTC) Subject: [master] f2da1a3f3 vcc_expr: bring back cname Message-ID: <20250417133704.F2973632AB@lists.varnish-cache.org> commit f2da1a3f3652273bcb9152f2ef475f2ccfb91e3f Author: Nils Goroll Date: Wed Feb 19 15:34:13 2025 +0100 vcc_expr: bring back cname This reverts commit ab78f460dc0e4a3add6a1c6df8621d71ddf08583. diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 003f1513c..1e3a6e054 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -444,6 +444,7 @@ vcc_priv_arg(struct vcc *tl, const char *p, struct symbol *sym) struct func_arg { vcc_type_t type; const struct vjsn_val *enums; + const char *cname; const char *name; const char *val; struct expr *result; From nils.goroll at uplex.de Thu Apr 17 13:37:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 17 Apr 2025 13:37:05 +0000 (UTC) Subject: [master] 99efe0ec8 vmodtool: Add option to specify c names of arguments and avoid "bool" Message-ID: <20250417133705.5A028632AF@lists.varnish-cache.org> commit 99efe0ec8a2630eef04533869e63adef6b416b0d Author: Nils Goroll Date: Tue Dec 3 18:32:29 2024 +0100 vmodtool: Add option to specify c names of arguments and avoid "bool" I tried gcc version 15.0.0 20241203 and even without -std=c23, it would reserve "bool": In file included from vcc_std_if.c:10: vcc_std_if.h:78:33: error: two or more data types in declaration specifiers 78 | VCL_BOOL bool; | ^~~~ (and more) So this patch adds the option to specify the c name of arguments to vmod functions/methods by separating it with a colon in the spec in the VCC file. vclname:cname In the next commit, we use this facility to rename the "bool" argument to vmod_std functions to "boolean". Implementation -------------- The cname needs to be specified by the VMOD author because it is also used in the vmod implementation. Obviously, VCC needs to know that name, too, to generate argument structs, so we need to transport it from the VMOD to VCC via the JSON spec. A logical place for cname is next to the name, because the other attributes following in the argument spec array are optional. So this changes the JSON spec format, and, consequently, we need to increase the version number. So, ultimately, this is a breaking change with respect to vmodtool: One can not import vmods built before this change. We could add compatibility for this case, but as we have a tradition of forcing rebuilds with each release by bumping the VRT major number anyway, I did not see my time well spent on implementing backwards compatibility. Groundwork for the fix of #4294 diff --git a/bin/varnishtest/tests/m00003.vtc b/bin/varnishtest/tests/m00003.vtc index 22bd4ba71..0ace9b61d 100644 --- a/bin/varnishtest/tests/m00003.vtc +++ b/bin/varnishtest/tests/m00003.vtc @@ -59,12 +59,15 @@ varnish v1 -errvcl {Not string[2]} { import wrong; } filewrite ${tmpdir}/libvmod_wrong.so "VMOD_JSON_SPEC\x02" "[[\"$VBLA\"]]" "\x03" varnish v1 -errvcl {Not $VMOD[3]} { import wrong; } +filewrite ${tmpdir}/libvmod_wrong.so "VMOD_JSON_SPEC\x02" "[[\"$VMOD\",\"1.0\"]]" "\x03" +varnish v1 -errvcl {Syntax != 2.0} { import wrong; } + filewrite ${tmpdir}/libvmod_wrong.so "VMOD_JSON_SPEC\x02" filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "wrong", "Vmod_vmod_wrong_Func", "0000000000000000000000000000000000000000000000000000000000000000", @@ -82,7 +85,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "wrong", "Vmod_vmod_wrong_Func", "0000000000000000000000000000000000000000000000000000000000000000", @@ -103,7 +106,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "wrong", "Vmod_vmod_wrong_Func", "0000000000000000000000000000000000000000000000000000000000000000", @@ -123,7 +126,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "wrong", "Vmod_vmod_wrong_Func", "0000000000000000000000000000000000000000000000000000000000000000", @@ -141,7 +144,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "wrong", "Vmod_vmod_wrong_Func", "0000000000000000000000000000000000000000000000000000000000000000", @@ -163,7 +166,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "std", "Vmod_vmod_std_Func", "0000000000000000000000000000000000000000000000000000000000000000", diff --git a/bin/varnishtest/tests/m00055.vtc b/bin/varnishtest/tests/m00055.vtc index 7c4c70342..e41f61dde 100644 --- a/bin/varnishtest/tests/m00055.vtc +++ b/bin/varnishtest/tests/m00055.vtc @@ -16,7 +16,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so { [ [ "$VMOD", - "1.0", + "2.0", "wrong", "Vmod_vmod_wrong_Func", "0000000000000000000000000000000000000000000000000000000000000000", diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index 781929383..20cb31b46 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -196,6 +196,9 @@ declarations: with `n` starting at 1 and incrementing with the argument's position. +Optionally, the VCL and C argument names can be specified independently using +the ``:`` syntax. See :ref:`ref-vmod-symbols` for details. + .. _ref-vmod-vcl-c-objects: Objects and methods @@ -550,13 +553,14 @@ For the above, the ** placeholders are defined as: The vmod name fro the ``$Module`` stanza of the ``.vcc`` file. ** - The function or method argument name + The function or method argument *cname* or, if not given, *vclname* + as specified using the *:* syntax. The other placeholders should be self-explanatory as the name of the respective -function, class, method or handler name. +function, class, method or handler. -In summary, only some symbol names (those with **) can be influenced by -the vmod author. +In summary, symbol names can either be influenced by the vmod author globally +using ``$Prefix``, or using the *:* syntax for argument names. .. _ref-vmod-private-pointers: diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 1e3a6e054..280476245 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -558,7 +558,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, fa->result = vcc_priv_arg(tl, vvp->value, sym); vvp = VTAILQ_NEXT(vvp, list); if (vvp != NULL) - fa->name = vvp->value; + fa->cname = fa->name = vvp->value; continue; } fa->type = VCC_Type(vvp->value); @@ -567,6 +567,9 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (vvp != NULL) { fa->name = vvp->value; vvp = VTAILQ_NEXT(vvp, list); + AN(vvp); /* vmod_syntax 2.0 */ + fa->cname = vvp->value; + vvp = VTAILQ_NEXT(vvp, list); if (vvp != NULL) { fa->val = vvp->value; vvp = VTAILQ_NEXT(vvp, list); @@ -642,9 +645,9 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) { n++; if (fa->optional) { - AN(fa->name); + AN(fa->cname); bprintf(ssa, "\v1.valid_%s = %d,\n", - fa->name, fa->avail); + fa->cname, fa->avail); e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL); } if (fa->result == NULL && fa->type == ENUM && fa->val != NULL) @@ -652,8 +655,8 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (fa->result == NULL && fa->val != NULL) fa->result = vcc_mk_expr(fa->type, "%s", fa->val); if (fa->result != NULL && sa != NULL) { - if (fa->name) - bprintf(ssa, "\v1.%s = \v2,\n", fa->name); + if (fa->cname) + bprintf(ssa, "\v1.%s = \v2,\n", fa->cname); else bprintf(ssa, "\v1.arg%d = \v2,\n", n); e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result); diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c index 7e7b3b8af..6fe8b0450 100644 --- a/lib/libvcc/vcc_vmod.c +++ b/lib/libvcc/vcc_vmod.c @@ -162,7 +162,8 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim) AN(vv3); assert(vjsn_is_string(vv3)); vim->vmod_syntax = strtod(vv3->value, NULL); - assert (vim->vmod_syntax == 1.0); + if (vim->vmod_syntax != 2.0) + return ("Syntax != 2.0"); vv3 = VTAILQ_NEXT(vv3, list); AN(vv3); diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index a2e8969ee..e4be1760c 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -27,6 +27,10 @@ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. +# +# syntax version history: +# 1.0: initial +# 2.0: added cname (nm2) after argument name """ Read the first existing file from arguments or vmod.vcc and produce: @@ -319,7 +323,7 @@ class arg(CType): self.defval = x def jsonproto(self, jl): - jl.append([self.vt, self.nm, self.defval, self.spec]) + jl.append([self.vt, self.nm, self.nm2, self.defval, self.spec]) if self.opt: jl[-1].append(True) while jl[-1][-1] is None: @@ -385,6 +389,8 @@ class ProtoType(): err("arguments cannot be of type '%s'" % t.vt, warn=False) if t.nm is None: t.nm2 = "arg%d" % n + elif ':' in t.nm: + [t.nm, t.nm2] = t.nm.split(':') else: t.nm2 = t.nm self.args.append(t) @@ -466,8 +472,8 @@ class ProtoType(): s = "\n" + self.argstructname() + " {\n" for i in self.args: if i.opt: - assert i.nm is not None - s += "\tchar\t\t\tvalid_%s;\n" % i.nm + assert i.nm2 is not None + s += "\tchar\t\t\tvalid_%s;\n" % i.nm2 for i in self.args: s += "\t" + i.ct if len(i.ct) < 8: @@ -1163,7 +1169,7 @@ class vcc(): def iter_json(self, fnx): - jl = [["$VMOD", "1.0", self.modname, self.csn, self.file_id]] + jl = [["$VMOD", "2.0", self.modname, self.csn, self.file_id]] jl.append(["$CPROTO"]) for i in open(fnx): jl[-1].append(i.rstrip()) From nils.goroll at uplex.de Thu Apr 17 13:37:05 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 17 Apr 2025 13:37:05 +0000 (UTC) Subject: [master] bfdf6d440 vmod_std: Use new : syntax to avoid reserved C symbol "bool" Message-ID: <20250417133705.8CD85632B3@lists.varnish-cache.org> commit bfdf6d440b412cd4cfe7ec60772b839fc2e23c7a Author: Nils Goroll Date: Thu Apr 17 15:26:23 2025 +0200 vmod_std: Use new : syntax to avoid reserved C symbol "bool" Fixes #4294 diff --git a/vmod/vmod_std.vcc b/vmod/vmod_std.vcc index 9320147e8..2fb65f7bf 100644 --- a/vmod/vmod_std.vcc +++ b/vmod/vmod_std.vcc @@ -308,7 +308,7 @@ Example:: std.cache_req_body(std.bytes(real=10.0*1024)); $Function INT integer([STRING s], [INT fallback], - [BOOL bool], [BYTES bytes], [DURATION duration], [REAL real], + [BOOL bool:boolean], [BYTES bytes], [DURATION duration], [REAL real], [TIME time]) Returns an INT from a STRING, BOOL or other quantity. @@ -376,7 +376,7 @@ Example:: } $Function REAL real([STRING s], [REAL fallback], [INT integer], - [BOOL bool], [BYTES bytes], [DURATION duration], + [BOOL bool:boolean], [BYTES bytes], [DURATION duration], [TIME time]) Returns a REAL from a STRING, BOOL or other quantity. diff --git a/vmod/vmod_std_conversions.c b/vmod/vmod_std_conversions.c index c45410114..f8ef8d936 100644 --- a/vmod/vmod_std_conversions.c +++ b/vmod/vmod_std_conversions.c @@ -149,15 +149,15 @@ vmod_integer(VRT_CTX, struct VARGS(integer) *a) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - nargs = a->valid_s + a->valid_bool + a->valid_bytes + + nargs = a->valid_s + a->valid_boolean + a->valid_bytes + a->valid_duration + a->valid_real + a->valid_time; if (!onearg(ctx, "integer", nargs)) return (0); r = NAN; - if (a->valid_bool) - return (a->bool ? 1 : 0); + if (a->valid_boolean) + return (a->boolean ? 1 : 0); if (a->valid_bytes) return (a->bytes); @@ -245,7 +245,7 @@ vmod_real(VRT_CTX, struct VARGS(real) *a) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - nargs = a->valid_s + a->valid_integer + a->valid_bool + a->valid_bytes + + nargs = a->valid_s + a->valid_integer + a->valid_boolean + a->valid_bytes + a->valid_duration + a->valid_time; if (!onearg(ctx, "real", nargs)) @@ -254,8 +254,8 @@ vmod_real(VRT_CTX, struct VARGS(real) *a) if (a->valid_integer) return ((VCL_REAL)a->integer); - if (a->valid_bool) - return ((VCL_REAL)(a->bool ? 1 : 0)); + if (a->valid_boolean) + return ((VCL_REAL)(a->boolean ? 1 : 0)); if (a->valid_bytes) return ((VCL_REAL)a->bytes); From dridi at varni.sh Thu Apr 17 14:12:36 2025 From: dridi at varni.sh (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 14:12:36 +0000 Subject: [master] 956d529fb vtree: Constify generated NFIND arguments In-Reply-To: <97b9e516-7499-444e-a341-cb742eccd1f9@uplex.de> References: <20250417110305.21CF64CAD@lists.varnish-cache.org> <97b9e516-7499-444e-a341-cb742eccd1f9@uplex.de> Message-ID: On Thu, Apr 17, 2025 at 1:35?PM Nils Goroll wrote: > > You only patched VRBT_PROTOTYPE_NFIND, not VRBT_GENERATE_NFIND Thanks, I will also fix that. I tried the script from [4317] and it constifies both, but trying to execute it on the commit hash currently present in the script gave me a completely different version of tree.h unfortunately. I strongly suspect the last import was entirely manual. Dridi [4317] https://github.com/varnishcache/varnish-cache/pull/4317 From dridi.boukelmoune at gmail.com Thu Apr 17 14:18:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 17 Apr 2025 14:18:05 +0000 (UTC) Subject: [master] 4c8fb8628 vtree: Finish NFIND constification Message-ID: <20250417141805.45C6D650A7@lists.varnish-cache.org> commit 4c8fb86287a0e9c9ebe066bc5e69b586f39bcb39 Author: Dridi Boukelmoune Date: Thu Apr 17 16:14:28 2025 +0200 vtree: Finish NFIND constification Spotted by Nils. Refs 956d529fb8236596e3bd2c01e78e4dac9ec13b27 diff --git a/include/vtree.h b/include/vtree.h index 2d9cdf9cd..7296b48d6 100644 --- a/include/vtree.h +++ b/include/vtree.h @@ -885,7 +885,7 @@ name##_VRBT_FIND(const struct name *head, const struct type *elm) \ #define VRBT_GENERATE_NFIND(name, type, field, cmp, attr) \ /* Finds the first node greater than or equal to the search key */ \ attr struct type * \ -name##_VRBT_NFIND(struct name *head, struct type *elm) \ +name##_VRBT_NFIND(const struct name *head, const struct type *elm) \ { \ struct type *tmp = VRBT_ROOT(head); \ struct type *res = NULL; \ From nils.goroll at uplex.de Tue Apr 22 07:38:08 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 22 Apr 2025 07:38:08 +0000 (UTC) Subject: [master] e11b49eb4 vmodtool.py: Polish cname() use Message-ID: <20250422073808.3C8714777@lists.varnish-cache.org> commit e11b49eb48b0cdf745285a3247bd5923463bb260 Author: Nils Goroll Date: Thu Apr 17 18:47:22 2025 +0200 vmodtool.py: Polish cname() use diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index e4be1760c..9bd44c04a 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -583,7 +583,7 @@ class Stanza(): fmt_cstruct( fo, '.f_' + proto.cname() + ' =', - self.vcc.sympfx + proto.cname() + ',' + proto.cname(True) + ',' ) def cstruct(self, unused_fo, unused_define): From nils.goroll at uplex.de Tue Apr 22 07:38:08 2025 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 22 Apr 2025 07:38:08 +0000 (UTC) Subject: [master] a34ea21b5 vmod_debug: Test all VCL types as optional arguments Message-ID: <20250422073808.489934779@lists.varnish-cache.org> commit a34ea21b5e8e9dbac4e04f333404d3c791932e49 Author: Nils Goroll Date: Thu Apr 17 19:13:56 2025 +0200 vmod_debug: Test all VCL types as optional arguments diff --git a/bin/varnishtest/tests/m00019.vtc b/bin/varnishtest/tests/m00019.vtc index 8d480854a..54562521f 100644 --- a/bin/varnishtest/tests/m00019.vtc +++ b/bin/varnishtest/tests/m00019.vtc @@ -28,7 +28,7 @@ varnish v1 -vcl+backend { set resp.http.foo4 = debug.argtest("1", 2.4, three="3d", four=-1); set resp.http.foo5 = debug.argtest("1", 2.5); set resp.http.foo6 = debug.argtest("1", four=6); - set resp.http.foo7 = debug.argtest("1", opt="7"); + set resp.http.foo7 = debug.argtest("1", string="7"); set resp.http.obj0 = obj0.string() + ", " + obj0.number(); set resp.http.obj1 = obj1.string() + ", " + obj1.number(); diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c index 73155871a..ecdd41155 100644 --- a/vmod/vmod_debug.c +++ b/vmod/vmod_debug.c @@ -223,7 +223,7 @@ xyzzy_argtest(VRT_CTX, struct VARGS(argtest) *arg) AN(arg); bprintf(buf, "%s %g %s %s %jd %d %s", arg->one, arg->two, arg->three, arg->comma, (intmax_t)arg->four, - arg->valid_opt, arg->valid_opt ? arg->opt : ""); + arg->valid_string, arg->valid_string ? arg->string : ""); return (WS_Copy(ctx->ws, buf, -1)); } diff --git a/vmod/vmod_debug.vcc b/vmod/vmod_debug.vcc index fcf7cca27..bf69c6e34 100644 --- a/vmod/vmod_debug.vcc +++ b/vmod/vmod_debug.vcc @@ -138,7 +138,26 @@ Encrypt the HTTP header with quad-ROT13 encryption, $Function STRING argtest( STRING one, REAL two =2, STRING three= "3", STRING comma=",", INT four = 4, - [ STRING opt]) + [ ACL acl], + [ BACKEND backend], + [ BLOB blob], + [ BODY body], + [ BOOL bool:boolean], + [ BYTES bytes], + [ DURATION duration], + [ ENUM enum:enumeration], + [ HEADER header], + [ HTTP http], + [ INT int:integer], + [ IP ip], + [ PROBE probe], + [ REAL real], + [ REGEX regex], + [ STEVEDORE stevedore], + [ STRANDS strands], + [ STRING string], + [ SUB sub], + [ TIME time]) $Function INT vre_limit() From dridi.boukelmoune at gmail.com Mon Apr 28 13:22:06 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 28 Apr 2025 13:22:06 +0000 (UTC) Subject: [master] 8ce9d4069 vtree: Inject contextual parent checks during import Message-ID: <20250428132206.5468A11653E@lists.varnish-cache.org> commit 8ce9d40697edfaabd38866bf47df5644058e5dbd Author: Dridi Boukelmoune Date: Thu Apr 17 13:26:17 2025 +0200 vtree: Inject contextual parent checks during import This is an attempt at adding assertions without keeping track of a specific line of code. Tested with tree.h from the current tip of the main branch. Refs freebsd/freebsd-src at a962800a09a45b8f702ebd1a06b8f20bc84e97b1 diff --git a/tools/import_vtree_from_freebsd.sh b/tools/import_vtree_from_freebsd.sh index dd8fd69c1..3a2d8f3ba 100644 --- a/tools/import_vtree_from_freebsd.sh +++ b/tools/import_vtree_from_freebsd.sh @@ -16,8 +16,7 @@ git diff vtree.h | git apply -R > /dev/null 2>&1 || true GR=f6e54eb360a78856dcde930a00d9b2b3627309ab (cd /usr/src/ && git show $GR:sys/sys/tree.h ) | sed -E ' -485a\ - AN(parent); \\ +s/(\t*)parent = RB_PARENT.*/\0\n\1AN(parent);\t\t\t\t\\/ s/_SYS_TREE_H_/_VTREE_H_/ s/__uintptr_t/uintptr_t/g s/SPLAY/VSPLAY/g From dridi.boukelmoune at gmail.com Mon Apr 28 18:19:04 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 28 Apr 2025 18:19:04 +0000 (UTC) Subject: [master] 92570c961 circleci: Install awk on Fedora Message-ID: <20250428181904.E0F1911FF82@lists.varnish-cache.org> commit 92570c961a5742f9aa54437c4c88fb4e9a87a45a Author: Guillaume Quintard Date: Wed Apr 16 01:20:14 2025 -0700 circleci: Install awk on Fedora It's no longer present since the fedora:42 base image. diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile index 9ef231e0f..f2196d253 100644 --- a/.circleci/Dockerfile +++ b/.circleci/Dockerfile @@ -2,6 +2,7 @@ FROM fedora-latest RUN set -e; \ dnf -y install \ + awk \ automake \ git \ jemalloc-devel \ diff --git a/.circleci/config.yml b/.circleci/config.yml index b1491127f..ce11e78cc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,6 +36,7 @@ jobs: name: Install deps command: | dnf -y install \ + awk \ automake \ jemalloc-devel \ git \ @@ -245,6 +246,7 @@ jobs: ;; fedora:*) dnf -y group install development-tools + dnf -y install awk ;; esac dnf -y install \ From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:04 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:04 +0000 (UTC) Subject: [master] 396460f75 vcl: Expose global parameters to VCL Message-ID: <20250430144904.E07BE101F47@lists.varnish-cache.org> commit 396460f759e20a90e7af47b09a6f9809a74e980a Author: Dridi Boukelmoune Date: Wed Apr 30 14:52:53 2025 +0200 vcl: Expose global parameters to VCL The goal is to allow constructs avoiding hard-coded values when they could be relative to existing parameters. Let's take the first one in the list for example, backend_idle_timeout. In a clustered deployment, with our without multiple tiers, this timeout can be used to increase timeout_idle for a fellow Varnish server in a way that allows it to pool its connections: sub vcl_recv { if (req.http.via ~ "varnish") { set sess.timeout_idle = param.backend_idle_timeout * 1.5; } } One would obviously have a more reliable way of identifying a member of the cluster, but assuming a similar configuration across the cluster, this enables adaptive timeouts without resorting to VCL reloads or VMODs to access parameters. diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 778c9a42f..ca4f765ee 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -1178,3 +1178,34 @@ SESS_VAR_DUR(timeout_idle, ) SESS_VAR_DUR(timeout_linger, ) SESS_VAR_DUR(send_timeout, ) SESS_VAR_DUR(idle_send_timeout, set_idle_send_timeout(ctx->sp, d)) + +/*--------------------------------------------------------------------*/ + +#define PARAM_VAR(x, type) \ +VCL_##type \ +VRT_r_param_##x(VRT_CTX) \ +{ \ + \ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ + return (cache_param->x); \ +} \ + +PARAM_VAR(backend_idle_timeout, DURATION) +PARAM_VAR(backend_wait_limit, INT) +PARAM_VAR(backend_wait_timeout, DURATION) +PARAM_VAR(between_bytes_timeout, DURATION) +PARAM_VAR(connect_timeout, DURATION) +PARAM_VAR(default_grace, DURATION) +PARAM_VAR(default_keep, DURATION) +PARAM_VAR(default_ttl, DURATION) +PARAM_VAR(first_byte_timeout, DURATION) +PARAM_VAR(idle_send_timeout, DURATION) +PARAM_VAR(max_esi_depth, INT) +PARAM_VAR(max_restarts, INT) +PARAM_VAR(max_retries, INT) +PARAM_VAR(pipe_task_deadline, DURATION) +PARAM_VAR(pipe_timeout, DURATION) +PARAM_VAR(send_timeout, DURATION) +PARAM_VAR(shortlived, DURATION) +PARAM_VAR(timeout_idle, DURATION) +PARAM_VAR(transit_buffer, BYTES) diff --git a/bin/varnishtest/tests/c00136.vtc b/bin/varnishtest/tests/c00136.vtc new file mode 100644 index 000000000..0e97be57f --- /dev/null +++ b/bin/varnishtest/tests/c00136.vtc @@ -0,0 +1,34 @@ +varnishtest "Rearm timeout_idle upon HTTP/1 keep-alive" + +barrier b1 cond 2 +barrier b2 cond 2 + +varnish v1 -cliok "param.set timeout_idle 1h" +varnish v1 -vcl { + backend be none; + sub vcl_recv { + set sess.timeout_idle = param.timeout_idle; + return (synth(200)); + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + + barrier b1 sync + barrier b2 sync + + txreq + rxresp + expect resp.status == 200 + + expect_close +} -start + +barrier b1 sync +varnish v1 -cliok "param.set timeout_idle 1ms" +barrier b2 sync + +client c1 -wait diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index f59abf263..c13402c7d 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -1948,3 +1948,164 @@ storage..used_space Used space in the named stevedore. Only available for the malloc stevedore. +Runtime parameters +------------------ + +Some of the global runtime parameters related to VCL transactions are +readable anywhere in VCL. The value of a parameter can change between +accesses, it is not cached for the duration of a VCL task. + +.. TODO: sphinx references to param docs. + +param.backend_idle_timeout + + Type: DURATION + + Readable from: all + + Global parameter backend_idle_timeout. + +param.backend_wait_limit + + Type: INT + + Readable from: all + + Global parameter backend_wait_limit. + +param.backend_wait_timeout + + Type: DURATION + + Readable from: all + + Global parameter backend_wait_timeout. + +param.between_bytes_timeout + + Type: DURATION + + Readable from: all + + Global parameter between_bytes_timeout. + +param.connect_timeout + + Type: DURATION + + Readable from: all + + Global parameter connect_timeout. + +param.default_grace + + Type: DURATION + + Readable from: all + + Global parameter default_grace. + +param.default_keep + + Type: DURATION + + Readable from: all + + Global parameter default_keep. + +param.default_ttl + + Type: DURATION + + Readable from: all + + Global parameter default_ttl. + +param.first_byte_timeout + + Type: DURATION + + Readable from: all + + Global parameter first_byte_timeout. + +param.idle_send_timeout + + Type: DURATION + + Readable from: all + + Global parameter idle_send_timeout. + +param.max_esi_depth + + Type: INT + + Readable from: all + + Global parameter max_esi_depth. + +param.max_restarts + + Type: INT + + Readable from: all + + Global parameter max_restarts. + +param.max_retries + + Type: INT + + Readable from: all + + Global parameter max_retries. + +param.pipe_task_deadline + + Type: DURATION + + Readable from: all + + Global parameter pipe_task_deadline. + +param.pipe_timeout + + Type: DURATION + + Readable from: all + + Global parameter pipe_timeout. + +param.send_timeout + + Type: DURATION + + Readable from: all + + Global parameter send_timeout. + +param.shortlived + + Type: DURATION + + Readable from: all + + Global parameter shortlived. + +param.timeout_idle + + Type: DURATION + + Readable from: all + + Global parameter timeout_idle. + +param.transit_buffer + + Type: BYTES + + Readable from: all + + Global parameter transit_buffer. + From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] f8d65d442 param: New uncacheable_ttl for the built-in VCL Message-ID: <20250430144905.14644101F4A@lists.varnish-cache.org> commit f8d65d44233bbd3c457f1568f53a7edab331c7f4 Author: Dridi Boukelmoune Date: Wed Apr 30 14:55:34 2025 +0200 param: New uncacheable_ttl for the built-in VCL This way the hit-for-miss TTL can be updated without requiring a VCL reload or a dynamic vcl_beresp_hitmiss override involving a VMOD. diff --git a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl index ed459ce13..271a0217e 100644 --- a/bin/varnishd/builtin.vcl +++ b/bin/varnishd/builtin.vcl @@ -255,7 +255,7 @@ sub vcl_beresp_range { } sub vcl_beresp_hitmiss { - set beresp.ttl = 120s; + set beresp.ttl = param.uncacheable_ttl; set beresp.uncacheable = true; return (deliver); } diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index ca4f765ee..24c69cbfc 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -1209,3 +1209,4 @@ PARAM_VAR(send_timeout, DURATION) PARAM_VAR(shortlived, DURATION) PARAM_VAR(timeout_idle, DURATION) PARAM_VAR(transit_buffer, BYTES) +PARAM_VAR(uncacheable_ttl, DURATION) diff --git a/bin/varnishtest/tests/c00137.vtc b/bin/varnishtest/tests/c00137.vtc new file mode 100644 index 000000000..79cc5a6e2 --- /dev/null +++ b/bin/varnishtest/tests/c00137.vtc @@ -0,0 +1,34 @@ +varnishtest "Tweak uncacheable_ttl for built-in VCL" + +server s1 { + loop 3 { + rxreq + expect req.http.is-hitmiss == false + txresp + } + + rxreq + expect req.http.is-hitmiss == true + txresp +} -start + +varnish v1 -cliok "param.set default_ttl 0s" +varnish v1 -cliok "param.set default_grace 0s" +varnish v1 -cliok "param.set default_keep 0s" +varnish v1 -cliok "param.set uncacheable_ttl 1ms" +varnish v1 -vcl+backend { + sub vcl_miss { + set req.http.is-hitmiss = req.is_hitmiss; + } +} -start + +client c1 -repeat 2 { + txreq + rxresp + delay 0.5 +} -run + +varnish v1 -cliok "param.set uncacheable_ttl 1m" + +client c1 -run +server s1 -wait diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index c13402c7d..970ba3656 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -2109,3 +2109,12 @@ param.transit_buffer Global parameter transit_buffer. + +param.uncacheable_ttl + + Type: DURATION + + Readable from: all + + Global parameter uncacheable_ttl. + diff --git a/include/tbl/params.h b/include/tbl/params.h index 9f0f581b2..c613d86c8 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -484,6 +484,21 @@ PARAM_SIMPLE( /* dyn_def_reason */ "2m" ) +PARAM_SIMPLE( + /* name */ uncacheable_ttl, + /* type */ duration, + /* min */ "0.000", + /* max */ NULL, + /* def */ "2m", + /* units */ "seconds", + /* descr */ + "The TTL assigned to uncacheable objects by the built-in VCL.", + /* flags */ OBJ_STICKY, + /* dyn_min_reason */ NULL, + /* dyn_max_reason */ NULL, + /* dyn_def_reason */ "2m" +) + PARAM_SIMPLE( /* name */ http1_iovs, /* type */ uint, From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] ea29f870d SQUASHME: link param.* VCL variables to param docs Message-ID: <20250430144905.31047101F54@lists.varnish-cache.org> commit ea29f870dfb03cc68e3cccb355525fea78cfbd9a Author: Dridi Boukelmoune Date: Wed Apr 30 16:08:37 2025 +0200 SQUASHME: link param.* VCL variables to param docs diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 970ba3656..c62bd3152 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -1963,7 +1963,7 @@ param.backend_idle_timeout Readable from: all - Global parameter backend_idle_timeout. + Global parameter :ref:`ref_param_backend_idle_timeout`. param.backend_wait_limit @@ -1971,7 +1971,7 @@ param.backend_wait_limit Readable from: all - Global parameter backend_wait_limit. + Global parameter :ref:`ref_param_backend_wait_limit`. param.backend_wait_timeout @@ -1979,7 +1979,7 @@ param.backend_wait_timeout Readable from: all - Global parameter backend_wait_timeout. + Global parameter :ref:`ref_param_backend_wait_timeout`. param.between_bytes_timeout @@ -1987,7 +1987,7 @@ param.between_bytes_timeout Readable from: all - Global parameter between_bytes_timeout. + Global parameter :ref:`ref_param_between_bytes_timeout`. param.connect_timeout @@ -1995,7 +1995,7 @@ param.connect_timeout Readable from: all - Global parameter connect_timeout. + Global parameter :ref:`ref_param_connect_timeout`. param.default_grace @@ -2003,7 +2003,7 @@ param.default_grace Readable from: all - Global parameter default_grace. + Global parameter :ref:`ref_param_default_grace`. param.default_keep @@ -2011,7 +2011,7 @@ param.default_keep Readable from: all - Global parameter default_keep. + Global parameter :ref:`ref_param_default_keep`. param.default_ttl @@ -2019,7 +2019,7 @@ param.default_ttl Readable from: all - Global parameter default_ttl. + Global parameter :ref:`ref_param_default_ttl`. param.first_byte_timeout @@ -2027,7 +2027,7 @@ param.first_byte_timeout Readable from: all - Global parameter first_byte_timeout. + Global parameter :ref:`ref_param_first_byte_timeout`. param.idle_send_timeout @@ -2035,7 +2035,7 @@ param.idle_send_timeout Readable from: all - Global parameter idle_send_timeout. + Global parameter :ref:`ref_param_idle_send_timeout`. param.max_esi_depth @@ -2043,7 +2043,7 @@ param.max_esi_depth Readable from: all - Global parameter max_esi_depth. + Global parameter :ref:`ref_param_max_esi_depth`. param.max_restarts @@ -2051,7 +2051,7 @@ param.max_restarts Readable from: all - Global parameter max_restarts. + Global parameter :ref:`ref_param_max_restarts`. param.max_retries @@ -2059,7 +2059,7 @@ param.max_retries Readable from: all - Global parameter max_retries. + Global parameter :ref:`ref_param_max_retries`. param.pipe_task_deadline @@ -2067,7 +2067,7 @@ param.pipe_task_deadline Readable from: all - Global parameter pipe_task_deadline. + Global parameter :ref:`ref_param_pipe_task_deadline`. param.pipe_timeout @@ -2075,7 +2075,7 @@ param.pipe_timeout Readable from: all - Global parameter pipe_timeout. + Global parameter :ref:`ref_param_pipe_timeout`. param.send_timeout @@ -2083,7 +2083,7 @@ param.send_timeout Readable from: all - Global parameter send_timeout. + Global parameter :ref:`ref_param_send_timeout`. param.shortlived @@ -2091,7 +2091,7 @@ param.shortlived Readable from: all - Global parameter shortlived. + Global parameter :ref:`ref_param_shortlived`. param.timeout_idle @@ -2099,7 +2099,7 @@ param.timeout_idle Readable from: all - Global parameter timeout_idle. + Global parameter :ref:`ref_param_timeout_idle`. param.transit_buffer @@ -2107,7 +2107,7 @@ param.transit_buffer Readable from: all - Global parameter transit_buffer. + Global parameter :ref:`ref_param_transit_buffer`. param.uncacheable_ttl From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] f72d8a958 SQUASHME: add VRT_r_param_*() to VRT history Message-ID: <20250430144905.5CD64101F58@lists.varnish-cache.org> commit f72d8a9580ba52ab096a714978d7c54be3f67e81 Author: Dridi Boukelmoune Date: Wed Apr 30 16:14:29 2025 +0200 SQUASHME: add VRT_r_param_*() to VRT history diff --git a/include/vrt.h b/include/vrt.h index 712735b1d..cd296a125 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -62,6 +62,25 @@ * struct gethdr_s.what changed to hdr_t * VRT_VSC_Alloc() renamed to VRT_VSC_Allocv() * new VRT_VSC_Alloc() added + * VRT_r_param_backend_idle_timeout() added + * VRT_r_param_backend_wait_limit() added + * VRT_r_param_backend_wait_timeout() added + * VRT_r_param_between_bytes_timeout() added + * VRT_r_param_connect_timeout() added + * VRT_r_param_default_grace() added + * VRT_r_param_default_keep() added + * VRT_r_param_default_ttl() added + * VRT_r_param_first_byte_timeout() added + * VRT_r_param_idle_send_timeout() added + * VRT_r_param_max_esi_depth() added + * VRT_r_param_max_restarts() added + * VRT_r_param_max_retries() added + * VRT_r_param_pipe_task_deadline() added + * VRT_r_param_pipe_timeout() added + * VRT_r_param_send_timeout() added + * VRT_r_param_shortlived() added + * VRT_r_param_timeout_idle() added + * VRT_r_param_transit_buffer() added * 21.0 (2025-03-17) * VRT_u_req_grace() added * VRT_u_req_ttl() added From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] 0996babf3 SQUASHME: link param.uncacheable_ttl to param docs Message-ID: <20250430144905.76F34101F5C@lists.varnish-cache.org> commit 0996babf38f1e8b82072a1cc89811414f0cf0f11 Author: Dridi Boukelmoune Date: Wed Apr 30 16:15:30 2025 +0200 SQUASHME: link param.uncacheable_ttl to param docs diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index c62bd3152..5475c789d 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -2109,12 +2109,11 @@ param.transit_buffer Global parameter :ref:`ref_param_transit_buffer`. - param.uncacheable_ttl Type: DURATION Readable from: all - Global parameter uncacheable_ttl. + Global parameter :ref:`ref_param_uncacheable_ttl`. From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] 83bb26662 SQUASHME: add VRT_r_param_uncacheable_ttl() to VRT history Message-ID: <20250430144905.8ECC1101F5F@lists.varnish-cache.org> commit 83bb26662f9482a78a69d2c6aadab365aa91d94c Author: Dridi Boukelmoune Date: Wed Apr 30 16:16:11 2025 +0200 SQUASHME: add VRT_r_param_uncacheable_ttl() to VRT history diff --git a/include/vrt.h b/include/vrt.h index cd296a125..0644063f7 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -81,6 +81,7 @@ * VRT_r_param_shortlived() added * VRT_r_param_timeout_idle() added * VRT_r_param_transit_buffer() added + * VRT_r_param_uncacheable_ttl() added * 21.0 (2025-03-17) * VRT_u_req_grace() added * VRT_u_req_ttl() added From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] c0b914c6e SQUASHME: remove stale TODO Message-ID: <20250430144905.A945F101F66@lists.varnish-cache.org> commit c0b914c6e0504a6f966d4ae69ee57c7b91845f4e Author: Dridi Boukelmoune Date: Wed Apr 30 16:17:13 2025 +0200 SQUASHME: remove stale TODO diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 5475c789d..6b724ebb8 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -1955,8 +1955,6 @@ Some of the global runtime parameters related to VCL transactions are readable anywhere in VCL. The value of a parameter can change between accesses, it is not cached for the duration of a VCL task. -.. TODO: sphinx references to param docs. - param.backend_idle_timeout Type: DURATION From dridi.boukelmoune at gmail.com Wed Apr 30 14:49:05 2025 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Wed, 30 Apr 2025 14:49:05 +0000 (UTC) Subject: [master] d8f15a696 SQUASHME: check resp status Message-ID: <20250430144905.CC5D3101F85@lists.varnish-cache.org> commit d8f15a696e70c790a538495cde8dd8a5a7ca17b2 Author: Dridi Boukelmoune Date: Wed Apr 30 16:47:35 2025 +0200 SQUASHME: check resp status diff --git a/bin/varnishtest/tests/c00137.vtc b/bin/varnishtest/tests/c00137.vtc index 79cc5a6e2..c0435c1bc 100644 --- a/bin/varnishtest/tests/c00137.vtc +++ b/bin/varnishtest/tests/c00137.vtc @@ -25,6 +25,7 @@ varnish v1 -vcl+backend { client c1 -repeat 2 { txreq rxresp + expect resp.status == 200 delay 0.5 } -run