Switch to using a socket for ndhc/sockd IPC so that fd passing works.

This commit is contained in:
Nicholas J. Kain 2014-04-05 05:25:56 -04:00
parent 9622640698
commit 5212e0dfc5
3 changed files with 19 additions and 34 deletions

View File

@ -343,10 +343,8 @@ int pToNdhcW;
int pToIfchR; int pToIfchR;
int pToIfchW; int pToIfchW;
int psToNdhcR; int sockdSock[2];
int psToNdhcW; int sockdPipe[2];
int pToSockdR;
int pToSockdW;
static void create_ifch_ipc_pipes(void) { static void create_ifch_ipc_pipes(void) {
int niPipe[2]; int niPipe[2];
@ -371,22 +369,10 @@ static void create_ifch_ipc_pipes(void) {
} }
static void create_sockd_ipc_pipes(void) { static void create_sockd_ipc_pipes(void) {
int nsPipe[2]; if (pipe2(sockdPipe, 0))
int snPipe[2]; suicide("FATAL - can't create ndhc/sockd pipe: %s", strerror(errno));
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockdSock) < 0)
if (pipe2(nsPipe, 0)) suicide("FATAL - can't create ndhc/sockd socket: %s", strerror(errno));
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];
} }
static void spawn_ifch(void) static void spawn_ifch(void)
@ -411,14 +397,14 @@ static void spawn_sockd(void)
create_sockd_ipc_pipes(); create_sockd_ipc_pipes();
pid_t sockd_pid = fork(); pid_t sockd_pid = fork();
if (sockd_pid == 0) { if (sockd_pid == 0) {
close(psToNdhcR); close(sockdPipe[0]);
close(pToSockdW); close(sockdSock[0]);
// Don't share the RNG state with the master process. // Don't share the RNG state with the master process.
nk_random_u32_init(&cs.rnd32_state); nk_random_u32_init(&cs.rnd32_state);
sockd_main(); sockd_main();
} else if (sockd_pid > 0) { } else if (sockd_pid > 0) {
close(pToSockdR); close(sockdSock[1]);
close(psToNdhcW); close(sockdPipe[1]);
} else } else
suicide("failed to fork ndhc-sockd: %s", strerror(errno)); suicide("failed to fork ndhc-sockd: %s", strerror(errno));
} }

View File

@ -71,10 +71,8 @@ extern int pToIfchR;
extern int pToIfchW; extern int pToIfchW;
extern int pToNdhcR; extern int pToNdhcR;
extern int pToNdhcW; extern int pToNdhcW;
extern int psToNdhcR; extern int sockdSock[2];
extern int psToNdhcW; extern int sockdPipe[2];
extern int pToSockdR;
extern int pToSockdW;
extern char state_dir[PATH_MAX]; extern char state_dir[PATH_MAX];
extern char chroot_dir[PATH_MAX]; extern char chroot_dir[PATH_MAX];
extern char resolv_conf_d[PATH_MAX]; extern char resolv_conf_d[PATH_MAX];

View File

@ -70,7 +70,7 @@ int request_sockd_fd(char *buf, size_t buflen, char *response)
{ {
if (!buflen) if (!buflen)
return -1; 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) if (r < 0 || (size_t)r != buflen)
suicide("%s: (%s) write failed: %d", client_config.interface, suicide("%s: (%s) write failed: %d", client_config.interface,
__func__, r); __func__, r);
@ -87,7 +87,7 @@ int request_sockd_fd(char *buf, size_t buflen, char *response)
.msg_controllen = sizeof control .msg_controllen = sizeof control
}; };
retry: retry:
r = recvmsg(psToNdhcR, &msg, 0); r = recvmsg(sockdSock[0], &msg, 0);
if (r == 0) { if (r == 0) {
suicide("%s: (%s) recvmsg received EOF", client_config.interface, suicide("%s: (%s) recvmsg received EOF", client_config.interface,
__func__); __func__);
@ -405,7 +405,7 @@ static void xfer_fd(int fd, char cmd)
*cmsg_fd = fd; *cmsg_fd = fd;
msg.msg_controllen = cmsg->cmsg_len; msg.msg_controllen = cmsg->cmsg_len;
retry: retry:
if (sendmsg(psToNdhcW, &msg, 0) < 0) { if (sendmsg(sockdSock[1], &msg, 0) < 0) {
if (errno == EINTR) if (errno == EINTR)
goto retry; goto retry;
suicide("%s: (%s) sendmsg failed: %s", client_config.interface, 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, suicide("%s: (%s) receive buffer exhausted", client_config.interface,
__func__); __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) { if (r == 0) {
// Remote end hung up. // Remote end hung up.
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -474,7 +475,7 @@ static void do_sockd_work(void)
if (enforce_seccomp_sockd()) if (enforce_seccomp_sockd())
log_line("sockd seccomp filter cannot be installed"); log_line("sockd seccomp filter cannot be installed");
epoll_add(epollfd, pToSockdR); epoll_add(epollfd, sockdSock[1]);
epoll_add(epollfd, signalFd); epoll_add(epollfd, signalFd);
for (;;) { for (;;) {
@ -487,7 +488,7 @@ static void do_sockd_work(void)
} }
for (int i = 0; i < r; ++i) { for (int i = 0; i < r; ++i) {
int fd = events[i].data.fd; int fd = events[i].data.fd;
if (fd == pToSockdR) if (fd == sockdSock[1])
process_client_pipe(); process_client_pipe();
else if (fd == signalFd) else if (fd == signalFd)
signal_dispatch(); signal_dispatch();