From phk at FreeBSD.org Wed May 4 07:07:06 2022 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 4 May 2022 07:07:06 +0000 (UTC) Subject: [master] a50db76fa Grossly hack the (debug only) persistent stevedore to cope with ASLR Message-ID: <20220504070706.82DD2111684@lists.varnish-cache.org> commit a50db76fa6c5f8092a1a7f0a63a2a8860ec81e8c Author: Poul-Henning Kamp Date: Wed May 4 07:06:48 2022 +0000 Grossly hack the (debug only) persistent stevedore to cope with ASLR diff --git a/bin/varnishd/storage/mgt_storage_persistent.c b/bin/varnishd/storage/mgt_storage_persistent.c index 77e8049a2..22c58ab19 100644 --- a/bin/varnishd/storage/mgt_storage_persistent.c +++ b/bin/varnishd/storage/mgt_storage_persistent.c @@ -143,7 +143,8 @@ smp_mgt_init(struct stevedore *parent, int ac, char * const *av) struct smp_sc *sc; struct smp_sign sgn; void *target; - int i; + int i, mmap_flags; + uintptr_t up; ASSERT_MGT(); @@ -205,12 +206,38 @@ smp_mgt_init(struct stevedore *parent, int ac, char * const *av) else target = NULL; + mmap_flags = MAP_NOCORE | MAP_NOSYNC | MAP_SHARED; + if (target) { + mmap_flags |= MAP_FIXED; +#ifdef MAP_EXCL + mmap_flags |= MAP_EXCL; +#endif + } else { + /* + * I guess the people who came up with ASLR never learned + * that virtual memory can have benficial uses, because they + * added no facility for realiably and portably allocing + * stable address-space. + * This stevedore is only for testing these days, so we + * can get away with just hacking something up: 16M below + * the break seems to work on FreeBSD. + */ + up = (uintptr_t)sbrk(0); + up -= 1ULL<<24; + up -= sc->mediasize; + up &= ~(getpagesize() - 1ULL); + target = (void *)up; + +#ifdef MAP_ALIGNED_SUPER + mmap_flags |= MAP_ALIGNED_SUPER; +#endif + } sc->base = (void*)mmap(target, sc->mediasize, PROT_READ|PROT_WRITE, - MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0); + mmap_flags, sc->fd, 0); if (sc->base == MAP_FAILED) - ARGV_ERR("(-spersistent) failed to mmap (%s)\n", - VAS_errtxt(errno)); + ARGV_ERR("(-spersistent) failed to mmap (%s) @%p\n", + VAS_errtxt(errno), target); if (target != NULL && sc->base != target) fprintf(stderr, "WARNING: Persistent silo lost to ASLR %s\n", sc->filename); From phk at FreeBSD.org Wed May 4 07:24:05 2022 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 4 May 2022 07:24:05 +0000 (UTC) Subject: [master] fa69f349e ... and as I expected, that hack breaks on all sorts of other systems, so #ifdef __FreeBSD__, which is OK, since the intent is just to get VTEST code coverage. Message-ID: <20220504072405.66BE4111F8C@lists.varnish-cache.org> commit fa69f349ef7e423573e0b60d2d9447108526daf8 Author: Poul-Henning Kamp Date: Wed May 4 07:22:50 2022 +0000 ... and as I expected, that hack breaks on all sorts of other systems, so #ifdef __FreeBSD__, which is OK, since the intent is just to get VTEST code coverage. diff --git a/bin/varnishd/storage/mgt_storage_persistent.c b/bin/varnishd/storage/mgt_storage_persistent.c index 22c58ab19..fdd4419c8 100644 --- a/bin/varnishd/storage/mgt_storage_persistent.c +++ b/bin/varnishd/storage/mgt_storage_persistent.c @@ -144,7 +144,6 @@ smp_mgt_init(struct stevedore *parent, int ac, char * const *av) struct smp_sign sgn; void *target; int i, mmap_flags; - uintptr_t up; ASSERT_MGT(); @@ -213,6 +212,7 @@ smp_mgt_init(struct stevedore *parent, int ac, char * const *av) mmap_flags |= MAP_EXCL; #endif } else { +#ifdef __FreeBSD__ /* * I guess the people who came up with ASLR never learned * that virtual memory can have benficial uses, because they @@ -222,11 +222,13 @@ smp_mgt_init(struct stevedore *parent, int ac, char * const *av) * can get away with just hacking something up: 16M below * the break seems to work on FreeBSD. */ + uintptr_t up; up = (uintptr_t)sbrk(0); up -= 1ULL<<24; up -= sc->mediasize; up &= ~(getpagesize() - 1ULL); target = (void *)up; +#endif #ifdef MAP_ALIGNED_SUPER mmap_flags |= MAP_ALIGNED_SUPER; From phk at FreeBSD.org Wed May 4 07:41:04 2022 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 4 May 2022 07:41:04 +0000 (UTC) Subject: [master] 7b4e1a346 Disable p00008 on Darwin, it is too random Message-ID: <20220504074104.9F412112820@lists.varnish-cache.org> commit 7b4e1a34670ba1360c701f7612b4f73165c9ea99 Author: Poul-Henning Kamp Date: Wed May 4 07:40:12 2022 +0000 Disable p00008 on Darwin, it is too random diff --git a/bin/varnishtest/tests/p00008.vtc b/bin/varnishtest/tests/p00008.vtc index cde88be53..a1dab907c 100644 --- a/bin/varnishtest/tests/p00008.vtc +++ b/bin/varnishtest/tests/p00008.vtc @@ -2,6 +2,9 @@ varnishtest "Ban list sync across silos" feature persistent_storage +# VM-remapping is too random on OSX +feature cmd {test $(uname) != "Darwin"} + shell "rm -f ${tmpdir}/_.per[12]" # Silo 1 & 2 From nils.goroll at uplex.de Thu May 12 15:44:14 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 12 May 2022 15:44:14 +0000 (UTC) Subject: [master] 142c3a012 Fix RX_BODY description Message-ID: <20220512154414.968EF11651C@lists.varnish-cache.org> commit 142c3a012935ceb68ffd6fe753f5498eedd0c8ed Author: Nils Goroll Date: Thu May 12 17:42:25 2022 +0200 Fix RX_BODY description This session close reason is also used for receiving response bodies, for example: -- TTL RFC 86400 10 0 1652368707 1652368707 1652368707 0 86400 cacheable -- VCL_call BACKEND_RESPONSE -- VCL_return deliver -- Timestamp Process: 1652368707.157422 0.063369 0.000054 -- Filters -- Storage file s0 -- Fetch_Body 2 chunked stream -- FetchError chunked read err -- BackendClose 53 self close Failure receiving req.body -- BereqAcct 1337 0 1337 987 3465216 3466203 -- End diff --git a/include/tbl/sess_close.h b/include/tbl/sess_close.h index 3660bb9bb..b91c93951 100644 --- a/include/tbl/sess_close.h +++ b/include/tbl/sess_close.h @@ -36,7 +36,7 @@ SESS_CLOSE(REM_CLOSE, rem_close, 0, "Client Closed") SESS_CLOSE(REQ_CLOSE, req_close, 0, "Client requested close") SESS_CLOSE(REQ_HTTP10, req_http10, 1, "Proto < HTTP/1.1") SESS_CLOSE(RX_BAD, rx_bad, 1, "Received bad req/resp") -SESS_CLOSE(RX_BODY, rx_body, 1, "Failure receiving req.body") +SESS_CLOSE(RX_BODY, rx_body, 1, "Failure receiving body") SESS_CLOSE(RX_JUNK, rx_junk, 1, "Received junk data") SESS_CLOSE(RX_OVERFLOW, rx_overflow, 1, "Received buffer overflow") SESS_CLOSE(RX_TIMEOUT, rx_timeout, 1, "Receive timeout") From phk at FreeBSD.org Mon May 23 13:10:11 2022 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 23 May 2022 13:10:11 +0000 (UTC) Subject: [master] 9134cdea9 tcp_keepidle socket option support for macOs. Message-ID: <20220523131011.7DABB111D70@lists.varnish-cache.org> commit 9134cdea99df08838069d1acb89a7bccc8c3ee02 Author: David CARLIER Date: Mon May 16 19:40:47 2022 +0100 tcp_keepidle socket option support for macOs. TCP_KEEPALIVE is the TCP_KEEPIDLE's equivalent and uses seconds for the idle time. diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 5232f2a7a..afdfbf222 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -105,10 +105,12 @@ static struct sock_opt { SOCK_OPT(IPPROTO_TCP, TCP_NODELAY, int) -#ifdef HAVE_TCP_KEEP +#if defined(HAVE_TCP_KEEP) SOCK_OPT(IPPROTO_TCP, TCP_KEEPIDLE, int) SOCK_OPT(IPPROTO_TCP, TCP_KEEPCNT, int) SOCK_OPT(IPPROTO_TCP, TCP_KEEPINTVL, int) +#elif defined(HAVE_TCP_KEEPALIVE) + SOCK_OPT(IPPROTO_TCP, TCP_KEEPALIVE, int) #endif #undef SOCK_OPT @@ -206,13 +208,16 @@ vca_sock_opt_init(void) NEW_VAL(SO_RCVTIMEO, so, tv, VTIM_timeval(cache_param->timeout_idle)); SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); -#ifdef HAVE_TCP_KEEP +#if defined(HAVE_TCP_KEEP) NEW_VAL(TCP_KEEPIDLE, so, i, (int)cache_param->tcp_keepalive_time); NEW_VAL(TCP_KEEPCNT, so, i, (int)cache_param->tcp_keepalive_probes); NEW_VAL(TCP_KEEPINTVL, so, i, (int)cache_param->tcp_keepalive_intvl); +#elif defined(HAVE_TCP_KEEPALIVE) + NEW_VAL(TCP_KEEPALIVE, so, i, + (int)cache_param->tcp_keepalive_time); #endif } return (chg); diff --git a/bin/varnishd/mgt/mgt_param_tcp.c b/bin/varnishd/mgt/mgt_param_tcp.c index 80648c763..b9b87cc6b 100644 --- a/bin/varnishd/mgt/mgt_param_tcp.c +++ b/bin/varnishd/mgt/mgt_param_tcp.c @@ -49,7 +49,7 @@ #include "vtcp.h" -#ifdef HAVE_TCP_KEEP +#if defined(HAVE_TCP_KEEP) || defined(HAVE_TCP_KEEPALIVE) static void tcp_probe(int sock, int nam, const char *param, unsigned def) @@ -75,9 +75,13 @@ tcp_keep_probes(void) if (err != NULL) ARGV_ERR("Could not probe TCP keepalives: %s", err); assert(s > 0); +#ifdef HAVE_TCP_KEEP tcp_probe(s, TCP_KEEPIDLE, "tcp_keepalive_time", 600); tcp_probe(s, TCP_KEEPCNT, "tcp_keepalive_probes", 5); tcp_probe(s, TCP_KEEPINTVL, "tcp_keepalive_intvl", 5); +#else + tcp_probe(s, TCP_KEEPALIVE, "tcp_keepalive_time", 600); +#endif closefd(&s); } #endif @@ -85,7 +89,7 @@ tcp_keep_probes(void) void MCF_TcpParams(void) { -#ifdef HAVE_TCP_KEEP +#if defined(HAVE_TCP_KEEP) || defined(HAVE_TCP_KEEPALIVE) tcp_keep_probes(); #endif } diff --git a/configure.ac b/configure.ac index 555267a11..f3096aa34 100644 --- a/configure.ac +++ b/configure.ac @@ -589,6 +589,32 @@ return (0); ]) if test "$ac_cv_have_tcp_keep" = yes; then AC_DEFINE([HAVE_TCP_KEEP], [1], [Define if OS supports TCP_KEEP* socket options]) +else + # Check TCP_KEEPALIVE on macOs which uses seconds as idle time unit like TCP_KEEPIDLE + AC_CACHE_CHECK([for TCP_KEEPALIVE socket option], + [ac_cv_have_tcp_keepalive], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include + ]],[[ +int s = socket(AF_INET, SOCK_STREAM, 0); +int i = 5; +if (s < 0) + return (1); +if (setsockopt(s, IPPROTO_TCP, TCP_KEEPALIVE, &i, sizeof i)) + return (1); +return 0; + ]])], + [ac_cv_have_tcp_keepalive=yes], + [ac_cv_have_tcp_keepalive=no]) + ]) + if test "$ac_cv_have_tcp_keepalive" = yes; then + AC_DEFINE([HAVE_TCP_KEEPALIVE], [1], [Define if OS supports TCP_KEEPALIVE socket option]) + fi fi LIBS="${save_LIBS}" From nils.goroll at uplex.de Tue May 24 10:56:08 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 24 May 2022 10:56:08 +0000 (UTC) Subject: [master] 0244e1cb2 fix/polish .port VCL backend attribute documentation Message-ID: <20220524105608.608581153E6@lists.varnish-cache.org> commit 0244e1cb2f60bc6253f5b689e3b7177ab25b2592 Author: Nils Goroll Date: Tue May 24 12:32:29 2022 +0200 fix/polish .port VCL backend attribute documentation diff --git a/bin/varnishtest/tests/b00058.vtc b/bin/varnishtest/tests/b00058.vtc new file mode 100644 index 000000000..c794fa6e9 --- /dev/null +++ b/bin/varnishtest/tests/b00058.vtc @@ -0,0 +1,12 @@ +varnishtest "Test backend definition documentation examples" + +feature cmd {getent hosts localhost && getent services http} + +varnish v1 -arg "-p vcc_err_unref=off" -vcl { + backend b1 {.host = "127.0.0.1";} + backend b2 {.host = "[::1]:8080";} + backend b3 {.host = "localhost:8081";} + backend b4 {.host = "localhost:http";} + backend b5 {.host = "127.0.0.1";.port = "8081";} + backend b6 {.host = "127.0.0.1";.port = "http";} +} \ No newline at end of file diff --git a/doc/sphinx/reference/vcl-backend.rst b/doc/sphinx/reference/vcl-backend.rst index 148172295..a1f66e9f7 100644 --- a/doc/sphinx/reference/vcl-backend.rst +++ b/doc/sphinx/reference/vcl-backend.rst @@ -57,10 +57,17 @@ one IPv4 and one IPv6 address:: .host = "example.com:8081"; -The TCP port number can be specified as part of ``.host`` as above -or separately using the ``.port`` attribute:: + .host = "example.com:http"; - .port = 8081; +Attribute ``.port`` +------------------- + +The TCP port number or service name can be specified as part of +``.host`` as above or separately using the ``.port`` attribute:: + + .port = "8081"; + + .port = "http"; Attribute ``.path`` ------------------- From dridi.boukelmoune at gmail.com Tue May 24 15:49:06 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 24 May 2022 15:49:06 +0000 (UTC) Subject: [master] b34774ee6 param: Further generalize tweak_generic_double() Message-ID: <20220524154906.27D3C54B2@lists.varnish-cache.org> commit b34774ee6222026045a6d696fc85807b06900a74 Author: Dridi Boukelmoune Date: Thu Dec 30 06:03:06 2021 +0100 param: Further generalize tweak_generic_double() This is a first step towards even more generalization. diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index a385263c6..e6e7aaedd 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -53,26 +53,27 @@ const char * const JSON_FMT = (const char *)&JSON_FMT; */ static int -tweak_generic_double(struct vsb *vsb, volatile double *dest, - const char *arg, const char *min, const char *max, const char *fmt) +tweak_generic_double(struct vsb *vsb, const char *arg, const struct parspec *pp, + const char *fmt) { volatile double u, minv = VRT_DECIMAL_MIN, maxv = VRT_DECIMAL_MAX; + volatile double *dest = pp->priv; const char *p, *err; if (arg != NULL && arg != JSON_FMT) { - if (min != NULL) { - p = min; + if (pp->min != NULL) { + p = pp->min; minv = SF_Parse_Decimal(&p, 0, &err); if (errno) { - VSB_printf(vsb, "Min: %s (%s)\n", err, min); + VSB_printf(vsb, "Min: %s (%s)\n", err, pp->min); return (-1); } } - if (max != NULL) { - p = max; + if (pp->max != NULL) { + p = pp->max; maxv = SF_Parse_Decimal(&p, 0, &err); if (errno) { - VSB_printf(vsb, "Max: %s (%s)\n", err, max); + VSB_printf(vsb, "Max: %s (%s)\n", err, pp->max); return (-1); } } @@ -85,12 +86,12 @@ tweak_generic_double(struct vsb *vsb, volatile double *dest, } if (u < minv) { VSB_printf(vsb, - "Must be greater or equal to %s\n", min); + "Must be greater or equal to %s\n", pp->min); return (-1); } if (u > maxv) { VSB_printf(vsb, - "Must be less than or equal to %s\n", max); + "Must be less than or equal to %s\n", pp->max); return (-1); } *dest = u; @@ -105,11 +106,8 @@ tweak_generic_double(struct vsb *vsb, volatile double *dest, int v_matchproto_(tweak_t) tweak_timeout(struct vsb *vsb, const struct parspec *par, const char *arg) { - volatile double *dest; - dest = par->priv; - return (tweak_generic_double(vsb, dest, arg, - par->min, par->max, "%.3f")); + return (tweak_generic_double(vsb, arg, par, "%.3f")); } /*--------------------------------------------------------------------*/ @@ -117,10 +115,8 @@ tweak_timeout(struct vsb *vsb, const struct parspec *par, const char *arg) int v_matchproto_(tweak_t) tweak_double(struct vsb *vsb, const struct parspec *par, const char *arg) { - volatile double *dest; - dest = par->priv; - return (tweak_generic_double(vsb, dest, arg, par->min, par->max, "%g")); + return (tweak_generic_double(vsb, arg, par, "%g")); } /*--------------------------------------------------------------------*/ @@ -396,6 +392,7 @@ int v_matchproto_(tweak_t) tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg) { volatile struct poolparam *pp, px; + struct parspec pt; char **av; int retval = 0; @@ -437,8 +434,10 @@ tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg) par->dyn_max_reason); if (retval) break; - retval = tweak_generic_double(vsb, - &px.max_age, av[3], "0", "1000000", "%.0f"); + pt.priv = &px.max_age; + pt.min = "0"; + pt.max = "1000000"; + retval = tweak_generic_double(vsb, av[3], &pt, "%.0f"); if (retval) break; if (px.min_pool > px.max_pool) { From dridi.boukelmoune at gmail.com Tue May 24 15:49:06 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 24 May 2022 15:49:06 +0000 (UTC) Subject: [master] 34e161f94 param: Deny extra input after a double Message-ID: <20220524154906.40DB154B4@lists.varnish-cache.org> commit 34e161f948d6e627ffed06752ec8dd4a8ce2e800 Author: Dridi Boukelmoune Date: Thu Dec 30 06:21:53 2021 +0100 param: Deny extra input after a double By themselves, structured fields parsing functions don't fail on extra input. To avoid repeating the same checks twice, they are wrapped into a function that will help generalize tweak_generic_double() at least once more. diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index e6e7aaedd..ea6e935d9 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -52,34 +52,44 @@ const char * const JSON_FMT = (const char *)&JSON_FMT; * Generic handling of double typed parameters */ +static double +parse_decimal(const char *p, const char **err) +{ + double v; + + v = SF_Parse_Decimal(&p, 0, err); + if (errno == 0 && *p != '\0') { + errno = EINVAL; + *err = "Invalid number"; + } + return (v); +} + static int tweak_generic_double(struct vsb *vsb, const char *arg, const struct parspec *pp, const char *fmt) { volatile double u, minv = VRT_DECIMAL_MIN, maxv = VRT_DECIMAL_MAX; volatile double *dest = pp->priv; - const char *p, *err; + const char *err; if (arg != NULL && arg != JSON_FMT) { if (pp->min != NULL) { - p = pp->min; - minv = SF_Parse_Decimal(&p, 0, &err); + minv = parse_decimal(pp->min, &err); if (errno) { VSB_printf(vsb, "Min: %s (%s)\n", err, pp->min); return (-1); } } if (pp->max != NULL) { - p = pp->max; - maxv = SF_Parse_Decimal(&p, 0, &err); + maxv = parse_decimal(pp->max, &err); if (errno) { VSB_printf(vsb, "Max: %s (%s)\n", err, pp->max); return (-1); } } - p = arg; - u = SF_Parse_Decimal(&p, 0, &err); + u = parse_decimal(arg, &err); if (errno) { VSB_printf(vsb, "%s (%s)\n", err, arg); return (-1); diff --git a/bin/varnishtest/tests/b00042.vtc b/bin/varnishtest/tests/b00042.vtc index 037469ec7..cda710935 100644 --- a/bin/varnishtest/tests/b00042.vtc +++ b/bin/varnishtest/tests/b00042.vtc @@ -4,6 +4,7 @@ varnish v1 -vcl {backend be none;} -start varnish v1 -clierr 106 "param.set default_ttl -1" +varnish v1 -clierr 106 {param.set acceptor_sleep_decay "0.42 is not a number"} varnish v1 -clierr 106 "param.set acceptor_sleep_max 20" varnish v1 -cliok "param.set prefer_ipv6 off" varnish v1 -cliok "param.set prefer_ipv6 no" From dridi.boukelmoune at gmail.com Tue May 24 15:49:06 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 24 May 2022 15:49:06 +0000 (UTC) Subject: [master] 1767205d4 param: Optionally pass a duration unit to timeouts Message-ID: <20220524154906.69AE554B8@lists.varnish-cache.org> commit 1767205d4354bb6a0cc2b57515394c9c3f2cf55e Author: Dridi Boukelmoune Date: Thu Dec 30 06:25:19 2021 +0100 param: Optionally pass a duration unit to timeouts Allowing units is much more convenient and keeping them optional maintains compatibility. On the other hand, changing the defaults for default_ttl and default_grace has no impact on the generated RST. Keeping track of the user input could help since default values are "washed" like user input, without resorting to a dynamic default. Refs #3756 diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index ea6e935d9..4b4d793e8 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -52,6 +52,8 @@ const char * const JSON_FMT = (const char *)&JSON_FMT; * Generic handling of double typed parameters */ +typedef double parse_double_f(const char *, const char **); + static double parse_decimal(const char *p, const char **err) { @@ -67,7 +69,7 @@ parse_decimal(const char *p, const char **err) static int tweak_generic_double(struct vsb *vsb, const char *arg, const struct parspec *pp, - const char *fmt) + parse_double_f parse, const char *fmt) { volatile double u, minv = VRT_DECIMAL_MIN, maxv = VRT_DECIMAL_MAX; volatile double *dest = pp->priv; @@ -75,21 +77,21 @@ tweak_generic_double(struct vsb *vsb, const char *arg, const struct parspec *pp, if (arg != NULL && arg != JSON_FMT) { if (pp->min != NULL) { - minv = parse_decimal(pp->min, &err); + minv = parse(pp->min, &err); if (errno) { VSB_printf(vsb, "Min: %s (%s)\n", err, pp->min); return (-1); } } if (pp->max != NULL) { - maxv = parse_decimal(pp->max, &err); + maxv = parse(pp->max, &err); if (errno) { VSB_printf(vsb, "Max: %s (%s)\n", err, pp->max); return (-1); } } - u = parse_decimal(arg, &err); + u = parse(arg, &err); if (errno) { VSB_printf(vsb, "%s (%s)\n", err, arg); return (-1); @@ -113,11 +115,29 @@ tweak_generic_double(struct vsb *vsb, const char *arg, const struct parspec *pp, /*--------------------------------------------------------------------*/ +static double +parse_duration(const char *p, const char **err) +{ + double v, r; + + v = SF_Parse_Decimal(&p, 0, err); + if (*p == '\0') + return (v); + + r = VNUM_duration_unit(v, p, NULL); + if (isnan(r)) { + errno = EINVAL; + *err = "Invalid duration unit"; + } + + return (r); +} + int v_matchproto_(tweak_t) tweak_timeout(struct vsb *vsb, const struct parspec *par, const char *arg) { - return (tweak_generic_double(vsb, arg, par, "%.3f")); + return (tweak_generic_double(vsb, arg, par, parse_duration, "%.3f")); } /*--------------------------------------------------------------------*/ @@ -126,7 +146,7 @@ int v_matchproto_(tweak_t) tweak_double(struct vsb *vsb, const struct parspec *par, const char *arg) { - return (tweak_generic_double(vsb, arg, par, "%g")); + return (tweak_generic_double(vsb, arg, par, parse_decimal, "%g")); } /*--------------------------------------------------------------------*/ @@ -447,7 +467,8 @@ tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg) pt.priv = &px.max_age; pt.min = "0"; pt.max = "1000000"; - retval = tweak_generic_double(vsb, av[3], &pt, "%.0f"); + retval = tweak_generic_double(vsb, av[3], &pt, + parse_decimal, "%.0f"); if (retval) break; if (px.min_pool > px.max_pool) { diff --git a/bin/varnishtest/tests/b00042.vtc b/bin/varnishtest/tests/b00042.vtc index cda710935..b506139ef 100644 --- a/bin/varnishtest/tests/b00042.vtc +++ b/bin/varnishtest/tests/b00042.vtc @@ -4,6 +4,10 @@ varnish v1 -vcl {backend be none;} -start varnish v1 -clierr 106 "param.set default_ttl -1" +varnish v1 -clierr 106 "param.set default_ttl 1x" +varnish v1 -cliok "param.set default_ttl 1s" +varnish v1 -clierr 106 {param.set default_ttl "1 x"} +varnish v1 -cliok {param.set default_ttl "1 s"} varnish v1 -clierr 106 {param.set acceptor_sleep_decay "0.42 is not a number"} varnish v1 -clierr 106 "param.set acceptor_sleep_max 20" varnish v1 -cliok "param.set prefer_ipv6 off" diff --git a/include/tbl/params.h b/include/tbl/params.h index 3e76272b6..0d8ba1c4f 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -385,13 +385,16 @@ PARAM_SIMPLE( /* type */ timeout, /* min */ "0.000", /* max */ NULL, - /* def */ "10.000", + /* def */ "10s", /* units */ "seconds", /* descr */ "Default grace period. We will deliver an object this long after " "it has expired, provided another thread is attempting to get a " "new copy.", - /* flags */ OBJ_STICKY + /* flags */ OBJ_STICKY, + /* dyn_min_reason */ NULL, + /* dyn_max_reason */ NULL, + /* dyn_def_reason */ "10s" ) PARAM_SIMPLE( @@ -399,14 +402,17 @@ PARAM_SIMPLE( /* type */ timeout, /* min */ "0.000", /* max */ NULL, - /* def */ "0.000", + /* def */ "0s", /* units */ "seconds", /* descr */ "Default keep period. We will keep a useless object around this " "long, making it available for conditional backend fetches. That " "means that the object will be removed from the cache at the end " "of ttl+grace+keep.", - /* flags */ OBJ_STICKY + /* flags */ OBJ_STICKY, + /* dyn_min_reason */ NULL, + /* dyn_max_reason */ NULL, + /* dyn_def_reason */ "0s" ) PARAM_SIMPLE( @@ -414,12 +420,15 @@ PARAM_SIMPLE( /* type */ timeout, /* min */ "0.000", /* max */ NULL, - /* def */ "120.000", + /* def */ "2m", /* units */ "seconds", /* descr */ "The TTL assigned to objects if neither the backend nor the VCL " "code assigns one.", - /* flags */ OBJ_STICKY + /* flags */ OBJ_STICKY, + /* dyn_min_reason */ NULL, + /* dyn_max_reason */ NULL, + /* dyn_def_reason */ "2m" ) PARAM_SIMPLE( From nils.goroll at uplex.de Sat May 28 11:38:08 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 28 May 2022 11:38:08 +0000 (UTC) Subject: [master] 199998799 Remove superfluous server commands from test case Message-ID: <20220528113808.C3BDA6E9D3@lists.varnish-cache.org> commit 1999987992f667d33b27ec1bf5cc7472d457b599 Author: Nils Goroll Date: Sat May 28 13:21:29 2022 +0200 Remove superfluous server commands from test case In d7695e488a003bd7b89279c50990864d4763dd8f, a legit caching case was turned into an error case. diff --git a/bin/varnishtest/tests/c00067.vtc b/bin/varnishtest/tests/c00067.vtc index fff734c46..9c1b98775 100644 --- a/bin/varnishtest/tests/c00067.vtc +++ b/bin/varnishtest/tests/c00067.vtc @@ -4,9 +4,8 @@ server s1 { rxreq expect req.bodylen == 106 txresp -body "ABCD" - rxreq - expect req.bodylen == 108 - txresp -body "ABCDE" + # the second request fails on the client side and + # does not reach the backend } -start varnish v1 -vcl+backend { From nils.goroll at uplex.de Sat May 28 11:38:08 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 28 May 2022 11:38:08 +0000 (UTC) Subject: [master] 24fe3772c Improve std.cache_req_body() with chunked test Message-ID: <20220528113808.DC2386E9D6@lists.varnish-cache.org> commit 24fe3772c520700b32711eb3b466dc1737327546 Author: Nils Goroll Date: Sat May 28 13:34:22 2022 +0200 Improve std.cache_req_body() with chunked test Bring back the positive test, testing with a chunked body one byte less, exactly and one byte more (than) the cache size. diff --git a/bin/varnishtest/tests/c00067.vtc b/bin/varnishtest/tests/c00067.vtc index 9c1b98775..f68775617 100644 --- a/bin/varnishtest/tests/c00067.vtc +++ b/bin/varnishtest/tests/c00067.vtc @@ -4,7 +4,18 @@ server s1 { rxreq expect req.bodylen == 106 txresp -body "ABCD" - # the second request fails on the client side and + + rxreq + expect req.url == "/2" + expect req.bodylen == 109 + txresp -body "ABCDE" + + rxreq + expect req.url == "/3" + expect req.bodylen == 110 + txresp -body "ABCDEF" + + # the last request fails on the client side and # does not reach the backend } -start @@ -38,10 +49,51 @@ varnish v1 -vcl+backend { } } +logexpect l2 -v v1 -g vxid -q {ReqURL ~ "^/2"} { + expect * * ReqUnset {^Transfer-encoding: chunked} + expect 0 = ReqHeader {^Content-Length: 109} + expect * = ReqAcct {^65 109 } +} -start + +logexpect l3 -v v1 -g vxid -q {ReqURL ~ "^/3"} { + expect * * ReqUnset {^Transfer-encoding: chunked} + expect 0 = ReqHeader {^Content-Length: 110} + expect * = ReqAcct {^65 110 } +} -start + +logexpect l4 -v v1 -g vxid -q {ReqURL ~ "^/4"} { + expect * * FetchError {^Request body too big to cache} + expect * = ReqAcct {^65 111 } +} -start + client c1 { - txreq -req POST -nolen -hdr "Transfer-encoding: chunked" - chunked {BLAS} + txreq -url "/2" -req POST -nolen -hdr "Transfer-encoding: chunked" + chunkedlen 50 + delay .2 + chunkedlen 59 delay .2 - chunkedlen 110 + chunkedlen 0 + rxresp + expect resp.status == 200 + expect resp.bodylen == 5 + + txreq -url "/3" -req POST -nolen -hdr "Transfer-encoding: chunked" + chunkedlen 50 + delay .2 + chunkedlen 60 + delay .2 + chunkedlen 0 + rxresp + expect resp.status == 200 + expect resp.bodylen == 6 + + txreq -url "/4" -req POST -nolen -hdr "Transfer-encoding: chunked" + chunked {BLAST} + delay .2 + chunkedlen 106 expect_close } -run + +logexpect l2 -wait +logexpect l3 -wait +logexpect l4 -wait \ No newline at end of file From nils.goroll at uplex.de Sat May 28 13:33:04 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 28 May 2022 13:33:04 +0000 (UTC) Subject: [master] d0345f9b2 c67.vtc: Ignore the Request header length Message-ID: <20220528133304.DB548102F3E@lists.varnish-cache.org> commit d0345f9b2da30ea993a663278255674244b591a1 Author: Nils Goroll Date: Sat May 28 15:31:45 2022 +0200 c67.vtc: Ignore the Request header length It differs for vtest running on IPv6 diff --git a/bin/varnishtest/tests/c00067.vtc b/bin/varnishtest/tests/c00067.vtc index f68775617..71e8c90f0 100644 --- a/bin/varnishtest/tests/c00067.vtc +++ b/bin/varnishtest/tests/c00067.vtc @@ -52,18 +52,18 @@ varnish v1 -vcl+backend { logexpect l2 -v v1 -g vxid -q {ReqURL ~ "^/2"} { expect * * ReqUnset {^Transfer-encoding: chunked} expect 0 = ReqHeader {^Content-Length: 109} - expect * = ReqAcct {^65 109 } + expect * = ReqAcct {^\d+ 109 } } -start logexpect l3 -v v1 -g vxid -q {ReqURL ~ "^/3"} { expect * * ReqUnset {^Transfer-encoding: chunked} expect 0 = ReqHeader {^Content-Length: 110} - expect * = ReqAcct {^65 110 } + expect * = ReqAcct {^\d+ 110 } } -start logexpect l4 -v v1 -g vxid -q {ReqURL ~ "^/4"} { expect * * FetchError {^Request body too big to cache} - expect * = ReqAcct {^65 111 } + expect * = ReqAcct {^\d+ 111 } } -start client c1 { From nils.goroll at uplex.de Sat May 28 13:55:05 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 28 May 2022 13:55:05 +0000 (UTC) Subject: [master] 8d5d94f76 Rename v1f_* pull callbacks for consistency Message-ID: <20220528135505.D089F103A18@lists.varnish-cache.org> commit 8d5d94f76515bd8edc61de08519f3a8bd620c6e7 Author: Nils Goroll Date: Sat May 28 15:53:42 2022 +0200 Rename v1f_* pull callbacks for consistency For other VFPs, we use the scheme _ diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c index 06869a59a..69c3099d0 100644 --- a/bin/varnishd/http1/cache_http1_vfp.c +++ b/bin/varnishd/http1/cache_http1_vfp.c @@ -96,7 +96,7 @@ v1f_read(const struct vfp_ctx *vc, struct http_conn *htc, void *d, ssize_t len) */ static enum vfp_status v_matchproto_(vfp_pull_f) -v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, +v1f_chunked_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) { struct http_conn *htc; @@ -185,14 +185,14 @@ v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, static const struct vfp v1f_chunked = { .name = "V1F_CHUNKED", - .pull = v1f_pull_chunked, + .pull = v1f_chunked_pull, }; /*--------------------------------------------------------------------*/ static enum vfp_status v_matchproto_(vfp_pull_f) -v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, +v1f_straight_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { ssize_t l, lr; @@ -222,13 +222,13 @@ v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, static const struct vfp v1f_straight = { .name = "V1F_STRAIGHT", - .pull = v1f_pull_straight, + .pull = v1f_straight_pull, }; /*--------------------------------------------------------------------*/ static enum vfp_status v_matchproto_(vfp_pull_f) -v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) +v1f_eof_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { ssize_t l, lr; struct http_conn *htc; @@ -253,7 +253,7 @@ v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) static const struct vfp v1f_eof = { .name = "V1F_EOF", - .pull = v1f_pull_eof, + .pull = v1f_eof_pull, }; /*-------------------------------------------------------------------- From nils.goroll at uplex.de Sat May 28 16:42:05 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Sat, 28 May 2022 16:42:05 +0000 (UTC) Subject: [master] 5e34d67f7 Simplify testcase Message-ID: <20220528164205.393CF10836B@lists.varnish-cache.org> commit 5e34d67f7b25ff8a5dda6dc9939a3c1148bd7aad Author: Nils Goroll Date: Sat May 28 18:41:18 2022 +0200 Simplify testcase diff --git a/bin/varnishtest/tests/c00092.vtc b/bin/varnishtest/tests/c00092.vtc index df85d1965..7860d2075 100644 --- a/bin/varnishtest/tests/c00092.vtc +++ b/bin/varnishtest/tests/c00092.vtc @@ -1,32 +1,23 @@ varnishtest "Check aborted backend body with a backend listening at UDS" barrier b1 cond 2 -barrier b2 cond 2 server s1 -listen "${tmpdir}/s1.sock" { rxreq txresp -nolen -hdr "Transfer-encoding: chunked" chunked {} barrier b1 sync - chunked {} - barrier b2 sync } -start varnish v1 -cliok "param.set debug +syncvsl" -vcl+backend { } -start - client c1 { txreq rxresphdrs expect resp.status == 200 rxchunk barrier b1 sync - rxchunk - barrier b2 sync expect_close } -run - - - From nils.goroll at uplex.de Sun May 29 12:29:07 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Sun, 29 May 2022 12:29:07 +0000 (UTC) Subject: [master] d8a627ec1 Clarify VFP_NULL semantics Message-ID: <20220529122907.1F9C39D044@lists.varnish-cache.org> commit d8a627ec138c838a2e7e96318a5b8569e1e65d61 Author: Nils Goroll Date: Sun May 29 14:28:07 2022 +0200 Clarify VFP_NULL semantics diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c index ed7fbea59..150b473f9 100644 --- a/bin/varnishd/cache/cache_fetch_proc.c +++ b/bin/varnishd/cache/cache_fetch_proc.c @@ -201,6 +201,7 @@ VFP_Suck(struct vfp_ctx *vc, void *p, ssize_t *lp) vp = vfe->closed; } vc->vfp_nxt = vfe; + assert(vp != VFP_NULL); return (vp); } diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 2b262d1eb..13fa35bcd 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -40,7 +40,7 @@ enum vfp_status { VFP_ERROR = -1, VFP_OK = 0, VFP_END = 1, - VFP_NULL = 2, + VFP_NULL = 2, // signal bypass, never returned by VFP_Suck() }; typedef enum vfp_status vfp_init_f(VRT_CTX, struct vfp_ctx *, From dridi.boukelmoune at gmail.com Mon May 30 12:17:04 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 30 May 2022 12:17:04 +0000 (UTC) Subject: [master] 2937cac1d vtc: add process pNAME -match-text LIN COL PAT Message-ID: <20220530121704.B0ED0109E97@lists.varnish-cache.org> commit 2937cac1dac6926c165ff8ec5182f98cb7c6d8d8 Author: Asad Sajjad Ahmed Date: Fri Feb 4 13:19:23 2022 +0100 vtc: add process pNAME -match-text LIN COL PAT Signed-off-by: Dridi Boukelmoune diff --git a/bin/varnishtest/tests/a00009.vtc b/bin/varnishtest/tests/a00009.vtc new file mode 100644 index 000000000..79c5aec7b --- /dev/null +++ b/bin/varnishtest/tests/a00009.vtc @@ -0,0 +1,34 @@ +varnishtest "VTC process: match text" + +process p1 { + echo 0123 + echo 4567 + echo 89AB + echo CDEF +} -run -screen-dump + +# y == 0, x == 0 +process p1 -match-text 0 0 "0123" +process p1 -match-text 0 0 "0.*3" +process p1 -match-text 0 0 "0123\(.|\n)*^CDEF" +process p1 -match-text 0 0 "0123\(.|\n)*^89AB\(.|\n)*F$" + +# y != 0, x == 0 +process p1 -match-text 1 0 "4567" +process p1 -match-text 2 0 "4567" +process p1 -match-text 2 0 "4567\(.|\n)*^9" +process p1 -match-text 3 0 "89AB" +process p1 -match-text 4 0 "C.*F" + +# y == 0, x != 0 +process p1 -match-text 0 1 "4567" +process p1 -match-text 0 2 "567" +process p1 -match-text 0 2 "123\(.|\n)*^5" +process p1 -match-text 0 2 "567\(.|\n)*^9" + +# y != 0, x != 0 +process p1 -match-text 1 1 "4567\(.|\n)*^89" +process p1 -match-text 2 2 "567\(.|\n)*^9" +process p1 -match-text 3 4 "B\(.|\n)*^F" +process p1 -match-text 4 3 "EF" + diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 4f6356b34..6a148a5bb 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -50,6 +50,7 @@ #include "vtc.h" +#include "vre.h" #include "vev.h" #include "vlu.h" #include "vsb.h" @@ -354,6 +355,64 @@ term_expect_cursor(const struct process *pp, const char *lin, const char *col) pos->tp_col + 1, y); } +static void +term_match_text(struct process *pp, + const char *lin, const char *col, const char *re) +{ + int i, x, y, l, err, erroff; + struct vsb *vsb, re_vsb[1]; + size_t len; + vre_t *vre; + char errbuf[VRE_ERROR_LEN]; + + vsb = VSB_new_auto(); + AN(vsb); + + y = strtoul(lin, NULL, 0); + if (y < 0 || y > pp->nlin) + vtc_fatal(pp->vl, "YYY %d nlin %d", y, pp->nlin); + x = strtoul(col, NULL, 0); + for(l = 0; l < 10 && x > pp->ncol; l++) // wait for screen change + usleep(100000); + if (x < 0 || x > pp->ncol) + vtc_fatal(pp->vl, "XXX %d ncol %d", x, pp->ncol); + + if (x) + x--; + + if (y) + y--; + + vre = VRE_compile(re, 0, &err, &erroff, 1); + if (vre == NULL) { + AN(VSB_init(re_vsb, errbuf, sizeof errbuf)); + AZ(VRE_error(re_vsb, err)); + AZ(VSB_finish(re_vsb)); + VSB_fini(re_vsb); + vtc_fatal(pp->vl, "invalid regexp \"%s\" at %d (%s)", + re, erroff, errbuf); + } + + AZ(pthread_mutex_lock(&pp->mtx)); + + len = (pp->nlin - y) * (pp->ncol - x); + for (i = y; i < pp->nlin; i++) { + VSB_bcat(vsb, &pp->vram[i][x], pp->ncol - x); + VSB_putc(vsb, '\n'); + } + + AZ(VSB_finish(vsb)); + + if (VRE_match(vre, VSB_data(vsb), len, 0, NULL) < 1) + vtc_fatal(pp->vl, "match failed: (\"%s\")", re); + else + vtc_log(pp->vl, 4, "match succeeded"); + + AZ(pthread_mutex_unlock(&pp->mtx)); + VSB_destroy(&vsb); + VRE_free(&vre); +} + /********************************************************************** * Allocate and initialize a process */ @@ -932,6 +991,12 @@ process_close(struct process *p) * LIN==0 means "on any line" * COL==0 means "anywhere on the line" * + * \-match-text LIN COL PAT + * Wait for the PAT regular expression to match the text at LIN,COL on the virtual screen. + * Lines and columns are numbered 1...N + * LIN==0 means "on any line" + * COL==0 means "anywhere on the line" + * * \-close * Alias for "-kill HUP" * @@ -1067,6 +1132,14 @@ cmd_process(CMD_ARGS) av += 2; continue; } + if (!strcmp(*av, "-match-text")) { + AN(av[1]); + AN(av[2]); + AN(av[3]); + term_match_text(p, av[1], av[2], av[3]); + av += 3; + continue; + } if (!strcmp(*av, "-screen_dump") || !strcmp(*av, "-screen-dump")) { term_screen_dump(p); From dridi.boukelmoune at gmail.com Mon May 30 14:04:05 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 30 May 2022 14:04:05 +0000 (UTC) Subject: [master] 00d3b77a8 param: Wrap the table entries definitions Message-ID: <20220530140405.DB8F910F197@lists.varnish-cache.org> commit 00d3b77a833b84969ac1f116ba45e52a035a8e03 Author: Dridi Boukelmoune Date: Fri Mar 11 18:01:18 2022 +0100 param: Wrap the table entries definitions This will allow the conditional definition of parameters in multiple steps, which is needed by bits parameters. diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c index 6b4110b08..50995411c 100644 --- a/bin/varnishd/mgt/mgt_param_tbl.c +++ b/bin/varnishd/mgt/mgt_param_tbl.c @@ -38,7 +38,9 @@ struct parspec mgt_parspec[] = { #define PARAM_ALL -#define PARAM(typ, fld, nm, ...) { #nm, __VA_ARGS__ }, +#define PARAM_PRE { +#define PARAM(typ, fld, nm, ...) #nm, __VA_ARGS__ +#define PARAM_POST }, #include "tbl/params.h" { NULL, NULL, NULL } }; diff --git a/include/tbl/params.h b/include/tbl/params.h index 0d8ba1c4f..1adf3d429 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -36,12 +36,19 @@ /*lint -save -e525 -e539 -e835 */ +#ifndef PARAM_ALL +# define PARAM_PRE +# define PARAM_POST +#endif + /*-------------------------------------------------------------------- * Simple parameters */ -#define PARAM_SIMPLE(nm, typ, ...) \ - PARAM(typ, nm, nm, tweak_##typ, &mgt_param.nm, __VA_ARGS__) +#define PARAM_SIMPLE(nm, typ, ...) \ + PARAM_PRE \ + PARAM(typ, nm, nm, tweak_##typ, &mgt_param.nm, __VA_ARGS__) \ + PARAM_POST #if defined(PLATFORM_FLAGS) # error "Temporary macro PLATFORM_FLAGS already defined" @@ -1216,13 +1223,15 @@ PARAM_SIMPLE( */ #define PARAM_MEMPOOL(nm, def, descr) \ + PARAM_PRE \ PARAM(poolparam, nm, nm, tweak_poolparam, &mgt_param.nm, \ NULL, NULL, def, NULL, \ descr \ "The three numbers are:\n" \ "\tmin_pool\tminimum size of free pool.\n" \ "\tmax_pool\tmaximum size of free pool.\n" \ - "\tmax_age\tmax age of free element.") + "\tmax_age\tmax age of free element.") \ + PARAM_POST PARAM_MEMPOOL( /* name */ pool_req, @@ -1250,8 +1259,10 @@ PARAM_MEMPOOL( */ #define PARAM_THREAD(nm, fld, typ, ...) \ + PARAM_PRE \ PARAM(typ, wthread_ ## fld, nm, tweak_ ## typ, \ - &mgt_param.wthread_ ## fld, __VA_ARGS__) + &mgt_param.wthread_ ## fld, __VA_ARGS__) \ + PARAM_POST PARAM_THREAD( /* name */ thread_pools, @@ -1530,8 +1541,10 @@ PARAM_THREAD( * String parameters */ -# define PARAM_STRING(nm, tw, pv, def, ...) \ - PARAM(, , nm, tw, pv, NULL, NULL, def, NULL, __VA_ARGS__) +# define PARAM_STRING(nm, tw, pv, def, ...) \ + PARAM_PRE \ + PARAM(, , nm, tw, pv, NULL, NULL, def, NULL, __VA_ARGS__) \ + PARAM_POST PARAM_STRING( /* name */ cc_command, @@ -1625,8 +1638,11 @@ PARAM_STRING( * VCC parameters */ -# define PARAM_VCC(nm, def, descr) \ - PARAM(, , nm, tweak_boolean, &mgt_ ## nm, NULL, NULL, def, "bool", descr) +# define PARAM_VCC(nm, def, descr) \ + PARAM_PRE \ + PARAM(, , nm, tweak_boolean, &mgt_ ## nm, NULL, NULL, def, \ + "bool", descr) \ + PARAM_POST PARAM_VCC( /* name */ vcc_err_unref, @@ -1655,8 +1671,10 @@ PARAM_VCC( */ # define PARAM_PCRE2(nm, pv, min, def, descr) \ + PARAM_PRE \ PARAM(, , nm, tweak_uint, &mgt_param.vre_limits.pv, \ - min, NULL, def, NULL, descr) + min, NULL, def, NULL, descr) \ + PARAM_POST PARAM_PCRE2( /* name */ pcre2_match_limit, @@ -1699,9 +1717,11 @@ PARAM_PCRE2( * The deprecated_dummy alias is here for test coverage. */ -#define PARAM_ALIAS(al, nm) \ +#define PARAM_ALIAS(al, nm) \ + PARAM_PRE \ PARAM(, , al, tweak_alias, NULL, NULL, NULL, #nm, NULL, \ - "Deprecated alias for the " #nm " parameter.") + "Deprecated alias for the " #nm " parameter.") \ + PARAM_POST PARAM_ALIAS(deprecated_dummy, debug) @@ -1713,6 +1733,8 @@ PARAM_ALIAS(deprecated_dummy, debug) #endif /* defined(PARAM_ALL) */ #undef PARAM_MEMPOOL +#undef PARAM_POST +#undef PARAM_PRE #undef PARAM_SIMPLE #undef PARAM_THREAD #undef PARAM From dridi.boukelmoune at gmail.com Mon May 30 14:04:06 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 30 May 2022 14:04:06 +0000 (UTC) Subject: [master] c6ee37a57 param: Declare bits parameters in the include table Message-ID: <20220530140406.0C30910F19B@lists.varnish-cache.org> commit c6ee37a572ca17b78dde9c8fbdc7aee3270dfc1e Author: Dridi Boukelmoune Date: Fri Mar 11 18:24:56 2022 +0100 param: Declare bits parameters in the include table With the help of PARAM_PRE and PARAM_POST macros we can deal with the include tables bits included by the params include tables without the nested macro evaluation limitation. diff --git a/bin/varnishd/common/common_param.h b/bin/varnishd/common/common_param.h index 201bfd381..4a34dfa4f 100644 --- a/bin/varnishd/common/common_param.h +++ b/bin/varnishd/common/common_param.h @@ -95,13 +95,17 @@ struct params { #define ptyp_boolean unsigned #define ptyp_bytes ssize_t #define ptyp_bytes_u unsigned +#define ptyp_debug debug_t #define ptyp_double double +#define ptyp_experimental experimental_t +#define ptyp_feature feature_t #define ptyp_poolparam struct poolparam #define ptyp_thread_pool_max unsigned #define ptyp_thread_pool_min unsigned #define ptyp_timeout vtim_dur #define ptyp_uint unsigned #define ptyp_vsl_buffer unsigned +#define ptyp_vsl_mask vsl_mask_t #define ptyp_vsl_reclen unsigned #define PARAM(typ, fld, nm, ...) \ ptyp_##typ fld; @@ -109,13 +113,17 @@ struct params { #undef ptyp_boolean #undef ptyp_bytes #undef ptyp_bytes_u +#undef ptyp_debug #undef ptyp_double +#undef ptyp_experimental +#undef ptyp_feature #undef ptyp_poolparam #undef ptyp_thread_pool_max #undef ptyp_thread_pool_min #undef ptyp_timeout #undef ptyp_uint #undef ptyp_vsl_buffer +#undef ptyp_vsl_mask #undef ptyp_vsl_reclen /* Unprivileged user / group */ @@ -123,9 +131,4 @@ struct params { gid_t gid; struct vre_limits vre_limits; - - vsl_mask_t vsl_mask; - debug_t debug_bits; - experimental_t experimental_bits; - feature_t feature_bits; }; diff --git a/bin/varnishd/mgt/mgt_param.h b/bin/varnishd/mgt/mgt_param.h index b15286f89..694b26d31 100644 --- a/bin/varnishd/mgt/mgt_param.h +++ b/bin/varnishd/mgt/mgt_param.h @@ -74,6 +74,9 @@ tweak_t tweak_boolean; tweak_t tweak_bytes; tweak_t tweak_bytes_u; tweak_t tweak_double; +tweak_t tweak_debug; +tweak_t tweak_experimental; +tweak_t tweak_feature; tweak_t tweak_poolparam; tweak_t tweak_storage; tweak_t tweak_string; @@ -82,6 +85,7 @@ tweak_t tweak_thread_pool_max; tweak_t tweak_timeout; tweak_t tweak_uint; tweak_t tweak_vsl_buffer; +tweak_t tweak_vsl_mask; tweak_t tweak_vsl_reclen; extern struct parspec mgt_parspec[]; /* mgt_param_tbl.c */ diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c index bec9625b4..96e8a6df3 100644 --- a/bin/varnishd/mgt/mgt_param_bits.c +++ b/bin/varnishd/mgt/mgt_param_bits.c @@ -154,7 +154,7 @@ static const char * const VSL_tags[256] = { # include "tbl/vsl_tags.h" }; -static int v_matchproto_(tweak_t) +int v_matchproto_(tweak_t) tweak_vsl_mask(struct vsb *vsb, const struct parspec *par, const char *arg) { @@ -172,7 +172,7 @@ static const char * const debug_tags[] = { NULL }; -static int v_matchproto_(tweak_t) +int v_matchproto_(tweak_t) tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg) { @@ -190,7 +190,7 @@ static const char * const experimental_tags[] = { NULL }; -static int v_matchproto_(tweak_t) +int v_matchproto_(tweak_t) tweak_experimental(struct vsb *vsb, const struct parspec *par, const char *arg) { @@ -208,7 +208,7 @@ static const char * const feature_tags[] = { NULL }; -static int v_matchproto_(tweak_t) +int v_matchproto_(tweak_t) tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) { @@ -221,62 +221,5 @@ tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) */ struct parspec VSL_parspec[] = { - { "vsl_mask", tweak_vsl_mask, NULL, - NULL, NULL, - /* default */ - "-Debug," - "-ExpKill," - "-H2RxBody," - "-H2RxHdr," - "-H2TxBody," - "-H2TxHdr," - "-Hash," - "-ObjHeader," - "-ObjProtocol," - "-ObjReason," - "-ObjStatus," - "-VCL_trace," - "-VdpAcct," - "-VfpAcct," - "-WorkThread", - NULL, - "Mask individual VSL messages from being logged.\n" - "\tdefault\tSet default value\n" - "\nUse +/- prefix in front of VSL tag name to unmask/mask " - "individual VSL messages." }, - { "debug", tweak_debug, NULL, - NULL, NULL, - /* default */ - "none", - NULL, - "Enable/Disable various kinds of debugging.\n" - "\tnone\tDisable all debugging\n\n" - "Use +/- prefix to set/reset individual bits:" -#define DEBUG_BIT(U, l, d) "\n\t" #l "\t" d -#include "tbl/debug_bits.h" - }, - { "experimental", tweak_experimental, NULL, - NULL, NULL, - /* default */ - "none", - NULL, - "Enable/Disable experimental features.\n" - "\tnone\tDisable all experimental features\n\n" - "Use +/- prefix to set/reset individual bits:" -#define EXPERIMENTAL_BIT(U, l, d) "\n\t" #l "\t" d -#include "tbl/experimental_bits.h" - }, - { "feature", tweak_feature, NULL, - NULL, NULL, - /* default */ - "+validate_headers", - NULL, - "Enable/Disable various minor features.\n" - "\tdefault\tSet default value\n" - "\tnone\tDisable all features.\n\n" - "Use +/- prefix to enable/disable individual feature:" -#define FEATURE_BIT(U, l, d) "\n\t" #l "\t" d -#include "tbl/feature_bits.h" - }, { NULL, NULL, NULL } }; diff --git a/include/tbl/params.h b/include/tbl/params.h index 1adf3d429..5c69d0438 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -1726,102 +1726,99 @@ PARAM_PCRE2( PARAM_ALIAS(deprecated_dummy, debug) # undef PARAM_ALIAS -# undef PARAM_ALL # undef PARAM_PCRE2 # undef PARAM_STRING # undef PARAM_VCC #endif /* defined(PARAM_ALL) */ -#undef PARAM_MEMPOOL -#undef PARAM_POST -#undef PARAM_PRE -#undef PARAM_SIMPLE -#undef PARAM_THREAD -#undef PARAM +/*-------------------------------------------------------------------- + * Bits parameters + */ + +#define PARAM_BITS(nm, fld, def, descr) \ + PARAM(nm, fld, nm, tweak_ ## nm, &mgt_param.fld, NULL, NULL, \ + def, NULL, descr) -#if 0 /* NOT ACTUALLY DEFINED HERE */ -/* actual location mgt_param_bits.c*/ -/* see tbl/debug_bits.h */ -PARAM( +PARAM_PRE +PARAM_BITS( /* name */ debug, - /* type */ debug, - /* min */ NULL, - /* max */ NULL, - /* def */ NULL, - /* units */ NULL, + /* fld */ debug_bits, + /* def */ "none", /* descr */ "Enable/Disable various kinds of debugging.\n" - " none Disable all debugging\n" - "\n" - "Use +/- prefix to set/reset individual bits:\n" - " req_state VSL Request state engine\n" - " workspace VSL Workspace operations\n" - " waiter VSL Waiter internals\n" - " waitinglist VSL Waitinglist events\n" - " syncvsl Make VSL synchronous\n" - " hashedge Edge cases in Hash\n" - " vclrel Rapid VCL release\n" - " lurker VSL Ban lurker\n" - " esi_chop Chop ESI fetch to bits\n" - " flush_head Flush after http1 head\n" - " vtc_mode Varnishtest Mode" -) - -/* actual location mgt_param_bits.c*/ -/* see tbl/experimental_bits.h */ -PARAM( + "\tnone\tDisable all debugging\n\n" + "Use +/- prefix to set/reset individual bits:") +#ifdef PARAM_ALL +# define DEBUG_BIT(U, l, d) "\n\t" #l "\t" d +# include "tbl/debug_bits.h" +#endif +PARAM_POST + +PARAM_PRE +PARAM_BITS( /* name */ experimental, - /* type */ experimental, - /* min */ NULL, - /* max */ NULL, - /* def */ NULL, - /* units */ NULL, + /* fld */ experimental_bits, + /* def */ "none", /* descr */ "Enable/Disable experimental features.\n" - " none Disable all experimental features\n" - "\n" - "Use +/- prefix to set/reset individual bits:\n" - " drop_pools Drop thread pools\n" -) + "\tnone\tDisable all experimental features\n\n" + "Use +/- prefix to set/reset individual bits:") +#ifdef PARAM_ALL +# define EXPERIMENTAL_BIT(U, l, d) "\n\t" #l "\t" d +# include "tbl/experimental_bits.h" +#endif +PARAM_POST -/* actual location mgt_param_bits.c*/ -/* See tbl/feature_bits.h */ -PARAM( +PARAM_PRE +PARAM_BITS( /* name */ feature, - /* type */ feature, - /* min */ NULL, - /* max */ NULL, - /* def */ NULL, - /* units */ NULL, + /* fld */ feature_bits, + /* def */ "+validate_headers", /* descr */ "Enable/Disable various minor features.\n" - " none Disable all features.\n" - "\n" - "Use +/- prefix to enable/disable individual feature:\n" - " short_panic Short panic message.\n" - " wait_silo Wait for persistent silo.\n" - " no_coredump No coredumps.\n" - " esi_ignore_https Treat HTTPS as HTTP in ESI:includes\n" - " esi_disable_xml_check Don't check of body looks like XML\n" - " esi_ignore_other_elements Ignore non-esi XML-elements\n" - " esi_remove_bom Remove UTF-8 BOM" -) - -/* actual location mgt_param_bits.c*/ -PARAM( + "\tdefault\tSet default value\n" + "\tnone\tDisable all features.\n\n" + "Use +/- prefix to enable/disable individual feature:") +#ifdef PARAM_ALL +# define FEATURE_BIT(U, l, d) "\n\t" #l "\t" d +# include "tbl/feature_bits.h" +#endif +PARAM_POST + +PARAM_PRE +PARAM_BITS( /* name */ vsl_mask, - /* type */ vsl_mask, - /* min */ NULL, - /* max */ NULL, - /* def */ "default", - /* units */ NULL, + /* fld */ vsl_mask, + /* def */ + "-Debug," + "-ExpKill," + "-H2RxBody," + "-H2RxHdr," + "-H2TxBody," + "-H2TxHdr," + "-Hash," + "-ObjHeader," + "-ObjProtocol," + "-ObjReason," + "-ObjStatus," + "-VCL_trace," + "-VdpAcct," + "-VfpAcct," + "-WorkThread", /* descr */ "Mask individual VSL messages from being logged.\n" - " default Set default value\n" - "\n" - "Use +/- prefix in front of VSL tag name to unmask/mask " - "individual VSL messages." -) -#endif /* NOT ACTUALLY DEFINED HERE */ + "\tdefault\tSet default value\n" + "\nUse +/- prefix in front of VSL tag name to unmask/mask " + "individual VSL messages.") +PARAM_POST + +#undef PARAM_ALL +#undef PARAM_BITS +#undef PARAM_MEMPOOL +#undef PARAM_POST +#undef PARAM_PRE +#undef PARAM_SIMPLE +#undef PARAM_THREAD +#undef PARAM /*lint -restore */ From dridi.boukelmoune at gmail.com Mon May 30 14:04:06 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 30 May 2022 14:04:06 +0000 (UTC) Subject: [master] a093bd646 param: Fold mgt_param_tbl.c into mgt_param.c Message-ID: <20220530140406.55C4710F1A1@lists.varnish-cache.org> commit a093bd646075c09713f4e08d91bbac2d07b6f85b Author: Dridi Boukelmoune Date: Fri Mar 11 18:55:38 2022 +0100 param: Fold mgt_param_tbl.c into mgt_param.c diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 8e8d6b117..79383fbb6 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -87,7 +87,6 @@ varnishd_SOURCES = \ mgt/mgt_main.c \ mgt/mgt_param.c \ mgt/mgt_param_bits.c \ - mgt/mgt_param_tbl.c \ mgt/mgt_param_tcp.c \ mgt/mgt_param_tweak.c \ mgt/mgt_shmem.c \ diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h index 9853f51a5..2ca6a8594 100644 --- a/bin/varnishd/mgt/mgt.h +++ b/bin/varnishd/mgt/mgt.h @@ -191,7 +191,6 @@ void MCF_ParamConf(enum mcf_which_e, const char *param, const char *, ...) void MCF_ParamSet(struct cli *, const char *param, const char *val); void MCF_ParamProtect(struct cli *, const char *arg); void MCF_DumpRstParam(void); -void MCF_AddParams(struct parspec *ps); extern struct params mgt_param; /* mgt_shmem.c */ diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 0aae0c75f..b34fe6772 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -610,16 +610,25 @@ mcf_param_reset(struct cli *cli, const char * const *av, void *priv) } /*-------------------------------------------------------------------- - * Add a group of parameters to the global set and sort by name. + * Initialize parameters and sort by name. */ -void -MCF_AddParams(struct parspec *ps) +static struct parspec mgt_parspec[] = { +#define PARAM_ALL +#define PARAM_PRE { +#define PARAM(typ, fld, nm, ...) #nm, __VA_ARGS__ +#define PARAM_POST }, +#include "tbl/params.h" + { NULL, NULL, NULL } +}; + +static void +mcf_init_params(void) { struct parspec *pp; const char *s; - for (pp = ps; pp->name != NULL; pp++) { + for (pp = mgt_parspec; pp->name != NULL; pp++) { AN(pp->func); s = strchr(pp->descr, '\0'); if (isspace(s[-1])) { @@ -720,9 +729,7 @@ MCF_InitParams(struct cli *cli) struct vsb *vsb; ssize_t def, low; - MCF_AddParams(mgt_parspec); - MCF_AddParams(VSL_parspec); - + mcf_init_params(); MCF_TcpParams(); def = 80 * 1024; diff --git a/bin/varnishd/mgt/mgt_param.h b/bin/varnishd/mgt/mgt_param.h index 694b26d31..f95e965fd 100644 --- a/bin/varnishd/mgt/mgt_param.h +++ b/bin/varnishd/mgt/mgt_param.h @@ -87,7 +87,3 @@ tweak_t tweak_uint; tweak_t tweak_vsl_buffer; tweak_t tweak_vsl_mask; tweak_t tweak_vsl_reclen; - -extern struct parspec mgt_parspec[]; /* mgt_param_tbl.c */ -extern struct parspec VSL_parspec[]; /* mgt_param_vsl.c */ -extern struct parspec WRK_parspec[]; /* mgt_pool.c */ diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c index 96e8a6df3..3ec359ffe 100644 --- a/bin/varnishd/mgt/mgt_param_bits.c +++ b/bin/varnishd/mgt/mgt_param_bits.c @@ -215,11 +215,3 @@ tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) return (tweak_generic_bits(vsb, par, arg, mgt_param.feature_bits, FEATURE_Reserved, feature_tags, "feature bit", '+')); } - -/*-------------------------------------------------------------------- - * The parameter table itself - */ - -struct parspec VSL_parspec[] = { - { NULL, NULL, NULL } -}; diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c deleted file mode 100644 index 50995411c..000000000 --- a/bin/varnishd/mgt/mgt_param_tbl.c +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2015 Varnish Software AS - * All rights reserved. - * - * Author: Poul-Henning Kamp - * - * 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. - */ - -#include "config.h" - -#include - -#include "mgt/mgt.h" -#include "mgt/mgt_param.h" - -struct parspec mgt_parspec[] = { -#define PARAM_ALL -#define PARAM_PRE { -#define PARAM(typ, fld, nm, ...) #nm, __VA_ARGS__ -#define PARAM_POST }, -#include "tbl/params.h" - { NULL, NULL, NULL } -}; From dridi.boukelmoune at gmail.com Mon May 30 14:04:06 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 30 May 2022 14:04:06 +0000 (UTC) Subject: [master] 9c1d4fb6d param: Fold mgt_param_bits.c into mgt_param_tweak.c Message-ID: <20220530140406.8F9B410F1A5@lists.varnish-cache.org> commit 9c1d4fb6d62b82417f30b282f56f39bb68d3503a Author: Dridi Boukelmoune Date: Fri Mar 11 18:58:42 2022 +0100 param: Fold mgt_param_bits.c into mgt_param_tweak.c diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 79383fbb6..aabfce050 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -86,7 +86,6 @@ varnishd_SOURCES = \ mgt/mgt_jail_unix.c \ mgt/mgt_main.c \ mgt/mgt_param.c \ - mgt/mgt_param_bits.c \ mgt/mgt_param_tcp.c \ mgt/mgt_param_tweak.c \ mgt/mgt_shmem.c \ diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c deleted file mode 100644 index 3ec359ffe..000000000 --- a/bin/varnishd/mgt/mgt_param_bits.c +++ /dev/null @@ -1,217 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software AS - * All rights reserved. - * - * Author: Poul-Henning Kamp - * - * 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. - */ - -#include "config.h" - -#include - -#include "mgt/mgt.h" -#include "mgt/mgt_param.h" - -#include "vav.h" - -#include "vsl_priv.h" - -/*-------------------------------------------------------------------- - */ - -enum bit_do {BSET, BCLR, BTST}; - -static int -bit(uint8_t *p, unsigned no, enum bit_do act) -{ - uint8_t b; - - p += (no >> 3); - b = (0x80 >> (no & 7)); - if (act == BSET) - *p |= b; - else if (act == BCLR) - *p &= ~b; - return (*p & b); -} - -/*-------------------------------------------------------------------- - */ - -static int -bit_tweak(struct vsb *vsb, uint8_t *p, unsigned l, const char *arg, - const char * const *tags, const char *desc, char sign) -{ - int i, n; - unsigned j; - char **av; - const char *s; - - av = VAV_Parse(arg, &n, ARGV_COMMA); - if (av[0] != NULL) { - VSB_printf(vsb, "Cannot parse: %s\n", av[0]); - VAV_Free(av); - return (-1); - } - for (i = 1; av[i] != NULL; i++) { - s = av[i]; - if (*s != '-' && *s != '+') { - VSB_printf(vsb, "Missing '+' or '-' (%s)\n", s); - VAV_Free(av); - return (-1); - } - for (j = 0; j < l; j++) { - if (tags[j] != NULL && !strcasecmp(s + 1, tags[j])) - break; - } - if (tags[j] == NULL) { - VSB_printf(vsb, "Unknown %s (%s)\n", desc, s); - VAV_Free(av); - return (-1); - } - assert(j < l); - if (s[0] == sign) - (void)bit(p, j, BSET); - else - (void)bit(p, j, BCLR); - } - VAV_Free(av); - return (0); -} - - -/*-------------------------------------------------------------------- - */ - -static int -tweak_generic_bits(struct vsb *vsb, const struct parspec *par, const char *arg, - uint8_t *p, unsigned l, const char * const *tags, const char *desc, - char sign) -{ - const char *s; - unsigned j; - - if (arg != NULL && !strcmp(arg, "default") && - strcmp(par->def, "none")) { - memset(p, 0, l >> 3); - return (tweak_generic_bits(vsb, par, par->def, p, l, tags, - desc, sign)); - } - - if (arg != NULL && arg != JSON_FMT) { - if (sign == '+' && !strcmp(arg, "none")) - memset(p, 0, l >> 3); - else - return (bit_tweak(vsb, p, l, arg, tags, desc, sign)); - } else { - if (arg == JSON_FMT) - VSB_putc(vsb, '"'); - s = ""; - for (j = 0; j < l; j++) { - if (bit(p, j, BTST)) { - VSB_printf(vsb, "%s%c%s", s, sign, tags[j]); - s = ","; - } - } - if (*s == '\0') - VSB_cat(vsb, sign == '+' ? "none" : "(all enabled)"); - if (arg == JSON_FMT) - VSB_putc(vsb, '"'); - } - return (0); -} - -/*-------------------------------------------------------------------- - * The vsl_mask parameter - */ - -static const char * const VSL_tags[256] = { -# define SLTM(foo,flags,sdesc,ldesc) [SLT_##foo] = #foo, -# include "tbl/vsl_tags.h" -}; - -int v_matchproto_(tweak_t) -tweak_vsl_mask(struct vsb *vsb, const struct parspec *par, const char *arg) -{ - - return (tweak_generic_bits(vsb, par, arg, mgt_param.vsl_mask, - SLT__Reserved, VSL_tags, "VSL tag", '-')); -} - -/*-------------------------------------------------------------------- - * The debug parameter - */ - -static const char * const debug_tags[] = { -# define DEBUG_BIT(U, l, d) [DBG_##U] = #l, -# include "tbl/debug_bits.h" - NULL -}; - -int v_matchproto_(tweak_t) -tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg) -{ - - return (tweak_generic_bits(vsb, par, arg, mgt_param.debug_bits, - DBG_Reserved, debug_tags, "debug bit", '+')); -} - -/*-------------------------------------------------------------------- - * The experimental parameter - */ - -static const char * const experimental_tags[] = { -# define EXPERIMENTAL_BIT(U, l, d) [EXPERIMENT_##U] = #l, -# include "tbl/experimental_bits.h" - NULL -}; - -int v_matchproto_(tweak_t) -tweak_experimental(struct vsb *vsb, const struct parspec *par, const char *arg) -{ - - return (tweak_generic_bits(vsb, par, arg, mgt_param.experimental_bits, - EXPERIMENT_Reserved, experimental_tags, "experimental bit", '+')); -} - -/*-------------------------------------------------------------------- - * The feature parameter - */ - -static const char * const feature_tags[] = { -# define FEATURE_BIT(U, l, d) [FEATURE_##U] = #l, -# include "tbl/feature_bits.h" - NULL -}; - -int v_matchproto_(tweak_t) -tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) -{ - - return (tweak_generic_bits(vsb, par, arg, mgt_param.feature_bits, - FEATURE_Reserved, feature_tags, "feature bit", '+')); -} diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index 4b4d793e8..6f0e26803 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -45,6 +45,7 @@ #include "storage/storage.h" #include "vav.h" #include "vnum.h" +#include "vsl_priv.h" const char * const JSON_FMT = (const char *)&JSON_FMT; @@ -568,3 +569,180 @@ tweak_alias(struct vsb *vsb, const struct parspec *par, const char *arg) par = TRUST_ME(par->priv); return (par->func(vsb, par, arg)); } + +/*-------------------------------------------------------------------- + * Tweak bits + */ + +enum bit_do {BSET, BCLR, BTST}; + +static int +bit(uint8_t *p, unsigned no, enum bit_do act) +{ + uint8_t b; + + p += (no >> 3); + b = (0x80 >> (no & 7)); + if (act == BSET) + *p |= b; + else if (act == BCLR) + *p &= ~b; + return (*p & b); +} + +/*-------------------------------------------------------------------- + */ + +static int +bit_tweak(struct vsb *vsb, uint8_t *p, unsigned l, const char *arg, + const char * const *tags, const char *desc, char sign) +{ + int i, n; + unsigned j; + char **av; + const char *s; + + av = VAV_Parse(arg, &n, ARGV_COMMA); + if (av[0] != NULL) { + VSB_printf(vsb, "Cannot parse: %s\n", av[0]); + VAV_Free(av); + return (-1); + } + for (i = 1; av[i] != NULL; i++) { + s = av[i]; + if (*s != '-' && *s != '+') { + VSB_printf(vsb, "Missing '+' or '-' (%s)\n", s); + VAV_Free(av); + return (-1); + } + for (j = 0; j < l; j++) { + if (tags[j] != NULL && !strcasecmp(s + 1, tags[j])) + break; + } + if (tags[j] == NULL) { + VSB_printf(vsb, "Unknown %s (%s)\n", desc, s); + VAV_Free(av); + return (-1); + } + assert(j < l); + if (s[0] == sign) + (void)bit(p, j, BSET); + else + (void)bit(p, j, BCLR); + } + VAV_Free(av); + return (0); +} + + +/*-------------------------------------------------------------------- + */ + +static int +tweak_generic_bits(struct vsb *vsb, const struct parspec *par, const char *arg, + uint8_t *p, unsigned l, const char * const *tags, const char *desc, + char sign) +{ + const char *s; + unsigned j; + + if (arg != NULL && !strcmp(arg, "default") && + strcmp(par->def, "none")) { + memset(p, 0, l >> 3); + return (tweak_generic_bits(vsb, par, par->def, p, l, tags, + desc, sign)); + } + + if (arg != NULL && arg != JSON_FMT) { + if (sign == '+' && !strcmp(arg, "none")) + memset(p, 0, l >> 3); + else + return (bit_tweak(vsb, p, l, arg, tags, desc, sign)); + } else { + if (arg == JSON_FMT) + VSB_putc(vsb, '"'); + s = ""; + for (j = 0; j < l; j++) { + if (bit(p, j, BTST)) { + VSB_printf(vsb, "%s%c%s", s, sign, tags[j]); + s = ","; + } + } + if (*s == '\0') + VSB_cat(vsb, sign == '+' ? "none" : "(all enabled)"); + if (arg == JSON_FMT) + VSB_putc(vsb, '"'); + } + return (0); +} + +/*-------------------------------------------------------------------- + * The vsl_mask parameter + */ + +static const char * const VSL_tags[256] = { +# define SLTM(foo,flags,sdesc,ldesc) [SLT_##foo] = #foo, +# include "tbl/vsl_tags.h" +}; + +int v_matchproto_(tweak_t) +tweak_vsl_mask(struct vsb *vsb, const struct parspec *par, const char *arg) +{ + + return (tweak_generic_bits(vsb, par, arg, mgt_param.vsl_mask, + SLT__Reserved, VSL_tags, "VSL tag", '-')); +} + +/*-------------------------------------------------------------------- + * The debug parameter + */ + +static const char * const debug_tags[] = { +# define DEBUG_BIT(U, l, d) [DBG_##U] = #l, +# include "tbl/debug_bits.h" + NULL +}; + +int v_matchproto_(tweak_t) +tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg) +{ + + return (tweak_generic_bits(vsb, par, arg, mgt_param.debug_bits, + DBG_Reserved, debug_tags, "debug bit", '+')); +} + +/*-------------------------------------------------------------------- + * The experimental parameter + */ + +static const char * const experimental_tags[] = { +# define EXPERIMENTAL_BIT(U, l, d) [EXPERIMENT_##U] = #l, +# include "tbl/experimental_bits.h" + NULL +}; + +int v_matchproto_(tweak_t) +tweak_experimental(struct vsb *vsb, const struct parspec *par, const char *arg) +{ + + return (tweak_generic_bits(vsb, par, arg, mgt_param.experimental_bits, + EXPERIMENT_Reserved, experimental_tags, "experimental bit", '+')); +} + +/*-------------------------------------------------------------------- + * The feature parameter + */ + +static const char * const feature_tags[] = { +# define FEATURE_BIT(U, l, d) [FEATURE_##U] = #l, +# include "tbl/feature_bits.h" + NULL +}; + +int v_matchproto_(tweak_t) +tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) +{ + + return (tweak_generic_bits(vsb, par, arg, mgt_param.feature_bits, + FEATURE_Reserved, feature_tags, "feature bit", '+')); +} From dridi.boukelmoune at gmail.com Tue May 31 08:02:05 2022 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 31 May 2022 08:02:05 +0000 (UTC) Subject: [master] f0ee94ecf vbe: Try fetching beresp when sending bereq failed Message-ID: <20220531080206.00E91105F5A@lists.varnish-cache.org> commit f0ee94ecf548e936ce64c0cfb484877dfb0e4b88 Author: Dridi Boukelmoune Date: Thu Dec 16 16:56:06 2021 +0100 vbe: Try fetching beresp when sending bereq failed There is no cancellation mechanism in the middle of an HTTP/1 transaction besides closing the session. If a backend closes the connection before the end of the bereq delivery, it may also send a 4XX or 5XX response that could be valuable for the original client. There are several things to take into consideration: it is the responsibility of the backend implementation to raise the bo->send_failed flag, if the backend replied something before closing we shouldn't trigger a timeout, the connection must not be recycled, and the object must not be cached. Fixes #2332 Closes #3686 diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 7ac117cc4..0e328bb18 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -243,7 +243,8 @@ vbe_dir_finish(VRT_CTX, VCL_BACKEND d) AZ(pfd); Lck_Lock(bp->director->mtx); } else { - assert (PFD_State(pfd) == PFD_STATE_USED); + assert(PFD_State(pfd) == PFD_STATE_USED); + AZ(bo->send_failed); VSLb(bo->vsl, SLT_BackendClose, "%d %s recycle", *PFD_Fd(pfd), VRT_BACKEND_string(d)); Lck_Lock(bp->director->mtx); @@ -268,6 +269,7 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) struct pfd *pfd; struct busyobj *bo; struct worker *wrk; + stream_close_t sc; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); @@ -275,6 +277,7 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); if (bo->htc != NULL) CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC); + AZ(bo->send_failed); wrk = ctx->bo->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC); @@ -301,8 +304,10 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) i = V1F_SendReq(wrk, bo, &bo->acct.bereq_hdrbytes, &bo->acct.bereq_bodybytes); - if (i == 0 && PFD_State(pfd) != PFD_STATE_USED) { - if (VCP_Wait(wrk, pfd, VTIM_real() + + if (PFD_State(pfd) != PFD_STATE_USED) { + if (bo->send_failed) + (void)VCP_Wait(wrk, pfd, VTIM_real()); + else if (VCP_Wait(wrk, pfd, VTIM_real() + bo->htc->first_byte_timeout) != 0) { bo->htc->doclose = SC_RX_TIMEOUT; VSLb(bo->vsl, SLT_FetchError, @@ -311,17 +316,25 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) } } - if (bo->htc->doclose == SC_NULL) { + if (bo->htc->doclose == SC_NULL) assert(PFD_State(pfd) == PFD_STATE_USED); + + sc = bo->htc->doclose; + if (i == 0 || bo->send_failed) { + i = V1F_FetchRespHdr(bo); if (i == 0) - i = V1F_FetchRespHdr(bo); - if (i == 0) { AN(bo->htc->priv); - return (0); - } } CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC); + if (bo->send_failed) { + assert(sc != SC_NULL); + bo->htc->doclose = sc; + } + + if (i == 0) + return (0); + /* * If we recycled a backend connection, there is a finite chance * that the backend closed it before we got the bereq to it. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index fde7e29a9..047dec969 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -330,6 +330,7 @@ vbf_stp_retry(struct worker *wrk, struct busyobj *bo) bo->do_esi = 0; bo->do_stream = 1; bo->was_304 = 0; + bo->send_failed = 0; bo->err_code = 0; bo->err_reason = NULL; if (bo->htc != NULL) @@ -547,6 +548,8 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) } if (bo->uncacheable) oc->flags |= OC_F_HFM; + if (bo->send_failed) + HSH_Kill(oc); assert(wrk->handling == VCL_RET_DELIVER); @@ -746,7 +749,7 @@ vbf_stp_fetchend(struct worker *wrk, struct busyobj *bo) ObjSetState(wrk, oc, BOS_FINISHED); VSLb_ts_busyobj(bo, "BerespBody", W_TIM_real(wrk)); - if (bo->stale_oc != NULL) + if (bo->stale_oc != NULL && !bo->send_failed) HSH_Kill(bo->stale_oc); return (F_STP_DONE); } diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 7d0e6c015..8a3245f4e 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -119,15 +119,6 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes, bo->no_retry = "req.body not cached"; if (bo->req->req_body_status == BS_ERROR) { - /* - * XXX: (#2332) We should test to see if the backend - * XXX: sent us some headers explaining why. - * XXX: This is hard because of the mistaken API split - * XXX: between cache_backend.c and V1F, and therefore - * XXX: Parked in this comment, pending renovation of - * XXX: the VDI/backend-protocol API to allow non-H1 - * XXX: backends. - */ assert(i < 0); VSLb(bo->vsl, SLT_FetchError, "req.body read error: %d (%s)", @@ -158,10 +149,15 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes, errno, VAS_errtxt(errno), sc->desc); VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); htc->doclose = sc; + /* NB: only raise the flag if we managed to at least send + * the request headers. + */ + bo->send_failed = bytes >= hdrbytes; return (-1); } CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC); VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); + bo->send_failed = 0; return (0); } @@ -171,7 +167,7 @@ V1F_FetchRespHdr(struct busyobj *bo) struct http *hp; int i; - double t; + vtim_real t; struct http_conn *htc; enum htc_status_e hs; @@ -190,7 +186,9 @@ V1F_FetchRespHdr(struct busyobj *bo) CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - t = VTIM_real() + htc->first_byte_timeout; + t = VTIM_real(); + if (!bo->send_failed) + t += htc->first_byte_timeout; hs = HTC_RxStuff(htc, HTTP1_Complete, NULL, NULL, t, NAN, htc->between_bytes_timeout, cache_param->http_resp_size); if (hs != HTC_S_COMPLETE) { @@ -214,6 +212,8 @@ V1F_FetchRespHdr(struct busyobj *bo) htc->doclose = SC_RX_OVERFLOW; break; case HTC_S_IDLE: + if (bo->send_failed) + break; VSLb(bo->vsl, SLT_FetchError, "first byte timeout"); htc->doclose = SC_RX_TIMEOUT; break; diff --git a/bin/varnishtest/tests/b00073.vtc b/bin/varnishtest/tests/b00073.vtc index 3372ba094..3aea0207e 100644 --- a/bin/varnishtest/tests/b00073.vtc +++ b/bin/varnishtest/tests/b00073.vtc @@ -27,13 +27,20 @@ server s1 { expect req.http.unset-connection == true txresp expect_close + + accept + rxreq } -start varnish v1 -vcl+backend { + backend bad { .host = "${bad_backend}"; } sub vcl_recv { return (pass); } sub vcl_backend_fetch { + if (bereq.http.fail == "send") { + set bereq.backend = bad; + } set bereq.http.connection = bereq.http.bereq-connection; } sub vcl_backend_response { @@ -61,9 +68,19 @@ client c1 { txreq -hdr "bereq-connection: close" -hdr "unset-connection: true" rxresp expect resp.status == 200 + + txreq -hdr "fail: fetch" + rxresp + expect resp.status == 503 } -run server s1 -wait +client c2 { + txreq -hdr "fail: send" + rxresp + expect resp.status == 503 +} -run + varnish v1 -expect MAIN.backend_recycle == 0 varnish v1 -expect VBE.vcl1.s1.conn == 0 diff --git a/bin/varnishtest/tests/f00001.vtc b/bin/varnishtest/tests/f00001.vtc index 2c756c9cd..9d52b06fc 100644 --- a/bin/varnishtest/tests/f00001.vtc +++ b/bin/varnishtest/tests/f00001.vtc @@ -4,7 +4,7 @@ varnishtest "Check that we handle bogusly large chunks correctly" server s1 { rxreq - txresp + txresp -status 400 } -start varnish v1 -vcl+backend { @@ -18,7 +18,7 @@ client c1 { send "0\r\n\r\n" rxresp - expect resp.status == 503 + expect resp.status == 400 } -run # Check that the published workaround does not cause harm diff --git a/bin/varnishtest/tests/r02332.vtc b/bin/varnishtest/tests/r02332.vtc new file mode 100644 index 000000000..b76d8a3d2 --- /dev/null +++ b/bin/varnishtest/tests/r02332.vtc @@ -0,0 +1,99 @@ +varnishtest "Fetch beresp despite failure to send bereq" + +barrier b1 cond 2 +barrier b2 cond 2 + +# bo->send_failed + +server s1 { + rxreqhdrs + txresp -status 400 -body "Invalid request" +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_fetch { + if (bereq.http.ignore == "bgfetch") { + return (abandon); + } + return (fetch); # don't unset bereq.body + } +} -start + +logexpect l1 -v v1 -g raw -i BackendClose { + expect 0 1002 BackendClose "s1 close" + expect 1 1007 BackendClose "s1 close" +} -start + +client c1 { + txreq -method POST -hdr "Transfer-Encoding: chunked" + chunkedlen 100 + barrier b1 sync + non_fatal + chunkedlen 100 + chunkedlen 0 + fatal + rxresp + expect resp.status == 400 + expect resp.body == "Invalid request" +} -start + +server s1 -wait +barrier b1 sync +client c1 -wait + +# bo->send_failed && 304 + +server s1 { + rxreq + txresp -hdr "Cache-Control: public, max-age=1" -hdr {Etag: "abc"} \ + -hdr "version: original" -body can-revalidate + + rxreqhdrs + expect req.http.if-none-match == {"abc"} + txresp -status 304 -hdr "Cache-Control: public" -hdr {Etag: "abc"} \ + -hdr "version: refreshed" +} -start + +client c2 { + txreq -hdr "Transfer-Encoding: chunked" + chunkedlen 100 + chunkedlen 100 + chunkedlen 0 + rxresp + expect resp.http.etag == {"abc"} + expect resp.http.version == original + expect resp.body == can-revalidate + + delay 2 + + # bereq.send_failed during grace + txreq -hdr "Transfer-Encoding: chunked" + chunkedlen 100 + barrier b2 sync + non_fatal + chunkedlen 100 + chunkedlen 0 + fatal + rxresp + expect resp.status == 200 + expect resp.http.etag == {"abc"} + expect resp.http.version == original + expect resp.body == can-revalidate +} -start + +server s1 -wait +barrier b2 sync +client c2 -wait + +client c3 { + txreq -hdr "Transfer-Encoding: chunked" -hdr "ignore: bgfetch" + chunkedlen 100 + chunkedlen 100 + chunkedlen 0 + rxresp + expect resp.http.etag == {"abc"} + expect resp.http.version == original + expect resp.body == can-revalidate +} -run + +logexpect l1 -wait diff --git a/doc/sphinx/reference/directors.rst b/doc/sphinx/reference/directors.rst index 66c0f406c..30888a99e 100644 --- a/doc/sphinx/reference/directors.rst +++ b/doc/sphinx/reference/directors.rst @@ -195,7 +195,9 @@ statistics, it is essentially a director which state is a ``struct backend``. Varnish native backends currently speak HTTP/1 over TCP or UDS, and as such, you need to make your own custom backend if you want Varnish to do otherwise such as connect over UDP or speak a different -protocol. +protocol. A custom backend implementation must implement the ``gethdrs`` +method, and optionally ``http1pipe``. It is the responsibility of the +custom backend to raise the ``send_failed`` flag from ``struct busyobj``. If you want to leverage probes declarations in VCL, which have the advantage of being reusable since they are only specifications, you can. However, you need diff --git a/include/tbl/bo_flags.h b/include/tbl/bo_flags.h index 4a4f1dd4b..624494d43 100644 --- a/include/tbl/bo_flags.h +++ b/include/tbl/bo_flags.h @@ -44,6 +44,7 @@ BO_FLAG(was_304, 0, 1, 0, 0, "") BO_FLAG(is_bgfetch, 1, 0, 0, 0, "") BO_FLAG(is_hitmiss, 1, 0, 0, 0, "") BO_FLAG(is_hitpass, 1, 0, 0, 0, "") +BO_FLAG(send_failed, 0, 0, 0, 0, "") #undef BO_FLAG /*lint -restore */ From nils.goroll at uplex.de Tue May 31 10:06:04 2022 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 31 May 2022 10:06:04 +0000 (UTC) Subject: [master] 55e4a206e Revert "vbe: Try fetching beresp when sending bereq failed" Message-ID: <20220531100604.631D4109893@lists.varnish-cache.org> commit 55e4a206e85b8fa7f88b9d2b4dc04ef5e35194bb Author: Nils Goroll Date: Tue May 31 12:04:38 2022 +0200 Revert "vbe: Try fetching beresp when sending bereq failed" Only momentarily until we understand and fix the newly introduced issues. This reverts commit f0ee94ecf548e936ce64c0cfb484877dfb0e4b88. Ref #3813 Reopen #3761 diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 0e328bb18..7ac117cc4 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -243,8 +243,7 @@ vbe_dir_finish(VRT_CTX, VCL_BACKEND d) AZ(pfd); Lck_Lock(bp->director->mtx); } else { - assert(PFD_State(pfd) == PFD_STATE_USED); - AZ(bo->send_failed); + assert (PFD_State(pfd) == PFD_STATE_USED); VSLb(bo->vsl, SLT_BackendClose, "%d %s recycle", *PFD_Fd(pfd), VRT_BACKEND_string(d)); Lck_Lock(bp->director->mtx); @@ -269,7 +268,6 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) struct pfd *pfd; struct busyobj *bo; struct worker *wrk; - stream_close_t sc; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); @@ -277,7 +275,6 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); if (bo->htc != NULL) CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC); - AZ(bo->send_failed); wrk = ctx->bo->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC); @@ -304,10 +301,8 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) i = V1F_SendReq(wrk, bo, &bo->acct.bereq_hdrbytes, &bo->acct.bereq_bodybytes); - if (PFD_State(pfd) != PFD_STATE_USED) { - if (bo->send_failed) - (void)VCP_Wait(wrk, pfd, VTIM_real()); - else if (VCP_Wait(wrk, pfd, VTIM_real() + + if (i == 0 && PFD_State(pfd) != PFD_STATE_USED) { + if (VCP_Wait(wrk, pfd, VTIM_real() + bo->htc->first_byte_timeout) != 0) { bo->htc->doclose = SC_RX_TIMEOUT; VSLb(bo->vsl, SLT_FetchError, @@ -316,25 +311,17 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) } } - if (bo->htc->doclose == SC_NULL) + if (bo->htc->doclose == SC_NULL) { assert(PFD_State(pfd) == PFD_STATE_USED); - - sc = bo->htc->doclose; - if (i == 0 || bo->send_failed) { - i = V1F_FetchRespHdr(bo); if (i == 0) + i = V1F_FetchRespHdr(bo); + if (i == 0) { AN(bo->htc->priv); + return (0); + } } CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC); - if (bo->send_failed) { - assert(sc != SC_NULL); - bo->htc->doclose = sc; - } - - if (i == 0) - return (0); - /* * If we recycled a backend connection, there is a finite chance * that the backend closed it before we got the bereq to it. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 047dec969..fde7e29a9 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -330,7 +330,6 @@ vbf_stp_retry(struct worker *wrk, struct busyobj *bo) bo->do_esi = 0; bo->do_stream = 1; bo->was_304 = 0; - bo->send_failed = 0; bo->err_code = 0; bo->err_reason = NULL; if (bo->htc != NULL) @@ -548,8 +547,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) } if (bo->uncacheable) oc->flags |= OC_F_HFM; - if (bo->send_failed) - HSH_Kill(oc); assert(wrk->handling == VCL_RET_DELIVER); @@ -749,7 +746,7 @@ vbf_stp_fetchend(struct worker *wrk, struct busyobj *bo) ObjSetState(wrk, oc, BOS_FINISHED); VSLb_ts_busyobj(bo, "BerespBody", W_TIM_real(wrk)); - if (bo->stale_oc != NULL && !bo->send_failed) + if (bo->stale_oc != NULL) HSH_Kill(bo->stale_oc); return (F_STP_DONE); } diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 8a3245f4e..7d0e6c015 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -119,6 +119,15 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes, bo->no_retry = "req.body not cached"; if (bo->req->req_body_status == BS_ERROR) { + /* + * XXX: (#2332) We should test to see if the backend + * XXX: sent us some headers explaining why. + * XXX: This is hard because of the mistaken API split + * XXX: between cache_backend.c and V1F, and therefore + * XXX: Parked in this comment, pending renovation of + * XXX: the VDI/backend-protocol API to allow non-H1 + * XXX: backends. + */ assert(i < 0); VSLb(bo->vsl, SLT_FetchError, "req.body read error: %d (%s)", @@ -149,15 +158,10 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes, errno, VAS_errtxt(errno), sc->desc); VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); htc->doclose = sc; - /* NB: only raise the flag if we managed to at least send - * the request headers. - */ - bo->send_failed = bytes >= hdrbytes; return (-1); } CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC); VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); - bo->send_failed = 0; return (0); } @@ -167,7 +171,7 @@ V1F_FetchRespHdr(struct busyobj *bo) struct http *hp; int i; - vtim_real t; + double t; struct http_conn *htc; enum htc_status_e hs; @@ -186,9 +190,7 @@ V1F_FetchRespHdr(struct busyobj *bo) CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - t = VTIM_real(); - if (!bo->send_failed) - t += htc->first_byte_timeout; + t = VTIM_real() + htc->first_byte_timeout; hs = HTC_RxStuff(htc, HTTP1_Complete, NULL, NULL, t, NAN, htc->between_bytes_timeout, cache_param->http_resp_size); if (hs != HTC_S_COMPLETE) { @@ -212,8 +214,6 @@ V1F_FetchRespHdr(struct busyobj *bo) htc->doclose = SC_RX_OVERFLOW; break; case HTC_S_IDLE: - if (bo->send_failed) - break; VSLb(bo->vsl, SLT_FetchError, "first byte timeout"); htc->doclose = SC_RX_TIMEOUT; break; diff --git a/bin/varnishtest/tests/b00073.vtc b/bin/varnishtest/tests/b00073.vtc index 3aea0207e..3372ba094 100644 --- a/bin/varnishtest/tests/b00073.vtc +++ b/bin/varnishtest/tests/b00073.vtc @@ -27,20 +27,13 @@ server s1 { expect req.http.unset-connection == true txresp expect_close - - accept - rxreq } -start varnish v1 -vcl+backend { - backend bad { .host = "${bad_backend}"; } sub vcl_recv { return (pass); } sub vcl_backend_fetch { - if (bereq.http.fail == "send") { - set bereq.backend = bad; - } set bereq.http.connection = bereq.http.bereq-connection; } sub vcl_backend_response { @@ -68,19 +61,9 @@ client c1 { txreq -hdr "bereq-connection: close" -hdr "unset-connection: true" rxresp expect resp.status == 200 - - txreq -hdr "fail: fetch" - rxresp - expect resp.status == 503 } -run server s1 -wait -client c2 { - txreq -hdr "fail: send" - rxresp - expect resp.status == 503 -} -run - varnish v1 -expect MAIN.backend_recycle == 0 varnish v1 -expect VBE.vcl1.s1.conn == 0 diff --git a/bin/varnishtest/tests/f00001.vtc b/bin/varnishtest/tests/f00001.vtc index 9d52b06fc..2c756c9cd 100644 --- a/bin/varnishtest/tests/f00001.vtc +++ b/bin/varnishtest/tests/f00001.vtc @@ -4,7 +4,7 @@ varnishtest "Check that we handle bogusly large chunks correctly" server s1 { rxreq - txresp -status 400 + txresp } -start varnish v1 -vcl+backend { @@ -18,7 +18,7 @@ client c1 { send "0\r\n\r\n" rxresp - expect resp.status == 400 + expect resp.status == 503 } -run # Check that the published workaround does not cause harm diff --git a/bin/varnishtest/tests/r02332.vtc b/bin/varnishtest/tests/r02332.vtc deleted file mode 100644 index b76d8a3d2..000000000 --- a/bin/varnishtest/tests/r02332.vtc +++ /dev/null @@ -1,99 +0,0 @@ -varnishtest "Fetch beresp despite failure to send bereq" - -barrier b1 cond 2 -barrier b2 cond 2 - -# bo->send_failed - -server s1 { - rxreqhdrs - txresp -status 400 -body "Invalid request" -} -start - -varnish v1 -vcl+backend { - sub vcl_backend_fetch { - if (bereq.http.ignore == "bgfetch") { - return (abandon); - } - return (fetch); # don't unset bereq.body - } -} -start - -logexpect l1 -v v1 -g raw -i BackendClose { - expect 0 1002 BackendClose "s1 close" - expect 1 1007 BackendClose "s1 close" -} -start - -client c1 { - txreq -method POST -hdr "Transfer-Encoding: chunked" - chunkedlen 100 - barrier b1 sync - non_fatal - chunkedlen 100 - chunkedlen 0 - fatal - rxresp - expect resp.status == 400 - expect resp.body == "Invalid request" -} -start - -server s1 -wait -barrier b1 sync -client c1 -wait - -# bo->send_failed && 304 - -server s1 { - rxreq - txresp -hdr "Cache-Control: public, max-age=1" -hdr {Etag: "abc"} \ - -hdr "version: original" -body can-revalidate - - rxreqhdrs - expect req.http.if-none-match == {"abc"} - txresp -status 304 -hdr "Cache-Control: public" -hdr {Etag: "abc"} \ - -hdr "version: refreshed" -} -start - -client c2 { - txreq -hdr "Transfer-Encoding: chunked" - chunkedlen 100 - chunkedlen 100 - chunkedlen 0 - rxresp - expect resp.http.etag == {"abc"} - expect resp.http.version == original - expect resp.body == can-revalidate - - delay 2 - - # bereq.send_failed during grace - txreq -hdr "Transfer-Encoding: chunked" - chunkedlen 100 - barrier b2 sync - non_fatal - chunkedlen 100 - chunkedlen 0 - fatal - rxresp - expect resp.status == 200 - expect resp.http.etag == {"abc"} - expect resp.http.version == original - expect resp.body == can-revalidate -} -start - -server s1 -wait -barrier b2 sync -client c2 -wait - -client c3 { - txreq -hdr "Transfer-Encoding: chunked" -hdr "ignore: bgfetch" - chunkedlen 100 - chunkedlen 100 - chunkedlen 0 - rxresp - expect resp.http.etag == {"abc"} - expect resp.http.version == original - expect resp.body == can-revalidate -} -run - -logexpect l1 -wait diff --git a/doc/sphinx/reference/directors.rst b/doc/sphinx/reference/directors.rst index 30888a99e..66c0f406c 100644 --- a/doc/sphinx/reference/directors.rst +++ b/doc/sphinx/reference/directors.rst @@ -195,9 +195,7 @@ statistics, it is essentially a director which state is a ``struct backend``. Varnish native backends currently speak HTTP/1 over TCP or UDS, and as such, you need to make your own custom backend if you want Varnish to do otherwise such as connect over UDP or speak a different -protocol. A custom backend implementation must implement the ``gethdrs`` -method, and optionally ``http1pipe``. It is the responsibility of the -custom backend to raise the ``send_failed`` flag from ``struct busyobj``. +protocol. If you want to leverage probes declarations in VCL, which have the advantage of being reusable since they are only specifications, you can. However, you need diff --git a/include/tbl/bo_flags.h b/include/tbl/bo_flags.h index 624494d43..4a4f1dd4b 100644 --- a/include/tbl/bo_flags.h +++ b/include/tbl/bo_flags.h @@ -44,7 +44,6 @@ BO_FLAG(was_304, 0, 1, 0, 0, "") BO_FLAG(is_bgfetch, 1, 0, 0, 0, "") BO_FLAG(is_hitmiss, 1, 0, 0, 0, "") BO_FLAG(is_hitpass, 1, 0, 0, 0, "") -BO_FLAG(send_failed, 0, 0, 0, 0, "") #undef BO_FLAG /*lint -restore */