[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