Home | History | Annotate | Line # | Download | only in dist
      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 static void
    170 send_quit_to_child(struct main_ipc_handler_data* data, int fd)
    171 {
    172 	sig_atomic_t cmd = NSD_QUIT;
    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 quit to child %d command: %s",
    177 			(int)data->child->pid, strerror(errno));
    178 		return;
    179 	}
    180 	data->child->need_to_send_QUIT = 0;
    181 	DEBUG(DEBUG_IPC,2, (LOG_INFO, "main: sent quit to child %d",
    182 		(int)data->child->pid));
    183 }
    184 
    185 /** the child is done, mark it as exited */
    186 static void
    187 child_is_done(struct nsd* nsd, int fd)
    188 {
    189 	size_t i;
    190 	if(fd != -1) close(fd);
    191 	for(i=0; i<nsd->child_count; ++i)
    192 		if(nsd->children[i].child_fd == fd) {
    193 			nsd->children[i].child_fd = -1;
    194 			nsd->children[i].handler->fd = -1;
    195 			if(nsd->children[i].need_to_exit) {
    196 				DEBUG(DEBUG_IPC,1, (LOG_INFO, "server %d is done",
    197 					(int)nsd->children[i].pid));
    198 				nsd->children[i].has_exited = 1;
    199 			} else {
    200 				log_msg(LOG_WARNING,
    201 				       "server %d died unexpectedly, restarting",
    202 				       (int)nsd->children[i].pid);
    203 				/* this child is now going to be re-forked as
    204 				 * a subprocess of this server-main, and if a
    205 				 * reload is in progress the other children
    206 				 * are subprocesses of reload.  Until the
    207 				 * reload is done and they are all reforked. */
    208 				nsd->children[i].pid = -1;
    209 				nsd->restart_children = 1;
    210 			}
    211 		}
    212 	parent_check_all_children_exited(nsd);
    213 }
    214 
    215 #ifdef BIND8_STATS
    216 /** add stats to total */
    217 void
    218 stats_add(struct nsdst* total, struct nsdst* s)
    219 {
    220 	unsigned i;
    221 	for(i=0; i<sizeof(total->qtype)/sizeof(stc_type); i++)
    222 		total->qtype[i] += s->qtype[i];
    223 	for(i=0; i<sizeof(total->qclass)/sizeof(stc_type); i++)
    224 		total->qclass[i] += s->qclass[i];
    225 	total->qudp += s->qudp;
    226 	total->qudp6 += s->qudp6;
    227 	total->ctcp += s->ctcp;
    228 	total->ctcp6 += s->ctcp6;
    229 	total->ctls += s->ctls;
    230 	total->ctls6 += s->ctls6;
    231 	for(i=0; i<sizeof(total->rcode)/sizeof(stc_type); i++)
    232 		total->rcode[i] += s->rcode[i];
    233 	for(i=0; i<sizeof(total->opcode)/sizeof(stc_type); i++)
    234 		total->opcode[i] += s->opcode[i];
    235 	total->dropped += s->dropped;
    236 	total->truncated += s->truncated;
    237 	total->wrongzone += s->wrongzone;
    238 	total->txerr += s->txerr;
    239 	total->rxerr += s->rxerr;
    240 	total->edns += s->edns;
    241 	total->ednserr += s->ednserr;
    242 	total->raxfr += s->raxfr;
    243 	total->nona += s->nona;
    244 	total->rixfr += s->rixfr;
    245 
    246 	total->db_disk = s->db_disk;
    247 	total->db_mem = s->db_mem;
    248 }
    249 
    250 /** subtract stats from total */
    251 void
    252 stats_subtract(struct nsdst* total, struct nsdst* s)
    253 {
    254 	unsigned i;
    255 	for(i=0; i<sizeof(total->qtype)/sizeof(stc_type); i++)
    256 		total->qtype[i] -= s->qtype[i];
    257 	for(i=0; i<sizeof(total->qclass)/sizeof(stc_type); i++)
    258 		total->qclass[i] -= s->qclass[i];
    259 	total->qudp -= s->qudp;
    260 	total->qudp6 -= s->qudp6;
    261 	total->ctcp -= s->ctcp;
    262 	total->ctcp6 -= s->ctcp6;
    263 	total->ctls -= s->ctls;
    264 	total->ctls6 -= s->ctls6;
    265 	for(i=0; i<sizeof(total->rcode)/sizeof(stc_type); i++)
    266 		total->rcode[i] -= s->rcode[i];
    267 	for(i=0; i<sizeof(total->opcode)/sizeof(stc_type); i++)
    268 		total->opcode[i] -= s->opcode[i];
    269 	total->dropped -= s->dropped;
    270 	total->truncated -= s->truncated;
    271 	total->wrongzone -= s->wrongzone;
    272 	total->txerr -= s->txerr;
    273 	total->rxerr -= s->rxerr;
    274 	total->edns -= s->edns;
    275 	total->ednserr -= s->ednserr;
    276 	total->raxfr -= s->raxfr;
    277 	total->nona -= s->nona;
    278 	total->rixfr -= s->rixfr;
    279 }
    280 #endif /* BIND8_STATS */
    281 
    282 void
    283 parent_handle_child_command(netio_type *ATTR_UNUSED(netio),
    284 		      netio_handler_type *handler,
    285 		      netio_event_types_type event_types)
    286 {
    287 	sig_atomic_t mode;
    288 	int len;
    289 	struct main_ipc_handler_data *data =
    290 		(struct main_ipc_handler_data*)handler->user_data;
    291 
    292 	/* do a nonblocking write to the child if it is ready. */
    293 	if ((event_types & NETIO_EVENT_WRITE)) {
    294 		if(data->child->need_to_send_STATS &&
    295 			!data->child->need_to_exit) {
    296 			send_stat_to_child(data, handler->fd);
    297 		} else if(data->child->need_to_send_QUIT) {
    298 			send_quit_to_child(data, handler->fd);
    299 			if(!data->child->need_to_send_QUIT)
    300 				handler->event_types = NETIO_EVENT_READ;
    301 		} else {
    302 			handler->event_types = NETIO_EVENT_READ;
    303 		}
    304 	}
    305 
    306 	if (!(event_types & NETIO_EVENT_READ)) {
    307 		return;
    308 	}
    309 
    310 	/* read command from ipc */
    311 	if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) {
    312 		log_msg(LOG_ERR, "handle_child_command: read: %s",
    313 			strerror(errno));
    314 		return;
    315 	}
    316 	if (len == 0)
    317 	{
    318 		child_is_done(data->nsd, handler->fd);
    319 		return;
    320 	}
    321 
    322 	switch (mode) {
    323 	case NSD_QUIT:
    324 		data->nsd->mode = mode;
    325 		break;
    326 	case NSD_STATS:
    327 		data->nsd->signal_hint_stats = 1;
    328 		break;
    329 	case NSD_REAP_CHILDREN:
    330 		data->nsd->signal_hint_child = 1;
    331 		break;
    332 	default:
    333 		log_msg(LOG_ERR, "handle_child_command: bad mode %d",
    334 			(int) mode);
    335 		break;
    336 	}
    337 }
    338 
    339 void
    340 parent_check_all_children_exited(struct nsd* nsd)
    341 {
    342 	size_t i;
    343 	for(i=0; i < nsd->child_count; i++) {
    344 		if(!nsd->children[i].need_to_exit)
    345 		      return;
    346 		if(!nsd->children[i].has_exited)
    347 		      return;
    348 	}
    349 	nsd->mode = NSD_QUIT_SYNC;
    350 	DEBUG(DEBUG_IPC,2, (LOG_INFO, "main: all children exited. quit sync."));
    351 }
    352 
    353 void
    354 parent_handle_reload_command(netio_type *ATTR_UNUSED(netio),
    355 		      netio_handler_type *handler,
    356 		      netio_event_types_type event_types)
    357 {
    358 	sig_atomic_t mode;
    359 	int len;
    360 	size_t i;
    361 	struct nsd *nsd = (struct nsd*) handler->user_data;
    362 	if (!(event_types & NETIO_EVENT_READ)) {
    363 		return;
    364 	}
    365 	/* read command from ipc */
    366 	if ((len = read(handler->fd, &mode, sizeof(mode))) == -1) {
    367 		log_msg(LOG_ERR, "handle_reload_command: read: %s",
    368 			strerror(errno));
    369 		return;
    370 	}
    371 	if (len == 0)
    372 	{
    373 		assert(handler->fd != -1); /* or read() would have failed */
    374 		close(handler->fd);
    375 		handler->fd = -1;
    376 
    377 		log_msg(LOG_ERR, "handle_reload_cmd: reload closed cmd channel");
    378 		nsd->reload_failed = 1;
    379 		return;
    380 	}
    381 	switch (mode) {
    382 	case NSD_QUIT_SYNC:
    383 		/* set all children to exit, only then notify xfrd. */
    384 		/* so that buffered packets to pass to xfrd can arrive. */
    385 		for(i=0; i < nsd->child_count; i++) {
    386 			nsd->children[i].need_to_exit = 1;
    387 			if(nsd->children[i].pid > 0 &&
    388 			   nsd->children[i].child_fd != -1) {
    389 				nsd->children[i].need_to_send_QUIT = 1;
    390 				nsd->children[i].handler->event_types
    391 					|= NETIO_EVENT_WRITE;
    392 			} else {
    393 				if(nsd->children[i].child_fd == -1)
    394 					nsd->children[i].has_exited = 1;
    395 			}
    396 		}
    397 		parent_check_all_children_exited(nsd);
    398 		break;
    399 	default:
    400 		log_msg(LOG_ERR, "handle_reload_command: bad mode %d",
    401 			(int) mode);
    402 		break;
    403 	}
    404 }
    405 
    406 static void
    407 xfrd_send_reload_req(xfrd_state_type* xfrd)
    408 {
    409 	sig_atomic_t req = NSD_RELOAD;
    410 	uint64_t p = xfrd->last_task->data;
    411 	udb_ptr_unlink(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
    412 	task_process_sync(xfrd->nsd->task[xfrd->nsd->mytask]);
    413 	/* ask server_main for a reload */
    414 	if(write(xfrd->ipc_handler.ev_fd, &req, sizeof(req)) == -1) {
    415 		udb_ptr_init(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
    416 		udb_ptr_set(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask], p);
    417 		if(errno == EAGAIN || errno == EINTR)
    418 			return; /* try again later */
    419 		log_msg(LOG_ERR, "xfrd: problems sending reload command: %s",
    420 			strerror(errno));
    421 		return;
    422 	}
    423 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: asked nsd to reload new updates"));
    424 	/* swapped task to other side, start to use other task udb. */
    425 	xfrd->nsd->mytask = 1 - xfrd->nsd->mytask;
    426 	task_remap(xfrd->nsd->task[xfrd->nsd->mytask]);
    427 	udb_ptr_init(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
    428 	assert(udb_base_get_userdata(xfrd->nsd->task[xfrd->nsd->mytask])->data == 0);
    429 	if(!xfrd->reload_cmd_first_sent)
    430 		xfrd->reload_cmd_first_sent = xfrd_time();
    431 	xfrd->reload_cmd_last_sent = xfrd_time();
    432 	xfrd->need_to_send_reload = 0;
    433 	xfrd->can_send_reload = 0;
    434 }
    435 
    436 void
    437 ipc_xfrd_set_listening(struct xfrd_state* xfrd, short mode)
    438 {
    439 	int fd = xfrd->ipc_handler.ev_fd;
    440 	struct event_base* base = xfrd->event_base;
    441 	event_del(&xfrd->ipc_handler);
    442 	memset(&xfrd->ipc_handler, 0, sizeof(xfrd->ipc_handler));
    443 	event_set(&xfrd->ipc_handler, fd, mode, xfrd_handle_ipc, xfrd);
    444 	if(event_base_set(base, &xfrd->ipc_handler) != 0)
    445 		log_msg(LOG_ERR, "ipc: cannot set event_base");
    446 	/* no timeout for IPC events */
    447 	if(event_add(&xfrd->ipc_handler, NULL) != 0)
    448 		log_msg(LOG_ERR, "ipc: cannot add event");
    449 	xfrd->ipc_handler_flags = mode;
    450 }
    451 
    452 static void
    453 xfrd_send_shutdown_req(xfrd_state_type* xfrd)
    454 {
    455 	sig_atomic_t cmd = NSD_SHUTDOWN;
    456 	xfrd->ipc_send_blocked = 1;
    457 	ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
    458 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send shutdown"));
    459 	if(!write_socket(xfrd->ipc_handler.ev_fd, &cmd, sizeof(cmd))) {
    460 		log_msg(LOG_ERR, "xfrd: error writing shutdown to main: %s",
    461 			strerror(errno));
    462 	}
    463 	xfrd->need_to_send_shutdown = 0;
    464 }
    465 
    466 static void
    467 xfrd_send_quit_req(xfrd_state_type* xfrd)
    468 {
    469 	sig_atomic_t cmd = NSD_QUIT;
    470 	xfrd->ipc_send_blocked = 1;
    471 	ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
    472 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send ackreload(quit)"));
    473 	if(!write_socket(xfrd->ipc_handler.ev_fd, &cmd, sizeof(cmd))) {
    474 		log_msg(LOG_ERR, "xfrd: error writing ack to main: %s",
    475 			strerror(errno));
    476 	}
    477 	xfrd->need_to_send_quit = 0;
    478 }
    479 
    480 static void
    481 xfrd_send_stats(xfrd_state_type* xfrd)
    482 {
    483 	sig_atomic_t cmd = NSD_STATS;
    484 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc send stats"));
    485 	if(!write_socket(xfrd->ipc_handler.ev_fd, &cmd, sizeof(cmd))) {
    486 		log_msg(LOG_ERR, "xfrd: error writing stats to main: %s",
    487 			strerror(errno));
    488 	}
    489 	xfrd->need_to_send_stats = 0;
    490 }
    491 
    492 void
    493 xfrd_handle_ipc(int ATTR_UNUSED(fd), short event, void* arg)
    494 {
    495 	xfrd_state_type* xfrd = (xfrd_state_type*)arg;
    496 	if ((event & EV_READ))
    497 	{
    498 		/* first attempt to read as a signal from main
    499 		 * could block further send operations */
    500 		xfrd_handle_ipc_read(&xfrd->ipc_handler, xfrd);
    501 	}
    502 	if ((event & EV_WRITE))
    503 	{
    504 		if(xfrd->ipc_send_blocked) { /* wait for RELOAD_DONE */
    505 			ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
    506 			return;
    507 		}
    508 		if(xfrd->need_to_send_shutdown) {
    509 			xfrd_send_shutdown_req(xfrd);
    510 		} else if(xfrd->need_to_send_quit) {
    511 			xfrd_send_quit_req(xfrd);
    512 		} else if(xfrd->can_send_reload && xfrd->need_to_send_reload) {
    513 			xfrd_send_reload_req(xfrd);
    514 		} else if(xfrd->need_to_send_stats) {
    515 			xfrd_send_stats(xfrd);
    516 		}
    517 		if(!(xfrd->can_send_reload && xfrd->need_to_send_reload) &&
    518 			!xfrd->need_to_send_shutdown &&
    519 			!xfrd->need_to_send_quit &&
    520 			!xfrd->need_to_send_stats) {
    521 			/* disable writing for now */
    522 			ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ);
    523 		}
    524 	}
    525 
    526 }
    527 
    528 static void
    529 xfrd_handle_ipc_read(struct event* handler, xfrd_state_type* xfrd)
    530 {
    531 	sig_atomic_t cmd;
    532 	int len;
    533 
    534 	if((len = read(handler->ev_fd, &cmd, sizeof(cmd))) == -1) {
    535 		if(errno != EINTR && errno != EAGAIN)
    536 			log_msg(LOG_ERR, "xfrd_handle_ipc: read: %s",
    537 				strerror(errno));
    538 		return;
    539 	}
    540 	if(len == 0)
    541 	{
    542 		/* parent closed the connection. Quit */
    543 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: main closed connection."));
    544 		xfrd->shutdown = 1;
    545 		return;
    546 	}
    547 
    548 	switch(cmd) {
    549 	case NSD_QUIT:
    550 	case NSD_SHUTDOWN:
    551 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: main sent shutdown cmd."));
    552 		xfrd->shutdown = 1;
    553 		break;
    554 	case NSD_RELOAD_FAILED:
    555 		xfrd->reload_failed = 1;
    556 		/* fall through */
    557 	case NSD_RELOAD_DONE:
    558 		/* reload has finished */
    559 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv %s",
    560 			xfrd->reload_failed ? "RELOAD FAILED" : "RELOAD DONE"));
    561 		if(block_read(NULL, handler->ev_fd, &xfrd->reload_pid,
    562 			sizeof(pid_t), -1) != sizeof(pid_t)) {
    563 			log_msg(LOG_ERR, "xfrd cannot get reload_pid");
    564 		}
    565 		/* read the not-mytask for the results and soainfo */
    566 		xfrd_process_task_result(xfrd,
    567 			xfrd->nsd->task[1-xfrd->nsd->mytask]);
    568 		/* reset the IPC, (and the nonblocking ipc write;
    569 		   the new parent does not want half a packet) */
    570 		xfrd->can_send_reload = 1;
    571 		xfrd->ipc_send_blocked = 0;
    572 		ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
    573 		xfrd_reopen_logfile();
    574 		if(!xfrd->reload_failed) {
    575 			xfrd_check_failed_updates();
    576 			xfrd->reload_cmd_first_sent = 0;
    577 		} else {
    578 			/* make reload happen again, right away */
    579 			xfrd_set_reload_now(xfrd);
    580 		}
    581 		xfrd_prepare_zones_for_reload();
    582 		xfrd->reload_failed = 0;
    583 		break;
    584 	case NSD_RELOAD_REQ:
    585 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv RELOAD_REQ"));
    586 		/* make reload happen, right away, and schedule file check */
    587 		task_new_check_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
    588 			xfrd->last_task, NULL);
    589 		xfrd_set_reload_now(xfrd);
    590 		break;
    591 	case NSD_RELOAD:
    592 		/* main tells us that reload is done, stop ipc send to main */
    593 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: ipc recv RELOAD"));
    594 		ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
    595 		xfrd->need_to_send_quit = 1;
    596 		break;
    597 	default:
    598 		log_msg(LOG_ERR, "xfrd_handle_ipc: bad mode %d (%d)", (int)cmd,
    599 			(int)ntohl(cmd));
    600 		break;
    601 	}
    602 }
    603 
    604 void
    605 xfrd_handle_notify(int ATTR_UNUSED(fd), short event, void* arg)
    606 {
    607 	struct xfrd_tcp* notify_pipe = (struct xfrd_tcp*)arg;
    608 	uint32_t acl_num;
    609 	int32_t acl_xfr;
    610 
    611 	if(!(event & EV_READ))
    612 		return;
    613 
    614 	switch(conn_read(notify_pipe)){
    615 	case -1: /* TODO: What to do here? */
    616 		 return;
    617 	case  0: return; /* call back later */
    618 	default: break;
    619 	}
    620 	if(buffer_limit(notify_pipe->packet) < sizeof(acl_xfr)+sizeof(acl_num))
    621 		log_msg(LOG_ERR, "xfrd_handle_notify invalid message size");
    622 	else {
    623 		size_t eop = buffer_position(notify_pipe->packet)
    624 		           - sizeof(acl_xfr) - sizeof(acl_num);
    625 
    626 		buffer_set_position(notify_pipe->packet, eop);
    627 		acl_num = buffer_read_u32(notify_pipe->packet);
    628 		acl_xfr = (int32_t)buffer_read_u32(notify_pipe->packet);
    629 		buffer_set_position(notify_pipe->packet, eop);
    630 		buffer_flip(notify_pipe->packet);
    631 		xfrd_handle_passed_packet(notify_pipe->packet,acl_num,acl_xfr);
    632 	}
    633 	notify_pipe->total_bytes = 0;
    634 	notify_pipe->msglen = 0;
    635 	buffer_clear(notify_pipe->packet);
    636 }
    637