[master] 04354217d acceptor: split mgt_acceptor.c
Nils Goroll
nils.goroll at uplex.de
Mon Sep 30 15:53:06 UTC 2024
commit 04354217dc0b94a094e53304037692a6336a58ac
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Thu Sep 5 10:40:42 2024 +0200
acceptor: split mgt_acceptor.c
Currently, changes between TCP and UDS is inter-mixed when opening
listen sockets, so split them up into their own files. This is cleaner
and is needed to add QUIC listen endpoint in the future.
Signed-off-by: Asad Sajjad Ahmed <asadsa at varnish-software.com>
Conflicts:
bin/varnishd/acceptor/mgt_acceptor.c
Signed-off-by: Nils Goroll <slink at uplex.de>
diff --git a/bin/varnishd/acceptor/acceptor_tcp.h b/bin/varnishd/acceptor/acceptor_tcp.h
new file mode 100644
index 000000000..350d5f72a
--- /dev/null
+++ b/bin/varnishd/acceptor/acceptor_tcp.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2023 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Asad Sajjad Ahmed <asadsa at varnish-software.com>
+ *
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct listen_arg;
+
+int vca_tcp_config(void);
+int vca_tcp_open(char **, struct listen_arg *, const char **);
+int vca_tcp_reopen(void);
diff --git a/bin/varnishd/acceptor/acceptor_uds.h b/bin/varnishd/acceptor/acceptor_uds.h
new file mode 100644
index 000000000..6a04546c3
--- /dev/null
+++ b/bin/varnishd/acceptor/acceptor_uds.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2023 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Asad Sajjad Ahmed <asadsa at varnish-software.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct listen_arg;
+
+struct uds_perms {
+ unsigned magic;
+#define UDS_PERMS_MAGIC 0x84fb5635
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+};
+
+int vca_uds_config(void);
+int vca_uds_open(char **, struct listen_arg *, const char **);
+int vca_uds_reopen(void);
diff --git a/bin/varnishd/acceptor/mgt_acceptor.c b/bin/varnishd/acceptor/mgt_acceptor.c
index ce93f7b3e..1e25a9078 100644
--- a/bin/varnishd/acceptor/mgt_acceptor.c
+++ b/bin/varnishd/acceptor/mgt_acceptor.c
@@ -41,8 +41,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <pwd.h>
-#include <grp.h>
#include "mgt/mgt.h"
#include "acceptor/cache_acceptor.h" // XXX mgt_acceptor should not use
@@ -56,68 +54,9 @@
#include "vtcp.h"
#include "vus.h"
-struct listen_arg {
- unsigned magic;
-#define LISTEN_ARG_MAGIC 0xbb2fc333
- VTAILQ_ENTRY(listen_arg) list;
- const char *endpoint;
- const char *name;
- VTAILQ_HEAD(,listen_sock) socks;
- const struct transport *transport;
- const struct uds_perms *perms;
-};
-
-struct uds_perms {
- unsigned magic;
-#define UDS_PERMS_MAGIC 0x84fb5635
- mode_t mode;
- uid_t uid;
- gid_t gid;
-};
-
static VTAILQ_HEAD(,listen_arg) listen_args =
VTAILQ_HEAD_INITIALIZER(listen_args);
-static int
-vca_vus_bind(void *priv, const struct sockaddr_un *uds)
-{
- return (VUS_bind(uds, priv));
-}
-
-static int
-vca_opensocket(struct listen_sock *ls)
-{
- int fail;
- const char *err;
-
- CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
- if (ls->sock > 0) {
- MCH_Fd_Inherit(ls->sock, NULL);
- closefd(&ls->sock);
- }
- if (!ls->uds)
- ls->sock = VTCP_bind(ls->addr, NULL);
- else
- ls->sock = VUS_resolver(ls->endpoint, vca_vus_bind, NULL, &err);
- fail = errno;
- if (ls->sock < 0) {
- AN(fail);
- return (fail);
- }
- if (ls->perms != NULL) {
- CHECK_OBJ(ls->perms, UDS_PERMS_MAGIC);
- assert(ls->uds);
- errno = 0;
- if (ls->perms->mode != 0 &&
- chmod(ls->endpoint, ls->perms->mode) != 0)
- return (errno);
- if (chown(ls->endpoint, ls->perms->uid, ls->perms->gid) != 0)
- return (errno);
- }
- MCH_Fd_Inherit(ls->sock, "sock");
- return (0);
-}
-
/*=====================================================================
* Reopen the accept sockets to get rid of listen status.
* returns the highest errno encountered, 0 for success
@@ -126,118 +65,15 @@ vca_opensocket(struct listen_sock *ls)
int
VCA_reopen_sockets(void)
{
- struct listen_sock *ls;
- int err, fail = 0;
-
- VTAILQ_FOREACH(ls, &heritage.socks, list) {
- VJ_master(JAIL_MASTER_PRIVPORT);
- err = vca_opensocket(ls);
- VJ_master(JAIL_MASTER_LOW);
- if (err == 0)
- continue;
- fail = vmax(fail, err);
- MGT_Complain(C_ERR,
- "Could not reopen listen socket %s: %s",
- ls->endpoint, VAS_errtxt(err));
- }
- return (fail);
-}
-
-/*--------------------------------------------------------------------*/
-
-static struct listen_sock *
-mk_listen_sock(const struct listen_arg *la, const struct suckaddr *sa)
-{
- struct listen_sock *ls;
- int fail;
-
- ALLOC_OBJ(ls, LISTEN_SOCK_MAGIC);
- AN(ls);
- ls->sock = -1;
- ls->addr = VSA_Clone(sa);
- AN(ls->addr);
- REPLACE(ls->endpoint, la->endpoint);
- ls->name = la->name;
- ls->transport = la->transport;
- ls->perms = la->perms;
- ls->uds = VUS_is(la->endpoint);
- VJ_master(JAIL_MASTER_PRIVPORT);
- fail = vca_opensocket(ls);
- VJ_master(JAIL_MASTER_LOW);
- if (fail) {
- VSA_free(&ls->addr);
- free(ls->endpoint);
- FREE_OBJ(ls);
- if (fail != EAFNOSUPPORT)
- ARGV_ERR("Could not get socket %s: %s\n",
- la->endpoint, VAS_errtxt(fail));
- return (NULL);
- }
- return (ls);
-}
-
-static int v_matchproto_(vss_resolved_f)
-vca_tcp(void *priv, const struct suckaddr *sa)
-{
- struct listen_arg *la;
- struct listen_sock *ls;
- char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
- char nbuf[VTCP_ADDRBUFSIZE+VTCP_PORTBUFSIZE+2];
+ int fail, fail2;
- CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
+ fail = vca_tcp_open();
+ fail2 = vca_uds_open();
- VTAILQ_FOREACH(ls, &heritage.socks, list) {
- if (!ls->uds && !VSA_Compare(sa, ls->addr))
- ARGV_ERR("-a arguments %s and %s have same address\n",
- ls->endpoint, la->endpoint);
- }
- ls = mk_listen_sock(la, sa);
- if (ls == NULL)
- return (0);
- AZ(ls->uds);
- if (VSA_Port(ls->addr) == 0) {
- /*
- * If the argv port number is zero, we adopt whatever
- * port number this VTCP_bind() found us, as if
- * it was specified by the argv.
- */
- VSA_free(&ls->addr);
- ls->addr = VTCP_my_suckaddr(ls->sock);
- VTCP_myname(ls->sock, abuf, sizeof abuf,
- pbuf, sizeof pbuf);
- if (VSA_Get_Proto(sa) == AF_INET6)
- bprintf(nbuf, "[%s]:%s", abuf, pbuf);
- else
- bprintf(nbuf, "%s:%s", abuf, pbuf);
- REPLACE(ls->endpoint, nbuf);
- }
- VTAILQ_INSERT_TAIL(&la->socks, ls, arglist);
- VTAILQ_INSERT_TAIL(&heritage.socks, ls, list);
- return (0);
+ return (vmax(fail, fail2));
}
-static int v_matchproto_(vus_resolved_f)
-vca_uds(void *priv, const struct sockaddr_un *uds)
-{
- struct listen_arg *la;
- struct listen_sock *ls;
-
- CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
- (void) uds;
-
- VTAILQ_FOREACH(ls, &heritage.socks, list) {
- if (ls->uds && strcmp(ls->endpoint, la->endpoint) == 0)
- ARGV_ERR("-a arguments %s and %s have same address\n",
- ls->endpoint, la->endpoint);
- }
- ls = mk_listen_sock(la, bogo_ip);
- if (ls == NULL)
- return (0);
- AN(ls->uds);
- VTAILQ_INSERT_TAIL(&la->socks, ls, arglist);
- VTAILQ_INSERT_TAIL(&heritage.socks, ls, list);
- return (0);
-}
+/*--------------------------------------------------------------------*/
void
VCA_Arg(const char *spec)
@@ -246,14 +82,9 @@ VCA_Arg(const char *spec)
struct listen_arg *la;
const char *err;
int error;
- const struct transport *xp = NULL;
const char *name;
char name_buf[8];
static unsigned seq = 0;
- struct passwd *pwd = NULL;
- struct group *grp = NULL;
- mode_t mode = 0;
- struct uds_perms *perms;
av = MGT_NamedArg(spec, &name, "-a");
AN(av);
@@ -269,111 +100,13 @@ VCA_Arg(const char *spec)
name = strdup(name_buf);
AN(name);
}
- la->name = name;
-
- if (*la->endpoint != '/' && strchr(la->endpoint, '/') != NULL)
- ARGV_ERR("Unix domain socket addresses must be"
- " absolute paths in -a (%s)\n", la->endpoint);
-
- if (VUS_is(la->endpoint) && heritage.min_vcl_version < 41)
- heritage.min_vcl_version = 41;
-
- for (int i = 2; av[i] != NULL; i++) {
- char *eq, *val;
- int len;
-
- if ((eq = strchr(av[i], '=')) == NULL) {
- if (xp != NULL)
- ARGV_ERR("Too many protocol sub-args"
- " in -a (%s)\n", av[i]);
- xp = XPORT_Find(av[i]);
- if (xp == NULL)
- ARGV_ERR("Unknown protocol '%s'\n", av[i]);
- continue;
- }
- if (la->endpoint[0] != '/')
- ARGV_ERR("Invalid sub-arg %s"
- " in -a\n", av[i]);
-
- val = eq + 1;
- len = eq - av[i];
- assert(len >= 0);
- if (len == 0)
- ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
-
- if (strncmp(av[i], "user", len) == 0) {
- if (pwd != NULL)
- ARGV_ERR("Too many user sub-args in -a (%s)\n",
- av[i]);
- pwd = getpwnam(val);
- if (pwd == NULL)
- ARGV_ERR("Unknown user %s in -a\n", val);
- continue;
- }
-
- if (strncmp(av[i], "group", len) == 0) {
- if (grp != NULL)
- ARGV_ERR("Too many group sub-args in -a (%s)\n",
- av[i]);
- grp = getgrnam(val);
- if (grp == NULL)
- ARGV_ERR("Unknown group %s in -a\n", val);
- continue;
- }
-
- if (strncmp(av[i], "mode", len) == 0) {
- long m;
- char *p;
-
- if (mode != 0)
- ARGV_ERR("Too many mode sub-args in -a (%s)\n",
- av[i]);
- if (*val == '\0')
- ARGV_ERR("Empty mode sub-arg in -a\n");
- errno = 0;
- m = strtol(val, &p, 8);
- if (*p != '\0')
- ARGV_ERR("Invalid mode sub-arg %s in -a\n",
- val);
- if (errno)
- ARGV_ERR("Cannot parse mode sub-arg %s in -a: "
- "%s\n", val, VAS_errtxt(errno));
- if (m <= 0 || m > 0777)
- ARGV_ERR("Mode sub-arg %s out of range in -a\n",
- val);
- mode = (mode_t) m;
- continue;
- }
-
- ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
- }
-
- if (xp == NULL)
- xp = XPORT_Find("http");
- AN(xp);
- la->transport = xp;
- if (pwd != NULL || grp != NULL || mode != 0) {
- ALLOC_OBJ(perms, UDS_PERMS_MAGIC);
- AN(perms);
- if (pwd != NULL)
- perms->uid = pwd->pw_uid;
- else
- perms->uid = (uid_t) -1;
- if (grp != NULL)
- perms->gid = grp->gr_gid;
- else
- perms->gid = (gid_t) -1;
- perms->mode = mode;
- la->perms = perms;
- }
- else
- AZ(la->perms);
+ la->name = name;
if (VUS_is(la->endpoint))
- error = VUS_resolver(av[1], vca_uds, la, &err);
+ error = vca_uds_open(av[1], la, &err);
else
- error = VSS_resolver_range(av[1], "80", vca_tcp, la, &err);
+ error = vca_tcp_open(av[1], la, &err);
if (error)
ARGV_ERR("Got no socket(s) for %s (%s)\n", av[1], err);
diff --git a/bin/varnishd/acceptor/mgt_acceptor.h b/bin/varnishd/acceptor/mgt_acceptor.h
index 91ef0dcbe..5558383c5 100644
--- a/bin/varnishd/acceptor/mgt_acceptor.h
+++ b/bin/varnishd/acceptor/mgt_acceptor.h
@@ -32,5 +32,16 @@
/* mgt_acceptor.c */
+struct listen_arg {
+ unsigned magic;
+#define LISTEN_ARG_MAGIC 0xbb2fc333
+ VTAILQ_ENTRY(listen_arg) list;
+ const char *endpoint;
+ const char *name;
+ VTAILQ_HEAD(,listen_sock) socks;
+ const struct transport *transport;
+ const struct uds_perms *perms;
+};
+
void VCA_Arg(const char *);
int VCA_reopen_sockets(void);
diff --git a/bin/varnishd/acceptor/mgt_acceptor_tcp.c b/bin/varnishd/acceptor/mgt_acceptor_tcp.c
new file mode 100644
index 000000000..279ea7479
--- /dev/null
+++ b/bin/varnishd/acceptor/mgt_acceptor_tcp.c
@@ -0,0 +1,225 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2023 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Asad Sajjad Ahmed <asadsa at varnish-software.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "mgt/mgt.h"
+#include "common/heritage.h"
+
+#include "acceptor/cache_acceptor.h"
+#include "acceptor/acceptor_tcp.h"
+#include "acceptor/mgt_acceptor.h"
+
+#include "vav.h"
+#include "vcli_serve.h"
+#include "vsa.h"
+#include "vss.h"
+#include "vtcp.h"
+
+int
+vca_tcp_config(void)
+{
+
+ return (0);
+}
+
+static int
+vca_tcp_opensocket(struct listen_sock *ls)
+{
+ int fail;
+
+ CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
+
+ if (ls->sock > 0) {
+ MCH_Fd_Inherit(ls->sock, NULL);
+ closefd(&ls->sock);
+ }
+
+ ls->sock = VTCP_bind(ls->addr, NULL);
+ fail = errno;
+
+ if (ls->sock < 0) {
+ AN(fail);
+ return (fail);
+ }
+
+ AZ(ls->perms);
+ MCH_Fd_Inherit(ls->sock, "sock");
+
+ return (0);
+}
+
+static int v_matchproto_(vss_resolved_f)
+vca_tcp_open_cb(void *priv, const struct suckaddr *sa)
+{
+ struct listen_arg *la;
+ struct listen_sock *ls;
+ char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
+ char nbuf[VTCP_ADDRBUFSIZE+VTCP_PORTBUFSIZE+2];
+ int fail;
+
+ CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
+
+ VTAILQ_FOREACH(ls, &heritage.socks, list) {
+ CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
+
+ if (!ls->uds && !VSA_Compare(sa, ls->addr))
+ ARGV_ERR("-a arguments %s and %s have same address\n",
+ ls->endpoint, la->endpoint);
+ }
+
+ ALLOC_OBJ(ls, LISTEN_SOCK_MAGIC);
+ AN(ls);
+
+ ls->sock = -1;
+
+ ls->addr = VSA_Clone(sa);
+ AN(ls->addr);
+
+ REPLACE(ls->endpoint, la->endpoint);
+ ls->name = la->name;
+ ls->transport = la->transport;
+ ls->perms = la->perms;
+
+ VJ_master(JAIL_MASTER_PRIVPORT);
+ fail = vca_tcp_opensocket(ls);
+ VJ_master(JAIL_MASTER_LOW);
+
+ if (fail) {
+ VSA_free(&ls->addr);
+ free(ls->endpoint);
+ FREE_OBJ(ls);
+ if (fail != EAFNOSUPPORT)
+ ARGV_ERR("Could not get socket %s: %s\n",
+ la->endpoint, VAS_errtxt(fail));
+ return (0);
+ }
+
+ AZ(ls->uds);
+
+ if (VSA_Port(ls->addr) == 0) {
+ /*
+ * If the argv port number is zero, we adopt whatever
+ * port number this VTCP_bind() found us, as if
+ * it was specified by the argv.
+ */
+ VSA_free(&ls->addr);
+ ls->addr = VTCP_my_suckaddr(ls->sock);
+ VTCP_myname(ls->sock, abuf, sizeof abuf,
+ pbuf, sizeof pbuf);
+ if (VSA_Get_Proto(sa) == AF_INET6)
+ bprintf(nbuf, "[%s]:%s", abuf, pbuf);
+ else
+ bprintf(nbuf, "%s:%s", abuf, pbuf);
+ REPLACE(ls->endpoint, nbuf);
+ }
+
+ VTAILQ_INSERT_TAIL(&la->socks, ls, arglist);
+ VTAILQ_INSERT_TAIL(&heritage.socks, ls, list);
+
+ return (0);
+}
+
+
+int
+vca_tcp_open(char **av, struct listen_arg *la, const char **err)
+{
+ const struct transport *xp = NULL;
+
+ CHECK_OBJ_NOTNULL(la, LISTEN_ARG_MAGIC);
+ AN(av);
+ AN(err);
+ AZ(la->perms);
+
+ if (strchr(la->endpoint, '/') != NULL)
+ ARGV_ERR("Unix domain socket addresses must be"
+ " absolute paths in -a (%s)\n", la->endpoint);
+
+ for (int i = 2; av[i] != NULL; i++) {
+ if (strchr(av[i], '=') == NULL) {
+ if (xp != NULL)
+ ARGV_ERR("Too many protocol sub-args"
+ " in -a (%s)\n", av[i]);
+ xp = XPORT_Find(av[i]);
+ if (xp == NULL)
+ ARGV_ERR("Unknown protocol '%s'\n", av[i]);
+ continue;
+ }
+
+ ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
+ }
+
+ if (xp == NULL)
+ xp = XPORT_Find("http");
+
+ AN(xp);
+ la->transport = xp;
+
+ return (VSS_resolver_range(av[1], "80", vca_tcp_open_cb, la, err));
+}
+
+int
+vca_tcp_reopen(void)
+{
+ struct listen_sock *ls;
+ int err, fail = 0;
+
+ VTAILQ_FOREACH(ls, &heritage.socks, list) {
+ CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
+
+ if (ls->uds)
+ continue;
+
+ VJ_master(JAIL_MASTER_PRIVPORT);
+ err = vca_tcp_opensocket(ls);
+ VJ_master(JAIL_MASTER_LOW);
+
+ if (err == 0)
+ continue;
+
+ fail = vmax(fail, err);
+ MGT_Complain(C_ERR, "Could not reopen listen socket %s: %s",
+ ls->endpoint, VAS_errtxt(err));
+ }
+
+ return (fail);
+}
diff --git a/bin/varnishd/acceptor/mgt_acceptor_uds.c b/bin/varnishd/acceptor/mgt_acceptor_uds.c
new file mode 100644
index 000000000..93641e39d
--- /dev/null
+++ b/bin/varnishd/acceptor/mgt_acceptor_uds.c
@@ -0,0 +1,301 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2023 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Asad Sajjad Ahmed <asadsa at varnish-software.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Acceptor socket management
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "mgt/mgt.h"
+#include "common/heritage.h"
+
+#include "acceptor/cache_acceptor.h"
+#include "acceptor/acceptor_uds.h"
+#include "acceptor/mgt_acceptor.h"
+
+#include "vav.h"
+#include "vcli_serve.h"
+#include "vsa.h"
+#include "vss.h"
+#include "vus.h"
+
+int
+vca_uds_config(void)
+{
+
+ return (0);
+}
+
+static int
+vca_vus_bind(void *priv, const struct sockaddr_un *uds)
+{
+ return (VUS_bind(uds, priv));
+}
+
+static int
+vca_uds_opensocket(struct listen_sock *ls)
+{
+ int fail;
+ const char *err;
+
+ CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
+
+ if (ls->sock > 0) {
+ MCH_Fd_Inherit(ls->sock, NULL);
+ closefd(&ls->sock);
+ }
+
+ ls->sock = VUS_resolver(ls->endpoint, vca_vus_bind, NULL, &err);
+ fail = errno;
+
+ if (ls->sock < 0) {
+ AN(fail);
+ return (fail);
+ }
+
+ if (ls->perms != NULL) {
+ CHECK_OBJ(ls->perms, UDS_PERMS_MAGIC);
+ assert(ls->uds);
+ errno = 0;
+ if (ls->perms->mode != 0 &&
+ chmod(ls->endpoint, ls->perms->mode) != 0)
+ return (errno);
+ if (chown(ls->endpoint, ls->perms->uid, ls->perms->gid) != 0)
+ return (errno);
+ }
+
+ MCH_Fd_Inherit(ls->sock, "sock");
+ return (0);
+}
+
+static int v_matchproto_(vus_resolved_f)
+vca_uds_open_cb(void *priv, const struct sockaddr_un *uds)
+{
+ struct listen_arg *la;
+ struct listen_sock *ls;
+ int fail;
+
+ CAST_OBJ_NOTNULL(la, priv, LISTEN_ARG_MAGIC);
+ (void) uds;
+
+ VTAILQ_FOREACH(ls, &heritage.socks, list) {
+ CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
+
+ if (ls->uds && strcmp(ls->endpoint, la->endpoint) == 0)
+ ARGV_ERR("-a arguments %s and %s have same address\n",
+ ls->endpoint, la->endpoint);
+ }
+
+ ALLOC_OBJ(ls, LISTEN_SOCK_MAGIC);
+ AN(ls);
+
+ ls->sock = -1;
+
+ ls->addr = VSA_Clone(bogo_ip);
+ AN(ls->addr);
+
+ REPLACE(ls->endpoint, la->endpoint);
+ ls->name = la->name;
+ ls->transport = la->transport;
+ ls->perms = la->perms;
+ ls->uds = 1;
+
+ VJ_master(JAIL_MASTER_PRIVPORT);
+ fail = vca_uds_opensocket(ls);
+ VJ_master(JAIL_MASTER_LOW);
+
+ if (fail) {
+ VSA_free(&ls->addr);
+ free(ls->endpoint);
+ FREE_OBJ(ls);
+ if (fail != EAFNOSUPPORT)
+ ARGV_ERR("Could not get socket %s: %s\n",
+ la->endpoint, VAS_errtxt(fail));
+ return (0);
+ }
+
+ VTAILQ_INSERT_TAIL(&la->socks, ls, arglist);
+ VTAILQ_INSERT_TAIL(&heritage.socks, ls, list);
+
+ return (0);
+}
+
+int
+vca_uds_open(char **av, struct listen_arg *la, const char **err)
+{
+
+ const struct transport *xp = NULL;
+ struct passwd *pwd = NULL;
+ struct group *grp = NULL;
+ struct uds_perms *perms;
+ mode_t mode = 0;
+
+ CHECK_OBJ_NOTNULL(la, LISTEN_ARG_MAGIC);
+ AN(av);
+ AN(err);
+
+ if (*la->endpoint != '/' && strchr(la->endpoint, '/') != NULL)
+ ARGV_ERR("Unix domain socket addresses must be"
+ " absolute paths in -a (%s)\n", la->endpoint);
+
+ heritage.min_vcl_version = vmax(heritage.min_vcl_version, 41U);
+
+ for (int i = 2; av[i] != NULL; i++) {
+ char *eq, *val;
+ int len;
+
+ if ((eq = strchr(av[i], '=')) == NULL) {
+ if (xp != NULL)
+ ARGV_ERR("Too many protocol sub-args"
+ " in -a (%s)\n", av[i]);
+ xp = XPORT_Find(av[i]);
+ if (xp == NULL)
+ ARGV_ERR("Unknown protocol '%s'\n", av[i]);
+ continue;
+ }
+ if (la->endpoint[0] != '/')
+ ARGV_ERR("Invalid sub-arg %s"
+ " in -a\n", av[i]);
+
+ val = eq + 1;
+ len = eq - av[i];
+ assert(len >= 0);
+ if (len == 0)
+ ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
+
+ if (strncmp(av[i], "user", len) == 0) {
+ if (pwd != NULL)
+ ARGV_ERR("Too many user sub-args in -a (%s)\n",
+ av[i]);
+ pwd = getpwnam(val);
+ if (pwd == NULL)
+ ARGV_ERR("Unknown user %s in -a\n", val);
+ continue;
+ }
+
+ if (strncmp(av[i], "group", len) == 0) {
+ if (grp != NULL)
+ ARGV_ERR("Too many group sub-args in -a (%s)\n",
+ av[i]);
+ grp = getgrnam(val);
+ if (grp == NULL)
+ ARGV_ERR("Unknown group %s in -a\n", val);
+ continue;
+ }
+
+ if (strncmp(av[i], "mode", len) == 0) {
+ long m;
+ char *p;
+
+ if (mode != 0)
+ ARGV_ERR("Too many mode sub-args in -a (%s)\n",
+ av[i]);
+ if (*val == '\0')
+ ARGV_ERR("Empty mode sub-arg in -a\n");
+ errno = 0;
+ m = strtol(val, &p, 8);
+ if (*p != '\0')
+ ARGV_ERR("Invalid mode sub-arg %s in -a\n",
+ val);
+ if (errno)
+ ARGV_ERR("Cannot parse mode sub-arg %s in -a: "
+ "%s\n", val, VAS_errtxt(errno));
+ if (m <= 0 || m > 0777)
+ ARGV_ERR("Mode sub-arg %s out of range in -a\n",
+ val);
+ mode = (mode_t) m;
+ continue;
+ }
+
+ ARGV_ERR("Invalid sub-arg %s in -a\n", av[i]);
+ }
+
+ if (xp == NULL)
+ xp = XPORT_Find("http");
+
+ AN(xp);
+ la->transport = xp;
+
+ if (pwd != NULL || grp != NULL || mode != 0) {
+ ALLOC_OBJ(perms, UDS_PERMS_MAGIC);
+ AN(perms);
+ if (pwd != NULL)
+ perms->uid = pwd->pw_uid;
+ else
+ perms->uid = (uid_t) -1;
+ if (grp != NULL)
+ perms->gid = grp->gr_gid;
+ else
+ perms->gid = (gid_t) -1;
+ perms->mode = mode;
+ la->perms = perms;
+ }
+
+ return (VUS_resolver(la->endpoint, vca_uds_open_cb, la, err));
+}
+
+int
+vca_uds_reopen(void)
+{
+ struct listen_sock *ls;
+ int err, fail = 0;
+
+ VTAILQ_FOREACH(ls, &heritage.socks, list) {
+ CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
+
+ if (!ls->uds)
+ continue;
+
+ VJ_master(JAIL_MASTER_PRIVPORT);
+ err = vca_uds_opensocket(ls);
+ VJ_master(JAIL_MASTER_LOW);
+
+ if (err == 0)
+ continue;
+
+ fail = vmax(fail, err);
+ MGT_Complain(C_ERR, "Could not reopen listen socket %s: %s",
+ ls->endpoint, VAS_errtxt(err));
+ }
+
+ return (fail);
+}
More information about the varnish-commit
mailing list