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

Reply via email to