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