From c8ea4868b37f53e138548b7adee756834ad7ea66 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 28 Mar 2012 18:42:24 +0200 Subject: Add single peer config options; also fix string handling in lexer --- src/config.c | 29 ++++++++++++++++++++------ src/config.l | 34 +++++++++++++++--------------- src/config.y | 67 ++++++++++++++++++++++++++++++++++++++++-------------------- src/fastd.h | 2 +- 4 files changed, 85 insertions(+), 47 deletions(-) diff --git a/src/config.c b/src/config.c index b53a0b9..af32975 100644 --- a/src/config.c +++ b/src/config.c @@ -81,17 +81,22 @@ static bool config_match(const char *opt, ...) { return match; } -void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, int depth) { +void 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 use_stdin = !strcmp(filename, "-"); FILE *file; - if (use_stdin) + if (use_stdin) { file = stdin; - else + } + else { file = fopen(filename, "r"); + if (!file) + exit_error(ctx, "can't open config file `%s': %s", filename, strerror(errno)); + } + yyscan_t scanner; fastd_config_yylex_init(&scanner); @@ -101,12 +106,18 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen int token; YYSTYPE token_val; - do { + + if (peer_config) + token = START_PEER_CONFIG; + else + token = START_CONFIG; + + while(fastd_config_push_parse(ps, token, &token_val, ctx, conf, depth+1) == YYPUSH_MORE) { token = fastd_config_yylex(&token_val, scanner); if (token < 0) exit_error(ctx, "config error: %s", token_val.str); - } while(fastd_config_push_parse(ps, token, &token_val, ctx, conf, depth+1) == YYPUSH_MORE); + } fastd_config_pstate_delete(ps); fastd_config_yylex_destroy(scanner); @@ -139,7 +150,13 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con while (i < argc) { IF_OPTION_ARG("-c", "--config") { - fastd_read_config(ctx, conf, arg, 0); + fastd_read_config(ctx, conf, arg, false, 0); + continue; + } + + IF_OPTION_ARG("--config-peer") { + fastd_peer_config_new(ctx, conf); + fastd_read_config(ctx, conf, arg, true, 0); continue; } diff --git a/src/config.l b/src/config.l index 6911e69..8a96b40 100644 --- a/src/config.l +++ b/src/config.l @@ -15,16 +15,17 @@ { [0-9]+ { yylval->num = atoi(yytext); return TOK_INTEGER; } -interface { yylval->str = yytext; return TOK_INTERFACE; } -bind { yylval->str = yytext; return TOK_BIND; } -mtu { yylval->str = yytext; return TOK_MTU; } -mode { yylval->str = yytext; return TOK_MODE; } -protocol { yylval->str = yytext; return TOK_PROTOCOL; } -peer { yylval->str = yytext; return TOK_PEER; } -address { yylval->str = yytext; return TOK_ADDRESS; } -secret { yylval->str = yytext; return TOK_SECRET; } -key { yylval->str = yytext; return TOK_KEY; } -include { yylval->str = yytext; return TOK_INCLUDE; } +interface { return TOK_INTERFACE; } +bind { return TOK_BIND; } +mtu { return TOK_MTU; } +mode { return TOK_MODE; } +protocol { return TOK_PROTOCOL; } +peer { return TOK_PEER; } +address { return TOK_ADDRESS; } +secret { return TOK_SECRET; } +key { return TOK_KEY; } +include { return TOK_INCLUDE; } +as { return TOK_AS; } [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} { if (!inet_pton(AF_INET, yytext, &yylval->addr)) { @@ -39,16 +40,14 @@ any { yylval->str = yytext; return TOK_ANY; } tap { yylval->str = yytext; return TOK_TAP; } tun { yylval->str = yytext; return TOK_TUN; } -[A-Za-z_][A-Za-z0-9_]* { yylval->str = yytext; return TOK_IDENTIFIER; } - [;:\{\}] { return yytext[0]; } [ \t\n] ; } -\"\" { yylval->str = ""; return TOK_STRING; } +\"\" { yylval->str = strdup(""); return TOK_STRING; } \" BEGIN(STRING); -[^"]* { yylval->str = yytext; return TOK_STRING; } +[^"]+ { yylval->str = strdup(yytext); return TOK_STRING; } \" BEGIN(INITIAL); \[ BEGIN(ADDR6); @@ -62,13 +61,12 @@ tun { yylval->str = yytext; return TOK_TUN; } } \] BEGIN(INITIAL); -#.* {} -\/\/.* {} +#.* /* ignore */ +\/\/.* /* ignore */ \/\* BEGIN(COMMENT); \*\/ BEGIN(INITIAL); -. {} -\n {} +.|\n /* ignore everything */ . { yylval->str = "invalid character"; diff --git a/src/config.y b/src/config.y index 6d005ac..da2015b 100644 --- a/src/config.y +++ b/src/config.y @@ -17,27 +17,30 @@ struct in6_addr addr6; } +%token START_CONFIG +%token START_PEER_CONFIG + %token TOK_INTEGER %token TOK_STRING -%token TOK_IDENTIFIER - -%token TOK_INTERFACE -%token TOK_BIND -%token TOK_MTU -%token TOK_MODE -%token TOK_PROTOCOL -%token TOK_PEER -%token TOK_ADDRESS -%token TOK_SECRET -%token TOK_KEY -%token TOK_INCLUDE + +%token TOK_INTERFACE +%token TOK_BIND +%token TOK_MTU +%token TOK_MODE +%token TOK_PROTOCOL +%token TOK_PEER +%token TOK_ADDRESS +%token TOK_SECRET +%token TOK_KEY +%token TOK_INCLUDE +%token TOK_AS +%token TOK_ANY +%token TOK_TAP +%token TOK_TUN %token TOK_ADDR %token TOK_ADDR6 -%token TOK_ANY -%token TOK_TAP -%token TOK_TUN %code { #include @@ -59,8 +62,13 @@ %type port %type maybe_port %type maybe_port_default +%type maybe_as %% +start: START_CONFIG config + | START_PEER_CONFIG peer_conf + ; + config: config statement | ; @@ -75,7 +83,7 @@ statement: TOK_INTERFACE interface ';' | TOK_INCLUDE include ';' ; -interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1); } +interface: TOK_STRING { free(conf->ifname); conf->ifname = $1; } ; bind: TOK_ADDR maybe_port { @@ -112,17 +120,17 @@ protocol: TOK_STRING { #endif else exit_error(ctx, "config error: invalid protocol `%s'", $1); + + free($1); } ; -secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1); } +secret: TOK_STRING { free(conf->secret); conf->secret = $1; } ; peer: maybe_string { fastd_peer_config_new(ctx, conf); - - if ($1) - conf->peers->name = strdup($1); + conf->peers->name = $1; } ; @@ -132,6 +140,7 @@ peer_conf: peer_conf peer_statement peer_statement: TOK_ADDRESS peer_address ';' | TOK_KEY peer_key ';' + | TOK_INCLUDE peer_include ';' ; peer_address: TOK_ADDR maybe_port_default { @@ -146,11 +155,21 @@ peer_address: TOK_ADDR maybe_port_default { } ; -peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = strdup($1); } +peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = $1; } + ; + +peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1, true, depth); free($1); } ; -include: TOK_STRING { fastd_read_config(ctx, conf, $1, depth); } +include: TOK_PEER TOK_STRING maybe_as { + fastd_peer_config_new(ctx, conf); + conf->peers->name = $3; + + fastd_read_config(ctx, conf, $2, true, depth); + free($2); + } + | TOK_STRING { fastd_read_config(ctx, conf, $1, false, depth); free($1); } ; @@ -166,6 +185,10 @@ maybe_port_default: ':' port { $$ = $2; } | { $$ = htons(1337); } ; +maybe_as: TOK_AS TOK_STRING { $$ = $2; } + | { $$ = NULL; } + ; + port: TOK_INTEGER { if ($1 < 0 || $1 > 65635) exit_error(ctx, "invalid port %i", $1); diff --git a/src/fastd.h b/src/fastd.h index 5e7d4bc..cd6dbb2 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -120,7 +120,7 @@ struct _fastd_context { void fastd_printf(const fastd_context *ctx, const char *format, ...); -void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, int depth); +void 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); -- cgit v1.2.3