Ejemplo n.º 1
0
int main(int argc, char * argv[])
{
	server_configuration config;
	bzero(&config, sizeof(config));

	if(!network_subsystem_init())
	{
		fprintf(stderr, "Network subsystem init failed.\n");
		return error_network_subsystem;
	}

	if(!read_configuration(argc, argv, &config))
	{
		fprintf(stderr, PROG_NAME ": configuration error! Exit.\n");
		return error_config;
	}

	if(config.discover)
		interfaces_discover(0);

	if(config.print_header_offsets)
	{
		print_dhcp_header_offsets();
		return 0;
	}

	if(!log_init(config.log_file_name,
			(config.debug_mode ? LOG_DEBUG_FLAG : 0) |
			(config.log_stdout ? LOG_STDOUT_FLAG : 0),
			config.uid)
		)
	{
		fprintf(stderr, "Can't open log file.\n");
		return error_log;
	}

	log_wr(ILOG, "Program " PROG_NAME " " PROG_VERS " " PROG_DESC " started.");

	struct sigaction sig_handler_s;
	sig_handler_s.sa_handler = sig_handler;
	sigemptyset(&sig_handler_s.sa_mask);
	sig_handler_s.sa_flags = 0;

	if(config.daemon)
		daemonize();

	/* Init DHCP cache */
	if(config.cache_ttl && !dhcp_cache_init(config.cache_ttl))
	{
		log_wr(CLOG, "Can't init DHCP cache. Exit.");
		return error_abnormal;
	}

	/* STARTING DATABASE CLIENTS */

	/* Create array of childen threads */
	request_handler_thread_t **handler_threads =
		(request_handler_thread_t **) malloc(sizeof(request_handler_thread_t *) * config.db_clients_count);

	CHECK_VALUE(handler_threads, "Can't allocate memory for array of children threads for connecting to DB.",
		error_memory);

	/* Create DHCP messages queue */
	config.dhcp_queue = dhcp_queue_create("DHCP requests", YES, DEFAULT_QUEUE_MAX_SIZE);
	CHECK_VALUE(config.dhcp_queue, "Can't create DHCP queue.", error_queue_init);

	/* Running DB clients */
	CHECK_VALUE(run_requests_handlers(handler_threads, &config), "", error_run_db_clients);

	/* STARTING DHCP PROCESSES  */
	dhcp_proc_thread_t **dhcp_threads =
		(dhcp_proc_thread_t**) malloc(sizeof(dhcp_proc_thread_t *) * config.if_count);

	CHECK_VALUE(dhcp_threads, "Can't allocate memory for array of children threads for "
			"processing DHCP clients.", error_run_dhcp_procs);

	CHECK_VALUE(run_dhcp_threads(dhcp_threads, &config, handler_threads), "", error_run_dhcp_procs);

	/* Set signal handlers */
    if( sigaction(SIGINT, &sig_handler_s, NULL) ||
        sigaction(SIGTERM, &sig_handler_s, NULL) ||
        sigaction(SIGUSR1, &sig_handler_s, NULL))
    {
		log_wr(CLOG, "Can't set signal handlers: '%s'", strerror(errno));
        return error_abnormal;
    }

#ifndef _WIN32
	if(config.uid)
	{
		log_wr(DLOG, "Set effective and real user ID to %u.", config.uid);
		if(setreuid(config.uid, config.uid))
		{
			log_wr(CLOG, "Can't execute setreuid(%u): '%s'", config.uid, strerror(errno));
			return 0;
		}
	}
	else
		log_wr(WLOG, "Running with uid 0 - it is not safe!!! Use configuration directive 'User' for set uid.");
#endif

	int i;
	for(i = 0; i < config.if_count; ++i)
		pthread_join(dhcp_threads[i]->thread_id, 0);

	log_wr(ILOG, "All DHCP threads finished");

	for(i = 0; i < config.db_clients_count; ++i)
		pthread_join(handler_threads[i]->thread_id, 0);

	log_wr(ILOG, "All DB threads finished.");

	/* Cleaning up */
	/* TODO 30 Need gracefull cleanup database connections and free all allocated memory */
	log_wr(ILOG, "Program exited.");
	log_close();

	return EXIT_SUCCESS;
}
Ejemplo n.º 2
0
int
main(int argc, char *argv[])
{
	struct passwd *pw;
	char *ctlpath = NULL;
	int ch, debug = 0;

	while ((ch = getopt(argc, argv, "ds:")) != -1) {
		switch (ch) {
		case 'd':
			++debug;
			break;
		case 's':
			ctlpath = optarg;
			break;
		default:
			return usage();
		}
	}

	argc -= optind;
	argv += optind;

	if ((pw = getpwnam(UNPRIVILEGED_USER)) == NULL)
		err(1, "there isn't any user called " UNPRIVILEGED_USER);

	if (control_sock == -1)
		control_sock = control_init(ctlpath, pw->pw_uid, pw->pw_gid);
	if (control_sock == -1)
		errx(1, "there isn't any control socket.");

	if ((kernel_rtsock = rtsock_init()) == -1)
		errx(1, "there isn't any routing socket.");

	log_init(debug);
	log_info("starting");

	if (!debug)
		daemon(1, 0);

	drop_privileges(pw);
	set_defaults();

	if (event_init() == NULL)
		fatal("event_init");

	if (interfaces_discover() == -1)
		fatal("discovering interfaces");

	signal_set(&sigevents[0], SIGHUP, unprivileged_signal_handler, NULL);
	signal_set(&sigevents[1], SIGINT, unprivileged_signal_handler, NULL);
	signal_set(&sigevents[2], SIGTERM, unprivileged_signal_handler, NULL);
	signal_set(&sigevents[3], SIGCHLD, unprivileged_signal_handler, NULL);
	signal_set(&sigevents[4], SIGPIPE, unprivileged_signal_handler, NULL);

	for (int i = 0; i < __SIGNAL_HANDLERS__; ++i)
		if (signal_add(&sigevents[i], NULL))
			fatal("signal_add");

	event_set(&events[CONTROL_SOCKET], control_sock, EV_READ | EV_PERSIST,
	    control_accept, NULL);
	event_set(&events[ROUTING_SOCKET], kernel_rtsock, EV_READ | EV_PERSIST,
	    rtsock_dispatch, NULL);
	event_set(&events[PRIVSEP_SOCKET], privsep_sock, EV_READ | EV_PERSIST,
	    unprivileged_dispatch, NULL);

	//for (int i = 0; i < __SOCKETS_ALWAYS_PRESENT__; ++i)
	for (int i = 0; i <= PRIVSEP_SOCKET; ++i)
		if (event_add(events + i, NULL))
			fatal("event_add");

	stats[STATS_DAEMON_STARTED] = time(NULL);
	event_dispatch();

	close(control_sock);
	unsatisfied_purge();
	interfaces_destroy();
	log_info("exitting %s", privileged_exit_code ? "badly" : "gracefully");
	return (privileged_exit_code);
}