Exemple #1
0
/* Create a new NetIO descriptor with TCP_SER method */
netio_desc_t *netio_desc_create_tcp_ser(char *nio_name,char *port)
{
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   if (netio_tcp_ser_create(&nio->u.nid,port) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   nio->type = NETIO_TYPE_TCP_SER;
   nio->send = (void *)netio_tcp_send;
   nio->recv = (void *)netio_tcp_recv;
   nio->free = (void *)netio_tcp_free;
   nio->dptr = &nio->u.nid;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #2
0
/* Create a new NetIO descriptor with VDE method */
netio_desc_t *netio_desc_create_vde(char *nio_name,char *control,char *local)
{
   netio_vde_desc_t *nvd;
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   nvd = &nio->u.nvd;

   if (netio_vde_create(nvd,control,local) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   nio->type     = NETIO_TYPE_VDE;
   nio->send     = (void *)netio_vde_send;
   nio->recv     = (void *)netio_vde_recv;
   nio->free     = (void *)netio_vde_free;
   nio->save_cfg = netio_vde_save_cfg;
   nio->dptr     = &nio->u.nvd;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #3
0
/* Create a new NetIO descriptor with TAP method */
netio_desc_t *netio_desc_create_tap(char *nio_name,char *tap_name)
{
   netio_tap_desc_t *ntd;
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   ntd = &nio->u.ntd;

   if (netio_tap_create(ntd,tap_name) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   nio->type     = NETIO_TYPE_TAP;
   nio->send     = (void *)netio_tap_send;
   nio->recv     = (void *)netio_tap_recv;
   nio->free     = (void *)netio_tap_free;
   nio->save_cfg = netio_tap_save_cfg;
   nio->dptr     = &nio->u.ntd;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #4
0
/* Create a new NetIO descriptor with FIFO method */
netio_desc_t *netio_desc_create_fifo(char *nio_name)
{
   netio_fifo_desc_t *nfd;
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   nfd = &nio->u.nfd;
   pthread_mutex_init(&nfd->lock,NULL);
   pthread_mutex_init(&nfd->endpoint_lock,NULL);
   pthread_cond_init(&nfd->cond,NULL);

   nio->type = NETIO_TYPE_FIFO;
   nio->send = (void *)netio_fifo_send;
   nio->recv = (void *)netio_fifo_recv;
   nio->free = (void *)netio_fifo_free;
   nio->dptr = nfd;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #5
0
/* Create a new NetIO descriptor with UNIX method */
netio_desc_t *netio_desc_create_unix(char *nio_name,char *local,char *remote)
{
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   if (netio_unix_create(&nio->u.nud,local,remote) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   nio->type     = NETIO_TYPE_UNIX;
   nio->send     = (void *)netio_unix_send;
   nio->recv     = (void *)netio_unix_recv;
   nio->free     = (void *)netio_unix_free;
   nio->save_cfg = netio_unix_save_cfg;
   nio->dptr     = &nio->u.nud;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #6
0
/**
 * Create zone transfer handler.
 *
 */
xfrhandler_type*
xfrhandler_create()
{
    xfrhandler_type* xfrh = NULL;
    CHECKALLOC(xfrh = (xfrhandler_type*) malloc(sizeof(xfrhandler_type)));
    xfrh->engine = NULL;
    xfrh->packet = NULL;
    xfrh->netio = NULL;
    xfrh->tcp_set = NULL;
    xfrh->tcp_waiting_first = NULL;
    xfrh->udp_waiting_first = NULL;
    xfrh->udp_waiting_last = NULL;
    xfrh->udp_use_num = 0;
    xfrh->start_time = 0;
    xfrh->current_time = 0;
    xfrh->got_time = 0;
    xfrh->need_to_exit = 0;
    xfrh->started = 0;
    /* notify */
    xfrh->notify_waiting_first = NULL;
    xfrh->notify_waiting_last = NULL;
    xfrh->notify_udp_num = 0;
    /* setup */
    xfrh->netio = netio_create();
    if (!xfrh->netio) {
        ods_log_error("[%s] unable to create xfrhandler: "
            "netio_create() failed", xfrh_str);
        xfrhandler_cleanup(xfrh);
        return NULL;
    }
    xfrh->packet = buffer_create(PACKET_BUFFER_SIZE);
    if (!xfrh->packet) {
        ods_log_error("[%s] unable to create xfrhandler: "
            "buffer_create() failed", xfrh_str);
        xfrhandler_cleanup(xfrh);
        return NULL;
    }
    xfrh->tcp_set = tcp_set_create();
    if (!xfrh->tcp_set) {
        ods_log_error("[%s] unable to create xfrhandler: "
            "tcp_set_create() failed", xfrh_str);
        xfrhandler_cleanup(xfrh);
        return NULL;
    }
    xfrh->dnshandler.fd = -1;
    xfrh->dnshandler.user_data = (void*) xfrh;
    xfrh->dnshandler.timeout = 0;
    xfrh->dnshandler.event_types = NETIO_EVENT_READ;
    xfrh->dnshandler.event_handler = xfrhandler_handle_dns;
    xfrh->dnshandler.free_handler = 0;
    return xfrh;
}
/**
 * Create dns handler.
 *
 */
dnshandler_type*
dnshandler_create(allocator_type* allocator, listener_type* interfaces)
{
    dnshandler_type* dnsh = NULL;
    if (!allocator || !interfaces || interfaces->count <= 0) {
        return NULL;
    }
    dnsh = (dnshandler_type*) allocator_alloc(allocator,
        sizeof(dnshandler_type));
    if (!dnsh) {
        ods_log_error("[%s] unable to create dnshandler: "
            "allocator_alloc() failed", dnsh_str);
        return NULL;
    }
    dnsh->allocator = allocator;
    dnsh->need_to_exit = 0;
    dnsh->engine = NULL;
    dnsh->interfaces = interfaces;
    dnsh->socklist = NULL;
    dnsh->netio = NULL;
    dnsh->query = NULL;
    /* setup */
    dnsh->socklist = (socklist_type*) allocator_alloc(allocator,
        sizeof(socklist_type));
    if (!dnsh->socklist) {
        ods_log_error("[%s] unable to create socklist: "
            "allocator_alloc() failed", dnsh_str);
        dnshandler_cleanup(dnsh);
        return NULL;
    }
    dnsh->netio = netio_create(allocator);
    if (!dnsh->netio) {
        ods_log_error("[%s] unable to create dnshandler: "
            "netio_create() failed", dnsh_str);
        dnshandler_cleanup(dnsh);
        return NULL;
    }
    dnsh->query = query_create();
    if (!dnsh->query) {
        ods_log_error("[%s] unable to create dnshandler: "
            "query_create() failed", dnsh_str);
        dnshandler_cleanup(dnsh);
        return NULL;
    }
    dnsh->xfrhandler.fd = -1;
    dnsh->xfrhandler.user_data = (void*) dnsh;
    dnsh->xfrhandler.timeout = 0;
    dnsh->xfrhandler.event_types = NETIO_EVENT_READ;
    dnsh->xfrhandler.event_handler = dnshandler_handle_xfr;
    return dnsh;
}
Exemple #8
0
/* Create a new NetIO descriptor with NULL method */
netio_desc_t *netio_desc_create_null(char *nio_name)
{
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   nio->type     = NETIO_TYPE_NULL;
   nio->send     = (void *)netio_null_send;
   nio->recv     = (void *)netio_null_recv;
   nio->save_cfg = netio_null_save_cfg;
   nio->dptr     = NULL;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #9
0
/* Create a new NetIO descriptor with raw Ethernet method */
netio_desc_t *netio_desc_create_lnxeth(char *nio_name,char *dev_name)
{
   netio_lnxeth_desc_t *nled;
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   nled = &nio->u.nled;

   if (strlen(dev_name) >= NETIO_DEV_MAXLEN) {
      fprintf(stderr,"netio_desc_create_lnxeth: bad Ethernet device string "
              "specified.\n");
      netio_free(nio,NULL);
      return NULL;
   }

   strcpy(nled->dev_name,dev_name);

   nled->fd = lnx_eth_init_socket(dev_name);
   nled->dev_id = lnx_eth_get_dev_index(dev_name);

   if (nled->fd < 0) {
      netio_free(nio,NULL);
      return NULL;
   }

   nio->type     = NETIO_TYPE_LINUX_ETH;
   nio->send     = (void *)netio_lnxeth_send;
   nio->recv     = (void *)netio_lnxeth_recv;
   nio->free     = (void *)netio_lnxeth_free;
   nio->save_cfg = netio_lnxeth_save_cfg;
   nio->dptr     = &nio->u.nled;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #10
0
/* Create a new NetIO descriptor with UDP method */
netio_desc_t *netio_desc_create_udp(char *nio_name,int local_port,
                                    char *remote_host,int remote_port)
{
   netio_inet_desc_t *nid;
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;

   nid = &nio->u.nid;
   nid->local_port  = local_port;
   nid->remote_port = remote_port;

   if (!(nid->remote_host = strdup(remote_host))) {
      fprintf(stderr,"netio_desc_create_udp: insufficient memory\n");
      goto error;
   }

   if ((nid->fd = udp_connect(local_port,remote_host,remote_port)) < 0) {
      fprintf(stderr,"netio_desc_create_udp: unable to connect to %s:%d\n",
              remote_host,remote_port);
      goto error;
   }

   nio->type     = NETIO_TYPE_UDP;
   nio->send     = (void *)netio_udp_send;
   nio->recv     = (void *)netio_udp_recv;
   nio->free     = (void *)netio_udp_free;
   nio->save_cfg = netio_udp_save_cfg;
   nio->dptr     = &nio->u.nid;

   if (netio_record(nio) == -1)
      goto error;

   return nio;

 error:
   netio_free(nio,NULL);
   return NULL;
}
Exemple #11
0
/* Create a new NetIO descriptor with auto UDP method */
netio_desc_t *netio_desc_create_udp_auto(char *nio_name,char *local_addr,
                                         int port_start,int port_end)
{
   netio_inet_desc_t *nid;
   netio_desc_t *nio;
   
   if (!(nio = netio_create(nio_name)))
      return NULL;
   
   nid = &nio->u.nid;
   nid->local_port  = -1;
   nid->remote_host = NULL;
   nid->remote_port = -1;
      
   if ((nid->fd = udp_listen_range(local_addr,port_start,port_end,
                                   &nid->local_port)) < 0) 
   {
      fprintf(stderr,
              "netio_desc_create_udp_auto: unable to create socket "
              "(addr=%s,port_start=%d,port_end=%d)\n",
              local_addr,port_start,port_end);
      goto error;
   }
   
   nio->type     = NETIO_TYPE_UDP_AUTO;
   nio->send     = (void *)netio_udp_send;
   nio->recv     = (void *)netio_udp_recv;
   nio->free     = (void *)netio_udp_free;
   nio->save_cfg = netio_udp_save_cfg;
   nio->dptr     = &nio->u.nid;
   
   if (netio_record(nio) == -1)
      goto error;
   
   return nio;
   
error:
   netio_free(nio,NULL);
   return NULL;
}
Exemple #12
0
/* Create a new NetIO descriptor with generic raw Ethernet method */
netio_desc_t *netio_desc_create_geneth(char *nio_name,char *dev_name)
{
   netio_geneth_desc_t *nged;
   netio_desc_t *nio;
      
   if (!(nio = netio_create(nio_name)))
      return NULL;

   nged = &nio->u.nged;

   if (strlen(dev_name) >= NETIO_DEV_MAXLEN) {
      fprintf(stderr,"netio_desc_create_geneth: bad Ethernet device string "
              "specified.\n");
      netio_free(nio,NULL);
      return NULL;
   }

   strcpy(nged->dev_name,dev_name);

   if (!(nged->pcap_dev = gen_eth_init(dev_name))) {
      netio_free(nio,NULL);
      return NULL;
   }

   nio->type     = NETIO_TYPE_GEN_ETH;
   nio->send     = (void *)netio_geneth_send;
   nio->recv     = (void *)netio_geneth_recv;
   nio->free     = (void *)netio_geneth_free;
   nio->save_cfg = netio_geneth_save_cfg;
   nio->dptr     = &nio->u.nged;

   if (netio_record(nio) == -1) {
      netio_free(nio,NULL);
      return NULL;
   }

   return nio;
}
Exemple #13
0
void
xfrd_init(int socket, struct nsd* nsd)
{
	region_type* region;

	assert(xfrd == 0);
	/* to setup signalhandling */
	nsd->server_kind = NSD_SERVER_BOTH;

	region = region_create(xalloc, free);
	xfrd = (xfrd_state_t*)region_alloc(region, sizeof(xfrd_state_t));
	memset(xfrd, 0, sizeof(xfrd_state_t));
	xfrd->region = region;
	xfrd->xfrd_start_time = time(0);
	xfrd->netio = netio_create(xfrd->region);
	xfrd->nsd = nsd;
	xfrd->packet = buffer_create(xfrd->region, QIOBUFSZ);
	xfrd->udp_waiting_first = NULL;
	xfrd->udp_waiting_last = NULL;
	xfrd->udp_use_num = 0;
	xfrd->ipc_pass = buffer_create(xfrd->region, QIOBUFSZ);
	xfrd->parent_soa_info_pass = 0;

	/* add the handlers already, because this involves allocs */
	xfrd->reload_handler.fd = -1;
	xfrd->reload_handler.timeout = NULL;
	xfrd->reload_handler.user_data = xfrd;
	xfrd->reload_handler.event_types = NETIO_EVENT_TIMEOUT;
	xfrd->reload_handler.event_handler = xfrd_handle_reload;
	xfrd->reload_timeout.tv_sec = 0;
	xfrd->reload_cmd_last_sent = xfrd->xfrd_start_time;
	xfrd->can_send_reload = 1;

	xfrd->ipc_send_blocked = 0;
	xfrd->ipc_handler.fd = socket;
	xfrd->ipc_handler.timeout = NULL;
	xfrd->ipc_handler.user_data = xfrd;
	xfrd->ipc_handler.event_types = NETIO_EVENT_READ;
	xfrd->ipc_handler.event_handler = xfrd_handle_ipc;
	xfrd->ipc_conn = xfrd_tcp_create(xfrd->region);
	/* not reading using ipc_conn yet */
	xfrd->ipc_conn->is_reading = 0;
	xfrd->ipc_conn->fd = xfrd->ipc_handler.fd;
	xfrd->ipc_conn_write = xfrd_tcp_create(xfrd->region);
	xfrd->ipc_conn_write->fd = xfrd->ipc_handler.fd;
	xfrd->need_to_send_reload = 0;
	xfrd->sending_zone_state = 0;
	xfrd->dirty_zones = stack_create(xfrd->region,
			nsd_options_num_zones(nsd->options));

	xfrd->notify_waiting_first = NULL;
	xfrd->notify_waiting_last = NULL;
	xfrd->notify_udp_num = 0;

	xfrd->tcp_set = xfrd_tcp_set_create(xfrd->region);
	xfrd->tcp_set->tcp_timeout = nsd->tcp_timeout;
	srandom((unsigned long) getpid() * (unsigned long) time(NULL));

	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd pre-startup"));
	diff_snip_garbage(nsd->db, nsd->options);
	xfrd_init_zones();
	xfrd_free_namedb();
	xfrd_read_state(xfrd);
	xfrd_send_expy_all_zones();

	/* add handlers after zone handlers so they are before them in list */
	netio_add_handler(xfrd->netio, &xfrd->reload_handler);
	netio_add_handler(xfrd->netio, &xfrd->ipc_handler);

	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd startup"));
	xfrd_main();
}
Exemple #14
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);
}