make starter behave more gracefully in the presence of non-fatal errors
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 25 Jun 2007 07:10:23 +0000 (07:10 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 25 Jun 2007 07:10:23 +0000 (07:10 -0000)
src/starter/confread.c
src/starter/confread.h
src/starter/starter.c

index e7a4789..76d0855 100644 (file)
@@ -695,7 +695,79 @@ find_also_ca(const char* name, starter_ca_t *ca, starter_config_t *cfg)
        return NULL;
 }
 
+/*
+ * free the memory used by also_t objects
+ */
+static void
+free_also(also_t *head)
+{
+       while (head != NULL)
+       {
+               also_t *also = head;
+
+               head = also->next;
+               pfree(also->name);
+               pfree(also);
+       }
+}
+
+/*
+ * free the memory used by a starter_conn_t object
+ */
+static void
+confread_free_conn(starter_conn_t *conn)
+{
+       free_args(KW_END_FIRST, KW_END_LAST,  (char *)&conn->left);
+       free_args(KW_END_FIRST, KW_END_LAST,  (char *)&conn->right);
+       free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
+       free_also(conn->also);
+}
+
+/*
+ * free the memory used by a starter_ca_t object
+ */
+static void
+confread_free_ca(starter_ca_t *ca)
+{
+       free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
+       free_also(ca->also);
+}
+
+/*
+ * free the memory used by a starter_config_t object
+ */
+void 
+confread_free(starter_config_t *cfg)
+{
+       starter_conn_t *conn = cfg->conn_first;
+       starter_ca_t   *ca   = cfg->ca_first;
+
+       free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
+
+       confread_free_conn(&cfg->conn_default);
+
+       while (conn != NULL)
+       {
+               starter_conn_t *conn_aux = conn;
+
+               conn = conn->next;
+               confread_free_conn(conn_aux);
+               pfree(conn_aux);
+       }
+
+       confread_free_ca(&cfg->ca_default);
+
+       while (ca != NULL)
+       {
+               starter_ca_t *ca_aux = ca;
+
+               ca = ca->next;
+               confread_free_ca(ca_aux);
+               pfree(ca_aux);
+       }
 
+       pfree(cfg);
+}
 
 /*
  * load and parse an IPsec configuration file
@@ -709,6 +781,7 @@ confread_load(const char *file)
        starter_conn_t   *conn;
        starter_ca_t     *ca;
 
+       u_int total_err;
        u_int visit     = 0;
 
        /* load IPSec configuration file  */
@@ -748,6 +821,8 @@ confread_load(const char *file)
        /* load other ca sections */
        for (sca = cfgp->ca_first; sca; sca = sca->next)
        {
+               u_int previous_err;
+
                /* skip %default ca section */
                if (streq(sca->name, "%default"))
                        continue;
@@ -761,13 +836,24 @@ confread_load(const char *file)
                ca->kw =  sca->kw;
                ca->next = NULL;
 
-               if (cfg->ca_last)
-                       cfg->ca_last->next = ca;
-               cfg->ca_last = ca;
-               if (!cfg->ca_first)
-                       cfg->ca_first = ca;
-
+               previous_err = cfg->err;
                load_ca(ca, ca->kw, cfg);
+               if (cfg->err > previous_err)
+               {
+                       /* errors occurred - free the ca */
+                       confread_free_ca(ca);
+                       cfg->non_fatal_err += cfg->err - previous_err;
+                       cfg->err = previous_err;
+               }
+               else
+               {
+                       /* success - insert the ca into the chained list */
+                       if (cfg->ca_last)
+                               cfg->ca_last->next = ca;
+                       cfg->ca_last = ca;
+                       if (!cfg->ca_first)
+                               cfg->ca_first = ca;
+               }
        }
 
        for (ca = cfg->ca_first; ca; ca = ca->next)
@@ -806,6 +892,8 @@ confread_load(const char *file)
        /* load other conn sections */
        for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
        {
+               u_int previous_err;
+               
                /* skip %default conn section */
                if (streq(sconn->name, "%default"))
                        continue;
@@ -818,14 +906,25 @@ confread_load(const char *file)
                conn_default(sconn->name, conn, &cfg->conn_default);
                conn->kw =  sconn->kw;
                conn->next = NULL;
-
-               if (cfg->conn_last)
-                       cfg->conn_last->next = conn;
-               cfg->conn_last = conn;
-               if (!cfg->conn_first)
-                       cfg->conn_first = conn;
-
+               
+               previous_err = cfg->err;
                load_conn(conn, conn->kw, cfg);
+               if (cfg->err > previous_err)
+               {
+                       /* error occurred - free the conn */
+                       confread_free_conn(conn);
+                       cfg->non_fatal_err += cfg->err - previous_err;
+                       cfg->err = previous_err;
+               }
+               else
+               {
+                       /* success - insert the conn into the chained list */
+                       if (cfg->conn_last)
+                               cfg->conn_last->next = conn;
+                       cfg->conn_last = conn;
+                       if (!cfg->conn_first)
+                               cfg->conn_first = conn;
+               }
        }
 
        /* in the second round do not parse also statements */
@@ -851,86 +950,12 @@ confread_load(const char *file)
 
        parser_free_conf(cfgp);
 
-       if (cfg->err)
+       total_err = cfg->err + cfg->non_fatal_err;
+       if (total_err > 0)
        {
-               plog("### %d parsing error%s ###", cfg->err, (cfg->err > 1)?"s":"");
-               confread_free(cfg);
-               cfg = NULL;
+               plog("### %d parsing error%s (%d fatal) ###"
+                       , total_err, (total_err > 1)?"s":"", cfg->err);
        }
 
        return cfg;
 }
-
-/*
- * free the memory used by also_t objects
- */
-static void
-free_also(also_t *head)
-{
-       while (head != NULL)
-       {
-               also_t *also = head;
-
-               head = also->next;
-               pfree(also->name);
-               pfree(also);
-       }
-}
-
-/*
- * free the memory used by a starter_conn_t object
- */
-static void
-confread_free_conn(starter_conn_t *conn)
-{
-       free_args(KW_END_FIRST, KW_END_LAST,  (char *)&conn->left);
-       free_args(KW_END_FIRST, KW_END_LAST,  (char *)&conn->right);
-       free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
-       free_also(conn->also);
-}
-
-/*
- * free the memory used by a starter_ca_t object
- */
-static void
-confread_free_ca(starter_ca_t *ca)
-{
-       free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
-       free_also(ca->also);
-}
-
-/*
- * free the memory used by a starter_config_t object
- */
-void 
-confread_free(starter_config_t *cfg)
-{
-       starter_conn_t *conn = cfg->conn_first;
-       starter_ca_t   *ca   = cfg->ca_first;
-
-       free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
-
-       confread_free_conn(&cfg->conn_default);
-
-       while (conn != NULL)
-       {
-               starter_conn_t *conn_aux = conn;
-
-               conn = conn->next;
-               confread_free_conn(conn_aux);
-               pfree(conn_aux);
-       }
-
-       confread_free_ca(&cfg->ca_default);
-
-       while (ca != NULL)
-       {
-               starter_ca_t *ca_aux = ca;
-
-               ca = ca->next;
-               confread_free_ca(ca_aux);
-               pfree(ca_aux);
-       }
-
-       pfree(cfg);
-}
index c0993f2..99851d5 100644 (file)
@@ -192,7 +192,8 @@ struct starter_config {
        defaultroute_t defaultroute;
 
        /* number of encountered parsing errors */
-       u_int err;      
+       u_int err;
+       u_int non_fatal_err;
 
        /* do we parse also statements */
        bool parse_also;
index f84d413..650ace3 100644 (file)
@@ -237,9 +237,10 @@ int main (int argc, char **argv)
     }
 
     cfg = confread_load(CONFIG_FILE);
-    if (!cfg)
+    if (cfg->err > 0)
     {
-       plog("unable to start strongSwan -- errors in config");
+       plog("unable to start strongSwan -- fatal errors in config");
+       confread_free(cfg);
        exit(1);
     }
 
@@ -373,7 +374,7 @@ int main (int argc, char **argv)
               );
            new_cfg = confread_load(CONFIG_FILE);
 
-           if (new_cfg)
+           if (new_cfg->err + new_cfg->non_fatal_err == 0)
            {
                /* Switch to new config. New conn will be loaded below */
                if (!starter_cmp_defaultroute(&new_cfg->defaultroute
@@ -466,7 +467,8 @@ int main (int argc, char **argv)
            }
            else
            {
-               plog("can't reload config file: %s -- keeping old one");
+               plog("can't reload config file due to errors -- keeping old one");
+               confread_free(new_cfg);
            }
            _action_ &= ~FLAG_ACTION_UPDATE;
            last_reload = time(NULL);