From: Roy Marples Date: Thu, 23 Apr 2020 22:45:38 +0000 (+0100) Subject: dhcpcd: Fix separation of per interface and per family X-Git-Tag: v9.1.0~112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70583515c845b3969dc746b4a7937821861c0ebd;p=thirdparty%2Fdhcpcd.git dhcpcd: Fix separation of per interface and per family While here improve privsep proess titles for this. --- diff --git a/src/control.c b/src/control.c index 44c57a92..744a4a1c 100644 --- a/src/control.c +++ b/src/control.c @@ -193,7 +193,8 @@ control_handle_unpriv(void *arg) } static int -make_sock(struct sockaddr_un *sa, const char *ifname, bool unpriv) +make_sock(struct sockaddr_un *sa, const char *ifname, uint16_t family, + bool unpriv) { int fd; @@ -206,8 +207,21 @@ make_sock(struct sockaddr_un *sa, const char *ifname, bool unpriv) if (unpriv) strlcpy(sa->sun_path, UNPRIVSOCKET, sizeof(sa->sun_path)); else { + const char *per; + + switch(family) { + case AF_INET: + per = "-4"; + break; + case AF_INET6: + per = "-6"; + break; + default: + per = ""; + break; + } snprintf(sa->sun_path, sizeof(sa->sun_path), CONTROLSOCKET, - ifname ? ifname : "", ifname ? "." : ""); + ifname ? ifname : "", ifname ? per : "", ifname ? "." : ""); } return fd; } @@ -216,14 +230,17 @@ make_sock(struct sockaddr_un *sa, const char *ifname, bool unpriv) #define S_UNPRIV (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) static int -control_start1(struct dhcpcd_ctx *ctx, const char *ifname, mode_t fmode) +control_start1(struct dhcpcd_ctx *ctx, const char *ifname, uint16_t family, + mode_t fmode) { struct sockaddr_un sa; int fd; socklen_t len; - if ((fd = make_sock(&sa, ifname, (fmode & S_UNPRIV) == S_UNPRIV)) == -1) + fd = make_sock(&sa, ifname, family, (fmode & S_UNPRIV) == S_UNPRIV); + if (fd == -1) return -1; + len = (socklen_t)SUN_LEN(&sa); unlink(sa.sun_path); if (bind(fd, (struct sockaddr *)&sa, len) == -1 || @@ -244,17 +261,19 @@ control_start1(struct dhcpcd_ctx *ctx, const char *ifname, mode_t fmode) } int -control_start(struct dhcpcd_ctx *ctx, const char *ifname) +control_start(struct dhcpcd_ctx *ctx, const char *ifname, uint16_t family) { int fd; - if ((fd = control_start1(ctx, ifname, S_PRIV)) == -1) + if ((fd = control_start1(ctx, ifname, family, S_PRIV)) == -1) return -1; ctx->control_fd = fd; eloop_event_add(ctx->eloop, fd, control_handle, ctx); - if (ifname == NULL && (fd = control_start1(ctx, NULL, S_UNPRIV)) != -1){ + if (ifname == NULL && + (fd = control_start1(ctx, NULL, AF_UNSPEC, S_UNPRIV)) != -1) + { /* We must be in master mode, so create an unprivileged socket * to allow normal users to learn the status of dhcpcd. */ ctx->control_unpriv_fd = fd; @@ -318,12 +337,12 @@ control_stop(struct dhcpcd_ctx *ctx) } int -control_open(const char *ifname, bool unpriv) +control_open(const char *ifname, uint16_t family, bool unpriv) { struct sockaddr_un sa; int fd; - if ((fd = make_sock(&sa, ifname, unpriv)) != -1) { + if ((fd = make_sock(&sa, ifname, family, unpriv)) != -1) { socklen_t len; len = (socklen_t)SUN_LEN(&sa); diff --git a/src/control.h b/src/control.h index a94cbd2f..0403f0cf 100644 --- a/src/control.h +++ b/src/control.h @@ -66,9 +66,9 @@ TAILQ_HEAD(fd_list_head, fd_list); #define FD_LISTEN (1<<0) #define FD_UNPRIV (1<<1) -int control_start(struct dhcpcd_ctx *, const char *); +int control_start(struct dhcpcd_ctx *, const char *, uint16_t); int control_stop(struct dhcpcd_ctx *); -int control_open(const char *, bool); +int control_open(const char *, uint16_t, bool); ssize_t control_send(struct dhcpcd_ctx *, int, char * const *); int control_queue(struct fd_list *, void *, size_t, bool); diff --git a/src/defs.h b/src/defs.h index 29d82193..f2ff56e7 100644 --- a/src/defs.h +++ b/src/defs.h @@ -60,7 +60,7 @@ # define PIDFILE RUNDIR "/%s%s%spid" #endif #ifndef CONTROLSOCKET -# define CONTROLSOCKET RUNDIR "/%s%ssock" +# define CONTROLSOCKET RUNDIR "/%s%s%ssock" #endif #ifndef UNPRIVSOCKET # define UNPRIVSOCKET RUNDIR "/unpriv.sock" diff --git a/src/dhcpcd.c b/src/dhcpcd.c index fa52fdfc..06e94961 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -1751,7 +1751,7 @@ main(int argc, char **argv) struct ifaddrs *ifaddrs = NULL; struct if_options *ifo; struct interface *ifp; - uint16_t family = 0; + uint16_t family = AF_UNSPEC; int opt, oi = 0, i; unsigned int logopts, t; ssize_t len; @@ -2034,19 +2034,52 @@ printpidfile: goto exit_failure; } + if (sig != 0) { + pid = pidfile_read(ctx.pidfile); + if (pid != 0 && pid != -1) + loginfox("sending signal %s to pid %d", siga, pid); + if (pid == 0 || pid == -1 || kill(pid, sig) != 0) { + if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM) + logerrx(PACKAGE" not running"); + if (pid != 0 && pid != -1 && errno != ESRCH) { + logerr("kill"); + goto exit_failure; + } + unlink(ctx.pidfile); + if (sig != SIGHUP && sig != SIGUSR1) + goto exit_failure; + } else { + struct timespec ts; + + if (sig == SIGHUP || sig == SIGUSR1) + goto exit_success; + /* Spin until it exits */ + loginfox("waiting for pid %d to exit", pid); + ts.tv_sec = 0; + ts.tv_nsec = 100000000; /* 10th of a second */ + for(i = 0; i < 100; i++) { + nanosleep(&ts, NULL); + if (pidfile_read(ctx.pidfile) == -1) + goto exit_success; + } + logerrx("pid %d failed to exit", pid); + goto exit_failure; + } + } +#endif + /* Test against siga instead of sig to avoid gcc * warning about a bogus potential signed overflow. * The end result will be the same. */ if ((siga == NULL || i == 4 || ctx.ifc != 0) && !(ctx.options & DHCPCD_TEST)) { -#endif ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */ if (!(ctx.options & DHCPCD_MASTER)) - ctx.control_fd = control_open(argv[optind], + ctx.control_fd = control_open(argv[optind], family, ctx.options & DHCPCD_DUMPLEASE); if (ctx.control_fd == -1) - ctx.control_fd = control_open(NULL, + ctx.control_fd = control_open(NULL, AF_UNSPEC, ctx.options & DHCPCD_DUMPLEASE); if (ctx.control_fd != -1) { if (!(ctx.options & DHCPCD_DUMPLEASE)) @@ -2075,42 +2108,6 @@ printpidfile: } } ctx.options &= ~DHCPCD_FORKED; -#ifdef USE_SIGNALS - } -#endif - -#ifdef USE_SIGNALS - if (sig != 0) { - pid = pidfile_read(ctx.pidfile); - if (pid != 0 && pid != -1) - loginfox("sending signal %s to pid %d", siga, pid); - if (pid == 0 || pid == -1 || kill(pid, sig) != 0) { - if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM) - logerrx(PACKAGE" not running"); - if (pid != 0 && pid != -1 && errno != ESRCH) { - logerr("kill"); - goto exit_failure; - } - unlink(ctx.pidfile); - if (sig != SIGHUP && sig != SIGUSR1) - goto exit_failure; - } else { - struct timespec ts; - - if (sig == SIGHUP || sig == SIGUSR1) - goto exit_success; - /* Spin until it exits */ - loginfox("waiting for pid %d to exit", pid); - ts.tv_sec = 0; - ts.tv_nsec = 100000000; /* 10th of a second */ - for(i = 0; i < 100; i++) { - nanosleep(&ts, NULL); - if (pidfile_read(ctx.pidfile) == -1) - goto exit_success; - } - logerrx("pid %d failed to exit", pid); - goto exit_failure; - } } if (!(ctx.options & DHCPCD_TEST)) { @@ -2128,7 +2125,6 @@ printpidfile: goto exit_failure; } } -#endif loginfox(PACKAGE "-" VERSION " starting"); freopen(_PATH_DEVNULL, "r", stdin); @@ -2211,7 +2207,7 @@ printpidfile: if (!(ctx.options & DHCPCD_TEST) && control_start(&ctx, - ctx.options & DHCPCD_MASTER ? NULL : argv[optind]) == -1) + ctx.options & DHCPCD_MASTER ? NULL : argv[optind], family) == -1) { logerr("%s: control_start", __func__); goto exit_failure; diff --git a/src/privsep-inet.c b/src/privsep-inet.c index 9f1eeab7..a21bd405 100644 --- a/src/privsep-inet.c +++ b/src/privsep-inet.c @@ -93,7 +93,13 @@ ps_inet_startcb(void *arg) struct dhcpcd_ctx *ctx = arg; int ret = 0; - setproctitle("[network proxy]"); + if (ctx->options & DHCPCD_MASTER) + setproctitle("[network proxy]"); + else + setproctitle("[network proxy] %s%s%s", + ctx->ifv[0], + ctx->options & DHCPCD_IPV4 ? " [ip4]" : "", + ctx->options & DHCPCD_IPV6 ? " [ip6]" : ""); /* This end is the main engine, so it's useless for us. */ close(ctx->ps_data_fd); diff --git a/src/privsep-root.c b/src/privsep-root.c index 95a62f96..a2aa1448 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -406,7 +406,13 @@ ps_root_startcb(void *arg) { struct dhcpcd_ctx *ctx = arg; - setproctitle("[privileged actioneer]"); + if (ctx->options & DHCPCD_MASTER) + setproctitle("[privileged actioneer]"); + else + setproctitle("[privileged actioneer] %s%s%s", + ctx->ifv[0], + ctx->options & DHCPCD_IPV4 ? " [ip4]" : "", + ctx->options & DHCPCD_IPV6 ? " [ip6]" : ""); ctx->ps_root_pid = getpid(); return 0; }