full support of ikev1 and ikev2 connection flags
[strongswan.git] / src / starter / starter.c
index 4b4e23f..069b219 100644 (file)
@@ -36,6 +36,7 @@
 #include "confread.h"
 #include "files.h"
 #include "starterwhack.h"
+#include "starterstroke.h"
 #include "invokepluto.h"
 #include "invokecharon.h"
 #include "netkey.h"
@@ -47,9 +48,7 @@
 #define FLAG_ACTION_RELOAD        0x04
 #define FLAG_ACTION_QUIT          0x08
 #define FLAG_ACTION_LISTEN        0x10
-#ifdef IKEV2
 #define FLAG_ACTION_START_CHARON  0x20
-#endif /* IKEV2 */
 
 static unsigned int _action_ = 0;
 
@@ -58,7 +57,7 @@ fsig(int signal)
 {
     switch (signal)
     {
-    case SIGCHLD:
+       case SIGCHLD:
        {
            int status;
            pid_t pid;
@@ -68,69 +67,62 @@ fsig(int signal)
            {
                if (pid == starter_pluto_pid())
                    name = " (Pluto)";
-#ifdef IKEV2
                if (pid == starter_charon_pid())
                    name = " (Charon)";
-#endif /* IKEV2 */
                if (WIFSIGNALED(status))
                    DBG(DBG_CONTROL,
                        DBG_log("child %d%s has been killed by sig %d\n",
                                pid, name?name:"", WTERMSIG(status))
-                   )
+                      )
                else if (WIFSTOPPED(status))
                    DBG(DBG_CONTROL,
                        DBG_log("child %d%s has been stopped by sig %d\n",
                                pid, name?name:"", WSTOPSIG(status))
-                   )
+                      )
                else if (WIFEXITED(status))
                    DBG(DBG_CONTROL,
                        DBG_log("child %d%s has quit (exit code %d)\n",
                                pid, name?name:"", WEXITSTATUS(status))
-                   )
+                      )
                else
                    DBG(DBG_CONTROL,
                        DBG_log("child %d%s has quit", pid, name?name:"")
-                   )
-
+                      )
                if (pid == starter_pluto_pid())
                    starter_pluto_sigchild(pid);
-#ifdef IKEV2
                if (pid == starter_charon_pid())
                    starter_charon_sigchild(pid);
-#endif /* IKEV2 */
            }
        }
        break;
 
-    case SIGPIPE:
-       /** ignore **/
-       break;
+       case SIGPIPE:
+           /** ignore **/
+           break;
 
-    case SIGALRM:
-       _action_ |= FLAG_ACTION_START_PLUTO;
-#ifdef IKEV2
-       _action_ |= FLAG_ACTION_START_CHARON;
-#endif /* IKEV2 */
-       break;
+       case SIGALRM:
+           _action_ |= FLAG_ACTION_START_PLUTO;
+           _action_ |= FLAG_ACTION_START_CHARON;
+           break;
 
-    case SIGHUP:
-       _action_ |= FLAG_ACTION_UPDATE;
-       break;
+       case SIGHUP:
+           _action_ |= FLAG_ACTION_UPDATE;
+           break;
 
-    case SIGTERM:
-    case SIGQUIT:
-    case SIGINT:
-       _action_ |= FLAG_ACTION_QUIT;
-       break;
+       case SIGTERM:
+       case SIGQUIT:
+       case SIGINT:
+           _action_ |= FLAG_ACTION_QUIT;
+           break;
 
-    case SIGUSR1:
-       _action_ |= FLAG_ACTION_RELOAD;
-       _action_ |= FLAG_ACTION_UPDATE;
-       break;
+       case SIGUSR1:
+           _action_ |= FLAG_ACTION_RELOAD;
+           _action_ |= FLAG_ACTION_UPDATE;
+           break;
 
-    default:
-       plog("fsig(): unknown signal %d -- investigate", signal);
-       break;
+       default:
+           plog("fsig(): unknown signal %d -- investigate", signal);
+           break;
     }
 }
 
@@ -138,7 +130,7 @@ static void
 usage(char *name)
 {
     fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
-                   "[--debug|--debug-more|--debug-all]\n");
+           "[--debug|--debug-more|--debug-all]\n");
     exit(1);
 }
 
@@ -190,7 +182,7 @@ int main (int argc, char **argv)
        }
        else
        {
-          usage(argv[0]);
+           usage(argv[0]);
        }
     }
 
@@ -206,9 +198,8 @@ int main (int argc, char **argv)
     signal(SIGQUIT, fsig);
     signal(SIGALRM, fsig);
     signal(SIGUSR1, fsig);
-       
-       
-       plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
+
+    plog("Starting strongSwan %s IPsec [starter]...", ipsec_version_code());
 
     /* verify that we can start */
     if (getuid() != 0)
@@ -225,7 +216,6 @@ int main (int argc, char **argv)
     {
        _action_ |= FLAG_ACTION_START_PLUTO;
     }
-#ifdef IKEV2
     if (stat(CHARON_PID_FILE, &stb) == 0)
     {
        plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
@@ -234,7 +224,6 @@ int main (int argc, char **argv)
     {
        _action_ |= FLAG_ACTION_START_CHARON;
     }
-#endif /* IKEV2 */
     if (stat(DEV_RANDOM, &stb) != 0)
     {
        plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
@@ -263,9 +252,9 @@ int main (int argc, char **argv)
 
     last_reload = time(NULL);
 
-    if (stat(MY_PID_FILE, &stb) == 0)
+    if (stat(STARTER_PID_FILE, &stb) == 0)
     {
-       plog("starter is already running (%s exists) -- no fork done", MY_PID_FILE);
+       plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE);
        exit(0);
     }
 
@@ -276,7 +265,7 @@ int main (int argc, char **argv)
 
        switch (fork())
        {
-       case 0:
+           case 0:
            {
                int fnull = open("/dev/null", O_RDWR);
 
@@ -289,17 +278,17 @@ int main (int argc, char **argv)
                }
            }
            break;
-       case -1:
-           plog("can't fork: %s", strerror(errno));
-           break;
-       default:
-           exit(0);
+           case -1:
+               plog("can't fork: %s", strerror(errno));
+               break;
+           default:
+               exit(0);
        }
     }
 
     /* save pid file in /var/run/starter.pid */
     {
-       FILE *fd = fopen(MY_PID_FILE, "w");
+       FILE *fd = fopen(STARTER_PID_FILE, "w");
 
        if (fd)
        {
@@ -317,13 +306,11 @@ int main (int argc, char **argv)
        {
            if (starter_pluto_pid())
                starter_stop_pluto();
-#ifdef IKEV2
-               if (starter_charon_pid())
+           if (starter_charon_pid())
                starter_stop_charon();
-#endif IKEV2
            starter_netkey_cleanup();
            confread_free(cfg);
-           unlink(MY_PID_FILE);
+           unlink(STARTER_PID_FILE);
            unlink(INFO_FILE);
 #ifdef LEAK_DETECTIVE
            report_leaks();
@@ -338,16 +325,20 @@ int main (int argc, char **argv)
         */
        if (_action_ & FLAG_ACTION_RELOAD)
        {
-           if (starter_pluto_pid())
+           if (starter_pluto_pid() || starter_charon_pid())
            {
                for (conn = cfg->conn_first; conn; conn = conn->next)
                {
                    if (conn->state == STATE_ADDED)
                    {
-                       starter_whack_del_conn(conn);
-#ifdef IKEV2
-                       starter_stroke_del_conn(conn);
-#endif /* IKEV2 */
+                       if (starter_charon_pid())
+                       {
+                           starter_stroke_del_conn(conn);
+                       }
+                       if (starter_pluto_pid())
+                       {
+                           starter_whack_del_conn(conn);
+                       }
                        conn->state = STATE_TO_ADD;
                    }
                }
@@ -355,8 +346,11 @@ int main (int argc, char **argv)
                {
                    if (ca->state == STATE_ADDED)
                    {
-                       starter_whack_del_ca(ca);
-                       ca->state = STATE_TO_ADD;
+                       if (starter_pluto_pid())
+                       {
+                           starter_whack_del_ca(ca);
+                           ca->state = STATE_TO_ADD;
+                       }
                    }
                }
            }
@@ -371,14 +365,14 @@ int main (int argc, char **argv)
            err = NULL;
            DBG(DBG_CONTROL,
                DBG_log("Reloading config...")
-           )
+              );
            new_cfg = confread_load(CONFIG_FILE);
 
            if (new_cfg)
            {
                /* Switch to new config. New conn will be loaded below */
                if (!starter_cmp_defaultroute(&new_cfg->defaultroute
-                   , &cfg->defaultroute))
+                                  , &cfg->defaultroute))
                {
                    _action_ |= FLAG_ACTION_LISTEN;
                }
@@ -402,8 +396,7 @@ int main (int argc, char **argv)
                        {
                            for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
                            {
-                               if (conn2->state == STATE_TO_ADD
-                               && starter_cmp_conn(conn, conn2))
+                               if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
                                {
                                    conn->state = STATE_REPLACED;
                                    conn2->state = STATE_ADDED;
@@ -418,10 +411,16 @@ int main (int argc, char **argv)
                    for (conn = cfg->conn_first; conn; conn = conn->next)
                    {
                        if (conn->state == STATE_ADDED)
-                           starter_whack_del_conn(conn);
-#ifdef IKEV2
-                           starter_stroke_del_conn(conn);
-#endif /* IKEV2 */
+                       {
+                           if (starter_charon_pid())
+                           {
+                               starter_stroke_del_conn(conn);
+                           }
+                           if (starter_pluto_pid())
+                           {
+                               starter_whack_del_conn(conn);
+                           }
+                       }
                    }
 
                    /* Look for new ca sections that are already loaded */
@@ -431,8 +430,7 @@ int main (int argc, char **argv)
                        {
                            for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
                            {
-                               if (ca2->state == STATE_TO_ADD
-                               && starter_cmp_ca(ca, ca2))
+                               if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
                                {
                                    ca->state = STATE_REPLACED;
                                    ca2->state = STATE_ADDED;
@@ -446,7 +444,12 @@ int main (int argc, char **argv)
                    for (ca = cfg->ca_first; ca; ca = ca->next)
                    {
                        if (ca->state == STATE_ADDED)
-                           starter_whack_del_ca(ca);
+                       {
+                           if (starter_pluto_pid())
+                           {
+                               starter_whack_del_ca(ca);
+                           }
+                       }
                    }
                }
                confread_free(cfg);
@@ -465,11 +468,11 @@ int main (int argc, char **argv)
         */
        if (_action_ & FLAG_ACTION_START_PLUTO)
        {
-           if (starter_pluto_pid() == 0)
+           if (cfg->setup.plutostart && !starter_pluto_pid())
            {
                DBG(DBG_CONTROL,
                    DBG_log("Attempting to start pluto...")
-               )
+                  );
 
                if (starter_start_pluto(cfg, no_fork) == 0)
                {
@@ -496,47 +499,51 @@ int main (int argc, char **argv)
            }
        }
        
-#ifdef IKEV2
        /*
         * Start charon
         */
        if (_action_ & FLAG_ACTION_START_CHARON)
        {
-               if (starter_charon_pid() == 0)
+           if (cfg->setup.charonstart && !starter_charon_pid())
+           {
+               DBG(DBG_CONTROL,
+                   DBG_log("Attempting to start charon...")
+                  );
+               if (starter_start_charon(cfg, no_fork))
                {
-                       DBG(DBG_CONTROL,
-                               DBG_log("Attempting to start charon...")
-                          )
-                       if (starter_start_charon(cfg, no_fork) != 0)
-                       {
-                               /* schedule next try */
-                               alarm(PLUTO_RESTART_DELAY);
-                       }
+                   /* schedule next try */
+                   alarm(PLUTO_RESTART_DELAY);
                }
-               _action_ &= ~FLAG_ACTION_START_CHARON;
+           }
+           _action_ &= ~FLAG_ACTION_START_CHARON;
        }
-#endif /* IKEV2 */
 
        /*
         * Tell pluto to reread its interfaces
         */
        if (_action_ & FLAG_ACTION_LISTEN)
        {
-           starter_whack_listen();
-           _action_ &= ~FLAG_ACTION_LISTEN;
+           if (starter_pluto_pid())
+           {
+               starter_whack_listen();
+               _action_ &= ~FLAG_ACTION_LISTEN;
+           }
        }
 
        /*
         * Add stale conn and ca sections
         */
-       if (starter_pluto_pid() != 0)
+       if (starter_pluto_pid() || starter_charon_pid())
        {
            for (ca = cfg->ca_first; ca; ca = ca->next)
            {
                if (ca->state == STATE_TO_ADD)
                {
-                   starter_whack_add_ca(ca);
-                   ca->state = STATE_ADDED;
+                   if (starter_pluto_pid())
+                   {
+                       starter_whack_add_ca(ca);
+                       ca->state = STATE_ADDED;
+                   }
                }
            }
 
@@ -549,35 +556,48 @@ int main (int argc, char **argv)
                        /* affect new unique id */
                        conn->id = id++;
                    }
-                   starter_whack_add_conn(conn);
-#ifdef IKEV2
-                   starter_stroke_add_conn(conn);
-#endif /* IKEV2 */
+                   if (starter_charon_pid())
+                   {
+                       starter_stroke_add_conn(conn);
+                   }
+                   if (starter_pluto_pid())
+                   {
+                       starter_whack_add_conn(conn);
+                   }
                    conn->state = STATE_ADDED;
+
                    if (conn->startup == STARTUP_START)
                    {
-#ifdef IKEV2
-                       if (conn->keyexchange == 2)
+                       if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
                        {
-                           starter_stroke_initiate_conn(conn);
+                           if (starter_charon_pid())
+                           {
+                               starter_stroke_initiate_conn(conn);
+                           }
                        }
                        else
-#endif /* IKEV2 */
                        {
-                           starter_whack_initiate_conn(conn);
+                           if (starter_pluto_pid())
+                           {
+                               starter_whack_initiate_conn(conn);
+                           }
                        }
                    }
                    else if (conn->startup == STARTUP_ROUTE)
                    {
-#ifdef IKEV2
-                       if (conn->keyexchange == 2)
+                       if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
                        {
+                           if (starter_charon_pid())
+                           {
                                starter_stroke_route_conn(conn);
+                           }
                        }
                        else
-#endif /* IKEV2 */
                        {
-                               starter_whack_route_conn(conn); 
+                           if (starter_pluto_pid())
+                           {
+                               starter_whack_route_conn(conn);
+                           }
                        }
                    }
                }
@@ -590,8 +610,9 @@ int main (int argc, char **argv)
        if (auto_update)
        {
            time_t now = time(NULL);
+
            tv.tv_sec = (now < last_reload + auto_update)
-                       ? (last_reload + auto_update-now) : 0;
+                   ? (last_reload + auto_update-now) : 0;
            tv.tv_usec = 0;
        }