[master] 1c19f3fed vtest: Untie vtest from 127.0.0.1 and support IPv6 only setups

Nils Goroll nils.goroll at uplex.de
Sat Jan 9 20:17:15 UTC 2021


commit 1c19f3fed3da8fae79ef200f2ebf01625a42bb27
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Sat Jan 9 14:42:38 2021 +0100

    vtest: Untie vtest from 127.0.0.1 and support IPv6 only setups
    
    to support IPv6 only hosts, we try to resolve "localhost" if resolving
    "127.0.0.1" fails.
    
    Whatever address we determine is stored in the ${localhost}
    macro. Because of the different address:port vs. [address]:port
    formats for IPv4 vs. IPv6, we store "${localhost}:0" /
    "[${localhost}]:0" in the ${listen_addr} macro.
    
    Likewise we unify the *_sock macros to ${Xaddr}:${Xport} (the colon
    used to be missing) for IPv4 and [${Xaddr}]:${Xport} for IPv6.
    
    We also save ${listen_addr} in default_listen_addr for use from within
    the vtest code whenever we want to bind to or listen on an emphemeral
    port.
    
    Ref #3490

diff --git a/bin/varnishtest/tests/b00053.vtc b/bin/varnishtest/tests/b00053.vtc
index ea33a284a..6e7f8301b 100644
--- a/bin/varnishtest/tests/b00053.vtc
+++ b/bin/varnishtest/tests/b00053.vtc
@@ -76,5 +76,5 @@ client c1 -connect ${v3_sock} {
 	expect resp.http.a0_sock == "${tmpdir}/v1.sock"
 	expect resp.http.a1_addr != "0.0.0.0"
 	expect resp.http.a1_port != "0"
-	expect resp.http.a1_sock ~ "[^ ]+ [^ ]+"
+	expect resp.http.a1_sock ~ "[^ ]+:[^ ]+"
 } -run
diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h
index 1c716508f..046df86d0 100644
--- a/bin/varnishtest/vtc.h
+++ b/bin/varnishtest/vtc.h
@@ -81,6 +81,7 @@ extern char *vmod_path;
 extern struct vsb *params_vsb;
 extern int leave_temp;
 extern int ign_unknown_macro;
+extern const char *default_listen_addr;
 
 void init_server(void);
 void init_syslog(void);
diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c
index ee334953f..5600401fa 100644
--- a/bin/varnishtest/vtc_barrier.c
+++ b/bin/varnishtest/vtc_barrier.c
@@ -41,6 +41,7 @@
 
 #include "vtc.h"
 #include "vtcp.h"
+#include "vsa.h"
 
 enum barrier_e {
 	BARRIER_NONE = 0,
@@ -128,7 +129,10 @@ barrier_sock_thread(void *priv)
 	struct barrier *b;
 	struct vtclog *vl;
 	const char *err;
-	char abuf[16], pbuf[6];
+	char buf[vsa_suckaddr_len];
+	struct suckaddr *sua;
+
+	char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
 	int i, sock, *conns;
 	struct pollfd pfd[1];
 
@@ -140,7 +144,7 @@ barrier_sock_thread(void *priv)
 	vl = vtc_logopen("%s", b->name);
 	pthread_cleanup_push(vtc_logclose, vl);
 
-	sock = VTCP_listen_on("127.0.0.1:0", NULL, b->expected, &err);
+	sock = VTCP_listen_on(default_listen_addr, NULL, b->expected, &err);
 	if (sock < 0) {
 		AZ(pthread_cond_signal(&b->cond));
 		AZ(pthread_mutex_unlock(&b->mtx));
@@ -149,11 +153,16 @@ barrier_sock_thread(void *priv)
 	}
 	assert(sock > 0);
 	VTCP_nonblocking(sock);
-	VTCP_myname(sock, abuf, sizeof abuf, pbuf, sizeof pbuf);
+	sua = VSA_getsockname(sock, buf, sizeof buf);
+	AN(sua);
+	VTCP_name(sua, abuf, sizeof abuf, pbuf, sizeof pbuf);
 
 	macro_def(vl, b->name, "addr", "%s", abuf);
 	macro_def(vl, b->name, "port", "%s", pbuf);
-	macro_def(vl, b->name, "sock", "%s:%s", abuf, pbuf);
+	if (VSA_Get_Proto(sua) == AF_INET)
+		macro_def(vl, b->name, "sock", "%s:%s", abuf, pbuf);
+	else
+		macro_def(vl, b->name, "sock", "[%s]:%s", abuf, pbuf);
 
 	AZ(pthread_cond_signal(&b->cond));
 	AZ(pthread_mutex_unlock(&b->mtx));
diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c
index 07a8d48c1..3ef81a0a8 100644
--- a/bin/varnishtest/vtc_client.c
+++ b/bin/varnishtest/vtc_client.c
@@ -106,7 +106,7 @@ client_tcp_connect(struct vtclog *vl, const char *addr, double tmo,
 		   const char **errp)
 {
 	int fd;
-	char mabuf[32], mpbuf[32];
+	char mabuf[VTCP_ADDRBUFSIZE], mpbuf[VTCP_PORTBUFSIZE];
 
 	AN(addr);
 	AN(errp);
diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c
index 46b4001da..ca0cb9259 100644
--- a/bin/varnishtest/vtc_haproxy.c
+++ b/bin/varnishtest/vtc_haproxy.c
@@ -45,6 +45,7 @@
 #include "vpf.h"
 #include "vre.h"
 #include "vtcp.h"
+#include "vsa.h"
 #include "vtim.h"
 
 #define HAPROXY_PROGRAM_ENV_VAR	"HAPROXY_PROGRAM"
@@ -173,7 +174,7 @@ haproxy_cli_tcp_connect(struct vtclog *vl, const char *addr, double tmo,
     const char **errp)
 {
 	int fd;
-	char mabuf[32], mpbuf[32];
+	char mabuf[VTCP_ADDRBUFSIZE], mpbuf[VTCP_PORTBUFSIZE];
 
 	AN(addr);
 	AN(errp);
@@ -519,16 +520,23 @@ haproxy_create_mcli(struct haproxy *h)
 	int sock;
 	const char *err;
 	char buf[128], addr[128], port[128];
+	char vsabuf[vsa_suckaddr_len];
+	struct suckaddr *sua;
 
-	sock = VTCP_listen_on("127.0.0.1:0", NULL, 100, &err);
+	sock = VTCP_listen_on(default_listen_addr, NULL, 100, &err);
 	if (err != NULL)
 		vtc_fatal(h->vl,
 			  "Create listen socket failed: %s", err);
 	assert(sock > 0);
+	sua = VSA_getsockname(sock, vsabuf, sizeof vsabuf);
+	AN(sua);
 
-	VTCP_myname(sock, addr, sizeof addr, port, sizeof port);
+	VTCP_name(sua, addr, sizeof addr, port, sizeof port);
 	bprintf(buf, "%s_mcli", h->name);
-	macro_def(h->vl, buf, "sock", "%s %s", addr, port);
+	if (VSA_Get_Proto(sua) == AF_INET)
+		macro_def(h->vl, buf, "sock", "%s:%s", addr, port);
+	else
+		macro_def(h->vl, buf, "sock", "[%s]:%s", addr, port);
 	macro_def(h->vl, buf, "addr", "%s", addr);
 	macro_def(h->vl, buf, "port", "%s", port);
 
@@ -558,6 +566,8 @@ haproxy_new(const char *name)
 	int closed_sock;
 	char addr[128], port[128];
 	const char *err;
+	char vsabuf[vsa_suckaddr_len];
+	struct suckaddr *sua;
 
 	ALLOC_OBJ(h, HAPROXY_MAGIC);
 	AN(h);
@@ -597,8 +607,13 @@ haproxy_new(const char *name)
 		vtc_fatal(h->vl,
 			"Create listen socket failed: %s", err);
 	assert(closed_sock > 0);
-	VTCP_myname(closed_sock, addr, sizeof addr, port, sizeof port);
-	macro_def(h->vl, h->closed_sock, "sock", "%s %s", addr, port);
+	sua = VSA_getsockname(closed_sock, vsabuf, sizeof vsabuf);
+	AN(sua);
+	VTCP_name(sua, addr, sizeof addr, port, sizeof port);
+	if (VSA_Get_Proto(sua) == AF_INET)
+		macro_def(h->vl, h->closed_sock, "sock", "%s:%s", addr, port);
+	else
+		macro_def(h->vl, h->closed_sock, "sock", "[%s]:%s", addr, port);
 	macro_def(h->vl, h->closed_sock, "addr", "%s", addr);
 	macro_def(h->vl, h->closed_sock, "port", "%s", port);
 	VTCP_close(&closed_sock);
@@ -836,6 +851,8 @@ haproxy_build_backends(struct haproxy *h, const char *vsb_data)
 		int sock;
 		char buf[128], addr[128], port[128];
 		const char *err;
+		char vsabuf[vsa_suckaddr_len];
+		struct suckaddr *sua;
 
 		p = strstr(p, HAPROXY_BE_FD_STR);
 		if (!p)
@@ -853,10 +870,15 @@ haproxy_build_backends(struct haproxy *h, const char *vsb_data)
 			vtc_fatal(h->vl,
 			    "Create listen socket failed: %s", err);
 		assert(sock > 0);
+		sua = VSA_getsockname(sock, vsabuf, sizeof vsabuf);
+		AN(sua);
 
-		VTCP_myname(sock, addr, sizeof addr, port, sizeof port);
+		VTCP_name(sua, addr, sizeof addr, port, sizeof port);
 		bprintf(buf, "%s_%s", h->name, p);
-		macro_def(h->vl, buf, "sock", "%s %s", addr, port);
+		if (VSA_Get_Proto(sua) == AF_INET)
+			macro_def(h->vl, buf, "sock", "%s:%s", addr, port);
+		else
+			macro_def(h->vl, buf, "sock", "[%s]:%s", addr, port);
 		macro_def(h->vl, buf, "addr", "%s", addr);
 		macro_def(h->vl, buf, "port", "%s", port);
 
diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c
index 6110540c2..9b5a60a25 100644
--- a/bin/varnishtest/vtc_main.c
+++ b/bin/varnishtest/vtc_main.c
@@ -51,6 +51,7 @@
 #include "vnum.h"
 #include "vrnd.h"
 #include "vss.h"
+#include "vsa.h"
 #include "vsub.h"
 #include "vtcp.h"
 #include "vtim.h"
@@ -116,6 +117,7 @@ static int bad_backend_fd;
 
 static int cleaner_fd = -1;
 static pid_t cleaner_pid;
+const char *default_listen_addr;
 
 static struct buf *
 get_buf(void)
@@ -594,8 +596,13 @@ ip_magic(void)
 	sa = VSS_ResolveOne(NULL, "127.0.0.1", "0", 0, SOCK_STREAM, 0);
 	AN(sa);
 	bad_backend_fd = VTCP_bind(sa, NULL);
+	if (bad_backend_fd < 0) {
+		free(sa);
+		sa = VSS_ResolveFirst(NULL, "localhost", "0", 0, SOCK_STREAM, 0);
+		AN(sa);
+		bad_backend_fd = VTCP_bind(sa, NULL);
+	}
 	assert(bad_backend_fd >= 0);
-	free(sa);
 	VTCP_myname(bad_backend_fd, abuf, sizeof abuf, pbuf, sizeof(pbuf));
 	extmacro_def("localhost", "%s", abuf);
 
@@ -609,7 +616,21 @@ ip_magic(void)
 #endif
 
 	/* Expose a backend that is forever down. */
-	extmacro_def("bad_backend", "%s %s", abuf, pbuf);
+	if (VSA_Get_Proto(sa) == AF_INET)
+		extmacro_def("bad_backend", "%s:%s", abuf, pbuf);
+	else
+		extmacro_def("bad_backend", "[%s]:%s", abuf, pbuf);
+
+	/* our default bind/listen address */
+	if (VSA_Get_Proto(sa) == AF_INET)
+		bprintf(abuf, "%s:0", macro_get("localhost", NULL));
+	else
+		bprintf(abuf, "[%s]:0", macro_get("localhost", NULL));
+
+	extmacro_def("listen_addr", "%s", abuf);
+	default_listen_addr = strdup(abuf);
+	AN(default_listen_addr);
+	free(sa);
 
 	/*
 	 * We need an IP number which will not repond, ever, and that is a
diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c
index f98f2b7bb..87637ed73 100644
--- a/bin/varnishtest/vtc_server.c
+++ b/bin/varnishtest/vtc_server.c
@@ -39,6 +39,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "vsa.h"
 #include "vtc.h"
 
 #include "vtcp.h"
@@ -59,8 +60,8 @@ struct server {
 	int			sock;
 	int			fd;
 	char			listen[256];
-	char			aaddr[32];
-	char			aport[32];
+	char			aaddr[VTCP_ADDRBUFSIZE];
+	char			aport[VTCP_PORTBUFSIZE];
 
 	pthread_t		tp;
 };
@@ -88,7 +89,7 @@ server_new(const char *name, struct vtclog *vl)
 	s->vsp = Sess_New(s->vl, name);
 	AN(s->vsp);
 
-	bprintf(s->listen, "%s", "127.0.0.1 0");
+	bprintf(s->listen, "%s", default_listen_addr);
 	s->depth = 10;
 	s->sock = -1;
 	s->fd = -1;
@@ -183,17 +184,27 @@ server_listen_uds(struct server *s, const char **errp)
 static void
 server_listen_tcp(struct server *s, const char **errp)
 {
+	char buf[vsa_suckaddr_len];
+	struct suckaddr *sua;
+
 	s->sock = VTCP_listen_on(s->listen, "0", s->depth, errp);
 	if (*errp != NULL)
 		return;
 	assert(s->sock > 0);
-	VTCP_myname(s->sock, s->aaddr, sizeof s->aaddr,
+	sua = VSA_getsockname(s->sock, buf, sizeof buf);
+	AN(sua);
+	VTCP_name(sua, s->aaddr, sizeof s->aaddr,
 	    s->aport, sizeof s->aport);
+
+	/* Record the actual port, and reuse it on subsequent starts */
+	if (VSA_Get_Proto(sua) == AF_INET)
+		bprintf(s->listen, "%s:%s", s->aaddr, s->aport);
+	else
+		bprintf(s->listen, "[%s]:%s", s->aaddr, s->aport);
+
 	macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
 	macro_def(s->vl, s->name, "port", "%s", s->aport);
-	macro_def(s->vl, s->name, "sock", "%s %s", s->aaddr, s->aport);
-	/* Record the actual port, and reuse it on subsequent starts */
-	bprintf(s->listen, "%s %s", s->aaddr, s->aport);
+	macro_def(s->vl, s->name, "sock", "%s", s->listen);
 }
 
 static void
diff --git a/bin/varnishtest/vtc_syslog.c b/bin/varnishtest/vtc_syslog.c
index f57bd38d1..403a394ab 100644
--- a/bin/varnishtest/vtc_syslog.c
+++ b/bin/varnishtest/vtc_syslog.c
@@ -265,7 +265,7 @@ syslog_new(const char *name, struct vtclog *vl)
 	AN(s->vl);
 	vtc_log_set_cmd(s->vl, syslog_cmds);
 
-	bprintf(s->bind, "%s", "127.0.0.1 0");
+	bprintf(s->bind, "%s", default_listen_addr);
 	s->repeat = 1;
 	s->sock = -1;
 	s->lvl = -1;
@@ -358,6 +358,8 @@ syslog_bind(struct syslog_srv *s)
 	const char *err;
 	char aaddr[VTCP_ADDRBUFSIZE];
 	char aport[VTCP_PORTBUFSIZE];
+	char buf[vsa_suckaddr_len];
+	struct suckaddr *sua;
 
 	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
 
@@ -369,10 +371,15 @@ syslog_bind(struct syslog_srv *s)
 		    "Syslog server bind address (%s) cannot be resolved: %s",
 		    s->bind, err);
 	assert(s->sock > 0);
-	VTCP_myname(s->sock, aaddr, sizeof aaddr, aport, sizeof aport);
+	sua = VSA_getsockname(s->sock, buf, sizeof buf);
+	AN(sua);
+	VTCP_name(sua, aaddr, sizeof aaddr, aport, sizeof aport);
 	macro_def(s->vl, s->name, "addr", "%s", aaddr);
 	macro_def(s->vl, s->name, "port", "%s", aport);
-	macro_def(s->vl, s->name, "sock", "%s %s", aaddr, aport);
+	if (VSA_Get_Proto(sua) == AF_INET)
+		macro_def(s->vl, s->name, "sock", "%s:%s", aaddr, aport);
+	else
+		macro_def(s->vl, s->name, "sock", "[%s]:%s", aaddr, aport);
 	/* Record the actual port, and reuse it on subsequent starts */
 	bprintf(s->bind, "%s %s", aaddr, aport);
 }
diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c
index 1a4a3e88a..4698aa4e9 100644
--- a/bin/varnishtest/vtc_varnish.c
+++ b/bin/varnishtest/vtc_varnish.c
@@ -392,7 +392,7 @@ varnish_launch(struct varnish *v)
 	char *r = NULL;
 
 	/* Create listener socket */
-	v->cli_fd = VTCP_listen_on("127.0.0.1:0", NULL, 1, &err);
+	v->cli_fd = VTCP_listen_on(default_listen_addr, NULL, 1, &err);
 	if (err != NULL)
 		vtc_fatal(v->vl, "Create CLI listen socket failed: %s", err);
 	assert(v->cli_fd > 0);
@@ -420,7 +420,7 @@ varnish_launch(struct varnish *v)
 	VSB_cat(vsb, " -p h2_initial_window_size=1m");
 	VSB_cat(vsb, " -p h2_rx_window_low_water=64k");
 	if (!v->has_a_arg) {
-		VSB_printf(vsb, " -a '%s'", "127.0.0.1:0");
+		VSB_printf(vsb, " -a '%s'", default_listen_addr);
 		if (v->proto != NULL)
 			VSB_printf(vsb, ",%s", v->proto);
 	}
@@ -572,12 +572,14 @@ varnish_listen(const struct varnish *v, char *la)
 		AN(*a);
 		AN(*p);
 
-		if (*p != '-') {
-			bprintf(s, "%s %s", a, p);
-		} else {
+		if (*p == '-') {
 			bprintf(s, "%s", a);
 			a = "0.0.0.0";
 			p = "0";
+		} else if (strchr(a, ':')) {
+			bprintf(s, "[%s]:%s", a, p);
+		} else {
+			bprintf(s, "%s:%s", a, p);
 		}
 
 		if (first) {


More information about the varnish-commit mailing list