diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-06-25 07:10:23 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-06-25 07:10:23 +0000 |
commit | 3345c0a1edbf07cfd9e4f52f5bf60eb450090ecf (patch) | |
tree | 579263dd24868079fd6d1b433a10bc53382983cc /src | |
parent | 17d92e9732195be3d75a71a2ab075785afa191e2 (diff) | |
download | strongswan-3345c0a1edbf07cfd9e4f52f5bf60eb450090ecf.tar.bz2 strongswan-3345c0a1edbf07cfd9e4f52f5bf60eb450090ecf.tar.xz |
make starter behave more gracefully in the presence of non-fatal errors
Diffstat (limited to 'src')
-rw-r--r-- | src/starter/confread.c | 207 | ||||
-rw-r--r-- | src/starter/confread.h | 3 | ||||
-rw-r--r-- | src/starter/starter.c | 10 |
3 files changed, 124 insertions, 96 deletions
diff --git a/src/starter/confread.c b/src/starter/confread.c index e7a4789a9..76d085513 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -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); -} diff --git a/src/starter/confread.h b/src/starter/confread.h index c0993f2b3..99851d5b6 100644 --- a/src/starter/confread.h +++ b/src/starter/confread.h @@ -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; diff --git a/src/starter/starter.c b/src/starter/starter.c index f84d41380..650ace34a 100644 --- a/src/starter/starter.c +++ b/src/starter/starter.c @@ -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); |