[master] 616bf3bf2 Add basic support of abstract sockets for accept and .path to backends

Nils Goroll nils.goroll at uplex.de
Mon Nov 21 17:11:05 UTC 2022


commit 616bf3bf2e29f4011d4a8e5e66f59cba553199a2
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Mon Nov 14 18:11:18 2022 +0100

    Add basic support of abstract sockets for accept and .path to backends
    
    We use the commonplace @<name> syntax to specify abstract socket names.
    
    Implements #3863

diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c
index 754911a23..9b649a7b9 100644
--- a/bin/varnishd/mgt/mgt_acceptor.c
+++ b/bin/varnishd/mgt/mgt_acceptor.c
@@ -221,9 +221,10 @@ mac_uds(void *priv, const struct sockaddr_un *uds)
 	struct listen_sock *ls;
 
 	CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
+	(void) uds;
 
 	VTAILQ_FOREACH(ls, &heritage.socks, list) {
-		if (ls->uds && strcmp(uds->sun_path, ls->endpoint) == 0)
+		if (ls->uds && strcmp(ls->endpoint, la->endpoint) == 0)
 			ARGV_ERR("-a arguments %s and %s have same address\n",
 			    ls->endpoint, la->endpoint);
 	}
@@ -289,7 +290,7 @@ MAC_Arg(const char *spec)
 			continue;
 		}
 		if (la->endpoint[0] != '/')
-			ARGV_ERR("Invalid sub-arg %s for IP addresses"
+			ARGV_ERR("Invalid sub-arg %s"
 			    " in -a\n", av[i]);
 
 		val = eq + 1;
diff --git a/bin/varnishtest/tests/c00003.vtc b/bin/varnishtest/tests/c00003.vtc
index 5c3b7fabd..1ad256922 100644
--- a/bin/varnishtest/tests/c00003.vtc
+++ b/bin/varnishtest/tests/c00003.vtc
@@ -33,18 +33,22 @@ shell -err -expect "Unix domain socket addresses must be absolute paths" {
 }
 
 # -a args for UDS permissions not permitted with IP addresses
-shell -err -expect "Invalid sub-arg user=u for IP addresses" {
+shell -err -expect "Invalid sub-arg user=u" {
 	varnishd -a ${localhost}:80000,user=u -d
 }
 
-shell -err -expect "Invalid sub-arg group=g for IP addresses" {
+shell -err -expect "Invalid sub-arg group=g" {
 	varnishd -a ${localhost}:80000,group=g -d
 }
 
-shell -err -expect "Invalid sub-arg mode=660 for IP addresses" {
+shell -err -expect "Invalid sub-arg mode=660" {
 	varnishd -a ${localhost}:80000,mode=660 -d
 }
 
+shell -err -expect "Invalid sub-arg mode=660" {
+	varnishd -a @abstract,mode=660 -d
+}
+
 # Illegal mode sub-args
 shell -err -expect "Too many mode sub-args" {
 	varnishd -a ${tmpdir}/vtc.sock,mode=660,mode=600 -d
diff --git a/bin/varnishtest/tests/c00121.vtc b/bin/varnishtest/tests/c00121.vtc
new file mode 100644
index 000000000..95b6aa14c
--- /dev/null
+++ b/bin/varnishtest/tests/c00121.vtc
@@ -0,0 +1,80 @@
+varnishtest "Abstract UDS backend: change path, drop poll"
+
+# XXX better test to check for abstract sockets
+feature cmd {socat abstract-listen:test file:/dev/null & date | socat fd:0  abstract-client:test}
+
+server s1 -listen "@vtc.s1.sock" {
+	non_fatal
+	timeout 3
+	loop 40 {
+		rxreq
+		txresp
+		accept
+	}
+} -start
+
+server s2 -listen "@vtc.s2.sock" {
+	non_fatal
+	timeout 3
+	loop 40 {
+		rxreq
+		txresp
+		accept
+	}
+} -start
+
+varnish v1 -arg "-a @vtc.v1.sock" -vcl {
+	probe default {
+		.window = 8;
+		.initial = 7;
+		.threshold = 8;
+		.interval = 0.1s;
+	}
+	backend s1 {
+		.path = "@vtc.s2.sock";
+	}
+} -start
+
+delay 1
+
+varnish v1 -vcl {
+	probe default {
+		.window = 8;
+		.initial = 7;
+		.threshold = 8;
+		.interval = 0.1s;
+	}
+	backend s1 {
+		.path = "@vtc.s1.sock";
+	}
+} -cliok "vcl.use vcl2" -cliok "vcl.discard vcl1"
+
+delay 1
+
+varnish v1 -vcl {
+	backend s1 {
+		.path = "@vtc.s1.sock";
+	}
+} -cliok "vcl.use vcl3" -cliok "vcl.discard vcl2"
+
+delay 1
+
+varnish v1 -cliok "vcl.list"
+varnish v1 -cliok "backend.list -p"
+
+server s1 -break {
+	rxreq
+	expect req.url == /foo
+	txresp -bodylen 4
+} -start
+
+delay 1
+
+client c1 -connect "@vtc.v1.sock" {
+	txreq -url /foo
+	rxresp
+	txreq -url /foo
+	rxresp
+	expect resp.status == 200
+	expect resp.bodylen == 4
+} -run
diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst
index 144910516..12bd0425f 100644
--- a/doc/sphinx/reference/varnishd.rst
+++ b/doc/sphinx/reference/varnishd.rst
@@ -93,11 +93,13 @@ Basic options
   (VCL4.1 and higher)
 
   Accept connections on a Unix domain socket.  Path must be absolute
-  ("/path/to/listen.sock").
+  ("/path/to/listen.sock") or "@" followed by the name of an abstract
+  socket ("@myvarnishd").
 
   The user, group and mode sub-arguments may be used to specify the
   permissions of the socket file -- use names for user and group, and
-  a 3-digit octal value for mode.
+  a 3-digit octal value for mode. These sub-arguments do not apply to
+  abstract sockets.
 
 -b <[host[:port]|path]>
 
diff --git a/doc/sphinx/reference/vcl-backend.rst b/doc/sphinx/reference/vcl-backend.rst
index a1f66e9f7..048f25cdd 100644
--- a/doc/sphinx/reference/vcl-backend.rst
+++ b/doc/sphinx/reference/vcl-backend.rst
@@ -76,6 +76,11 @@ The absolute path to a Unix(4) domain socket of a local backend::
 
     .path = "/var/run/http.sock";
 
+or, where available, ``@`` followed by the name of an abstract socket
+of a local backend::
+
+    .path = "@mybackend";
+
 A warning will be issued if the uds-socket does not exist when the
 VCL is loaded.  This makes it possible to start the UDS-listening peer,
 or set the socket file's permissions afterwards.
diff --git a/include/vus.h b/include/vus.h
index c2daf8f85..20d56fd15 100644
--- a/include/vus.h
+++ b/include/vus.h
@@ -40,5 +40,5 @@ int VUS_connect(const char *path, int msec);
 static inline int
 VUS_is(const char *path)
 {
-	return (*path == '/');
+	return (*path == '/' || *path == '@');
 }
diff --git a/lib/libvarnish/vsa.c b/lib/libvarnish/vsa.c
index 613555e3f..d1f1c91a0 100644
--- a/lib/libvarnish/vsa.c
+++ b/lib/libvarnish/vsa.c
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <sys/types.h>
 #include <netinet/in.h>
 
@@ -229,11 +230,14 @@ VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst)
 static inline
 socklen_t sua_len(const struct sockaddr *sa)
 {
+
 	switch (sa->sa_family) {
 	case PF_INET:
 		return (sizeof(struct sockaddr_in));
 	case PF_INET6:
 		return (sizeof(struct sockaddr_in6));
+	case AF_UNIX:
+		return (sizeof(struct sockaddr_un));
 	default:
 		return (0);
 	}
diff --git a/lib/libvarnish/vus.c b/lib/libvarnish/vus.c
index 07e3bf193..f1b943649 100644
--- a/lib/libvarnish/vus.c
+++ b/lib/libvarnish/vus.c
@@ -58,7 +58,10 @@ sun_init(struct sockaddr_un *uds, const char *path, const char **err)
 		return (-1);
 	}
 	memset(uds->sun_path, 0, sizeof(uds->sun_path));
-	bprintf(uds->sun_path, "%s", path);
+	if (*path == '@')
+		bprintf(uds->sun_path, "%c%s", 0, path + 1);
+	else
+		bprintf(uds->sun_path, "%s", path);
 	uds->sun_family = PF_UNIX;
 	return (0);
 }
diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c
index 8b357a58e..41b6d3739 100644
--- a/lib/libvcc/vcc_backend.c
+++ b/lib/libvcc/vcc_backend.c
@@ -91,6 +91,14 @@ Emit_Sockaddr(struct vcc *tl, struct vsb *vsb1, const struct token *t_host,
  * be accessed, and is a socket. If so, just emit the path field and set
  * the IP suckaddrs to NULL.
  */
+static void
+emit_path(struct vsb *vsb1, char *path)
+{
+	VSB_printf(vsb1, "\t.uds_path = \"%s\",\n", path);
+	VSB_cat(vsb1, "\t.ipv4 = (void *) 0,\n");
+	VSB_cat(vsb1, "\t.ipv6 = (void *) 0,\n");
+}
+
 static void
 Emit_UDS_Path(struct vcc *tl, struct vsb *vsb1,
     const struct token *t_path, const char *errid)
@@ -100,6 +108,10 @@ Emit_UDS_Path(struct vcc *tl, struct vsb *vsb1,
 	AN(t_path);
 	AN(t_path->dec);
 
+	if (*t_path->dec == '@') {
+		emit_path(vsb1, t_path->dec);
+		return;
+	}
 	if (*t_path->dec != '/') {
 		VSB_printf(tl->sb,
 			   "%s: Must be an absolute path:\n", errid);
@@ -121,9 +133,7 @@ Emit_UDS_Path(struct vcc *tl, struct vsb *vsb1,
 		vcc_ErrWhere(tl, t_path);
 		return;
 	}
-	VSB_printf(vsb1, "\t.uds_path = \"%s\",\n", t_path->dec);
-	VSB_cat(vsb1, "\t.ipv4 = (void *) 0,\n");
-	VSB_cat(vsb1, "\t.ipv6 = (void *) 0,\n");
+	emit_path(vsb1, t_path->dec);
 }
 
 /*--------------------------------------------------------------------


More information about the varnish-commit mailing list