From: Roy Marples Date: Mon, 12 Jan 2009 16:39:01 +0000 (+0000) Subject: Remove the limit for the number of connections to the control socket. X-Git-Tag: v5.0.0~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e467f4b21724ad4c3c9f7a3ee9af91c4385a8a88;p=thirdparty%2Fdhcpcd.git Remove the limit for the number of connections to the control socket. Send the dhcpcd-run-hooks enviornment to listeners on the control socket. --- diff --git a/configure.c b/configure.c index 917bd181..24bec760 100644 --- a/configure.c +++ b/configure.c @@ -26,6 +26,7 @@ */ #include +#include #include #include @@ -135,17 +136,41 @@ append_config(char ***env, ssize_t *len, *env = ne; } +static size_t +arraytostr(const char *const *argv, char **s) +{ + const char *const *ap; + char *p; + size_t len, l; + + len = 0; + ap = argv; + while (*ap) + len += strlen(*ap++) + 1; + *s = p = xmalloc(len); + ap = argv; + while (*ap) { + l = strlen(*ap) + 1; + memcpy(p, *ap, l); + p += l; + ap++; + } + return len; +} + int run_script(const struct interface *iface, const char *reason) { char *const argv[2] = { UNCONST(iface->state->options->script), NULL }; char **env = NULL, **ep; - char *path, *p; + char *path, *p, *bigenv; ssize_t e, elen, l; pid_t pid; int status = 0; const struct if_options *ifo = iface->state->options; const struct interface *ifp; + const struct fd_list *fd; + struct iovec iov[2]; syslog(LOG_DEBUG, "%s: executing `%s', reason %s", iface->name, argv[0], reason); @@ -236,6 +261,23 @@ run_script(const struct interface *iface, const char *reason) } } + /* Send to our listeners */ + bigenv = NULL; + for (fd = fds; fd != NULL; fd = fd->next) { + if (fd->listener) { + if (bigenv == NULL) { + elen = arraytostr((const char *const *)env, + &bigenv); + iov[0].iov_base = &elen; + iov[0].iov_len = sizeof(size_t); + iov[1].iov_base = bigenv; + iov[1].iov_len = elen; + } + writev(fd->fd, iov, 2); + } + } + free(bigenv); + /* Cleanup */ ep = env; while (*ep) diff --git a/control.c b/control.c index 185638ff..75120826 100644 --- a/control.c +++ b/control.c @@ -36,56 +36,61 @@ #include "config.h" #include "common.h" +#include "dhcpcd.h" #include "control.h" #include "eloop.h" -#include "dhcpcd.h" static int fd = -1; struct sockaddr_un sun; static char buffer[1024]; static char *argvp[255]; -static int fds[5]; +struct fd_list *fds = NULL; static void remove_control_data(void *arg) { - size_t i; - - for (i = 0; i < sizeof(fds); i++) { - if (&fds[i] == arg) { - close(fds[i]); - delete_event(fds[i]); - fds[i] = -1; + struct fd_list *l, *last = NULL; + + for (l = fds; l != NULL; l = l->next) { + if (l == arg) { + close(l->fd); + delete_event(l->fd); + if (last == NULL) + fds = l->next; + else + last->next = l->next; + free(l); + break; } + last = l; } } static void handle_control_data(void *arg) { + struct fd_list *l = arg; ssize_t bytes; - int argc, *s = arg; + int argc; char *e, *p; char **ap; - for (;;) { - bytes = read(*s, buffer, sizeof(buffer)); - if (bytes == -1 || bytes == 0) { - remove_control_data(arg); - return; - } - p = buffer; - e = buffer + bytes; - argc = 0; - ap = argvp; - while (p < e && (size_t)argc < sizeof(argvp)) { - argc++; - *ap++ = p; - p += strlen(p) + 1; - } - handle_args(*s, argc, argvp); + bytes = read(l->fd, buffer, sizeof(buffer)); + if (bytes == -1 || bytes == 0) { + remove_control_data(l); + return; } + p = buffer; + e = buffer + bytes; + argc = 0; + ap = argvp; + while (p < e && (size_t)argc < sizeof(argvp)) { + argc++; + *ap++ = p; + p += strlen(p) + 1; + } + handle_args(l, argc, argvp); } /* ARGSUSED */ @@ -94,21 +99,18 @@ handle_control(_unused void *arg) { struct sockaddr_un run; socklen_t len; - size_t i; - - for (i = 0; i < sizeof(fds); i++) { - if (fds[i] == -1) - break; - } - if (i >= sizeof(fds)) - return; + struct fd_list *l; + int f; len = sizeof(run); - if ((fds[i] = accept(fd, (struct sockaddr *)&run, &len)) == -1) + if ((f = accept(fd, (struct sockaddr *)&run, &len)) == -1) return; - add_event(fds[i], handle_control_data, &fds[i]); - /* Timeout the connection after 5 minutes - should be plenty */ - add_timeout_sec(300, remove_control_data, &fds[i]); + l = xmalloc(sizeof(*l)); + l->fd = f; + l->listener = 0; + l->next = fds; + fds = l; + add_event(l->fd, handle_control_data, l); } static int @@ -139,7 +141,6 @@ start_control(void) close(fd); return -1; } - memset(fds, -1, sizeof(fds)); add_event(fd, handle_control, NULL); return fd; } @@ -148,10 +149,22 @@ int stop_control(void) { int retval = 0; + struct fd_list *l, *ll; + + delete_event(fd); if (close(fd) == -1) retval = 1; + fd = -1; if (unlink(CONTROLSOCKET) == -1) retval = -1; + l = fds; + while (l != NULL) { + ll = l->next; + delete_event(l->fd); + close(l->fd); + free(l); + l = ll; + } return retval; } diff --git a/control.h b/control.h index 44406902..04d7aa1d 100644 --- a/control.h +++ b/control.h @@ -30,6 +30,13 @@ #include "dhcpcd.h" +struct fd_list { + int fd; + int listener; + struct fd_list *next; +}; +extern struct fd_list *fds; + int start_control(void); int stop_control(void); int open_control(void); diff --git a/dhcpcd.c b/dhcpcd.c index 325e4fd0..d79ff973 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -1098,14 +1098,34 @@ handle_signal(_unused void *arg) } int -handle_args(int fd, int argc, char **argv) +handle_args(struct fd_list *fd, int argc, char **argv) { struct interface *ifs, *ifp, *ifl, *ifn, *ift; int do_exit = 0, do_release = 0, do_reboot = 0, opt, oi = 0; + char *s, *p; + size_t l, len; - if (strcmp(*argv, "--version") == 0) { - if (fd != -1) { - write(fd, VERSION, strlen(VERSION)); + if (fd != NULL) { + if (strcmp(*argv, "--version") == 0) { + write(fd->fd, VERSION, strlen(VERSION)); + return 0; + } else if (strcmp(*argv, "--listinterfaces") == 0) { + l = 0; + for (ifp = ifaces; ifp; ifp = ifp->next) + l += strlen(ifp->name) + 1; + s = p = xmalloc(l); + for (ifp = ifaces; ifp; ifp = ifp->next) { + len = strlen(ifp->name); + memcpy(p, ifp->name, len); + p += len; + *p++ = ' '; + } + *--p = '\0'; + write(fd->fd, s, l); + free(s); + return 0; + } else if (strcmp(*argv, "--listen") == 0) { + fd->listener = 1; return 0; } } diff --git a/dhcpcd.h b/dhcpcd.h index 21a3f4c2..61e552de 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -33,6 +33,7 @@ #include +#include "control.h" #include "dhcp.h" #include "if-options.h" @@ -113,7 +114,7 @@ extern int ifdc; extern char **ifdv; extern struct interface *ifaces; -int handle_args(int, int, char **); +int handle_args(struct fd_list *, int, char **); void handle_exit_timeout(void *); void start_interface(void *); void start_discover(void *);