From 89208e7de1c477c8a49b559b36c3177ab1ff5645 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 3 Apr 2012 02:17:33 +0200 Subject: Ignore peer configs with errors in peer dirs instead of exiting --- src/config.c | 78 ++++++++++++++++++++++++++++++++++++++++-------------------- src/config.y | 33 +++++++++++++++++-------- src/fastd.h | 2 +- src/peer.c | 9 +++++++ src/peer.h | 1 + 5 files changed, 86 insertions(+), 37 deletions(-) diff --git a/src/config.c b/src/config.c index 3f18ea0..2cf7494 100644 --- a/src/config.c +++ b/src/config.c @@ -135,7 +135,11 @@ void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *d fastd_peer_config_new(ctx, conf); conf->peers->name = strdup(result->d_name); - fastd_read_config(ctx, conf, result->d_name, true, depth); + + if (!fastd_read_config(ctx, conf, result->d_name, true, depth)) { + pr_warn(ctx, "peer config %s will be ignored", result->d_name); + fastd_peer_config_delete(ctx, conf); + } } closedir(dirh); @@ -144,40 +148,47 @@ void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *d free(oldcwd); } -void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth) { +bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth) { if (depth >= MAX_CONFIG_DEPTH) exit_error(ctx, "maximum config include depth exceeded"); + bool ret = true; + char *oldcwd = get_current_dir_name(); + char *filename2 = NULL; + char *dir = NULL; FILE *file; + yyscan_t scanner; + fastd_config_pstate *ps; + fastd_config_str *strings = NULL; + + fastd_config_yylex_init(&scanner); + ps = fastd_config_pstate_new(); + if (!filename) { file = stdin; } else { file = fopen(filename, "r"); - if (!file) - exit_error(ctx, "can't open config file `%s': %s", filename, strerror(errno)); + if (!file) { + pr_error(ctx, "can't open config file `%s': %s", filename, strerror(errno)); + ret = false; + goto end_free; + } } - - char *oldcwd = get_current_dir_name(); - - char *filename2 = NULL; - char *dir = NULL; + fastd_config_yyset_in(file, scanner); if (filename) { filename2 = strdup(filename); dir = dirname(filename2); - if (chdir(dir)) - exit_error(ctx, "change from directory `%s' to `%s' failed", oldcwd, dir); + if (chdir(dir)) { + pr_error(ctx, "change from directory `%s' to `%s' failed", oldcwd, dir); + ret = false; + goto end_free; + } } - yyscan_t scanner; - fastd_config_yylex_init(&scanner); - fastd_config_yyset_in(file, scanner); - - fastd_config_pstate *ps = fastd_config_pstate_new(); - int token; YYSTYPE token_val; YYLTYPE loc = {1, 0, 1, 0}; @@ -187,20 +198,29 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen else token = START_CONFIG; - fastd_config_str *strings = NULL; + int parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, ctx, conf, filename, depth+1); - while(fastd_config_push_parse(ps, token, &token_val, &loc, ctx, conf, filename, depth+1) == YYPUSH_MORE) { + while(parse_ret == YYPUSH_MORE) { token = fastd_config_yylex(&token_val, &loc, scanner); - if (token < 0) - exit_error(ctx, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column); + if (token < 0) { + pr_error(ctx, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column); + ret = false; + goto end_free; + } if (token == TOK_STRING) { token_val.str->next = strings; strings = token_val.str; } + + parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, ctx, conf, filename, depth+1); } + if (parse_ret) + ret = false; + + end_free: fastd_config_str_free(strings); fastd_config_pstate_delete(ps); @@ -211,8 +231,10 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen free(filename2); free(oldcwd); - if (filename) + if (filename && file) fclose(file); + + return ret; } #define IF_OPTION(args...) if(config_match(argv[i], args, NULL) && (++i)) @@ -258,16 +280,20 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con } IF_OPTION_ARG("-c", "--config") { + const char *filename = arg; if (!strcmp(arg, "-")) - fastd_read_config(ctx, conf, NULL, false, 0); - else - fastd_read_config(ctx, conf, arg, false, 0); + filename = NULL; + + if (!fastd_read_config(ctx, conf, filename, false, 0)) + exit(1); continue; } IF_OPTION_ARG("--config-peer") { fastd_peer_config_new(ctx, conf); - fastd_read_config(ctx, conf, arg, true, 0); + + if(!fastd_read_config(ctx, conf, arg, true, 0)) + exit(1); continue; } diff --git a/src/config.y b/src/config.y index cbb58c7..df46f20 100644 --- a/src/config.y +++ b/src/config.y @@ -174,14 +174,18 @@ mode: TOK_TAP { conf->mode = MODE_TAP; } ; protocol: TOK_STRING { - if (!strcmp($1->str, "null")) + if (!strcmp($1->str, "null")) { conf->protocol = &fastd_protocol_null; + } #ifdef WITH_PROTOCOL_ECFXP - else if (!strcmp($1->str, "ecfxp")) + else if (!strcmp($1->str, "ecfxp")) { conf->protocol = &fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; + } #endif - else - exit_error(ctx, "config error: invalid protocol `%s'", $1->str); + else { + fastd_config_error(&@$, ctx, conf, filename, depth, "invalid protocol"); + YYERROR; + } } ; @@ -227,7 +231,10 @@ peer_address: TOK_ADDR ':' port { peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = strdup($1->str); } ; -peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1->str, true, depth); } +peer_include: TOK_STRING { + if (!fastd_read_config(ctx, conf, $1->str, true, depth)) + YYERROR; + } ; @@ -239,12 +246,16 @@ include: TOK_PEER TOK_STRING maybe_as { fastd_peer_config_new(ctx, conf); conf->peers->name = strdup($3->str); - fastd_read_config(ctx, conf, $2->str, true, depth); + if (!fastd_read_config(ctx, conf, $2->str, true, depth)) + YYERROR; } | TOK_PEERS TOK_FROM TOK_STRING { fastd_read_config_dir(ctx, conf, $3->str, depth); } - | TOK_STRING { fastd_read_config(ctx, conf, $1->str, false, depth); } + | TOK_STRING { + if (!fastd_read_config(ctx, conf, $1->str, false, depth)) + YYERROR; + } ; @@ -265,12 +276,14 @@ boolean: TOK_YES { $$ = true; } ; port: TOK_INTEGER { - if ($1 < 0 || $1 > 65635) - exit_error(ctx, "config error: invalid port %i", $1); + if ($1 < 0 || $1 > 65635) { + fastd_config_error(&@$, ctx, conf, filename, depth, "invalid port"); + YYERROR; + } $$ = htons($1); } ; %% void fastd_config_error(YYLTYPE *loc, fastd_context *ctx, fastd_config *conf, const char *filename, int depth, char *s) { - exit_error(ctx, "config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column); + pr_error(ctx, "config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column); } diff --git a/src/fastd.h b/src/fastd.h index f402be8..6eab856 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -140,7 +140,7 @@ struct _fastd_config_str { void fastd_printf(const fastd_context *ctx, const char *format, ...); void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *dir, int depth); -void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth); +bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth); void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]); void fastd_random_bytes(fastd_context *ctx, void *buffer, size_t len, bool secure); diff --git a/src/peer.c b/src/peer.c index c88152d..92e6aa5 100644 --- a/src/peer.c +++ b/src/peer.c @@ -93,6 +93,15 @@ fastd_peer_config* fastd_peer_config_new(fastd_context *ctx, fastd_config *conf) return peer; } +void fastd_peer_config_delete(fastd_context *ctx, fastd_config *conf) { + fastd_peer_config *peer = conf->peers, *next = peer->next; + + free(peer->name); + free(peer->key); + free(peer); + + conf->peers = next; +} void fastd_peer_reset(fastd_context *ctx, fastd_peer *peer) { pr_debug(ctx, "resetting peer %P", peer); diff --git a/src/peer.h b/src/peer.h index 1ffa18b..54f6ca8 100644 --- a/src/peer.h +++ b/src/peer.h @@ -71,6 +71,7 @@ struct _fastd_peer_eth_addr { fastd_peer_config* fastd_peer_config_new(fastd_context *ctx, fastd_config *conf); +void fastd_peer_config_delete(fastd_context *ctx, fastd_config *conf); void fastd_peer_reset(fastd_context *ctx, fastd_peer *peer); fastd_peer* fastd_peer_add(fastd_context *ctx, fastd_peer_config *conf); -- cgit v1.2.3