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