Annotation of embedaddon/strongswan/src/starter/starter.c, revision 1.1.1.1

1.1       misho       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>