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:
		| @@ -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) | ||||
| { | ||||
|     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) { | ||||
|         log_error("%s: (%s) write failed: %d", client_config.interface); | ||||
|         return; | ||||
|   | ||||
| @@ -307,7 +307,7 @@ static void signal_dispatch(void) | ||||
|  | ||||
| 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) { | ||||
|         // Remote end hung up. | ||||
|         exit(EXIT_SUCCESS); | ||||
| @@ -321,7 +321,7 @@ static void process_client_pipe(void) | ||||
|     char buf[MAX_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) { | ||||
|         // Remote end hung up. | ||||
|         exit(EXIT_SUCCESS); | ||||
| @@ -354,7 +354,7 @@ static void do_ifch_work(void) | ||||
|     memset(cl.namesvrs, 0, sizeof cl.namesvrs); | ||||
|     memset(cl.domains, 0, sizeof cl.domains); | ||||
|  | ||||
|     epoll_add(epollfd, pToIfchR); | ||||
|     epoll_add(epollfd, ifchSock[1]); | ||||
|     epoll_add(epollfd, signalFd); | ||||
|  | ||||
|     for (;;) { | ||||
| @@ -367,7 +367,7 @@ static void do_ifch_work(void) | ||||
|         } | ||||
|         for (int i = 0; i < r; ++i) { | ||||
|             int fd = events[i].data.fd; | ||||
|             if (fd == pToIfchR) | ||||
|             if (fd == ifchSock[1]) | ||||
|                 process_client_pipe(); | ||||
|             else if (fd == signalFd) | ||||
|                 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) | ||||
| { | ||||
|     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) { | ||||
|         // Remote end hung up. | ||||
|         exit(EXIT_SUCCESS); | ||||
| @@ -273,7 +273,7 @@ static void do_ndhc_work(void) | ||||
|     setup_signals_ndhc(); | ||||
|  | ||||
|     epoll_add(cs.epollFd, cs.nlFd); | ||||
|     epoll_add(cs.epollFd, pToNdhcR); | ||||
|     epoll_add(cs.epollFd, ifchSock[0]); | ||||
|     set_listen_raw(&cs); | ||||
|     nowts = curms(); | ||||
|     goto jumpstart; | ||||
| @@ -296,7 +296,7 @@ static void do_ndhc_work(void) | ||||
|                 handle_arp_response(&cs); | ||||
|             else if (fd == cs.nlFd) | ||||
|                 handle_nl_message(&cs); | ||||
|             else if (fd == pToNdhcR) | ||||
|             else if (fd == ifchSock[0]) | ||||
|                 handle_ifch_message(); | ||||
|             else | ||||
|                 suicide("epoll_wait: unknown fd"); | ||||
| @@ -336,39 +336,20 @@ char resolv_conf_d[PATH_MAX] = ""; | ||||
| static char pidfile[PATH_MAX] = PID_FILE_DEFAULT; | ||||
| static uid_t ndhc_uid = 0; | ||||
| static gid_t ndhc_gid = 0; | ||||
|  | ||||
| int pToNdhcR; | ||||
| int pToNdhcW; | ||||
| int pToIfchR; | ||||
| int pToIfchW; | ||||
|  | ||||
| int ifchSock[2]; | ||||
| int ifchPipe[2]; | ||||
| int sockdSock[2]; | ||||
| int sockdPipe[2]; | ||||
|  | ||||
| static void create_ifch_ipc_pipes(void) { | ||||
|     int niPipe[2]; | ||||
|     int inPipe[2]; | ||||
|  | ||||
|     if (pipe2(niPipe, 0)) | ||||
|         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]; | ||||
|     if (pipe(ifchPipe)) | ||||
|         suicide("FATAL - can't create ndhc/ifch pipe: %s", strerror(errno)); | ||||
|     if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ifchSock) < 0) | ||||
|         suicide("FATAL - can't create ndhc/ifch socket: %s", strerror(errno)); | ||||
| } | ||||
|  | ||||
| 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)); | ||||
|     if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockdSock) < 0) | ||||
|         suicide("FATAL - can't create ndhc/sockd socket: %s", strerror(errno)); | ||||
| @@ -379,14 +360,14 @@ static void spawn_ifch(void) | ||||
|     create_ifch_ipc_pipes(); | ||||
|     pid_t ifch_pid = fork(); | ||||
|     if (ifch_pid == 0) { | ||||
|         close(pToNdhcR); | ||||
|         close(pToIfchW); | ||||
|         close(ifchSock[0]); | ||||
|         close(ifchPipe[0]); | ||||
|         // Don't share the RNG state with the master process. | ||||
|         nk_random_u32_init(&cs.rnd32_state); | ||||
|         ifch_main(); | ||||
|     } else if (ifch_pid > 0) { | ||||
|         close(pToIfchR); | ||||
|         close(pToNdhcW); | ||||
|         close(ifchSock[1]); | ||||
|         close(ifchPipe[1]); | ||||
|     } else | ||||
|         suicide("failed to fork ndhc-ifch: %s", strerror(errno)); | ||||
| } | ||||
| @@ -396,8 +377,8 @@ static void spawn_sockd(void) | ||||
|     create_sockd_ipc_pipes(); | ||||
|     pid_t sockd_pid = fork(); | ||||
|     if (sockd_pid == 0) { | ||||
|         close(sockdPipe[0]); | ||||
|         close(sockdSock[0]); | ||||
|         close(sockdPipe[0]); | ||||
|         // Don't share the RNG state with the master process. | ||||
|         nk_random_u32_init(&cs.rnd32_state); | ||||
|         sockd_main(); | ||||
|   | ||||
| @@ -67,10 +67,8 @@ struct client_config_t { | ||||
|  | ||||
| extern struct client_config_t client_config; | ||||
|  | ||||
| extern int pToIfchR; | ||||
| extern int pToIfchW; | ||||
| extern int pToNdhcR; | ||||
| extern int pToNdhcW; | ||||
| extern int ifchSock[2]; | ||||
| extern int ifchPipe[2]; | ||||
| extern int sockdSock[2]; | ||||
| extern int sockdPipe[2]; | ||||
| extern char state_dir[PATH_MAX]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user