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