From 5212e0dfc5a8995c8c0b27e536b1cd0f20d66286 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sat, 5 Apr 2014 05:25:56 -0400 Subject: [PATCH] Switch to using a socket for ndhc/sockd IPC so that fd passing works. --- ndhc/ndhc.c | 34 ++++++++++------------------------ ndhc/ndhc.h | 6 ++---- ndhc/sockd.c | 13 +++++++------ 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/ndhc/ndhc.c b/ndhc/ndhc.c index 587d38a..7e938b0 100644 --- a/ndhc/ndhc.c +++ b/ndhc/ndhc.c @@ -343,10 +343,8 @@ int pToNdhcW; int pToIfchR; int pToIfchW; -int psToNdhcR; -int psToNdhcW; -int pToSockdR; -int pToSockdW; +int sockdSock[2]; +int sockdPipe[2]; static void create_ifch_ipc_pipes(void) { int niPipe[2]; @@ -371,22 +369,10 @@ static void create_ifch_ipc_pipes(void) { } static void create_sockd_ipc_pipes(void) { - int nsPipe[2]; - int snPipe[2]; - - if (pipe2(nsPipe, 0)) - suicide("FATAL - can't create ndhc -> ndhc-sockd pipe: %s", - strerror(errno)); - psToNdhcR = nsPipe[0]; - psToNdhcW = nsPipe[1]; - if (pipe2(snPipe, 0)) - suicide("FATAL - can't create ndhc-sockd -> ndhc pipe: %s", - strerror(errno)); - if (fcntl(snPipe[0], F_SETFL, fcntl(snPipe[0], F_GETFL) | O_NONBLOCK) < 0) - suicide("FATAL - failed to set ndhc-sockd -> ndhc read-side nonblocking: %s", - strerror(errno)); - pToSockdR = snPipe[0]; - pToSockdW = snPipe[1]; + if (pipe2(sockdPipe, 0)) + suicide("FATAL - can't create ndhc/sockd pipe: %s", strerror(errno)); + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockdSock) < 0) + suicide("FATAL - can't create ndhc/sockd socket: %s", strerror(errno)); } static void spawn_ifch(void) @@ -411,14 +397,14 @@ static void spawn_sockd(void) create_sockd_ipc_pipes(); pid_t sockd_pid = fork(); if (sockd_pid == 0) { - close(psToNdhcR); - close(pToSockdW); + close(sockdPipe[0]); + close(sockdSock[0]); // Don't share the RNG state with the master process. nk_random_u32_init(&cs.rnd32_state); sockd_main(); } else if (sockd_pid > 0) { - close(pToSockdR); - close(psToNdhcW); + close(sockdSock[1]); + close(sockdPipe[1]); } else suicide("failed to fork ndhc-sockd: %s", strerror(errno)); } diff --git a/ndhc/ndhc.h b/ndhc/ndhc.h index c86d0a5..b206422 100644 --- a/ndhc/ndhc.h +++ b/ndhc/ndhc.h @@ -71,10 +71,8 @@ extern int pToIfchR; extern int pToIfchW; extern int pToNdhcR; extern int pToNdhcW; -extern int psToNdhcR; -extern int psToNdhcW; -extern int pToSockdR; -extern int pToSockdW; +extern int sockdSock[2]; +extern int sockdPipe[2]; extern char state_dir[PATH_MAX]; extern char chroot_dir[PATH_MAX]; extern char resolv_conf_d[PATH_MAX]; diff --git a/ndhc/sockd.c b/ndhc/sockd.c index 3c32313..0f91b65 100644 --- a/ndhc/sockd.c +++ b/ndhc/sockd.c @@ -70,7 +70,7 @@ int request_sockd_fd(char *buf, size_t buflen, char *response) { if (!buflen) return -1; - ssize_t r = safe_write(pToSockdW, buf, buflen); + ssize_t r = safe_write(sockdSock[0], buf, buflen); if (r < 0 || (size_t)r != buflen) suicide("%s: (%s) write failed: %d", client_config.interface, __func__, r); @@ -87,7 +87,7 @@ int request_sockd_fd(char *buf, size_t buflen, char *response) .msg_controllen = sizeof control }; retry: - r = recvmsg(psToNdhcR, &msg, 0); + r = recvmsg(sockdSock[0], &msg, 0); if (r == 0) { suicide("%s: (%s) recvmsg received EOF", client_config.interface, __func__); @@ -405,7 +405,7 @@ static void xfer_fd(int fd, char cmd) *cmsg_fd = fd; msg.msg_controllen = cmsg->cmsg_len; retry: - if (sendmsg(psToNdhcW, &msg, 0) < 0) { + if (sendmsg(sockdSock[1], &msg, 0) < 0) { if (errno == EINTR) goto retry; suicide("%s: (%s) sendmsg failed: %s", client_config.interface, @@ -451,7 +451,8 @@ static void process_client_pipe(void) suicide("%s: (%s) receive buffer exhausted", client_config.interface, __func__); - int r = safe_read(pToSockdR, buf + buflen, sizeof buf - buflen); + int r = safe_recv(sockdSock[1], buf + buflen, sizeof buf - buflen, + MSG_DONTWAIT); if (r == 0) { // Remote end hung up. exit(EXIT_SUCCESS); @@ -474,7 +475,7 @@ static void do_sockd_work(void) if (enforce_seccomp_sockd()) log_line("sockd seccomp filter cannot be installed"); - epoll_add(epollfd, pToSockdR); + epoll_add(epollfd, sockdSock[1]); epoll_add(epollfd, signalFd); for (;;) { @@ -487,7 +488,7 @@ static void do_sockd_work(void) } for (int i = 0; i < r; ++i) { int fd = events[i].data.fd; - if (fd == pToSockdR) + if (fd == sockdSock[1]) process_client_pipe(); else if (fd == signalFd) signal_dispatch();