1 /*
2 * ipc.c - Interprocess communication routines. Handlers read and write.
3 *
4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10 #include "config.h"
11 #include <errno.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <fcntl.h>
15 #include "ipc.h"
16 #include "buffer.h"
17 #include "xfrd-tcp.h"
18 #include "nsd.h"
19 #include "namedb.h"
20 #include "xfrd.h"
21 #include "xfrd-notify.h"
22 #include "difffile.h"
23 #include "rrl.h"
24
25 /* attempt to send NSD_STATS command to child fd */
26 static void send_stat_to_child(struct main_ipc_handler_data* data, int fd);
27 /* send reload request over the IPC channel */
28 static void xfrd_send_reload_req(xfrd_state_type* xfrd);
29 /* send quit request over the IPC channel */
30 static void xfrd_send_quit_req(xfrd_state_type* xfrd);
31 /* perform read part of handle ipc for xfrd */
32 static void xfrd_handle_ipc_read(struct event* handler, xfrd_state_type* xfrd);
33 static void ipc_child_quit(struct nsd* nsd) ATTR_NORETURN;
34
35 static void
ipc_child_quit(struct nsd * nsd)36 ipc_child_quit(struct nsd* nsd)
37 {
38 /* call shutdown and quit routines */
39 nsd->mode = NSD_QUIT;
40 service_remaining_tcp(nsd);
41 #ifdef BIND8_STATS
42 bind8_stats(nsd);
43 #endif /* BIND8_STATS */
44
45 #ifdef MEMCLEAN /* OS collects memory pages */
46 #ifdef RATELIMIT
47 rrl_deinit(nsd->this_child->child_num);
48 #endif
49 event_base_free(nsd->event_base);
50 region_destroy(nsd->server_region);
51 #endif
52 server_shutdown(nsd);
53 /* ENOTREACH */
54 exit(0);
55 }
56
57 void
child_handle_parent_command(int fd,short event,void * arg)58 child_handle_parent_command(int fd, short event, void* arg)
59 {
60 sig_atomic_t mode;
61 int len;
62 struct ipc_handler_conn_data *data =
63 (struct ipc_handler_conn_data *) arg;
64 if (!(event & EV_READ)) {
65 return;
66 }
67
68 if ((len = read(fd, &mode, sizeof(mode))) == -1) {
69 log_msg(LOG_ERR, "handle_parent_command: read: %s",
70 strerror(errno));
71 return;
72 }
73 if (len == 0)
74 {
75 /* parent closed the connection. Quit */
76 ipc_child_quit(data->nsd);
77 return;
78 }
79
80 switch (mode) {
81 case NSD_STATS:
82 data->nsd->mode = mode;
83 break;
84 case NSD_QUIT:
85 ipc_child_quit(data->nsd);
86 break;
87 case NSD_QUIT_CHILD:
88 /* close our listening sockets and ack */
89 server_close_all_sockets(data->nsd->udp, data->nsd->ifs);
90 server_close_all_sockets(data->nsd->tcp, data->nsd->ifs);
91 /* mode == NSD_QUIT_CHILD */
92 if(write(fd, &mode, sizeof(mode)) == -1) {
93 VERBOSITY(3, (LOG_INFO, "quit child write: %s",
94 strerror(errno)));
95 }
96 ipc_child_quit(data->nsd);
97 break;
98 case NSD_QUIT_WITH_STATS:
99 #ifdef BIND8_STATS
100 DEBUG(DEBUG_IPC, 2, (LOG_INFO, "quit QUIT_WITH_STATS"));
101 /* reply with ack and stats and then quit */
102 if(!write_socket(fd, &mode, sizeof(mode))) {
103 log_msg(LOG_ERR, "cannot write quitwst to parent");
104 }
105 if(!write_socket(fd, &data->nsd->st, sizeof(data->nsd->st))) {
106 log_msg(LOG_ERR, "cannot write stats to parent");
107 }
108 fsync(fd);
109 #endif /* BIND8_STATS */
110 ipc_child_quit(data->nsd);
111 break;
112 default:
113 log_msg(LOG_ERR, "handle_parent_command: bad mode %d",
114 (int) mode);
115 break;
116 }
117 }
118
119 void
parent_handle_xfrd_command(netio_type * ATTR_UNUSED (netio),netio_handler_type * handler,netio_event_types_type event_types)120 parent_handle_xfrd_command(netio_type *ATTR_UNUSED(netio),
121 netio_handler_type *handler,
122 netio_event_types_type event_types)
123 {
124 sig_atomic_t mode;
125 int len;
126 struct ipc_handler_conn_data *data =
127 (struct ipc_handler_conn_data *) handler->user_data;
128 if (!(event_types & NETIO_EVENT_READ)) {
129 return;
130 }
131
132 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) {
133 log_msg(LOG_ERR, "handle_xfrd_command: read: %s",
134 strerror(errno));
135 return;
136 }
137 if (len == 0)
138 {
139 /* xfrd closed, we must quit */
140 DEBUG(DEBUG_IPC,1, (LOG_INFO, "handle_xfrd_command: xfrd closed channel."));
141 close(handler->fd);
142 handler->fd = -1;
143 data->nsd->mode = NSD_SHUTDOWN;
144 return;
145 }
146
147 switch (mode) {
148 case NSD_RELOAD:
149 DEBUG(DEBUG_IPC,1, (LOG_INFO, "parent handle xfrd command RELOAD"));
150 data->nsd->signal_hint_reload = 1;
151 break;
152 case NSD_QUIT:
153 case NSD_SHUTDOWN:
154 data->nsd->mode = mode;
155 break;
156 case NSD_STATS:
157 data->nsd->signal_hint_stats = 1;
158 break;
159 case NSD_REAP_CHILDREN:
160 data->nsd->signal_hint_child = 1;
161 break;
162 default:
163 log_msg(LOG_ERR, "handle_xfrd_command: bad mode %d",
164 (int) mode);
165 break;
166 }
167 }
168
169 static void
send_stat_to_child(struct main_ipc_handler_data * data,int fd)170 send_stat_to_child(struct main_ipc_handler_data* data, int fd)
171 {
172 sig_atomic_t cmd = NSD_STATS;
173 if(write(fd, &cmd, sizeof(cmd)) == -1) {
174 if(errno == EAGAIN || errno == EINTR)
175 return; /* try again later */
176 log_msg(LOG_ERR, "svrmain: problems sending stats to child %d command: %s",
177 (int)data->child->pid, strerror(errno));
178 return;
179 }
180 data->child->need_to_send_STATS = 0;
181 }
182
183 #ifndef NDEBUG
184 int packet_read_query_section(buffer_type *packet, uint8_t* dest, uint16_t* qtype, uint16_t* qclass);
185 static void
debug_print_fwd_name(int ATTR_UNUSED (len),buffer_type * packet,int acl_num)186 debug_print_fwd_name(int ATTR_UNUSED(len), buffer_type* packet, int acl_num)
187 {
188 uint8_t qnamebuf[MAXDOMAINLEN];
189 uint16_t qtype, qclass;
190 const dname_type* dname;
191 region_type* tempregion = region_create(xalloc, free);
192
193 size_t bufpos = buffer_position(packet);
194 buffer_rewind(packet);
195 buffer_skip(packet, 12);
196 if(packet_read_query_section(packet, qnamebuf, &qtype, &qclass)) {
197 dname = dname_make(tempregion, qnamebuf, 1);
198 log_msg(LOG_INFO, "main: fwd packet for %s, acl %d",
199 dname_to_string(dname,0), acl_num);
200 } else {
201 log_msg(LOG_INFO, "main: fwd packet badqname, acl %d", acl_num);
202 }
203 buffer_set_position(packet, bufpos);
204 region_destroy(tempregion);
205 }
206 #endif
207
208 static void
send_quit_to_child(struct main_ipc_handler_data * data,int fd)209 send_quit_to_child(struct main_ipc_handler_data* data, int fd)
210 {
211 #ifdef BIND8_STATS
212 sig_atomic_t cmd = NSD_QUIT_WITH_STATS;
213 #else
214 sig_atomic_t cmd = NSD_QUIT;
215 #endif
216 if(write(fd, &cmd, sizeof(cmd)) == -1) {
217 if(errno == EAGAIN || errno == EINTR)
218 return; /* try again later */
219 log_msg(LOG_ERR, "svrmain: problems sending quit to child %d command: %s",
220 (int)data->child->pid, strerror(errno));
221 return;
222 }
223 data->child->need_to_send_QUIT = 0;
224 DEBUG(DEBUG_IPC,2, (LOG_INFO, "main: sent quit to child %d",
225 (int)data->child->pid));
226 }
227
228 /** the child is done, mark it as exited */
229 static void
child_is_done(struct nsd * nsd,int fd)230 child_is_done(struct nsd* nsd, int fd)
231 {
232 size_t i;
233 if(fd != -1) close(fd);
234 for(i=0; i<nsd->child_count; ++i)
235 if(nsd->children[i].child_fd == fd) {
236 nsd->children[i].child_fd = -1;
237 nsd->children[i].handler->fd = -1;
238 if(nsd->children[i].need_to_exit) {
239 DEBUG(DEBUG_IPC,1, (LOG_INFO, "server %d is done",
240 (int)nsd->children[i].pid));
241 nsd->children[i].has_exited = 1;
242 } else {
243 log_msg(LOG_WARNING,
244 "server %d died unexpectedly, restarting",
245 (int)nsd->children[i].pid);
246 /* this child is now going to be re-forked as
247 * a subprocess of this server-main, and if a
248 * reload is in progress the other children
249 * are subprocesses of reload. Until the
250 * reload is done and they are all reforked. */
251 nsd->children[i].pid = -1;
252 nsd->restart_children = 1;
253 }
254 }
255 parent_check_all_children_exited(nsd);
256 }
257
258 #ifdef BIND8_STATS
259 /** add stats to total */
260 void
stats_add(struct nsdst * total,struct nsdst * s)261 stats_add(struct nsdst* total, struct nsdst* s)
262 {
263 unsigned i;
264 for(i=0; i<sizeof(total->qtype)/sizeof(stc_type); i++)
265 total->qtype[i] += s->qtype[i];
266 for(i=0; i<sizeof(total->qclass)/sizeof(stc_type); i++)
267 total->qclass[i] += s->qclass[i];
268 total->qudp += s->qudp;
269 total->qudp6 += s->qudp6;
270 total->ctcp += s->ctcp;
271 total->ctcp6 += s->ctcp6;
272 total->ctls += s->ctls;
273 total->ctls6 += s->ctls6;
274 for(i=0; i<sizeof(total->rcode)/sizeof(stc_type); i++)
275 total->rcode[i] += s->rcode[i];
276 for(i=0; i<sizeof(total->opcode)/sizeof(stc_type); i++)
277 total->opcode[i] += s->opcode[i];
278 total->dropped += s->dropped;
279 total->truncated += s->truncated;
280 total->wrongzone += s->wrongzone;
281 total->txerr += s->txerr;
282 total->rxerr += s->rxerr;
283 total->edns += s->edns;
284 total->ednserr += s->ednserr;
285 total->raxfr += s->raxfr;
286 total->nona += s->nona;
287 total->rixfr += s->rixfr;
288
289 total->db_disk = s->db_disk;
290 total->db_mem = s->db_mem;
291 }
292
293 /** subtract stats from total */
294 void
stats_subtract(struct nsdst * total,struct nsdst * s)295 stats_subtract(struct nsdst* total, struct nsdst* s)
296 {
297 unsigned i;
298 for(i=0; i<sizeof(total->qtype)/sizeof(stc_type); i++)
299 total->qtype[i] -= s->qtype[i];
300 for(i=0; i<sizeof(total->qclass)/sizeof(stc_type); i++)
301 total->qclass[i] -= s->qclass[i];
302 total->qudp -= s->qudp;
303 total->qudp6 -= s->qudp6;
304 total->ctcp -= s->ctcp;
305 total->ctcp6 -= s->ctcp6;
306 total->ctls -= s->ctls;
307 total->ctls6 -= s->ctls6;
308 for(i=0; i<sizeof(total->rcode)/sizeof(stc_type); i++)
309 total->rcode[i] -= s->rcode[i];
310 for(i=0; i<sizeof(total->opcode)/sizeof(stc_type); i++)
311 total->opcode[i] -= s->opcode[i];
312 total->dropped -= s->dropped;
313 total->truncated -= s->truncated;
314 total->wrongzone -= s->wrongzone;
315 total->txerr -= s->txerr;
316 total->rxerr -= s->rxerr;
317 total->edns -= s->edns;
318 total->ednserr -= s->ednserr;
319 total->raxfr -= s->raxfr;
320 total->nona -= s->nona;
321 total->rixfr -= s->rixfr;
322 }
323
324 #define FINAL_STATS_TIMEOUT 10 /* seconds */
325 static void
read_child_stats(struct nsd * nsd,struct nsd_child * child,int fd)326 read_child_stats(struct nsd* nsd, struct nsd_child* child, int fd)
327 {
328 struct nsdst s;
329 errno=0;
330 if(block_read(nsd, fd, &s, sizeof(s), FINAL_STATS_TIMEOUT)!=sizeof(s)) {
331 log_msg(LOG_ERR, "problems reading finalstats from server "
332 "%d: %s", (int)child->pid, strerror(errno));
333 } else {
334 stats_add(&nsd->st, &s);
335 child->query_count = s.qudp + s.qudp6 + s.ctcp + s.ctcp6
336 + s.ctls + s.ctls6;
337 /* we know that the child is going to close the connection
338 * now (this is an ACK of the QUIT_W_STATS so we know the
339 * child is done, no longer sending e.g. NOTIFY contents) */
340 child_is_done(nsd, fd);
341 }
342 }
343 #endif /* BIND8_STATS */
344
345 void
parent_handle_child_command(netio_type * ATTR_UNUSED (netio),netio_handler_type * handler,netio_event_types_type event_types)346 parent_handle_child_command(netio_type *ATTR_UNUSED(netio),
347 netio_handler_type *handler,
348 netio_event_types_type event_types)
349 {
350 sig_atomic_t mode;
351 int len;
352 struct main_ipc_handler_data *data =
353 (struct main_ipc_handler_data*)handler->user_data;
354
355 /* do a nonblocking write to the child if it is ready. */
356 if (event_types & NETIO_EVENT_WRITE) {
357 if(data->child->need_to_send_STATS &&
358 !data->child->need_to_exit) {
359 send_stat_to_child(data, handler->fd);
360 } else if(data->child->need_to_send_QUIT) {
361 send_quit_to_child(data, handler->fd);
362 if(!data->child->need_to_send_QUIT)
363 handler->event_types = NETIO_EVENT_READ;
364 } else {
365 handler->event_types = NETIO_EVENT_READ;
366 }
367 }
368
369 if (!(event_types & NETIO_EVENT_READ)) {
370 return;
371 }
372
373 if (data->forward_mode) {
374 int got_acl;
375 /* forward the data to xfrd */
376 DEBUG(DEBUG_IPC,2, (LOG_INFO,
377 "main passed packet readup %d", (int)data->got_bytes));
378 if(data->got_bytes < sizeof(data->total_bytes))
379 {
380 if ((len = read(handler->fd,
381 (char*)&data->total_bytes+data->got_bytes,
382 sizeof(data->total_bytes)-data->got_bytes)) == -1) {
383 log_msg(LOG_ERR, "handle_child_command: read: %s",
384 strerror(errno));
385 return;
386 }
387 if(len == 0) {
388 /* EOF */
389 data->forward_mode = 0;
390 return;
391 }
392 data->got_bytes += len;
393 if(data->got_bytes < sizeof(data->total_bytes))
394 return;
395 data->total_bytes = ntohs(data->total_bytes);
396 buffer_clear(data->packet);
397 if(data->total_bytes > buffer_capacity(data->packet)) {
398 log_msg(LOG_ERR, "internal error: ipc too large");
399 exit(1);
400 }
401 return;
402 }
403 /* read the packet */
404 if(data->got_bytes-sizeof(data->total_bytes) < data->total_bytes) {
405 if((len = read(handler->fd, buffer_current(data->packet),
406 data->total_bytes - (data->got_bytes-sizeof(data->total_bytes))
407 )) == -1 ) {
408 log_msg(LOG_ERR, "handle_child_command: read: %s",
409 strerror(errno));
410 return;
411 }
412 if(len == 0) {
413 /* EOF */
414 data->forward_mode = 0;
415 return;
416 }
417 data->got_bytes += len;
418 buffer_skip(data->packet, len);
419 /* read rest later */
420 return;
421 }
422 /* read the acl numbers */
423 got_acl = data->got_bytes - sizeof(data->total_bytes) - data->total_bytes;
424 if((len = read(handler->fd, (char*)&data->acl_num+got_acl,
425 sizeof(data->acl_num)+sizeof(data->acl_xfr)-got_acl)) == -1 ) {
426 log_msg(LOG_ERR, "handle_child_command: read: %s",
427 strerror(errno));
428 return;
429 }
430 if(len == 0) {
431 /* EOF */
432 data->forward_mode = 0;
433 return;
434 }
435 got_acl += len;
436 data->got_bytes += len;
437 if(got_acl >= (int)(sizeof(data->acl_num)+sizeof(data->acl_xfr))) {
438 uint16_t len = htons(data->total_bytes);
439 DEBUG(DEBUG_IPC,2, (LOG_INFO,
440 "main fwd passed packet write %d", (int)data->got_bytes));
441 #ifndef NDEBUG
442 if(nsd_debug_level >= 2)
443 debug_print_fwd_name(len, data->packet, data->acl_num);
444 #endif
445 data->forward_mode = 0;
446 mode = NSD_PASS_TO_XFRD;
447 if(!write_socket(*data->xfrd_sock, &mode, sizeof(mode)) ||
448 !write_socket(*data->xfrd_sock, &len, sizeof(len)) ||
449 !write_socket(*data->xfrd_sock, buffer_begin(data->packet),
450 data->total_bytes) ||
451 !write_socket(*data->xfrd_sock, &data->acl_num,
452 sizeof(data->acl_num)) ||
453 !write_socket(*data->xfrd_sock, &data->acl_xfr,
454 sizeof(data->acl_xfr))) {
455 log_msg(LOG_ERR, "error in ipc fwd main2xfrd: %s",
456 strerror(errno));
457 }
458 }
459 return;
460 }
461
462 /* read command from ipc */
463 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) {
464 log_msg(LOG_ERR, "handle_child_command: read: %s",
465 strerror(errno));
466 return;
467 }
468 if (len == 0)
469 {
470 child_is_done(data->nsd, handler->fd);
471 return;
472 }
473
474 switch (mode) {
475 case NSD_QUIT:
476 data->nsd->mode = mode;
477 break;
478 #ifdef BIND8_STATS
479 case NSD_QUIT_WITH_STATS:
480 read_child_stats(data->nsd, data->child, handler->fd);
481 break;
482 #endif /* BIND8_STATS */
483 case NSD_STATS:
484 data->nsd->signal_hint_stats = 1;
485 break;
486 case NSD_REAP_CHILDREN:
487 data->nsd->signal_hint_child = 1;
488 break;
489 case NSD_PASS_TO_XFRD:
490 /* set mode for handle_child_command; echo to xfrd. */
491 data->forward_mode = 1;
492 data->got_bytes = 0;
493 data->total_bytes = 0;
494 break;
495 default:
496 log_msg(LOG_ERR, "handle_child_command: bad mode %d",
497 (int) mode);
498 break;
499 }
500 }
501
502 void
parent_check_all_children_exited(struct nsd * nsd)503 parent_check_all_children_exited(struct nsd* nsd)
504 {
505 size_t i;
506 for(i=0; i < nsd->child_count; i++) {
507 if(!nsd->children[i].need_to_exit)
508 return;
509 if(!nsd->children[i].has_exited)
510 return;
511 }
512 nsd->mode = NSD_QUIT_SYNC;
513 DEBUG(DEBUG_IPC,2, (LOG_INFO, "main: all children exited. quit sync."));
514 }
515
516 void
parent_handle_reload_command(netio_type * ATTR_UNUSED (netio),netio_handler_type * handler,netio_event_types_type event_types)517 parent_handle_reload_command(netio_type *ATTR_UNUSED(netio),
518 netio_handler_type *handler,
519 netio_event_types_type event_types)
520 {
521 sig_atomic_t mode;
522 int len;
523 size_t i;
524 struct nsd *nsd = (struct nsd*) handler->user_data;
525 if (!(event_types & NETIO_EVENT_READ)) {
526 return;
527 }
528 /* read command from ipc */
529 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) {
530 log_msg(LOG_ERR, "handle_reload_command: read: %s",
531 strerror(errno));
532 return;
533 }
534 if (len == 0)
535 {
536 assert(handler->fd != -1); /* or read() would have failed */
537 close(handler->fd);
538 handler->fd = -1;
539
540 log_msg(LOG_ERR, "handle_reload_cmd: reload closed cmd channel");
541 nsd->reload_failed = 1;
542 return;
543 }
544 switch (mode) {
545 case NSD_QUIT_SYNC:
546 /* set all children to exit, only then notify xfrd. */
547 /* so that buffered packets to pass to xfrd can arrive. */
548 for(i=0; i < nsd->child_count; i++) {
549 nsd->children[i].need_to_exit = 1;
550 if(nsd->children[i].pid > 0 &&
551 nsd->children[i].child_fd != -1) {
552 nsd->children[i].need_to_send_QUIT = 1;
553 nsd->children[i].handler->event_types
554 |= NETIO_EVENT_WRITE;
555 } else {
556 if(nsd->children[i].child_fd == -1)
557 nsd->children[i].has_exited = 1;
558 }
559 }
560 parent_check_all_children_exited(nsd);
561 break;
562 default:
563 log_msg(LOG_ERR, "handle_reload_command: bad mode %d",
564 (int) mode);
565 break;
566 }
567 }
568
569 static void
xfrd_send_reload_req(xfrd_state_type * xfrd)570 xfrd_send_reload_req(xfrd_state_type* xfrd)
571 {
572 sig_atomic_t req = NSD_RELOAD;
573 uint64_t p = xfrd->last_task->data;
574 udb_ptr_unlink(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
575 task_process_sync(xfrd->nsd->task[xfrd->nsd->mytask]);
576 /* ask server_main for a reload */
577 if(write(xfrd->ipc_handler.ev_fd, &req, sizeof(req)) == -1) {
578 udb_ptr_init(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
579 udb_ptr_set(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask], p);
580 if(errno == EAGAIN || errno == EINTR)
581 return; /* try again later */
582 log_msg(LOG_ERR, "xfrd: problems sending reload command: %s",
583 strerror(errno));
584 return;
585 }
586 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: asked nsd to reload new updates"));
587 /* swapped task to other side, start to use other task udb. */
588 xfrd->nsd->mytask = 1 - xfrd->nsd->mytask;
589 task_remap(xfrd->nsd->task[xfrd->nsd->mytask]);
590 udb_ptr_init(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
591 assert(udb_base_get_userdata(xfrd->nsd->task[xfrd->nsd->mytask])->data == 0);
592 if(!xfrd->reload_cmd_first_sent)
593 xfrd->reload_cmd_first_sent = xfrd_time();
594 xfrd->reload_cmd_last_sent = xfrd_time();
595 xfrd->need_to_send_reload = 0;
596 xfrd->can_send_reload = 0;
597 }
598
599 void
ipc_xfrd_set_listening(struct xfrd_state * xfrd,short mode)600 ipc_xfrd_set_listening(struct xfrd_state* xfrd, short mode)
601 {
602 int fd = xfrd->ipc_handler.ev_fd;
603 struct event_base* base = xfrd->event_base;
604 event_del(&xfrd->ipc_handler);
605 memset(&xfrd->ipc_handler, 0, sizeof(xfrd->ipc_handler));
606 event_set(&xfrd->ipc_handler, fd, mode, xfrd_handle_ipc, xfrd);
607 if(event_base_set(base, &xfrd->ipc_handler) != 0)
608 log_msg(LOG_ERR, "ipc: cannot set event_base");
609 /* no timeout for IPC events */
610 if(event_add(&xfrd->ipc_handler, NULL) != 0)
611 log_msg(LOG_ERR, "ipc: cannot add event");
612 xfrd->ipc_handler_flags = mode;
613 }
614
615 static void
xfrd_send_shutdown_req(xfrd_state_type * xfrd)616 xfrd_send_shutdown_req(xfrd_state_type* xfrd)
617 {
618 sig_atomic_t cmd = NSD_SHUTDOWN;
619 xfrd->ipc_send_blocked = 1;
620 ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
621 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send shutdown"));
622 if(!write_socket(xfrd->ipc_handler.ev_fd, &cmd, sizeof(cmd))) {
623 log_msg(LOG_ERR, "xfrd: error writing shutdown to main: %s",
624 strerror(errno));
625 }
626 xfrd->need_to_send_shutdown = 0;
627 }
628
629 static void
xfrd_send_quit_req(xfrd_state_type * xfrd)630 xfrd_send_quit_req(xfrd_state_type* xfrd)
631 {
632 sig_atomic_t cmd = NSD_QUIT;
633 xfrd->ipc_send_blocked = 1;
634 ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
635 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send ackreload(quit)"));
636 if(!write_socket(xfrd->ipc_handler.ev_fd, &cmd, sizeof(cmd))) {
637 log_msg(LOG_ERR, "xfrd: error writing ack to main: %s",
638 strerror(errno));
639 }
640 xfrd->need_to_send_quit = 0;
641 }
642
643 static void
xfrd_send_stats(xfrd_state_type * xfrd)644 xfrd_send_stats(xfrd_state_type* xfrd)
645 {
646 sig_atomic_t cmd = NSD_STATS;
647 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send stats"));
648 if(!write_socket(xfrd->ipc_handler.ev_fd, &cmd, sizeof(cmd))) {
649 log_msg(LOG_ERR, "xfrd: error writing stats to main: %s",
650 strerror(errno));
651 }
652 xfrd->need_to_send_stats = 0;
653 }
654
655 void
xfrd_handle_ipc(int ATTR_UNUSED (fd),short event,void * arg)656 xfrd_handle_ipc(int ATTR_UNUSED(fd), short event, void* arg)
657 {
658 xfrd_state_type* xfrd = (xfrd_state_type*)arg;
659 if ((event & EV_READ))
660 {
661 /* first attempt to read as a signal from main
662 * could block further send operations */
663 xfrd_handle_ipc_read(&xfrd->ipc_handler, xfrd);
664 }
665 if ((event & EV_WRITE))
666 {
667 if(xfrd->ipc_send_blocked) { /* wait for RELOAD_DONE */
668 ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
669 return;
670 }
671 if(xfrd->need_to_send_shutdown) {
672 xfrd_send_shutdown_req(xfrd);
673 } else if(xfrd->need_to_send_quit) {
674 xfrd_send_quit_req(xfrd);
675 } else if(xfrd->can_send_reload && xfrd->need_to_send_reload) {
676 xfrd_send_reload_req(xfrd);
677 } else if(xfrd->need_to_send_stats) {
678 xfrd_send_stats(xfrd);
679 }
680 if(!(xfrd->can_send_reload && xfrd->need_to_send_reload) &&
681 !xfrd->need_to_send_shutdown &&
682 !xfrd->need_to_send_quit &&
683 !xfrd->need_to_send_stats) {
684 /* disable writing for now */
685 ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
686 }
687 }
688
689 }
690
691 static void
xfrd_handle_ipc_read(struct event * handler,xfrd_state_type * xfrd)692 xfrd_handle_ipc_read(struct event* handler, xfrd_state_type* xfrd)
693 {
694 sig_atomic_t cmd;
695 int len;
696
697 if(xfrd->ipc_conn->is_reading==2) {
698 buffer_type* tmp = xfrd->ipc_pass;
699 uint32_t acl_num;
700 int32_t acl_xfr;
701 /* read acl_num */
702 int ret = conn_read(xfrd->ipc_conn);
703 if(ret == -1) {
704 log_msg(LOG_ERR, "xfrd: error in read ipc: %s", strerror(errno));
705 xfrd->ipc_conn->is_reading = 0;
706 return;
707 }
708 if(ret == 0)
709 return;
710 buffer_flip(xfrd->ipc_conn->packet);
711 xfrd->ipc_pass = xfrd->ipc_conn->packet;
712 xfrd->ipc_conn->packet = tmp;
713 xfrd->ipc_conn->is_reading = 0;
714 acl_num = buffer_read_u32(xfrd->ipc_pass);
715 acl_xfr = (int32_t)buffer_read_u32(xfrd->ipc_pass);
716 xfrd_handle_passed_packet(xfrd->ipc_conn->packet, acl_num, acl_xfr);
717 return;
718 }
719 if(xfrd->ipc_conn->is_reading) {
720 /* reading an IPC message */
721 buffer_type* tmp;
722 int ret = conn_read(xfrd->ipc_conn);
723 if(ret == -1) {
724 log_msg(LOG_ERR, "xfrd: error in read ipc: %s", strerror(errno));
725 xfrd->ipc_conn->is_reading = 0;
726 return;
727 }
728 if(ret == 0)
729 return;
730 buffer_flip(xfrd->ipc_conn->packet);
731 /* use ipc_conn to read remaining data as well */
732 tmp = xfrd->ipc_pass;
733 xfrd->ipc_conn->is_reading=2;
734 xfrd->ipc_pass = xfrd->ipc_conn->packet;
735 xfrd->ipc_conn->packet = tmp;
736 xfrd->ipc_conn->total_bytes = sizeof(xfrd->ipc_conn->msglen);
737 xfrd->ipc_conn->msglen = 2*sizeof(uint32_t);
738 buffer_clear(xfrd->ipc_conn->packet);
739 buffer_set_limit(xfrd->ipc_conn->packet, xfrd->ipc_conn->msglen);
740 return;
741 }
742
743 if((len = read(handler->ev_fd, &cmd, sizeof(cmd))) == -1) {
744 if(errno != EINTR && errno != EAGAIN)
745 log_msg(LOG_ERR, "xfrd_handle_ipc: read: %s",
746 strerror(errno));
747 return;
748 }
749 if(len == 0)
750 {
751 /* parent closed the connection. Quit */
752 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: main closed connection."));
753 xfrd->shutdown = 1;
754 return;
755 }
756
757 switch(cmd) {
758 case NSD_QUIT:
759 case NSD_SHUTDOWN:
760 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: main sent shutdown cmd."));
761 xfrd->shutdown = 1;
762 break;
763 case NSD_RELOAD_FAILED:
764 xfrd->reload_failed = 1;
765 /* fall through */
766 case NSD_RELOAD_DONE:
767 /* reload has finished */
768 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv %s",
769 xfrd->reload_failed ? "RELOAD FAILED" : "RELOAD DONE"));
770 if(block_read(NULL, handler->ev_fd, &xfrd->reload_pid,
771 sizeof(pid_t), -1) != sizeof(pid_t)) {
772 log_msg(LOG_ERR, "xfrd cannot get reload_pid");
773 }
774 /* read the not-mytask for the results and soainfo */
775 xfrd_process_task_result(xfrd,
776 xfrd->nsd->task[1-xfrd->nsd->mytask]);
777 /* reset the IPC, (and the nonblocking ipc write;
778 the new parent does not want half a packet) */
779 xfrd->can_send_reload = 1;
780 xfrd->ipc_send_blocked = 0;
781 ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
782 xfrd_reopen_logfile();
783 if(!xfrd->reload_failed) {
784 xfrd_check_failed_updates();
785 xfrd->reload_cmd_first_sent = 0;
786 } else {
787 /* make reload happen again, right away */
788 xfrd_set_reload_now(xfrd);
789 }
790 xfrd_prepare_zones_for_reload();
791 xfrd->reload_failed = 0;
792 break;
793 case NSD_PASS_TO_XFRD:
794 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv PASS_TO_XFRD"));
795 xfrd->ipc_conn->is_reading = 1;
796 break;
797 case NSD_RELOAD_REQ:
798 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv RELOAD_REQ"));
799 /* make reload happen, right away, and schedule file check */
800 task_new_check_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
801 xfrd->last_task, NULL);
802 xfrd_set_reload_now(xfrd);
803 break;
804 case NSD_RELOAD:
805 /* main tells us that reload is done, stop ipc send to main */
806 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv RELOAD"));
807 ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
808 xfrd->need_to_send_quit = 1;
809 break;
810 default:
811 log_msg(LOG_ERR, "xfrd_handle_ipc: bad mode %d (%d)", (int)cmd,
812 (int)ntohl(cmd));
813 break;
814 }
815
816 if(xfrd->ipc_conn->is_reading) {
817 /* setup read of info */
818 xfrd->ipc_conn->total_bytes = 0;
819 xfrd->ipc_conn->msglen = 0;
820 buffer_clear(xfrd->ipc_conn->packet);
821 }
822 }
823