⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 2 页
字号:
		case SIGUSR1: got_sigusr1 = 1; break;		case SIGUSR2: got_sigusr2 = 1; break;		case SIGALRM: got_sigalrm = 1; break;		case SIGCHLD: got_sigchld = 1; break;		default: break;	}}/*--- signal_handler() --------------------------------------------------------------------------*//**************************************************************************************************	NAMED_CLEANUP**************************************************************************************************/voidnamed_cleanup(int signo){	register TASK *t;	shutting_down = 1;	server_status();	switch (signo)	{		case SIGINT:  Notice(_("interrupted")); break;		case SIGQUIT: Notice(_("quit")); break;		case SIGTERM: Notice(_("terminated")); break;		default: Notice(_("exiting due to signal %d"), signo); break;	}	if (is_master)	{		int n, status;		for (n = 0; n < multicpu - 1; n++)		{			kill(pidlist[n], signo);			waitpid(pidlist[n], &status, 0);		}	}	/* Close any TCP connections */	for (t = Tasks->head; t; t = Tasks->head)	{		if (t->protocol == SOCK_STREAM && t->fd != -1)			sockclose(t->fd);		dequeue(Tasks, t);	}	/* Close listening FDs */	if (is_master)	{		register int n;		for (n = 0; n < num_tcp4_fd; n++)			sockclose(tcp4_fd[n]);		for (n = 0; n < num_udp4_fd; n++)			sockclose(udp4_fd[n]);#if HAVE_IPV6		for (n = 0; n < num_tcp6_fd; n++)			sockclose(tcp6_fd[n]);		for (n = 0; n < num_udp6_fd; n++)			sockclose(udp6_fd[n]);#endif	/* HAVE_IPV6 */	}	cache_empty(ZoneCache);#if USE_NEGATIVE_CACHE	cache_empty(NegativeCache);#endif	cache_empty(ReplyCache);	unlink(conf_get(&Conf, "pidfile", NULL));	exit(EXIT_SUCCESS);}/*--- named_cleanup() ---------------------------------------------------------------------------*//**************************************************************************************************	CHILD_CLEANUP**************************************************************************************************/static voidchild_cleanup(int signo){	int n, status, pid;	got_sigchld = 0;	if (shutting_down)		return;	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)	{		if (!WIFEXITED(status))		{#ifdef WCOREDUMP			if (WIFSIGNALED(status))				Warnx("pid %d exited due to signal %d%s", pid, WTERMSIG(status),						WCOREDUMP(status) ? " (core dumped)" : "");			else				Warnx("pid %d exited with status %d%s", pid, WEXITSTATUS(status),						WCOREDUMP(status) ? " (core dumped)" : "");#else			if (WIFSIGNALED(status))				Warnx("pid %d exited due to signal %d", pid, WTERMSIG(status));			else				Warnx("pid %d exited with status %d", pid, WEXITSTATUS(status));#endif		}		else		{#if DEBUG_ENABLED			Debug("child pid %d exited successfully", pid);#endif		}		/* If the dead child is part of pidlist (for multicpu), restart */		for (n = 0; n < multicpu - 1; n++)			if (pid == pidlist[n])				Errx("pid %d died", pid);	}}/*--- child_cleanup() ---------------------------------------------------------------------------*//**************************************************************************************************	SPAWN_MULTICPU**************************************************************************************************/static voidspawn_multicpu(void){	int n;	is_master = 1;	if (!(pidlist = malloc(multicpu * sizeof(pid_t))))		Err(_("out of memory"));	for (n = 1; n < multicpu; n++)	{		pid_t pid;		if ((pid = fork()) < 0)			Err("fork");		if (pid > 0)		{			pidlist[n-1] = pid;		}		else		{			is_master = 0;			db_connect();			return;		}	}}/*--- spawn_multicpu() --------------------------------------------------------------------------*//**************************************************************************************************	_INIT_RLIMIT	Sets a single resource limit and optionally prints out a notification message; called by	init_rlimits().**************************************************************************************************/static void_init_rlimit(int resource, const char *desc, long long set){	struct rlimit rl;	if (getrlimit(resource, &rl) < 0)		Err("getrlimit");	if (set == -1)		rl.rlim_cur = rl.rlim_max;	else if (set > 0 && rl.rlim_cur < set)		rl.rlim_cur = set;	setrlimit(resource, &rl);	if (getrlimit(resource, &rl) < 0)		Err("getrlimit");}/*--- _init_rlimit() ----------------------------------------------------------------------------*//**************************************************************************************************	INIT_RLIMITS	Max out allowed resource limits.**************************************************************************************************/static voidinit_rlimits(void){#ifdef RLIMIT_CPU	_init_rlimit(RLIMIT_CPU, "RLIMIT_CPU", 0);#endif#ifdef RLIMIT_FSIZE	_init_rlimit(RLIMIT_FSIZE, "RLIMIT_FSIZE", 0);#endif#ifdef RLIMIT_DATA	_init_rlimit(RLIMIT_DATA, "RLIMIT_DATA", 0);#endif#ifdef RLIMIT_STACK	_init_rlimit(RLIMIT_STACK, "RLIMIT_STACK", -1);#endif#ifdef RLIMIT_CORE	_init_rlimit(RLIMIT_CORE, "RLIMIT_CORE", -1);#endif#ifdef RLIMIT_RSS	_init_rlimit(RLIMIT_RSS, "RLIMIT_RSS", 0);#endif#ifdef RLIMIT_NPROC	_init_rlimit(RLIMIT_NPROC, "RLIMIT_NPROC", -1);#endif#ifdef RLIMIT_NOFILE	_init_rlimit(RLIMIT_NOFILE, "RLIMIT_NOFILE", -1);#endif#ifdef RLIMIT_MEMLOCK	_init_rlimit(RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK", 0);#endif#ifdef RLIMIT_AS	_init_rlimit(RLIMIT_AS, "RLIMIT_AS", 0);#endif}/*--- init_rlimits() ----------------------------------------------------------------------------*//**************************************************************************************************	CLOSE_TIMED_OUT_TASK	Check for and dequeue timed out tasks.**************************************************************************************************/static inline voidclose_timed_out_task(register TASK *t){	Status.timedout++;	t->reason = ERR_TIMEOUT;	t->hdr.rcode = DNS_RCODE_SERVFAIL;	/* Close TCP connection */	if (t->protocol == SOCK_STREAM)		sockclose(t->fd);	dequeue(Tasks, t);}/*--- close_timed_out_task() --------------------------------------------------------------------*//**************************************************************************************************	MAIN**************************************************************************************************/intmain(int argc, char **argv){	register int n;	int plain_maxfd = 0, maxfd, rv, want_timeout = 0;	fd_set rfd, start_rfd, wfd;	struct timeval tv;	register TASK	*t, *next_task;	setlocale(LC_ALL, "");										/* Internationalization */	bindtextdomain(PACKAGE, LOCALEDIR);	textdomain(PACKAGE);	cmdline(argc, argv);											/* Process command line */	/* Set hostname */	gethostname(hostname, sizeof(hostname)-1);	set_sighandler(SIGHUP,	signal_handler);	set_sighandler(SIGUSR1, signal_handler);	set_sighandler(SIGUSR2, signal_handler);	set_sighandler(SIGALRM, signal_handler);	set_sighandler(SIGCHLD, child_cleanup);	set_sighandler(SIGINT,  named_cleanup);	set_sighandler(SIGQUIT, named_cleanup);	set_sighandler(SIGABRT, named_cleanup);	set_sighandler(SIGTERM, named_cleanup);	if (opt_daemon)												/* Move into background if requested */		become_daemon();	conf_set_logging();	db_connect();	create_pidfile();												/* Create PID file */	Tasks = queue_init();										/* Initialize task queue */	cache_init();													/* Initialize cache */	/* Start listening fd's */	create_listeners();	time(&Status.start_time);	/* Spawn a process for each CPU, if multicpu > 1 */	if ((multicpu = atoi(conf_get(&Conf, "multicpu", NULL))) > 1)		spawn_multicpu();	if (run_as_root)	{		init_rlimits();		chdir("/tmp");		Notice("%s", _("WARNING: running with superuser permissions (cwd=/tmp)"));	}	if (!run_as_root)	{#if PROFILING		/* If profiling, change to a dir that a user without perms can likely write profiling data to */		chdir("/tmp");#endif		/* Drop permissions */		if (getgid() == 0 && setgid(perms_gid))			Err(_("error setting group ID to %u"), (unsigned int)perms_gid);		if (getuid() == 0 && setuid(perms_uid))			Err(_("error setting user ID to %u"), (unsigned int)perms_uid);		if (!getgid() || !getuid())			Errx(_("refusing to run as superuser"));		check_config_file_perms();	}	FD_ZERO(&start_rfd);	for (n = 0; n < num_udp4_fd; n++)	{		FD_SET(udp4_fd[n], &start_rfd);		if (udp4_fd[n] > plain_maxfd)			plain_maxfd = udp4_fd[n];	}	for (n = 0; n < num_tcp4_fd; n++)	{		FD_SET(tcp4_fd[n], &start_rfd);		if (tcp4_fd[n] > plain_maxfd)			plain_maxfd = tcp4_fd[n];	}#if HAVE_IPV6	for (n = 0; n < num_udp6_fd; n++)	{		FD_SET(udp6_fd[n], &start_rfd);		if (udp6_fd[n] > plain_maxfd)			plain_maxfd = udp6_fd[n];	}	for (n = 0; n < num_tcp6_fd; n++)	{		FD_SET(tcp6_fd[n], &start_rfd);		if (tcp6_fd[n] > plain_maxfd)			plain_maxfd = tcp6_fd[n];	}#endif	periodic_task(SIGALRM);										/* Initialize alarm state */	/* Main loop: Read connections and process queue */	for (;;)	{		/* Handle signals */		if (got_sighup) sighup(SIGHUP);		if (got_sigusr1) sigusr1(SIGUSR1);		if (got_sigusr2) sigusr2(SIGUSR2);		if (got_sigalrm) periodic_task(SIGUSR1);		if (got_sigchld) child_cleanup(SIGCHLD);		memcpy(&rfd, &start_rfd, sizeof(rfd));		maxfd = plain_maxfd;		FD_ZERO(&wfd);		/* Add TCP requests to fd set */		if (num_tcp4_fd#if HAVE_IPV6			 || num_tcp6_fd#endif			 )			for (want_timeout = 0, t = Tasks->head; t; t = t->next)			{				if ((t->protocol == SOCK_STREAM) && (t->fd >= 0))				{					want_timeout = 10000;					switch (t->status)					{						case NEED_READ:							FD_SET(t->fd, &rfd);							if (t->fd > maxfd)								maxfd = t->fd;							break;						case NEED_WRITE:							FD_SET(t->fd, &wfd);							if (t->fd > maxfd)								maxfd = t->fd;							break;						default:							break;					}				}			}		tv.tv_sec = 0;		tv.tv_usec = want_timeout ? want_timeout : 10000;		rv = select(maxfd+1, &rfd, &wfd, NULL, &tv);		time(&current_time);		if (rv < 0)		{			if (errno == EINTR)				continue;			Err("select");		}		if (rv > 0)		{			/* Check incoming connections */			for (n = 0; n < num_tcp4_fd; n++)				if (FD_ISSET(tcp4_fd[n], &rfd))					if (accept_tcp_query(tcp4_fd[n], AF_INET) < 0)						continue;			for (n = 0; n < num_udp4_fd; n++)				if (FD_ISSET(udp4_fd[n], &rfd))					if (read_udp_query(udp4_fd[n], AF_INET) < 0)						continue;#if HAVE_IPV6			for (n = 0; n < num_tcp6_fd; n++)				if (FD_ISSET(tcp6_fd[n], &rfd))					if (accept_tcp_query(tcp6_fd[n], AF_INET6) < 0)						continue;			for (n = 0; n < num_udp6_fd; n++)				if (FD_ISSET(udp6_fd[n], &rfd))					if (read_udp_query(udp6_fd[n], AF_INET6) < 0)						continue;#endif		}		/* Process tasks */		for (t = Tasks->head; t; t = next_task)		{			next_task = t->next;			if (current_time > t->timeout)				close_timed_out_task(t);			else if (t->protocol == SOCK_DGRAM)				task_process(t);			else if (t->protocol == SOCK_STREAM && t->status == NEED_READ && FD_ISSET(t->fd, &rfd))				task_process(t);			else if (t->protocol == SOCK_STREAM && t->status == NEED_WRITE && FD_ISSET(t->fd, &wfd))				task_process(t);		}	}	return (0);}/*--- main() ------------------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -