File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / starter / starter.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:43 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /* strongSwan IPsec starter
    2:  * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
    3:  *
    4:  * This program is free software; you can redistribute it and/or modify it
    5:  * under the terms of the GNU General Public License as published by the
    6:  * Free Software Foundation; either version 2 of the License, or (at your
    7:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    8:  *
    9:  * This program is distributed in the hope that it will be useful, but
   10:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   11:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12:  * for more details.
   13:  */
   14: 
   15: #define _GNU_SOURCE
   16: 
   17: #include <sys/select.h>
   18: #include <sys/types.h>
   19: #include <sys/wait.h>
   20: #include <sys/stat.h>
   21: #include <stdlib.h>
   22: #include <stdio.h>
   23: #include <signal.h>
   24: #include <syslog.h>
   25: #include <unistd.h>
   26: #include <sys/time.h>
   27: #include <time.h>
   28: #include <string.h>
   29: #include <errno.h>
   30: #include <fcntl.h>
   31: #include <pwd.h>
   32: #include <grp.h>
   33: #include <pthread.h>
   34: 
   35: #include <library.h>
   36: #include <utils/backtrace.h>
   37: #include <threading/thread.h>
   38: #include <utils/debug.h>
   39: 
   40: #include "confread.h"
   41: #include "files.h"
   42: #include "starterstroke.h"
   43: #include "invokecharon.h"
   44: #include "cmp.h"
   45: 
   46: #ifndef LOG_AUTHPRIV
   47: #define LOG_AUTHPRIV LOG_AUTH
   48: #endif
   49: 
   50: #define CHARON_RESTART_DELAY 5
   51: 
   52: static const char* cmd_default = IPSEC_DIR "/charon";
   53: static const char* pid_file_default = IPSEC_PIDDIR "/charon.pid";
   54: static const char* starter_pid_file_default = IPSEC_PIDDIR "/starter.pid";
   55: 
   56: char *daemon_name = NULL;
   57: char *cmd = NULL;
   58: char *pid_file = NULL;
   59: char *starter_pid_file = NULL;
   60: 
   61: static char *config_file = NULL;
   62: 
   63: /* logging */
   64: static bool log_to_stderr = TRUE;
   65: static bool log_to_syslog = TRUE;
   66: static level_t current_loglevel = 1;
   67: 
   68: /**
   69:  * logging function for scepclient
   70:  */
   71: static void starter_dbg(debug_t group, level_t level, char *fmt, ...)
   72: {
   73: 	char buffer[8192];
   74: 	char *current = buffer, *next;
   75: 	va_list args;
   76: 
   77: 	if (level <= current_loglevel)
   78: 	{
   79: 		if (log_to_stderr)
   80: 		{
   81: 			va_start(args, fmt);
   82: 			vfprintf(stderr, fmt, args);
   83: 			va_end(args);
   84: 			fprintf(stderr, "\n");
   85: 		}
   86: 		if (log_to_syslog)
   87: 		{
   88: 			/* write in memory buffer first */
   89: 			va_start(args, fmt);
   90: 			vsnprintf(buffer, sizeof(buffer), fmt, args);
   91: 			va_end(args);
   92: 
   93: 			/* do a syslog with every line */
   94: 			while (current)
   95: 			{
   96: 				next = strchr(current, '\n');
   97: 				if (next)
   98: 				{
   99: 					*(next++) = '\0';
  100: 				}
  101: 				syslog(LOG_INFO, "%s\n", current);
  102: 				current = next;
  103: 			}
  104: 		}
  105: 	}
  106: }
  107: 
  108: /**
  109:  * Initialize logging to stderr/syslog
  110:  */
  111: static void init_log(const char *program)
  112: {
  113: 	dbg = starter_dbg;
  114: 
  115: 	if (log_to_stderr)
  116: 	{
  117: 		setbuf(stderr, NULL);
  118: 	}
  119: 	if (log_to_syslog)
  120: 	{
  121: 		openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
  122: 	}
  123: }
  124: 
  125: /**
  126:  * Deinitialize logging to syslog
  127:  */
  128: static void close_log()
  129: {
  130: 	if (log_to_syslog)
  131: 	{
  132: 		closelog();
  133: 	}
  134: }
  135: 
  136: /**
  137:  * Return codes defined by Linux Standard Base Core Specification 3.1
  138:  * in section 20.2. Init Script Actions
  139:  */
  140: #define LSB_RC_SUCCESS               0   /* success                          */
  141: #define LSB_RC_FAILURE               1   /* generic or unspecified error     */
  142: #define LSB_RC_INVALID_ARGUMENT      2   /* invalid or excess argument(s)    */
  143: #define LSB_RC_NOT_IMPLEMENTED       3   /* unimplemented feature (reload)   */
  144: #define LSB_RC_NOT_ALLOWED           4   /* user had insufficient privilege  */
  145: #define LSB_RC_NOT_INSTALLED         5   /* program is not installed         */
  146: #define LSB_RC_NOT_CONFIGURED        6   /* program is not configured        */
  147: #define LSB_RC_NOT_RUNNING           7   /* program is not running           */
  148: 
  149: #define FLAG_ACTION_START_PLUTO   0x01
  150: #define FLAG_ACTION_UPDATE        0x02
  151: #define FLAG_ACTION_RELOAD        0x04
  152: #define FLAG_ACTION_QUIT          0x08
  153: #define FLAG_ACTION_LISTEN        0x10
  154: #define FLAG_ACTION_START_CHARON  0x20
  155: 
  156: static unsigned int _action_ = 0;
  157: 
  158: /**
  159:  * Handle signals in the main thread
  160:  */
  161: static void signal_handler(int signal)
  162: {
  163: 	switch (signal)
  164: 	{
  165: 		case SIGCHLD:
  166: 		{
  167: 			int status, exit_status = 0;
  168: 			pid_t pid;
  169: 			char *name = NULL;
  170: 
  171: 			while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
  172: 			{
  173: 				if (pid == starter_charon_pid())
  174: 				{
  175: 					if (asprintf(&name, " (%s)", daemon_name) < 0)
  176: 					{
  177: 						 name = NULL;
  178: 					}
  179: 				}
  180: 				if (WIFSIGNALED(status))
  181: 				{
  182: 					DBG2(DBG_APP, "child %d%s has been killed by sig %d\n",
  183: 						 pid, name?name:"", WTERMSIG(status));
  184: 				}
  185: 				else if (WIFSTOPPED(status))
  186: 				{
  187: 					DBG2(DBG_APP, "child %d%s has been stopped by sig %d\n",
  188: 						 pid, name?name:"", WSTOPSIG(status));
  189: 				}
  190: 				else if (WIFEXITED(status))
  191: 				{
  192: 					exit_status =  WEXITSTATUS(status);
  193: 					if (exit_status >= SS_RC_FIRST && exit_status <= SS_RC_LAST)
  194: 					{
  195: 						_action_ =  FLAG_ACTION_QUIT;
  196: 					}
  197: 					DBG2(DBG_APP, "child %d%s has quit (exit code %d)\n",
  198: 						 pid, name?name:"", exit_status);
  199: 				}
  200: 				else
  201: 				{
  202: 					DBG2(DBG_APP, "child %d%s has quit", pid, name?name:"");
  203: 				}
  204: 				if (pid == starter_charon_pid())
  205: 				{
  206: 					starter_charon_sigchild(pid, exit_status);
  207: 				}
  208: 			}
  209: 
  210: 			if (name)
  211: 			{
  212: 				free(name);
  213: 			}
  214: 		}
  215: 		break;
  216: 
  217: 		case SIGALRM:
  218: 			_action_ |= FLAG_ACTION_START_CHARON;
  219: 			break;
  220: 
  221: 		case SIGHUP:
  222: 			_action_ |= FLAG_ACTION_UPDATE;
  223: 			break;
  224: 
  225: 		case SIGTERM:
  226: 		case SIGQUIT:
  227: 		case SIGINT:
  228: 			_action_ |= FLAG_ACTION_QUIT;
  229: 			break;
  230: 
  231: 		case SIGUSR1:
  232: 			_action_ |= FLAG_ACTION_RELOAD;
  233: 			_action_ |= FLAG_ACTION_UPDATE;
  234: 			break;
  235: 
  236: 		default:
  237: 			DBG1(DBG_APP, "fsig(): unknown signal %d -- investigate", signal);
  238: 			break;
  239: 	}
  240: }
  241: 
  242: /**
  243:  * Handle fatal signals raised by threads
  244:  */
  245: static void fatal_signal_handler(int signal)
  246: {
  247: 	backtrace_t *backtrace;
  248: 
  249: 	DBG1(DBG_APP, "thread %u received %d", thread_current_id(), signal);
  250: 	backtrace = backtrace_create(2);
  251: 	backtrace->log(backtrace, stderr, TRUE);
  252: 	backtrace->destroy(backtrace);
  253: 
  254: 	DBG1(DBG_APP, "killing ourself, received critical signal");
  255: 	abort();
  256: }
  257: 
  258: static bool check_pid(char *file)
  259: {
  260: 	struct stat stb;
  261: 	FILE *pidfile;
  262: 
  263: 	if (stat(file, &stb) == 0)
  264: 	{
  265: 		pidfile = fopen(file, "r");
  266: 		if (pidfile)
  267: 		{
  268: 			char buf[64];
  269: 			pid_t pid = 0;
  270: 			memset(buf, 0, sizeof(buf));
  271: 			if (fread(buf, 1, sizeof(buf), pidfile))
  272: 			{
  273: 				buf[sizeof(buf) - 1] = '\0';
  274: 				pid = atoi(buf);
  275: 			}
  276: 			fclose(pidfile);
  277: 			if (pid && pid != getpid() && kill(pid, 0) == 0)
  278: 			{	/* such a process is running */
  279: 				return TRUE;
  280: 			}
  281: 		}
  282: 		DBG1(DBG_APP, "removing pidfile '%s', process not running", file);
  283: 		unlink(file);
  284: 	}
  285: 	return FALSE;
  286: }
  287: 
  288: /* Set daemon name and adjust command and pid filenames accordingly */
  289: static bool set_daemon_name()
  290: {
  291: 	if (!daemon_name)
  292: 	{
  293: 		daemon_name = "charon";
  294: 	}
  295: 
  296: 	if (asprintf(&cmd, IPSEC_DIR"/%s", daemon_name) < 0)
  297: 	{
  298: 		 cmd = (char*)cmd_default;
  299: 	}
  300: 
  301: 	if (asprintf(&pid_file, IPSEC_PIDDIR"/%s.pid", daemon_name) < 0)
  302: 	{
  303: 		 pid_file = (char*)pid_file_default;
  304: 	}
  305: 
  306: 	if (asprintf(&starter_pid_file, IPSEC_PIDDIR"/starter.%s.pid",
  307: 				 daemon_name) < 0)
  308: 	{
  309: 		 starter_pid_file = (char*)starter_pid_file_default;
  310: 	}
  311: 
  312: 	return TRUE;
  313: }
  314: 
  315: static void cleanup()
  316: {
  317: 	if (cmd != cmd_default)
  318: 	{
  319: 		free(cmd);
  320: 	}
  321: 
  322: 	if (pid_file != pid_file_default)
  323: 	{
  324: 		free(pid_file);
  325: 	}
  326: 
  327: 	if (starter_pid_file != starter_pid_file_default)
  328: 	{
  329: 		free(starter_pid_file);
  330: 	}
  331: }
  332: 
  333: static void usage(char *name)
  334: {
  335: 	fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>]\n"
  336: 			"               [--debug|--debug-more|--debug-all|--nolog]\n"
  337: 			"               [--attach-gdb] [--daemon <name>]\n"
  338: 			"               [--conf <path to ipsec.conf>]\n");
  339: 	exit(LSB_RC_INVALID_ARGUMENT);
  340: }
  341: 
  342: int main (int argc, char **argv)
  343: {
  344: 	starter_config_t *cfg = NULL;
  345: 	starter_config_t *new_cfg;
  346: 	starter_conn_t *conn, *conn2;
  347: 	starter_ca_t *ca, *ca2;
  348: 
  349: 	struct sigaction action;
  350: 	struct stat stb;
  351: 
  352: 	int i;
  353: 	int id = 1;
  354: 	struct timespec ts;
  355: 	unsigned long auto_update = 0;
  356: 	time_t last_reload;
  357: 	bool no_fork = FALSE;
  358: 	bool attach_gdb = FALSE;
  359: 	bool load_warning = FALSE;
  360: 	bool conftest = FALSE;
  361: 
  362: 	library_init(NULL, "starter");
  363: 	atexit(library_deinit);
  364: 
  365: 	/* parse command line */
  366: 	for (i = 1; i < argc; i++)
  367: 	{
  368: 		if (streq(argv[i], "--debug"))
  369: 		{
  370: 			current_loglevel = 2;
  371: 		}
  372: 		else if (streq(argv[i], "--debug-more"))
  373: 		{
  374: 			current_loglevel = 3;
  375: 		}
  376: 		else if (streq(argv[i], "--debug-all"))
  377: 		{
  378: 			current_loglevel = 4;
  379: 		}
  380: 		else if (streq(argv[i], "--nolog"))
  381: 		{
  382: 			current_loglevel = 0;
  383: 		}
  384: 		else if (streq(argv[i], "--nofork"))
  385: 		{
  386: 			no_fork = TRUE;
  387: 		}
  388: 		else if (streq(argv[i], "--attach-gdb"))
  389: 		{
  390: 			no_fork = TRUE;
  391: 			attach_gdb = TRUE;
  392: 		}
  393: 		else if (streq(argv[i], "--auto-update") && i+1 < argc)
  394: 		{
  395: 			auto_update = atoi(argv[++i]);
  396: 			if (!auto_update)
  397: 				usage(argv[0]);
  398: 		}
  399: 		else if (streq(argv[i], "--daemon") && i+1 < argc)
  400: 		{
  401: 			daemon_name = argv[++i];
  402: 		}
  403: 		else if (streq(argv[i], "--conf") && i+1 < argc)
  404: 		{
  405: 			config_file = argv[++i];
  406: 		}
  407: 		else if (streq(argv[i], "--conftest"))
  408: 		{
  409: 			conftest = TRUE;
  410: 		}
  411: 		else
  412: 		{
  413: 			usage(argv[0]);
  414: 		}
  415: 	}
  416: 
  417: 	if (!set_daemon_name())
  418: 	{
  419: 		DBG1(DBG_APP, "unable to set daemon name");
  420: 		exit(LSB_RC_FAILURE);
  421: 	}
  422: 	if (!config_file)
  423: 	{
  424: 		config_file = lib->settings->get_str(lib->settings,
  425: 											 "starter.config_file", CONFIG_FILE);
  426: 	}
  427: 
  428: 	init_log("ipsec_starter");
  429: 
  430: 	if (conftest)
  431: 	{
  432: 		int status = LSB_RC_SUCCESS;
  433: 
  434: 		cfg = confread_load(config_file);
  435: 		if (cfg == NULL || cfg->err > 0)
  436: 		{
  437: 			DBG1(DBG_APP, "config invalid!");
  438: 			status = LSB_RC_INVALID_ARGUMENT;
  439: 		}
  440: 		else
  441: 		{
  442: 			DBG1(DBG_APP, "config OK");
  443: 		}
  444: 		if (cfg)
  445: 		{
  446: 			confread_free(cfg);
  447: 		}
  448: 		cleanup();
  449: 		exit(status);
  450: 	}
  451: 
  452: 	if (stat(cmd, &stb) != 0)
  453: 	{
  454: 		DBG1(DBG_APP, "IKE daemon '%s' not found", cmd);
  455: 		cleanup();
  456: 		exit(LSB_RC_FAILURE);
  457: 	}
  458: 
  459: 	DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...",
  460: 		lib->settings->get_bool(lib->settings,
  461: 			"charon.i_dont_care_about_security_and_use_aggressive_mode_psk",
  462: 				FALSE) ? "weak" : "strong");
  463: 
  464: #ifdef LOAD_WARNING
  465: 	load_warning = TRUE;
  466: #endif
  467: 
  468: 	if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning))
  469: 	{
  470: 		if (lib->settings->get_str(lib->settings, "charon.load", NULL))
  471: 		{
  472: 			DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon.");
  473: 			DBG1(DBG_APP, "!! This is recommended for experts only, see");
  474: 			DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad");
  475: 		}
  476: 	}
  477: 
  478: #ifndef STARTER_ALLOW_NON_ROOT
  479: 	/* verify that we can start */
  480: 	if (getuid() != 0)
  481: 	{
  482: 		DBG1(DBG_APP, "permission denied (must be superuser)");
  483: 		cleanup();
  484: 		exit(LSB_RC_NOT_ALLOWED);
  485: 	}
  486: #endif
  487: 
  488: 	if (check_pid(pid_file))
  489: 	{
  490: 		DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start",
  491: 			 daemon_name, pid_file);
  492: 	}
  493: 	else
  494: 	{
  495: 		_action_ |= FLAG_ACTION_START_CHARON;
  496: 	}
  497: 	if (stat(DEV_RANDOM, &stb) != 0)
  498: 	{
  499: 		DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
  500: 		cleanup();
  501: 		exit(LSB_RC_FAILURE);
  502: 	}
  503: 
  504: 	if (stat(DEV_URANDOM, &stb)!= 0)
  505: 	{
  506: 		DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
  507: 		cleanup();
  508: 		exit(LSB_RC_FAILURE);
  509: 	}
  510: 
  511: 	cfg = confread_load(config_file);
  512: 	if (cfg == NULL || cfg->err > 0)
  513: 	{
  514: 		DBG1(DBG_APP, "unable to start strongSwan -- fatal errors in config");
  515: 		if (cfg)
  516: 		{
  517: 			confread_free(cfg);
  518: 		}
  519: 		cleanup();
  520: 		exit(LSB_RC_INVALID_ARGUMENT);
  521: 	}
  522: 
  523: 	last_reload = time_monotonic(NULL);
  524: 
  525: 	if (check_pid(starter_pid_file))
  526: 	{
  527: 		DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done",
  528: 			 starter_pid_file);
  529: 		confread_free(cfg);
  530: 		cleanup();
  531: 		exit(LSB_RC_SUCCESS);
  532: 	}
  533: 
  534: 	/* fork if we're not debugging stuff */
  535: 	if (!no_fork)
  536: 	{
  537: 		log_to_stderr = FALSE;
  538: 
  539: 		switch (fork())
  540: 		{
  541: 			case 0:
  542: 			{
  543: 				int fnull;
  544: 
  545: 				close_log();
  546: 
  547: 				fnull = open("/dev/null", O_RDWR);
  548: 				if (fnull >= 0)
  549: 				{
  550: 					dup2(fnull, STDIN_FILENO);
  551: 					dup2(fnull, STDOUT_FILENO);
  552: 					dup2(fnull, STDERR_FILENO);
  553: 					close(fnull);
  554: 				}
  555: 
  556: 				setsid();
  557: 				init_log("ipsec_starter");
  558: 			}
  559: 			break;
  560: 			case -1:
  561: 				DBG1(DBG_APP, "can't fork: %s", strerror(errno));
  562: 				break;
  563: 			default:
  564: 				confread_free(cfg);
  565: 				cleanup();
  566: 				exit(LSB_RC_SUCCESS);
  567: 		}
  568: 	}
  569: 
  570: 	/* save pid file in /var/run/starter[.daemon_name].pid */
  571: 	{
  572: 		FILE *fd = fopen(starter_pid_file, "w");
  573: 
  574: 		if (fd)
  575: 		{
  576: 			fprintf(fd, "%u\n", getpid());
  577: 			fclose(fd);
  578: 		}
  579: 	}
  580: 
  581: 	/* we handle these signals only in pselect() */
  582: 	memset(&action, 0, sizeof(action));
  583: 	sigemptyset(&action.sa_mask);
  584: 	sigaddset(&action.sa_mask, SIGHUP);
  585: 	sigaddset(&action.sa_mask, SIGINT);
  586: 	sigaddset(&action.sa_mask, SIGTERM);
  587: 	sigaddset(&action.sa_mask, SIGQUIT);
  588: 	sigaddset(&action.sa_mask, SIGALRM);
  589: 	sigaddset(&action.sa_mask, SIGUSR1);
  590: 	pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
  591: 
  592: 	/* install a handler for fatal signals */
  593: 	action.sa_handler = fatal_signal_handler;
  594: 	sigaction(SIGSEGV, &action, NULL);
  595: 	sigaction(SIGILL, &action, NULL);
  596: 	sigaction(SIGBUS, &action, NULL);
  597: 	action.sa_handler = SIG_IGN;
  598: 	sigaction(SIGPIPE, &action, NULL);
  599: 
  600: 	/* install main signal handler */
  601: 	action.sa_handler = signal_handler;
  602: 	sigaction(SIGHUP, &action, NULL);
  603: 	sigaction(SIGINT, &action, NULL);
  604: 	sigaction(SIGTERM, &action, NULL);
  605: 	sigaction(SIGQUIT, &action, NULL);
  606: 	sigaction(SIGALRM, &action, NULL);
  607: 	sigaction(SIGUSR1, &action, NULL);
  608: 	/* this is not blocked above as we want to receive it asynchronously */
  609: 	sigaction(SIGCHLD, &action, NULL);
  610: 
  611: 	/* empty mask for pselect() call below */
  612: 	sigemptyset(&action.sa_mask);
  613: 
  614: 	for (;;)
  615: 	{
  616: 		/*
  617: 		 * Stop charon (if started) and exit
  618: 		 */
  619: 		if (_action_ & FLAG_ACTION_QUIT)
  620: 		{
  621: 			if (starter_charon_pid())
  622: 			{
  623: 				starter_stop_charon();
  624: 			}
  625: 			confread_free(cfg);
  626: 			unlink(starter_pid_file);
  627: 			cleanup();
  628: 			DBG1(DBG_APP, "ipsec starter stopped");
  629: 			close_log();
  630: 			exit(LSB_RC_SUCCESS);
  631: 		}
  632: 
  633: 		/*
  634: 		 * Delete all connections. Will be added below
  635: 		 */
  636: 		if (_action_ & FLAG_ACTION_RELOAD)
  637: 		{
  638: 			_action_ &= ~FLAG_ACTION_RELOAD;
  639: 			if (starter_charon_pid())
  640: 			{
  641: 				for (conn = cfg->conn_first; conn; conn = conn->next)
  642: 				{
  643: 					if (conn->state == STATE_ADDED)
  644: 					{
  645: 						if (starter_charon_pid())
  646: 						{
  647: 							if (conn->startup == STARTUP_ROUTE)
  648: 							{
  649: 								starter_stroke_unroute_conn(conn);
  650: 							}
  651: 							starter_stroke_del_conn(conn);
  652: 						}
  653: 						conn->state = STATE_TO_ADD;
  654: 					}
  655: 				}
  656: 				for (ca = cfg->ca_first; ca; ca = ca->next)
  657: 				{
  658: 					if (ca->state == STATE_ADDED)
  659: 					{
  660: 						if (starter_charon_pid())
  661: 						{
  662: 							starter_stroke_del_ca(ca);
  663: 						}
  664: 						ca->state = STATE_TO_ADD;
  665: 					}
  666: 				}
  667: 			}
  668: 		}
  669: 
  670: 		/*
  671: 		 * Update configuration
  672: 		 */
  673: 		if (_action_ & FLAG_ACTION_UPDATE)
  674: 		{
  675: 			_action_ &= ~FLAG_ACTION_UPDATE;
  676: 			DBG2(DBG_APP, "Reloading config...");
  677: 			new_cfg = confread_load(config_file);
  678: 
  679: 			if (new_cfg && (new_cfg->err == 0))
  680: 			{
  681: 				/* Switch to new config. New conn will be loaded below */
  682: 
  683: 				/* Look for new connections that are already loaded */
  684: 				for (conn = cfg->conn_first; conn; conn = conn->next)
  685: 				{
  686: 					if (conn->state == STATE_ADDED)
  687: 					{
  688: 						for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
  689: 						{
  690: 							if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
  691: 							{
  692: 								conn->state = STATE_REPLACED;
  693: 								conn2->state = STATE_ADDED;
  694: 								conn2->id = conn->id;
  695: 								break;
  696: 							}
  697: 						}
  698: 					}
  699: 				}
  700: 
  701: 				/* Remove conn sections that have become unused */
  702: 				for (conn = cfg->conn_first; conn; conn = conn->next)
  703: 				{
  704: 					if (conn->state == STATE_ADDED)
  705: 					{
  706: 						if (starter_charon_pid())
  707: 						{
  708: 							if (conn->startup == STARTUP_ROUTE)
  709: 							{
  710: 								starter_stroke_unroute_conn(conn);
  711: 							}
  712: 							starter_stroke_del_conn(conn);
  713: 						}
  714: 					}
  715: 				}
  716: 
  717: 				/* Look for new ca sections that are already loaded */
  718: 				for (ca = cfg->ca_first; ca; ca = ca->next)
  719: 				{
  720: 					if (ca->state == STATE_ADDED)
  721: 					{
  722: 						for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
  723: 						{
  724: 							if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
  725: 							{
  726: 								ca->state = STATE_REPLACED;
  727: 								ca2->state = STATE_ADDED;
  728: 								break;
  729: 							}
  730: 						}
  731: 					}
  732: 				}
  733: 
  734: 				/* Remove ca sections that have become unused */
  735: 				for (ca = cfg->ca_first; ca; ca = ca->next)
  736: 				{
  737: 					if (ca->state == STATE_ADDED)
  738: 					{
  739: 						if (starter_charon_pid())
  740: 						{
  741: 							starter_stroke_del_ca(ca);
  742: 						}
  743: 					}
  744: 				}
  745: 				confread_free(cfg);
  746: 				cfg = new_cfg;
  747: 			}
  748: 			else
  749: 			{
  750: 				DBG1(DBG_APP, "can't reload config file due to errors -- keeping old one");
  751: 				if (new_cfg)
  752: 				{
  753: 					confread_free(new_cfg);
  754: 				}
  755: 			}
  756: 			last_reload = time_monotonic(NULL);
  757: 		}
  758: 
  759: 		/*
  760: 		 * Start daemon
  761: 		 */
  762: 		if (_action_ & FLAG_ACTION_START_CHARON)
  763: 		{
  764: 			_action_ &= ~FLAG_ACTION_START_CHARON;
  765: 			if (!starter_charon_pid())
  766: 			{
  767: 				DBG2(DBG_APP, "Attempting to start %s...", daemon_name);
  768: 				if (starter_start_charon(cfg, no_fork, attach_gdb))
  769: 				{
  770: 					/* schedule next try */
  771: 					alarm(CHARON_RESTART_DELAY);
  772: 				}
  773: 				starter_stroke_configure(cfg);
  774: 			}
  775: 
  776: 			for (ca = cfg->ca_first; ca; ca = ca->next)
  777: 			{
  778: 				if (ca->state == STATE_ADDED)
  779: 				{
  780: 					ca->state = STATE_TO_ADD;
  781: 				}
  782: 			}
  783: 
  784: 			for (conn = cfg->conn_first; conn; conn = conn->next)
  785: 			{
  786: 				if (conn->state == STATE_ADDED)
  787: 				{
  788: 					conn->state = STATE_TO_ADD;
  789: 				}
  790: 			}
  791: 		}
  792: 
  793: 		/*
  794: 		 * Add stale conn and ca sections
  795: 		 */
  796: 		if (starter_charon_pid())
  797: 		{
  798: 			for (ca = cfg->ca_first; ca; ca = ca->next)
  799: 			{
  800: 				if (ca->state == STATE_TO_ADD)
  801: 				{
  802: 					if (starter_charon_pid())
  803: 					{
  804: 						starter_stroke_add_ca(ca);
  805: 					}
  806: 					ca->state = STATE_ADDED;
  807: 				}
  808: 			}
  809: 
  810: 			for (conn = cfg->conn_first; conn; conn = conn->next)
  811: 			{
  812: 				if (conn->state == STATE_TO_ADD)
  813: 				{
  814: 					if (conn->id == 0)
  815: 					{
  816: 						/* affect new unique id */
  817: 						conn->id = id++;
  818: 					}
  819: 					if (starter_charon_pid())
  820: 					{
  821: 						starter_stroke_add_conn(cfg, conn);
  822: 					}
  823: 					conn->state = STATE_ADDED;
  824: 
  825: 					if (conn->startup == STARTUP_START)
  826: 					{
  827: 						if (starter_charon_pid())
  828: 						{
  829: 							starter_stroke_initiate_conn(conn);
  830: 						}
  831: 					}
  832: 					else if (conn->startup == STARTUP_ROUTE)
  833: 					{
  834: 						if (starter_charon_pid())
  835: 						{
  836: 							starter_stroke_route_conn(conn);
  837: 						}
  838: 					}
  839: 				}
  840: 			}
  841: 		}
  842: 
  843: 		/*
  844: 		 * If auto_update activated, when to stop select
  845: 		 */
  846: 		if (auto_update)
  847: 		{
  848: 			time_t now = time_monotonic(NULL);
  849: 
  850: 			ts.tv_sec = (now < last_reload + auto_update) ?
  851: 						(last_reload + auto_update - now) : 0;
  852: 			ts.tv_nsec = 0;
  853: 		}
  854: 
  855: 		/*
  856: 		 * Wait for something to happen
  857: 		 */
  858: 		if (!_action_ &&
  859: 			pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
  860: 					&action.sa_mask) == 0)
  861: 		{
  862: 			/* timeout -> auto_update */
  863: 			_action_ |= FLAG_ACTION_UPDATE;
  864: 		}
  865: 	}
  866: 	exit(LSB_RC_SUCCESS);
  867: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>