示例#1
0
/**
 * Start zone transfer handler.
 *
 */
void
xfrhandler_start(xfrhandler_type* xfrhandler)
{
    ods_log_assert(xfrhandler);
    ods_log_assert(xfrhandler->engine);
    ods_log_debug("[%s] start", xfrh_str);
    /* setup */
    xfrhandler->start_time = time_now();
    /* handlers */
    netio_add_handler(xfrhandler->netio, &xfrhandler->dnshandler);
    /* service */
    while (xfrhandler->need_to_exit == 0) {
        /* dispatch may block for a longer period, so current is gone */
        xfrhandler->got_time = 0;
        ods_log_deeebug("[%s] netio dispatch", xfrh_str);
        if (netio_dispatch(xfrhandler->netio, NULL, NULL) == -1) {
            if (errno != EINTR) {
                ods_log_error("[%s] unable to dispatch netio: %s", xfrh_str,
                    strerror(errno));
            }
        }
    }
    /* shutdown */
    ods_log_debug("[%s] shutdown", xfrh_str);
}
示例#2
0
static void
xfrd_main()
{
	xfrd->shutdown = 0;
	while(!xfrd->shutdown)
	{
		/* dispatch may block for a longer period, so current is gone */
		xfrd->got_time = 0;
		if(netio_dispatch(xfrd->netio, NULL, 0) == -1) {
			if (errno != EINTR) {
				log_msg(LOG_ERR,
					"xfrd netio_dispatch failed: %s",
					strerror(errno));
			}
		}
		if(xfrd->nsd->signal_hint_quit || xfrd->nsd->signal_hint_shutdown)
			xfrd->shutdown = 1;
	}
	xfrd_shutdown();
}
示例#3
0
/*
 * Serve DNS requests.
 */
void
server_child(struct nsd *nsd)
{
	size_t i;
	region_type *server_region = region_create(xalloc, free);
	netio_type *netio = netio_create(server_region);
	netio_handler_type *tcp_accept_handlers;
	query_type *udp_query;
	sig_atomic_t mode;

	assert(nsd->server_kind != NSD_SERVER_MAIN);
	DEBUG(DEBUG_IPC, 2, (LOG_INFO, "child process started"));

	if (!(nsd->server_kind & NSD_SERVER_TCP)) {
		close_all_sockets(nsd->tcp, nsd->ifs);
	}
	if (!(nsd->server_kind & NSD_SERVER_UDP)) {
		close_all_sockets(nsd->udp, nsd->ifs);
	}

	if (nsd->this_child && nsd->this_child->parent_fd != -1) {
		netio_handler_type *handler;

		handler = (netio_handler_type *) region_alloc(
			server_region, sizeof(netio_handler_type));
		handler->fd = nsd->this_child->parent_fd;
		handler->timeout = NULL;
		handler->user_data = (struct ipc_handler_conn_data*)region_alloc(
			server_region, sizeof(struct ipc_handler_conn_data));
		((struct ipc_handler_conn_data*)handler->user_data)->nsd = nsd;
		((struct ipc_handler_conn_data*)handler->user_data)->conn =
			xfrd_tcp_create(server_region);
		handler->event_types = NETIO_EVENT_READ;
		handler->event_handler = child_handle_parent_command;
		netio_add_handler(netio, handler);
	}

	if (nsd->server_kind & NSD_SERVER_UDP) {
		udp_query = query_create(server_region,
			compressed_dname_offsets, compression_table_size);

		for (i = 0; i < nsd->ifs; ++i) {
			struct udp_handler_data *data;
			netio_handler_type *handler;

			data = (struct udp_handler_data *) region_alloc(
				server_region,
				sizeof(struct udp_handler_data));
			data->query = udp_query;
			data->nsd = nsd;
			data->socket = &nsd->udp[i];

			handler = (netio_handler_type *) region_alloc(
				server_region, sizeof(netio_handler_type));
			handler->fd = nsd->udp[i].s;
			handler->timeout = NULL;
			handler->user_data = data;
			handler->event_types = NETIO_EVENT_READ;
			handler->event_handler = handle_udp;
			netio_add_handler(netio, handler);
		}
	}

	/*
	 * Keep track of all the TCP accept handlers so we can enable
	 * and disable them based on the current number of active TCP
	 * connections.
	 */
	tcp_accept_handlers = (netio_handler_type *) region_alloc(
		server_region, nsd->ifs * sizeof(netio_handler_type));
	if (nsd->server_kind & NSD_SERVER_TCP) {
		for (i = 0; i < nsd->ifs; ++i) {
			struct tcp_accept_handler_data *data;
			netio_handler_type *handler;

			data = (struct tcp_accept_handler_data *) region_alloc(
				server_region,
				sizeof(struct tcp_accept_handler_data));
			data->nsd = nsd;
			data->socket = &nsd->tcp[i];
			data->tcp_accept_handler_count = nsd->ifs;
			data->tcp_accept_handlers = tcp_accept_handlers;

			handler = &tcp_accept_handlers[i];
			handler->fd = nsd->tcp[i].s;
			handler->timeout = NULL;
			handler->user_data = data;
			handler->event_types = NETIO_EVENT_READ | NETIO_EVENT_ACCEPT;
			handler->event_handler = handle_tcp_accept;
			netio_add_handler(netio, handler);
		}
	}

	/* The main loop... */
	while ((mode = nsd->mode) != NSD_QUIT) {
		if(mode == NSD_RUN) nsd->mode = mode = server_signal_mode(nsd);

		/* Do we need to do the statistics... */
		if (mode == NSD_STATS) {
#ifdef BIND8_STATS
			/* Dump the statistics */
			bind8_stats(nsd);
#else /* !BIND8_STATS */
			log_msg(LOG_NOTICE, "Statistics support not enabled at compile time.");
#endif /* BIND8_STATS */

			nsd->mode = NSD_RUN;
		}
		else if (mode == NSD_REAP_CHILDREN) {
			/* got signal, notify parent. parent reaps terminated children. */
			if (nsd->this_child->parent_fd != -1) {
				sig_atomic_t parent_notify = NSD_REAP_CHILDREN;
				if (write(nsd->this_child->parent_fd,
				    &parent_notify,
				    sizeof(parent_notify)) == -1)
				{
					log_msg(LOG_ERR, "problems sending command from %d to parent: %s",
						(int) nsd->this_child->pid, strerror(errno));
				}
			} else /* no parent, so reap 'em */
				while (waitpid(0, NULL, WNOHANG) > 0) ;
			nsd->mode = NSD_RUN;
		}
		else if(mode == NSD_RUN) {
			/* Wait for a query... */
			if (netio_dispatch(netio, NULL, NULL) == -1) {
				if (errno != EINTR) {
					log_msg(LOG_ERR, "netio_dispatch failed: %s", strerror(errno));
					break;
				}
			}
		} else if(mode == NSD_QUIT) {
			/* ignore here, quit */
		} else {
			log_msg(LOG_ERR, "mode bad value %d, back to service.",
				mode);
			nsd->mode = NSD_RUN;
		}
	}

#ifdef	BIND8_STATS
	bind8_stats(nsd);
#endif /* BIND8_STATS */

	namedb_fd_close(nsd->db);
	region_destroy(server_region);
	server_shutdown(nsd);
}
/**
 * Start dns handler.
 *
 */
void
dnshandler_start(dnshandler_type* dnshandler)
{
    size_t i = 0;
    engine_type* engine = NULL;
    netio_handler_type* tcp_accept_handlers = NULL;

    ods_log_assert(dnshandler);
    ods_log_assert(dnshandler->engine);
    ods_log_debug("[%s] start", dnsh_str);
    /* udp */
    for (i=0; i < dnshandler->interfaces->count; i++) {
        struct udp_data* data = NULL;
        netio_handler_type* handler = NULL;
        data = (struct udp_data*) allocator_alloc(dnshandler->allocator,
            sizeof(struct udp_data));
        if (!data) {
            ods_log_error("[%s] unable to start: allocator_alloc() "
                "failed", dnsh_str);
            dnshandler->thread_id = 0;
            engine->need_to_exit = 1;
            break;
        }
        data->query = dnshandler->query;
        data->engine = dnshandler->engine;
        data->socket = &dnshandler->socklist->udp[i];
        handler = (netio_handler_type*) allocator_alloc(
            dnshandler->allocator, sizeof(netio_handler_type));
        if (!handler) {
            ods_log_error("[%s] unable to start: allocator_alloc() "
                "failed", dnsh_str);
            allocator_deallocate(dnshandler->allocator, (void*)data);
            dnshandler->thread_id = 0;
            engine->need_to_exit = 1;
            break;
        }
        handler->fd = dnshandler->socklist->udp[i].s;
        handler->timeout = NULL;
        handler->user_data = data;
        handler->event_types = NETIO_EVENT_READ;
        handler->event_handler = sock_handle_udp;
        ods_log_debug("[%s] add udp network handler fd %u", dnsh_str,
            (unsigned) handler->fd);
        netio_add_handler(dnshandler->netio, handler);
    }
    /* tcp */
    tcp_accept_handlers = (netio_handler_type*) allocator_alloc(
        dnshandler->allocator,
        dnshandler->interfaces->count * sizeof(netio_handler_type));
    for (i=0; i < dnshandler->interfaces->count; i++) {
        struct tcp_accept_data* data = NULL;
        netio_handler_type* handler = NULL;
        data = (struct tcp_accept_data*) allocator_alloc(
            dnshandler->allocator, sizeof(struct tcp_accept_data));
        if (!data) {
            ods_log_error("[%s] unable to start: allocator_alloc() "
                "failed", dnsh_str);
            dnshandler->thread_id = 0;
            engine->need_to_exit = 1;
            return;
        }
        data->engine = dnshandler->engine;
        data->socket = &dnshandler->socklist->udp[i];
        data->tcp_accept_handler_count = dnshandler->interfaces->count;
        data->tcp_accept_handlers = tcp_accept_handlers;
        handler = &tcp_accept_handlers[i];
        handler->fd = dnshandler->socklist->tcp[i].s;
        handler->timeout = NULL;
        handler->user_data = data;
        handler->event_types = NETIO_EVENT_READ;
        handler->event_handler = sock_handle_tcp_accept;
        ods_log_debug("[%s] add tcp network handler fd %u", dnsh_str,
            (unsigned) handler->fd);
        netio_add_handler(dnshandler->netio, handler);
    }
    /* service */
    while (dnshandler->need_to_exit == 0) {
        ods_log_deeebug("[%s] netio dispatch", dnsh_str);
        if (netio_dispatch(dnshandler->netio, NULL, NULL) == -1) {
            if (errno != EINTR) {
                ods_log_error("[%s] unable to dispatch netio: %s", dnsh_str,
                    strerror(errno));
                break;
            }
        }
    }
    /* shutdown */
    ods_log_debug("[%s] shutdown", dnsh_str);
    for (i=0; i < dnshandler->interfaces->count; i++) {
        if (dnshandler->socklist->udp[i].s != -1) {
            close(dnshandler->socklist->udp[i].s);
            freeaddrinfo((void*)dnshandler->socklist->udp[i].addr);
        }
        if (dnshandler->socklist->tcp[i].s != -1) {
            close(dnshandler->socklist->tcp[i].s);
            freeaddrinfo((void*)dnshandler->socklist->tcp[i].addr);
        }
    }
    return;
}