Hi This patch is a fix for bug #1349
backend_find now does an extra traversal of the backend list to see if there is an exact match for the provided name argument. If ip and/or port is present, it will also check that these don't disagree with the configured ip/port of the backend. If no exact match can be found, we fall back to partial matching. Example: Consider a VCL with backends named foobar00, foobar0, foobar: backend.list foobar -> foobar (old behavior -> foobar00, foobar0, foobar) backend.list foobar0 -> foobar0 (old behavior -> foobar00, foobar0) backend.list foo -> foobar00, foobar0, foobar (old behavior -> same) Related to this, we should consider a different syntax for the ip/port specification, as the current one uses ':' as the separator, which breaks for IPv6. We could go with the square bracket syntax ([::1]:8080) or just use a different separator (::1,8080). Ideas? -- Dag Haavi Finstad Software Developer | Varnish Software Mobile: +47 476 64 134 We Make Websites Fly!
From 521cdc480238902f780d54be4635e43f8efc334f Mon Sep 17 00:00:00 2001 From: Dag Haavi Finstad <[email protected]> Date: Fri, 24 Oct 2014 11:42:44 +0200 Subject: [PATCH] Prefer exact matches in varnishadm backend.set_health. Fixes: #1349 --- bin/varnishd/cache/cache_backend_cfg.c | 25 +++++++++++++ bin/varnishtest/tests/r01349.vtc | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 bin/varnishtest/tests/r01349.vtc diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c index dbe07c1..e24c412 100644 --- a/bin/varnishd/cache/cache_backend_cfg.c +++ b/bin/varnishd/cache/cache_backend_cfg.c @@ -342,6 +342,31 @@ backend_find(struct cli *cli, const char *matcher, bf_func *func, void *priv) } } } + + /* First look for an exact match. */ + if (name_b != NULL) { + VTAILQ_FOREACH(b, &backends, list) { + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); + if (port_b != NULL && + strncmp(b->port, port_b, port_l) != 0) + continue; + if (name_b && + !(strncmp(b->vcl_name, name_b, name_l) == 0 && + b->vcl_name[name_l] == '\0')) + continue; + if (ip_b != NULL && + (b->ipv4_addr == NULL || + strncmp(b->ipv4_addr, ip_b, ip_l)) && + (b->ipv6_addr == NULL || + strncmp(b->ipv6_addr, ip_b, ip_l))) + continue; + i = func(cli, b, priv); + if (i) + return(i); + return (1); + } + } + VTAILQ_FOREACH(b, &backends, list) { CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); if (port_b != NULL && strncmp(b->port, port_b, port_l) != 0) diff --git a/bin/varnishtest/tests/r01349.vtc b/bin/varnishtest/tests/r01349.vtc new file mode 100644 index 0000000..60a2f6b --- /dev/null +++ b/bin/varnishtest/tests/r01349.vtc @@ -0,0 +1,67 @@ +varnishtest "Exact matching for varnishadm backend.set_health" + +server s1 -repeat 2 { + rxreq + txresp -hdr "Backend: b1" +} -start + +server s2 -repeat 2 { + rxreq + txresp -hdr "Backend: b" +} -start + +varnish v1 -vcl { + backend b1 { + .host = "${s1_addr}"; + .port = "${s1_port}"; + } + + backend b { + .host = "${s2_addr}"; + .port = "${s2_port}"; + } + + sub vcl_recv { + return(pass); + } + + sub vcl_backend_fetch { + if (bereq.http.backend == "b1") { + set bereq.backend = b1; + } + else { + set bereq.backend = b; + } + + } + +} -start + +varnish v1 -cliok "backend.list b" + +client c1 { + txreq -hdr "Backend: b1" + rxresp + expect resp.status == 200 + expect resp.http.backend == "b1" + + txreq -hdr "Backend: b" + rxresp + expect resp.status == 200 + expect resp.http.backend == "b" +} -run + +varnish v1 -cliok "backend.set_health b sick" + +client c1 { + txreq -hdr "Backend: b1" + rxresp + expect resp.status == 200 + expect resp.http.backend == "b1" + + txreq -hdr "Backend: b" + rxresp + expect resp.status == 503 +} -run + +varnish v1 -clierr 106 "backend.set_health b(1.2.3.4:) healthy" -- 2.1.1
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
