Use a socketpair rather than a pair of pipes for communication between
ndhc and ifch, similar to sockd. A single pipe is also maintained so that SIGPIPE can bound the lifetime of an orphaned ifch process.
This commit is contained in:
parent
e2ee728982
commit
5fa2030bab
@ -187,7 +187,7 @@ static int ifchd_cmd(char *b, size_t bl, uint8_t *od, ssize_t ol, uint8_t code)
|
|||||||
static void pipewrite(struct client_state_t *cs, const char *buf, size_t count)
|
static void pipewrite(struct client_state_t *cs, const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
cs->ifchWorking = 1;
|
cs->ifchWorking = 1;
|
||||||
ssize_t r = safe_write(pToIfchW, buf, count);
|
ssize_t r = safe_write(ifchSock[0], buf, count);
|
||||||
if (r < 0 || (size_t)r != count) {
|
if (r < 0 || (size_t)r != count) {
|
||||||
log_error("%s: (%s) write failed: %d", client_config.interface);
|
log_error("%s: (%s) write failed: %d", client_config.interface);
|
||||||
return;
|
return;
|
||||||
|
@ -307,7 +307,7 @@ static void signal_dispatch(void)
|
|||||||
|
|
||||||
static void inform_execute(char c)
|
static void inform_execute(char c)
|
||||||
{
|
{
|
||||||
ssize_t r = safe_write(pToNdhcW, &c, sizeof c);
|
ssize_t r = safe_write(ifchSock[1], &c, sizeof c);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
// Remote end hung up.
|
// Remote end hung up.
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
@ -321,7 +321,7 @@ static void process_client_pipe(void)
|
|||||||
char buf[MAX_BUF];
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
memset(buf, '\0', sizeof buf);
|
memset(buf, '\0', sizeof buf);
|
||||||
ssize_t r = safe_read(pToIfchR, buf, sizeof buf - 1);
|
ssize_t r = safe_recv(ifchSock[1], buf, sizeof buf - 1, MSG_DONTWAIT);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
// Remote end hung up.
|
// Remote end hung up.
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
@ -354,7 +354,7 @@ static void do_ifch_work(void)
|
|||||||
memset(cl.namesvrs, 0, sizeof cl.namesvrs);
|
memset(cl.namesvrs, 0, sizeof cl.namesvrs);
|
||||||
memset(cl.domains, 0, sizeof cl.domains);
|
memset(cl.domains, 0, sizeof cl.domains);
|
||||||
|
|
||||||
epoll_add(epollfd, pToIfchR);
|
epoll_add(epollfd, ifchSock[1]);
|
||||||
epoll_add(epollfd, signalFd);
|
epoll_add(epollfd, signalFd);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -367,7 +367,7 @@ static void do_ifch_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 == pToIfchR)
|
if (fd == ifchSock[1])
|
||||||
process_client_pipe();
|
process_client_pipe();
|
||||||
else if (fd == signalFd)
|
else if (fd == signalFd)
|
||||||
signal_dispatch();
|
signal_dispatch();
|
||||||
|
49
src/ndhc.c
49
src/ndhc.c
@ -241,7 +241,7 @@ static void fail_if_state_dir_dne(void)
|
|||||||
static void handle_ifch_message(void)
|
static void handle_ifch_message(void)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
ssize_t r = safe_read(pToNdhcR, &c, sizeof c);
|
ssize_t r = safe_recv(ifchSock[0], &c, sizeof c, MSG_DONTWAIT);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
// Remote end hung up.
|
// Remote end hung up.
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
@ -273,7 +273,7 @@ static void do_ndhc_work(void)
|
|||||||
setup_signals_ndhc();
|
setup_signals_ndhc();
|
||||||
|
|
||||||
epoll_add(cs.epollFd, cs.nlFd);
|
epoll_add(cs.epollFd, cs.nlFd);
|
||||||
epoll_add(cs.epollFd, pToNdhcR);
|
epoll_add(cs.epollFd, ifchSock[0]);
|
||||||
set_listen_raw(&cs);
|
set_listen_raw(&cs);
|
||||||
nowts = curms();
|
nowts = curms();
|
||||||
goto jumpstart;
|
goto jumpstart;
|
||||||
@ -296,7 +296,7 @@ static void do_ndhc_work(void)
|
|||||||
handle_arp_response(&cs);
|
handle_arp_response(&cs);
|
||||||
else if (fd == cs.nlFd)
|
else if (fd == cs.nlFd)
|
||||||
handle_nl_message(&cs);
|
handle_nl_message(&cs);
|
||||||
else if (fd == pToNdhcR)
|
else if (fd == ifchSock[0])
|
||||||
handle_ifch_message();
|
handle_ifch_message();
|
||||||
else
|
else
|
||||||
suicide("epoll_wait: unknown fd");
|
suicide("epoll_wait: unknown fd");
|
||||||
@ -336,39 +336,20 @@ char resolv_conf_d[PATH_MAX] = "";
|
|||||||
static char pidfile[PATH_MAX] = PID_FILE_DEFAULT;
|
static char pidfile[PATH_MAX] = PID_FILE_DEFAULT;
|
||||||
static uid_t ndhc_uid = 0;
|
static uid_t ndhc_uid = 0;
|
||||||
static gid_t ndhc_gid = 0;
|
static gid_t ndhc_gid = 0;
|
||||||
|
int ifchSock[2];
|
||||||
int pToNdhcR;
|
int ifchPipe[2];
|
||||||
int pToNdhcW;
|
|
||||||
int pToIfchR;
|
|
||||||
int pToIfchW;
|
|
||||||
|
|
||||||
int sockdSock[2];
|
int sockdSock[2];
|
||||||
int sockdPipe[2];
|
int sockdPipe[2];
|
||||||
|
|
||||||
static void create_ifch_ipc_pipes(void) {
|
static void create_ifch_ipc_pipes(void) {
|
||||||
int niPipe[2];
|
if (pipe(ifchPipe))
|
||||||
int inPipe[2];
|
suicide("FATAL - can't create ndhc/ifch pipe: %s", strerror(errno));
|
||||||
|
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ifchSock) < 0)
|
||||||
if (pipe2(niPipe, 0))
|
suicide("FATAL - can't create ndhc/ifch socket: %s", strerror(errno));
|
||||||
suicide("FATAL - can't create ndhc -> ndhc-ifch pipe: %s",
|
|
||||||
strerror(errno));
|
|
||||||
if (fcntl(niPipe[0], F_SETFL, fcntl(niPipe[0], F_GETFL) | O_NONBLOCK) < 0)
|
|
||||||
suicide("FATAL - failed to set ndhc -> ndhc-ifch read-side nonblocking: %s",
|
|
||||||
strerror(errno));
|
|
||||||
pToNdhcR = niPipe[0];
|
|
||||||
pToNdhcW = niPipe[1];
|
|
||||||
if (pipe2(inPipe, 0))
|
|
||||||
suicide("FATAL - can't create ndhc-ifch -> ndhc pipe: %s",
|
|
||||||
strerror(errno));
|
|
||||||
if (fcntl(inPipe[0], F_SETFL, fcntl(inPipe[0], F_GETFL) | O_NONBLOCK) < 0)
|
|
||||||
suicide("FATAL - failed to set ndhc-ifch -> ndhc read-side nonblocking: %s",
|
|
||||||
strerror(errno));
|
|
||||||
pToIfchR = inPipe[0];
|
|
||||||
pToIfchW = inPipe[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_sockd_ipc_pipes(void) {
|
static void create_sockd_ipc_pipes(void) {
|
||||||
if (pipe2(sockdPipe, 0))
|
if (pipe(sockdPipe))
|
||||||
suicide("FATAL - can't create ndhc/sockd pipe: %s", strerror(errno));
|
suicide("FATAL - can't create ndhc/sockd pipe: %s", strerror(errno));
|
||||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockdSock) < 0)
|
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockdSock) < 0)
|
||||||
suicide("FATAL - can't create ndhc/sockd socket: %s", strerror(errno));
|
suicide("FATAL - can't create ndhc/sockd socket: %s", strerror(errno));
|
||||||
@ -379,14 +360,14 @@ static void spawn_ifch(void)
|
|||||||
create_ifch_ipc_pipes();
|
create_ifch_ipc_pipes();
|
||||||
pid_t ifch_pid = fork();
|
pid_t ifch_pid = fork();
|
||||||
if (ifch_pid == 0) {
|
if (ifch_pid == 0) {
|
||||||
close(pToNdhcR);
|
close(ifchSock[0]);
|
||||||
close(pToIfchW);
|
close(ifchPipe[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);
|
||||||
ifch_main();
|
ifch_main();
|
||||||
} else if (ifch_pid > 0) {
|
} else if (ifch_pid > 0) {
|
||||||
close(pToIfchR);
|
close(ifchSock[1]);
|
||||||
close(pToNdhcW);
|
close(ifchPipe[1]);
|
||||||
} else
|
} else
|
||||||
suicide("failed to fork ndhc-ifch: %s", strerror(errno));
|
suicide("failed to fork ndhc-ifch: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
@ -396,8 +377,8 @@ 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(sockdPipe[0]);
|
|
||||||
close(sockdSock[0]);
|
close(sockdSock[0]);
|
||||||
|
close(sockdPipe[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();
|
||||||
|
@ -67,10 +67,8 @@ struct client_config_t {
|
|||||||
|
|
||||||
extern struct client_config_t client_config;
|
extern struct client_config_t client_config;
|
||||||
|
|
||||||
extern int pToIfchR;
|
extern int ifchSock[2];
|
||||||
extern int pToIfchW;
|
extern int ifchPipe[2];
|
||||||
extern int pToNdhcR;
|
|
||||||
extern int pToNdhcW;
|
|
||||||
extern int sockdSock[2];
|
extern int sockdSock[2];
|
||||||
extern int sockdPipe[2];
|
extern int sockdPipe[2];
|
||||||
extern char state_dir[PATH_MAX];
|
extern char state_dir[PATH_MAX];
|
||||||
|
Loading…
Reference in New Issue
Block a user