1 /* 2 * ipc.c - Interprocess communication routines. Handlers read and write. 3 * 4 * Copyright (c) 2001-2011, 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 "ipc.h" 15 #include "buffer.h" 16 #include "xfrd-tcp.h" 17 #include "nsd.h" 18 #include "namedb.h" 19 #include "xfrd.h" 20 #include "xfrd-notify.h" 21 22 /* set is_ok for the zone according to the zone message */ 23 static zone_type* handle_xfrd_zone_state(struct nsd* nsd, buffer_type* packet); 24 /* write ipc ZONE_STATE message into the buffer */ 25 static void write_zone_state_packet(buffer_type* packet, zone_type* zone); 26 /* attempt to send NSD_STATS command to child fd */ 27 static void send_stat_to_child(struct main_ipc_handler_data* data, int fd); 28 /* write IPC expire notification msg to a buffer */ 29 static void xfrd_write_expire_notification(buffer_type* buffer, xfrd_zone_t* zone); 30 /* send reload request over the IPC channel */ 31 static void xfrd_send_reload_req(xfrd_state_t* xfrd); 32 /* send quit request over the IPC channel */ 33 static void xfrd_send_quit_req(xfrd_state_t* xfrd); 34 /* get SOA INFO out of IPC packet buffer */ 35 static void xfrd_handle_ipc_SOAINFO(xfrd_state_t* xfrd, buffer_type* packet); 36 /* perform read part of handle ipc for xfrd */ 37 static void xfrd_handle_ipc_read(netio_handler_type *handler, xfrd_state_t* xfrd); 38 39 static zone_type* 40 handle_xfrd_zone_state(struct nsd* nsd, buffer_type* packet) 41 { 42 uint8_t ok; 43 const dname_type *dname; 44 domain_type *domain; 45 zone_type *zone; 46 47 ok = buffer_read_u8(packet); 48 dname = (dname_type*)buffer_current(packet); 49 DEBUG(DEBUG_IPC,1, (LOG_INFO, "handler zone state %s is %s", 50 dname_to_string(dname, NULL), ok?"ok":"expired")); 51 /* find in zone_types, if does not exist, we cannot serve anyway */ 52 /* find zone in config, since that one always exists */ 53 domain = domain_table_find(nsd->db->domains, dname); 54 if(!domain) { 55 DEBUG(DEBUG_IPC,1, (LOG_INFO, "zone state msg, empty zone (domain %s)", 56 dname_to_string(dname, NULL))); 57 return NULL; 58 } 59 zone = domain_find_zone(domain); 60 if(!zone || dname_compare(domain_dname(zone->apex), dname) != 0) { 61 DEBUG(DEBUG_IPC,1, (LOG_INFO, "zone state msg, empty zone (zone %s)", 62 dname_to_string(dname, NULL))); 63 return NULL; 64 } 65 assert(zone); 66 /* only update zone->is_ok if needed to minimize copy-on-write 67 of memory pages shared after fork() */ 68 if(ok && !zone->is_ok) 69 zone->is_ok = 1; 70 if(!ok && zone->is_ok) 71 zone->is_ok = 0; 72 return zone; 73 } 74 75 void 76 child_handle_parent_command(netio_type *ATTR_UNUSED(netio), 77 netio_handler_type *handler, 78 netio_event_types_type event_types) 79 { 80 sig_atomic_t mode; 81 int len; 82 struct ipc_handler_conn_data *data = 83 (struct ipc_handler_conn_data *) handler->user_data; 84 if (!(event_types & NETIO_EVENT_READ)) { 85 return; 86 } 87 88 if(data->conn->is_reading) { 89 int ret = conn_read(data->conn); 90 if(ret == -1) { 91 log_msg(LOG_ERR, "handle_parent_command: error in conn_read: %s", 92 strerror(errno)); 93 data->conn->is_reading = 0; 94 return; 95 } 96 if(ret == 0) { 97 return; /* continue later */ 98 } 99 /* completed */ 100 data->conn->is_reading = 0; 101 buffer_flip(data->conn->packet); 102 (void)handle_xfrd_zone_state(data->nsd, data->conn->packet); 103 return; 104 } 105 106 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) { 107 log_msg(LOG_ERR, "handle_parent_command: read: %s", 108 strerror(errno)); 109 return; 110 } 111 if (len == 0) 112 { 113 /* parent closed the connection. Quit */ 114 data->nsd->mode = NSD_QUIT; 115 return; 116 } 117 118 switch (mode) { 119 case NSD_STATS: 120 case NSD_QUIT: 121 data->nsd->mode = mode; 122 break; 123 case NSD_ZONE_STATE: 124 data->conn->is_reading = 1; 125 data->conn->total_bytes = 0; 126 data->conn->msglen = 0; 127 data->conn->fd = handler->fd; 128 buffer_clear(data->conn->packet); 129 break; 130 default: 131 log_msg(LOG_ERR, "handle_parent_command: bad mode %d", 132 (int) mode); 133 break; 134 } 135 } 136 137 void 138 parent_handle_xfrd_command(netio_type *ATTR_UNUSED(netio), 139 netio_handler_type *handler, 140 netio_event_types_type event_types) 141 { 142 sig_atomic_t mode; 143 int len; 144 struct ipc_handler_conn_data *data = 145 (struct ipc_handler_conn_data *) handler->user_data; 146 if (!(event_types & NETIO_EVENT_READ)) { 147 return; 148 } 149 150 if(data->conn->is_reading) { 151 /* handle ZONE_STATE forward to children */ 152 int ret = conn_read(data->conn); 153 size_t i; 154 zone_type* zone; 155 if(ret == -1) { 156 log_msg(LOG_ERR, "main xfrd listener: error in conn_read: %s", 157 strerror(errno)); 158 data->conn->is_reading = 0; 159 return; 160 } 161 if(ret == 0) { 162 return; /* continue later */ 163 } 164 /* completed */ 165 data->conn->is_reading = 0; 166 buffer_flip(data->conn->packet); 167 zone = handle_xfrd_zone_state(data->nsd, data->conn->packet); 168 if(!zone) 169 return; 170 /* forward to all children */ 171 for (i = 0; i < data->nsd->child_count; ++i) { 172 if(!zone->dirty[i]) { 173 zone->dirty[i] = 1; 174 stack_push(data->nsd->children[i].dirty_zones, zone); 175 data->nsd->children[i].handler->event_types |= 176 NETIO_EVENT_WRITE; 177 } 178 } 179 return; 180 } 181 182 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) { 183 log_msg(LOG_ERR, "handle_xfrd_command: read: %s", 184 strerror(errno)); 185 return; 186 } 187 if (len == 0) 188 { 189 DEBUG(DEBUG_IPC,1, (LOG_ERR, "handle_xfrd_command: xfrd closed channel.")); 190 close(handler->fd); 191 handler->fd = -1; 192 return; 193 } 194 195 switch (mode) { 196 case NSD_RELOAD: 197 data->nsd->signal_hint_reload = 1; 198 break; 199 case NSD_QUIT: 200 data->nsd->mode = mode; 201 break; 202 case NSD_REAP_CHILDREN: 203 data->nsd->signal_hint_child = 1; 204 break; 205 case NSD_ZONE_STATE: 206 data->conn->is_reading = 1; 207 data->conn->total_bytes = 0; 208 data->conn->msglen = 0; 209 data->conn->fd = handler->fd; 210 buffer_clear(data->conn->packet); 211 break; 212 default: 213 log_msg(LOG_ERR, "handle_xfrd_command: bad mode %d", 214 (int) mode); 215 break; 216 } 217 } 218 219 static void 220 write_zone_state_packet(buffer_type* packet, zone_type* zone) 221 { 222 sig_atomic_t cmd = NSD_ZONE_STATE; 223 uint8_t ok = zone->is_ok; 224 uint16_t sz; 225 if(!zone->apex) { 226 return; 227 } 228 sz = dname_total_size(domain_dname(zone->apex)) + 1; 229 sz = htons(sz); 230 231 buffer_clear(packet); 232 buffer_write(packet, &cmd, sizeof(cmd)); 233 buffer_write(packet, &sz, sizeof(sz)); 234 buffer_write(packet, &ok, sizeof(ok)); 235 buffer_write(packet, domain_dname(zone->apex), 236 dname_total_size(domain_dname(zone->apex))); 237 buffer_flip(packet); 238 } 239 240 static void 241 send_stat_to_child(struct main_ipc_handler_data* data, int fd) 242 { 243 sig_atomic_t cmd = NSD_STATS; 244 if(write(fd, &cmd, sizeof(cmd)) == -1) { 245 if(errno == EAGAIN || errno == EINTR) 246 return; /* try again later */ 247 log_msg(LOG_ERR, "svrmain: problems sending stats to child %d command: %s", 248 (int)data->child->pid, strerror(errno)); 249 return; 250 } 251 data->child->need_to_send_STATS = 0; 252 } 253 254 int packet_read_query_section(buffer_type *packet, uint8_t* dest, uint16_t* qtype, uint16_t* qclass); 255 static void 256 debug_print_fwd_name(int ATTR_UNUSED(len), buffer_type* packet, int acl_num) 257 { 258 uint8_t qnamebuf[MAXDOMAINLEN]; 259 uint16_t qtype, qclass; 260 const dname_type* dname; 261 region_type* tempregion = region_create(xalloc, free); 262 263 size_t bufpos = buffer_position(packet); 264 buffer_rewind(packet); 265 buffer_skip(packet, 12); 266 if(packet_read_query_section(packet, qnamebuf, &qtype, &qclass)) { 267 dname = dname_make(tempregion, qnamebuf, 1); 268 log_msg(LOG_INFO, "main: fwd packet for %s, acl %d", 269 dname_to_string(dname,0), acl_num); 270 } else { 271 log_msg(LOG_INFO, "main: fwd packet badqname, acl %d", acl_num); 272 } 273 buffer_set_position(packet, bufpos); 274 region_destroy(tempregion); 275 } 276 277 static void 278 send_quit_to_child(struct main_ipc_handler_data* data, int fd) 279 { 280 sig_atomic_t cmd = NSD_QUIT; 281 if(write(fd, &cmd, sizeof(cmd)) == -1) { 282 if(errno == EAGAIN || errno == EINTR) 283 return; /* try again later */ 284 log_msg(LOG_ERR, "svrmain: problems sending quit to child %d command: %s", 285 (int)data->child->pid, strerror(errno)); 286 return; 287 } 288 data->child->need_to_send_QUIT = 0; 289 DEBUG(DEBUG_IPC,2, (LOG_INFO, "main: sent quit to child %d", 290 (int)data->child->pid)); 291 } 292 293 void 294 parent_handle_child_command(netio_type *ATTR_UNUSED(netio), 295 netio_handler_type *handler, 296 netio_event_types_type event_types) 297 { 298 sig_atomic_t mode; 299 int len; 300 struct main_ipc_handler_data *data = 301 (struct main_ipc_handler_data*)handler->user_data; 302 303 /* do a nonblocking write to the child if it is ready. */ 304 if (event_types & NETIO_EVENT_WRITE) { 305 if(!data->busy_writing_zone_state && 306 !data->child->need_to_send_STATS && 307 !data->child->need_to_send_QUIT && 308 !data->child->need_to_exit && 309 data->child->dirty_zones->num > 0) { 310 /* create packet from next dirty zone */ 311 zone_type* zone = (zone_type*)stack_pop(data->child->dirty_zones); 312 assert(zone); 313 zone->dirty[data->child_num] = 0; 314 data->busy_writing_zone_state = 1; 315 write_zone_state_packet(data->write_conn->packet, zone); 316 data->write_conn->msglen = buffer_limit(data->write_conn->packet); 317 data->write_conn->total_bytes = sizeof(uint16_t); /* len bytes already in packet */ 318 data->write_conn->fd = handler->fd; 319 } 320 if(data->busy_writing_zone_state) { 321 /* write more of packet */ 322 int ret = conn_write(data->write_conn); 323 if(ret == -1) { 324 log_msg(LOG_ERR, "handle_child_cmd %d: could not write: %s", 325 (int)data->child->pid, strerror(errno)); 326 data->busy_writing_zone_state = 0; 327 } else if(ret == 1) { 328 data->busy_writing_zone_state = 0; /* completed */ 329 } 330 } else if(data->child->need_to_send_STATS && 331 !data->child->need_to_exit) { 332 send_stat_to_child(data, handler->fd); 333 } else if(data->child->need_to_send_QUIT) { 334 send_quit_to_child(data, handler->fd); 335 if(!data->child->need_to_send_QUIT) 336 handler->event_types = NETIO_EVENT_READ; 337 } 338 if(!data->busy_writing_zone_state && 339 !data->child->need_to_send_STATS && 340 !data->child->need_to_send_QUIT && 341 data->child->dirty_zones->num == 0) { 342 handler->event_types = NETIO_EVENT_READ; 343 } 344 } 345 346 if (!(event_types & NETIO_EVENT_READ)) { 347 return; 348 } 349 350 if (data->forward_mode) { 351 int got_acl; 352 /* forward the data to xfrd */ 353 DEBUG(DEBUG_IPC,2, (LOG_INFO, 354 "main passed packet readup %d", (int)data->got_bytes)); 355 if(data->got_bytes < sizeof(data->total_bytes)) 356 { 357 if ((len = read(handler->fd, 358 (char*)&data->total_bytes+data->got_bytes, 359 sizeof(data->total_bytes)-data->got_bytes)) == -1) { 360 log_msg(LOG_ERR, "handle_child_command: read: %s", 361 strerror(errno)); 362 return; 363 } 364 if(len == 0) { 365 /* EOF */ 366 data->forward_mode = 0; 367 return; 368 } 369 data->got_bytes += len; 370 if(data->got_bytes < sizeof(data->total_bytes)) 371 return; 372 data->total_bytes = ntohs(data->total_bytes); 373 buffer_clear(data->packet); 374 if(data->total_bytes > buffer_capacity(data->packet)) { 375 log_msg(LOG_ERR, "internal error: ipc too large"); 376 exit(1); 377 } 378 return; 379 } 380 /* read the packet */ 381 if(data->got_bytes-sizeof(data->total_bytes) < data->total_bytes) { 382 if((len = read(handler->fd, buffer_current(data->packet), 383 data->total_bytes - (data->got_bytes-sizeof(data->total_bytes)) 384 )) == -1 ) { 385 log_msg(LOG_ERR, "handle_child_command: read: %s", 386 strerror(errno)); 387 return; 388 } 389 if(len == 0) { 390 /* EOF */ 391 data->forward_mode = 0; 392 return; 393 } 394 data->got_bytes += len; 395 buffer_skip(data->packet, len); 396 /* read rest later */ 397 return; 398 } 399 /* read the acl number */ 400 got_acl = data->got_bytes - sizeof(data->total_bytes) - data->total_bytes; 401 if((len = read(handler->fd, (char*)&data->acl_num+got_acl, 402 sizeof(data->acl_num)-got_acl)) == -1 ) { 403 log_msg(LOG_ERR, "handle_child_command: read: %s", 404 strerror(errno)); 405 return; 406 } 407 if(len == 0) { 408 /* EOF */ 409 data->forward_mode = 0; 410 return; 411 } 412 got_acl += len; 413 data->got_bytes += len; 414 if(got_acl >= (int)sizeof(data->acl_num)) { 415 uint16_t len = htons(data->total_bytes); 416 DEBUG(DEBUG_IPC,2, (LOG_INFO, 417 "main fwd passed packet write %d", (int)data->got_bytes)); 418 #ifndef NDEBUG 419 if(nsd_debug_level >= 2) 420 debug_print_fwd_name(len, data->packet, data->acl_num); 421 #endif 422 data->forward_mode = 0; 423 mode = NSD_PASS_TO_XFRD; 424 if(!write_socket(*data->xfrd_sock, &mode, sizeof(mode)) || 425 !write_socket(*data->xfrd_sock, &len, sizeof(len)) || 426 !write_socket(*data->xfrd_sock, buffer_begin(data->packet), 427 data->total_bytes) || 428 !write_socket(*data->xfrd_sock, &data->acl_num, 429 sizeof(data->acl_num))) { 430 log_msg(LOG_ERR, "error in ipc fwd main2xfrd: %s", 431 strerror(errno)); 432 } 433 } 434 return; 435 } 436 437 /* read command from ipc */ 438 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) { 439 log_msg(LOG_ERR, "handle_child_command: read: %s", 440 strerror(errno)); 441 return; 442 } 443 if (len == 0) 444 { 445 size_t i; 446 if(handler->fd > 0) close(handler->fd); 447 for(i=0; i<data->nsd->child_count; ++i) 448 if(data->nsd->children[i].child_fd == handler->fd) { 449 data->nsd->children[i].child_fd = -1; 450 data->nsd->children[i].has_exited = 1; 451 DEBUG(DEBUG_IPC,1, (LOG_INFO, 452 "server %d closed cmd channel", 453 (int) data->nsd->children[i].pid)); 454 } 455 handler->fd = -1; 456 parent_check_all_children_exited(data->nsd); 457 return; 458 } 459 460 switch (mode) { 461 case NSD_QUIT: 462 data->nsd->mode = mode; 463 break; 464 case NSD_STATS: 465 data->nsd->signal_hint_stats = 1; 466 break; 467 case NSD_REAP_CHILDREN: 468 data->nsd->signal_hint_child = 1; 469 break; 470 case NSD_PASS_TO_XFRD: 471 /* set mode for handle_child_command; echo to xfrd. */ 472 data->forward_mode = 1; 473 data->got_bytes = 0; 474 data->total_bytes = 0; 475 break; 476 default: 477 log_msg(LOG_ERR, "handle_child_command: bad mode %d", 478 (int) mode); 479 break; 480 } 481 } 482 483 void 484 parent_check_all_children_exited(struct nsd* nsd) 485 { 486 size_t i; 487 for(i=0; i < nsd->child_count; i++) { 488 if(!nsd->children[i].need_to_exit) 489 return; 490 if(!nsd->children[i].has_exited) 491 return; 492 } 493 nsd->mode = NSD_QUIT_SYNC; 494 DEBUG(DEBUG_IPC,2, (LOG_INFO, "main: all children exited. quit sync.")); 495 } 496 497 void 498 parent_handle_reload_command(netio_type *ATTR_UNUSED(netio), 499 netio_handler_type *handler, 500 netio_event_types_type event_types) 501 { 502 sig_atomic_t mode; 503 int len; 504 size_t i; 505 struct nsd *nsd = (struct nsd*) handler->user_data; 506 if (!(event_types & NETIO_EVENT_READ)) { 507 return; 508 } 509 /* read command from ipc */ 510 if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) { 511 log_msg(LOG_ERR, "handle_reload_command: read: %s", 512 strerror(errno)); 513 return; 514 } 515 if (len == 0) 516 { 517 if(handler->fd > 0) { 518 close(handler->fd); 519 handler->fd = -1; 520 } 521 log_msg(LOG_ERR, "handle_reload_cmd: reload closed cmd channel"); 522 return; 523 } 524 switch (mode) { 525 case NSD_QUIT_SYNC: 526 /* set all children to exit, only then notify xfrd. */ 527 /* so that buffered packets to pass to xfrd can arrive. */ 528 for(i=0; i < nsd->child_count; i++) { 529 nsd->children[i].need_to_exit = 1; 530 if(nsd->children[i].pid > 0 && 531 nsd->children[i].child_fd > 0) { 532 nsd->children[i].need_to_send_QUIT = 1; 533 nsd->children[i].handler->event_types 534 |= NETIO_EVENT_WRITE; 535 } else { 536 if(nsd->children[i].child_fd == -1) 537 nsd->children[i].has_exited = 1; 538 } 539 } 540 parent_check_all_children_exited(nsd); 541 break; 542 default: 543 log_msg(LOG_ERR, "handle_reload_command: bad mode %d", 544 (int) mode); 545 break; 546 } 547 } 548 549 static void 550 xfrd_write_expire_notification(buffer_type* buffer, xfrd_zone_t* zone) 551 { 552 sig_atomic_t cmd = NSD_ZONE_STATE; 553 uint8_t ok = 1; 554 uint16_t sz = dname_total_size(zone->apex) + 1; 555 sz = htons(sz); 556 if(zone->state == xfrd_zone_expired) 557 ok = 0; 558 559 DEBUG(DEBUG_IPC,1, (LOG_INFO, 560 "xfrd encoding ipc zone state msg for zone %s state %d.", 561 zone->apex_str, (int)zone->state)); 562 563 buffer_clear(buffer); 564 buffer_write(buffer, &cmd, sizeof(cmd)); 565 buffer_write(buffer, &sz, sizeof(sz)); 566 buffer_write(buffer, &ok, sizeof(ok)); 567 buffer_write(buffer, zone->apex, dname_total_size(zone->apex)); 568 buffer_flip(buffer); 569 } 570 571 static void 572 xfrd_send_reload_req(xfrd_state_t* xfrd) 573 { 574 sig_atomic_t req = NSD_RELOAD; 575 /* ask server_main for a reload */ 576 if(write(xfrd->ipc_handler.fd, &req, sizeof(req)) == -1) { 577 if(errno == EAGAIN || errno == EINTR) 578 return; /* try again later */ 579 log_msg(LOG_ERR, "xfrd: problems sending reload command: %s", 580 strerror(errno)); 581 return; 582 } 583 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: asked nsd to reload new updates")); 584 xfrd_prepare_zones_for_reload(); 585 xfrd->reload_cmd_last_sent = xfrd_time(); 586 xfrd->need_to_send_reload = 0; 587 xfrd->can_send_reload = 0; 588 } 589 590 static void 591 xfrd_send_quit_req(xfrd_state_t* xfrd) 592 { 593 sig_atomic_t cmd = NSD_QUIT; 594 xfrd->ipc_send_blocked = 1; 595 xfrd->ipc_handler.event_types &= (~NETIO_EVENT_WRITE); 596 xfrd->sending_zone_state = 0; 597 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send ackreload(quit)")); 598 if(write_socket(xfrd->ipc_handler.fd, &cmd, sizeof(cmd)) == -1) { 599 log_msg(LOG_ERR, "xfrd: error writing ack to main: %s", 600 strerror(errno)); 601 } 602 xfrd->need_to_send_quit = 0; 603 } 604 605 static void 606 xfrd_handle_ipc_SOAINFO(xfrd_state_t* xfrd, buffer_type* packet) 607 { 608 xfrd_soa_t soa; 609 xfrd_soa_t* soa_ptr = &soa; 610 xfrd_zone_t* zone; 611 /* dname is sent in memory format */ 612 const dname_type* dname = (const dname_type*)buffer_begin(packet); 613 614 /* find zone and decode SOA */ 615 zone = (xfrd_zone_t*)rbtree_search(xfrd->zones, dname); 616 buffer_skip(packet, dname_total_size(dname)); 617 618 if(!buffer_available(packet, sizeof(uint32_t)*6 + sizeof(uint8_t)*2)) { 619 /* NSD has zone without any info */ 620 DEBUG(DEBUG_IPC,1, (LOG_INFO, "SOAINFO for %s lost zone", 621 dname_to_string(dname,0))); 622 soa_ptr = NULL; 623 } else { 624 /* read soa info */ 625 memset(&soa, 0, sizeof(soa)); 626 /* left out type, klass, count for speed */ 627 soa.type = htons(TYPE_SOA); 628 soa.klass = htons(CLASS_IN); 629 soa.ttl = htonl(buffer_read_u32(packet)); 630 soa.rdata_count = htons(7); 631 soa.prim_ns[0] = buffer_read_u8(packet); 632 if(!buffer_available(packet, soa.prim_ns[0])) 633 return; 634 buffer_read(packet, soa.prim_ns+1, soa.prim_ns[0]); 635 soa.email[0] = buffer_read_u8(packet); 636 if(!buffer_available(packet, soa.email[0])) 637 return; 638 buffer_read(packet, soa.email+1, soa.email[0]); 639 640 soa.serial = htonl(buffer_read_u32(packet)); 641 soa.refresh = htonl(buffer_read_u32(packet)); 642 soa.retry = htonl(buffer_read_u32(packet)); 643 soa.expire = htonl(buffer_read_u32(packet)); 644 soa.minimum = htonl(buffer_read_u32(packet)); 645 DEBUG(DEBUG_IPC,1, (LOG_INFO, "SOAINFO for %s %u", 646 dname_to_string(dname,0), ntohl(soa.serial))); 647 } 648 649 if(!zone) { 650 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: zone %s master zone updated", 651 dname_to_string(dname,0))); 652 notify_handle_master_zone_soainfo(xfrd->notify_zones, 653 dname, soa_ptr); 654 return; 655 } 656 xfrd_handle_incoming_soa(zone, soa_ptr, xfrd_time()); 657 } 658 659 void 660 xfrd_handle_ipc(netio_type* ATTR_UNUSED(netio), 661 netio_handler_type *handler, 662 netio_event_types_type event_types) 663 { 664 xfrd_state_t* xfrd = (xfrd_state_t*)handler->user_data; 665 if ((event_types & NETIO_EVENT_READ)) 666 { 667 /* first attempt to read as a signal from main 668 * could block further send operations */ 669 xfrd_handle_ipc_read(handler, xfrd); 670 } 671 if ((event_types & NETIO_EVENT_WRITE)) 672 { 673 if(xfrd->ipc_send_blocked) { /* wait for SOA_END */ 674 handler->event_types = NETIO_EVENT_READ; 675 return; 676 } 677 /* if necessary prepare a packet */ 678 if(!(xfrd->can_send_reload && xfrd->need_to_send_reload) && 679 !xfrd->need_to_send_quit && 680 !xfrd->sending_zone_state && 681 xfrd->dirty_zones->num > 0) { 682 xfrd_zone_t* zone = (xfrd_zone_t*)stack_pop(xfrd->dirty_zones); 683 assert(zone); 684 zone->dirty = 0; 685 xfrd->sending_zone_state = 1; 686 xfrd_write_expire_notification(xfrd->ipc_conn_write->packet, zone); 687 xfrd->ipc_conn_write->msglen = buffer_limit(xfrd->ipc_conn_write->packet); 688 /* skip length bytes; they are encoded in the packet, after cmd */ 689 xfrd->ipc_conn_write->total_bytes = sizeof(uint16_t); 690 } 691 /* write a bit */ 692 if(xfrd->sending_zone_state) { 693 /* call conn_write */ 694 int ret = conn_write(xfrd->ipc_conn_write); 695 if(ret == -1) { 696 log_msg(LOG_ERR, "xfrd: error in write ipc: %s", strerror(errno)); 697 xfrd->sending_zone_state = 0; 698 } 699 else if(ret == 1) { /* done */ 700 xfrd->sending_zone_state = 0; 701 } 702 } else if(xfrd->need_to_send_quit) { 703 xfrd_send_quit_req(xfrd); 704 } else if(xfrd->can_send_reload && xfrd->need_to_send_reload) { 705 xfrd_send_reload_req(xfrd); 706 } 707 if(!(xfrd->can_send_reload && xfrd->need_to_send_reload) && 708 !xfrd->need_to_send_quit && 709 !xfrd->sending_zone_state && 710 xfrd->dirty_zones->num == 0) { 711 handler->event_types = NETIO_EVENT_READ; /* disable writing for now */ 712 } 713 } 714 715 } 716 717 static void 718 xfrd_handle_ipc_read(netio_handler_type *handler, xfrd_state_t* xfrd) 719 { 720 sig_atomic_t cmd; 721 int len; 722 723 if(xfrd->ipc_conn->is_reading==2) { 724 buffer_type* tmp = xfrd->ipc_pass; 725 uint32_t acl_num; 726 /* read acl_num */ 727 int ret = conn_read(xfrd->ipc_conn); 728 if(ret == -1) { 729 log_msg(LOG_ERR, "xfrd: error in read ipc: %s", strerror(errno)); 730 xfrd->ipc_conn->is_reading = 0; 731 return; 732 } 733 if(ret == 0) 734 return; 735 buffer_flip(xfrd->ipc_conn->packet); 736 xfrd->ipc_pass = xfrd->ipc_conn->packet; 737 xfrd->ipc_conn->packet = tmp; 738 xfrd->ipc_conn->is_reading = 0; 739 acl_num = buffer_read_u32(xfrd->ipc_pass); 740 xfrd_handle_passed_packet(xfrd->ipc_conn->packet, acl_num); 741 return; 742 } 743 if(xfrd->ipc_conn->is_reading) { 744 /* reading an IPC message */ 745 int ret = conn_read(xfrd->ipc_conn); 746 if(ret == -1) { 747 log_msg(LOG_ERR, "xfrd: error in read ipc: %s", strerror(errno)); 748 xfrd->ipc_conn->is_reading = 0; 749 return; 750 } 751 if(ret == 0) 752 return; 753 buffer_flip(xfrd->ipc_conn->packet); 754 if(xfrd->ipc_is_soa) { 755 xfrd->ipc_conn->is_reading = 0; 756 xfrd_handle_ipc_SOAINFO(xfrd, xfrd->ipc_conn->packet); 757 } else { 758 /* use ipc_conn to read remaining data as well */ 759 buffer_type* tmp = xfrd->ipc_pass; 760 xfrd->ipc_conn->is_reading=2; 761 xfrd->ipc_pass = xfrd->ipc_conn->packet; 762 xfrd->ipc_conn->packet = tmp; 763 xfrd->ipc_conn->total_bytes = sizeof(xfrd->ipc_conn->msglen); 764 xfrd->ipc_conn->msglen = sizeof(uint32_t); 765 buffer_clear(xfrd->ipc_conn->packet); 766 buffer_set_limit(xfrd->ipc_conn->packet, xfrd->ipc_conn->msglen); 767 } 768 return; 769 } 770 771 if((len = read(handler->fd, &cmd, sizeof(cmd))) == -1) { 772 log_msg(LOG_ERR, "xfrd_handle_ipc: read: %s", 773 strerror(errno)); 774 return; 775 } 776 if(len == 0) 777 { 778 /* parent closed the connection. Quit */ 779 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: main closed connection.")); 780 xfrd->shutdown = 1; 781 return; 782 } 783 784 switch(cmd) { 785 case NSD_QUIT: 786 case NSD_SHUTDOWN: 787 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: main send shutdown cmd.")); 788 xfrd->shutdown = 1; 789 break; 790 case NSD_SOA_BEGIN: 791 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv SOA_BEGIN")); 792 /* reload starts sending SOA INFOs; don't block */ 793 xfrd->parent_soa_info_pass = 1; 794 /* reset the nonblocking ipc write; 795 the new parent does not want half a packet */ 796 xfrd->sending_zone_state = 0; 797 break; 798 case NSD_SOA_INFO: 799 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv SOA_INFO")); 800 assert(xfrd->parent_soa_info_pass); 801 xfrd->ipc_is_soa = 1; 802 xfrd->ipc_conn->is_reading = 1; 803 break; 804 case NSD_SOA_END: 805 /* reload has finished */ 806 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv SOA_END")); 807 xfrd->can_send_reload = 1; 808 xfrd->parent_soa_info_pass = 0; 809 xfrd->ipc_send_blocked = 0; 810 handler->event_types |= NETIO_EVENT_WRITE; 811 xfrd_reopen_logfile(); 812 xfrd_check_failed_updates(); 813 xfrd_send_expy_all_zones(); 814 break; 815 case NSD_PASS_TO_XFRD: 816 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv PASS_TO_XFRD")); 817 xfrd->ipc_is_soa = 0; 818 xfrd->ipc_conn->is_reading = 1; 819 break; 820 case NSD_RELOAD: 821 /* main tells us that reload is done, stop ipc send to main */ 822 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv RELOAD")); 823 handler->event_types |= NETIO_EVENT_WRITE; 824 xfrd->need_to_send_quit = 1; 825 break; 826 default: 827 log_msg(LOG_ERR, "xfrd_handle_ipc: bad mode %d (%d)", (int)cmd, 828 ntohl(cmd)); 829 break; 830 } 831 832 if(xfrd->ipc_conn->is_reading) { 833 /* setup read of info */ 834 xfrd->ipc_conn->total_bytes = 0; 835 xfrd->ipc_conn->msglen = 0; 836 buffer_clear(xfrd->ipc_conn->packet); 837 } 838 } 839 840