pki: Add pki --signcrl man page
[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
422 library_init(NULL);
423 atexit(library_deinit);
424
425 libhydra_init("starter");
426 atexit(libhydra_deinit);
427
428 /* parse command line */
429 for (i = 1; i < argc; i++)
430 {
431 if (streq(argv[i], "--debug"))
432 {
433 current_loglevel = 2;
434 }
435 else if (streq(argv[i], "--debug-more"))
436 {
437 current_loglevel = 3;
438 }
439 else if (streq(argv[i], "--debug-all"))
440 {
441 current_loglevel = 4;
442 }
443 else if (streq(argv[i], "--nolog"))
444 {
445 current_loglevel = 0;
446 }
447 else if (streq(argv[i], "--nofork"))
448 {
449 no_fork = TRUE;
450 }
451 else if (streq(argv[i], "--attach-gdb"))
452 {
453 no_fork = TRUE;
454 attach_gdb = TRUE;
455 }
456 else if (streq(argv[i], "--auto-update") && i+1 < argc)
457 {
458 auto_update = atoi(argv[++i]);
459 if (!auto_update)
460 usage(argv[0]);
461 }
462 else if (streq(argv[i], "--daemon") && i+1 < argc)
463 {
464 daemon_name = argv[++i];
465 }
466 else if (streq(argv[i], "--conf") && i+1 < argc)
467 {
468 config_file = argv[++i];
469 }
470 else
471 {
472 usage(argv[0]);
473 }
474 }
475
476 if (!set_daemon_name())
477 {
478 DBG1(DBG_APP, "unable to set daemon name");
479 exit(LSB_RC_FAILURE);
480 }
481 if (!config_file)
482 {
483 config_file = CONFIG_FILE;
484 }
485
486 init_log("ipsec_starter");
487
488 DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...",
489 lib->settings->get_bool(lib->settings,
490 "charon.i_dont_care_about_security_and_use_aggressive_mode_psk",
491 FALSE) ? "weak" : "strong");
492
493 #ifdef LOAD_WARNING
494 load_warning = TRUE;
495 #endif
496
497 if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning))
498 {
499 if (lib->settings->get_str(lib->settings, "charon.load", NULL))
500 {
501 DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon.");
502 DBG1(DBG_APP, "!! This is recommended for experts only, see");
503 DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad");
504 }
505 }
506
507 /* verify that we can start */
508 if (getuid() != 0)
509 {
510 DBG1(DBG_APP, "permission denied (must be superuser)");
511 cleanup();
512 exit(LSB_RC_NOT_ALLOWED);
513 }
514
515 if (check_pid(pid_file))
516 {
517 DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start",
518 daemon_name, pid_file);
519 }
520 else
521 {
522 _action_ |= FLAG_ACTION_START_CHARON;
523 }
524 if (stat(DEV_RANDOM, &stb) != 0)
525 {
526 DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
527 cleanup();
528 exit(LSB_RC_FAILURE);
529 }
530
531 if (stat(DEV_URANDOM, &stb)!= 0)
532 {
533 DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
534 cleanup();
535 exit(LSB_RC_FAILURE);
536 }
537
538 cfg = confread_load(config_file);
539 if (cfg == NULL || cfg->err > 0)
540 {
541 DBG1(DBG_APP, "unable to start strongSwan -- fatal errors in config");
542 if (cfg)
543 {
544 confread_free(cfg);
545 }
546 cleanup();
547 exit(LSB_RC_INVALID_ARGUMENT);
548 }
549
550 /* determine if we have a native netkey IPsec stack */
551 if (!starter_netkey_init())
552 {
553 DBG1(DBG_APP, "no netkey IPsec stack detected");
554 if (!starter_klips_init())
555 {
556 DBG1(DBG_APP, "no KLIPS IPsec stack detected");
557 DBG1(DBG_APP, "no known IPsec stack detected, ignoring!");
558 }
559 }
560
561 last_reload = time_monotonic(NULL);
562
563 if (check_pid(starter_pid_file))
564 {
565 DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done",
566 starter_pid_file);
567 confread_free(cfg);
568 cleanup();
569 exit(LSB_RC_SUCCESS);
570 }
571
572 #ifdef GENERATE_SELFCERT
573 generate_selfcert();
574 #endif
575
576 /* fork if we're not debugging stuff */
577 if (!no_fork)
578 {
579 log_to_stderr = FALSE;
580
581 switch (fork())
582 {
583 case 0:
584 {
585 int fnull;
586
587 close_log();
588 closefrom(3);
589
590 fnull = open("/dev/null", O_RDWR);
591 if (fnull >= 0)
592 {
593 dup2(fnull, STDIN_FILENO);
594 dup2(fnull, STDOUT_FILENO);
595 dup2(fnull, STDERR_FILENO);
596 close(fnull);
597 }
598
599 setsid();
600 init_log("ipsec_starter");
601 }
602 break;
603 case -1:
604 DBG1(DBG_APP, "can't fork: %s", strerror(errno));
605 break;
606 default:
607 confread_free(cfg);
608 cleanup();
609 exit(LSB_RC_SUCCESS);
610 }
611 }
612
613 /* save pid file in /var/run/starter[.daemon_name].pid */
614 {
615 FILE *fd = fopen(starter_pid_file, "w");
616
617 if (fd)
618 {
619 fprintf(fd, "%u\n", getpid());
620 fclose(fd);
621 }
622 }
623
624 /* we handle these signals only in pselect() */
625 memset(&action, 0, sizeof(action));
626 sigemptyset(&action.sa_mask);
627 sigaddset(&action.sa_mask, SIGHUP);
628 sigaddset(&action.sa_mask, SIGINT);
629 sigaddset(&action.sa_mask, SIGTERM);
630 sigaddset(&action.sa_mask, SIGQUIT);
631 sigaddset(&action.sa_mask, SIGALRM);
632 sigaddset(&action.sa_mask, SIGUSR1);
633 pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
634
635 /* install a handler for fatal signals */
636 action.sa_handler = fatal_signal_handler;
637 sigaction(SIGSEGV, &action, NULL);
638 sigaction(SIGILL, &action, NULL);
639 sigaction(SIGBUS, &action, NULL);
640 action.sa_handler = SIG_IGN;
641 sigaction(SIGPIPE, &action, NULL);
642
643 /* install main signal handler */
644 action.sa_handler = signal_handler;
645 sigaction(SIGHUP, &action, NULL);
646 sigaction(SIGINT, &action, NULL);
647 sigaction(SIGTERM, &action, NULL);
648 sigaction(SIGQUIT, &action, NULL);
649 sigaction(SIGALRM, &action, NULL);
650 sigaction(SIGUSR1, &action, NULL);
651 /* this is not blocked above as we want to receive it asynchronously */
652 sigaction(SIGCHLD, &action, NULL);
653
654 /* empty mask for pselect() call below */
655 sigemptyset(&action.sa_mask);
656
657 for (;;)
658 {
659 /*
660 * Stop charon (if started) and exit
661 */
662 if (_action_ & FLAG_ACTION_QUIT)
663 {
664 if (starter_charon_pid())
665 {
666 starter_stop_charon();
667 }
668 starter_netkey_cleanup();
669 confread_free(cfg);
670 unlink(starter_pid_file);
671 cleanup();
672 DBG1(DBG_APP, "ipsec starter stopped");
673 close_log();
674 exit(LSB_RC_SUCCESS);
675 }
676
677 /*
678 * Delete all connections. Will be added below
679 */
680 if (_action_ & FLAG_ACTION_RELOAD)
681 {
682 if (starter_charon_pid())
683 {
684 for (conn = cfg->conn_first; conn; conn = conn->next)
685 {
686 if (conn->state == STATE_ADDED)
687 {
688 if (starter_charon_pid())
689 {
690 if (conn->startup == STARTUP_ROUTE)
691 {
692 starter_stroke_unroute_conn(conn);
693 }
694 starter_stroke_del_conn(conn);
695 }
696 conn->state = STATE_TO_ADD;
697 }
698 }
699 for (ca = cfg->ca_first; ca; ca = ca->next)
700 {
701 if (ca->state == STATE_ADDED)
702 {
703 if (starter_charon_pid())
704 {
705 starter_stroke_del_ca(ca);
706 }
707 ca->state = STATE_TO_ADD;
708 }
709 }
710 }
711 _action_ &= ~FLAG_ACTION_RELOAD;
712 }
713
714 /*
715 * Update configuration
716 */
717 if (_action_ & FLAG_ACTION_UPDATE)
718 {
719 DBG2(DBG_APP, "Reloading config...");
720 new_cfg = confread_load(config_file);
721
722 if (new_cfg && (new_cfg->err == 0))
723 {
724 /* Switch to new config. New conn will be loaded below */
725
726 /* Look for new connections that are already loaded */
727 for (conn = cfg->conn_first; conn; conn = conn->next)
728 {
729 if (conn->state == STATE_ADDED)
730 {
731 for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
732 {
733 if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
734 {
735 conn->state = STATE_REPLACED;
736 conn2->state = STATE_ADDED;
737 conn2->id = conn->id;
738 break;
739 }
740 }
741 }
742 }
743
744 /* Remove conn sections that have become unused */
745 for (conn = cfg->conn_first; conn; conn = conn->next)
746 {
747 if (conn->state == STATE_ADDED)
748 {
749 if (starter_charon_pid())
750 {
751 if (conn->startup == STARTUP_ROUTE)
752 {
753 starter_stroke_unroute_conn(conn);
754 }
755 starter_stroke_del_conn(conn);
756 }
757 }
758 }
759
760 /* Look for new ca sections that are already loaded */
761 for (ca = cfg->ca_first; ca; ca = ca->next)
762 {
763 if (ca->state == STATE_ADDED)
764 {
765 for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
766 {
767 if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
768 {
769 ca->state = STATE_REPLACED;
770 ca2->state = STATE_ADDED;
771 break;
772 }
773 }
774 }
775 }
776
777 /* Remove ca sections that have become unused */
778 for (ca = cfg->ca_first; ca; ca = ca->next)
779 {
780 if (ca->state == STATE_ADDED)
781 {
782 if (starter_charon_pid())
783 {
784 starter_stroke_del_ca(ca);
785 }
786 }
787 }
788 confread_free(cfg);
789 cfg = new_cfg;
790 }
791 else
792 {
793 DBG1(DBG_APP, "can't reload config file due to errors -- keeping old one");
794 if (new_cfg)
795 {
796 confread_free(new_cfg);
797 }
798 }
799 _action_ &= ~FLAG_ACTION_UPDATE;
800 last_reload = time_monotonic(NULL);
801 }
802
803 /*
804 * Start daemon
805 */
806 if (_action_ & FLAG_ACTION_START_CHARON)
807 {
808 if (cfg->setup.charonstart && !starter_charon_pid())
809 {
810 DBG2(DBG_APP, "Attempting to start %s...", daemon_name);
811 if (starter_start_charon(cfg, no_fork, attach_gdb))
812 {
813 /* schedule next try */
814 alarm(CHARON_RESTART_DELAY);
815 }
816 starter_stroke_configure(cfg);
817 }
818 _action_ &= ~FLAG_ACTION_START_CHARON;
819
820 for (ca = cfg->ca_first; ca; ca = ca->next)
821 {
822 if (ca->state == STATE_ADDED)
823 {
824 ca->state = STATE_TO_ADD;
825 }
826 }
827
828 for (conn = cfg->conn_first; conn; conn = conn->next)
829 {
830 if (conn->state == STATE_ADDED)
831 {
832 conn->state = STATE_TO_ADD;
833 }
834 }
835 }
836
837 /*
838 * Add stale conn and ca sections
839 */
840 if (starter_charon_pid())
841 {
842 for (ca = cfg->ca_first; ca; ca = ca->next)
843 {
844 if (ca->state == STATE_TO_ADD)
845 {
846 if (starter_charon_pid())
847 {
848 starter_stroke_add_ca(ca);
849 }
850 ca->state = STATE_ADDED;
851 }
852 }
853
854 for (conn = cfg->conn_first; conn; conn = conn->next)
855 {
856 if (conn->state == STATE_TO_ADD)
857 {
858 if (conn->id == 0)
859 {
860 /* affect new unique id */
861 conn->id = id++;
862 }
863 if (starter_charon_pid())
864 {
865 starter_stroke_add_conn(cfg, conn);
866 }
867 conn->state = STATE_ADDED;
868
869 if (conn->startup == STARTUP_START)
870 {
871 if (starter_charon_pid())
872 {
873 starter_stroke_initiate_conn(conn);
874 }
875 }
876 else if (conn->startup == STARTUP_ROUTE)
877 {
878 if (starter_charon_pid())
879 {
880 starter_stroke_route_conn(conn);
881 }
882 }
883 }
884 }
885 }
886
887 /*
888 * If auto_update activated, when to stop select
889 */
890 if (auto_update)
891 {
892 time_t now = time_monotonic(NULL);
893
894 ts.tv_sec = (now < last_reload + auto_update) ?
895 (last_reload + auto_update - now) : 0;
896 ts.tv_nsec = 0;
897 }
898
899 /*
900 * Wait for something to happen
901 */
902 if (!_action_ &&
903 pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
904 &action.sa_mask) == 0)
905 {
906 /* timeout -> auto_update */
907 _action_ |= FLAG_ACTION_UPDATE;
908 }
909 }
910 exit(LSB_RC_SUCCESS);
911 }