summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c29
-rw-r--r--src/config.l34
-rw-r--r--src/config.y67
-rw-r--r--src/fastd.h2
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 @@
<INITIAL>{
[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] ;
}
-<INITIAL>\"\" { yylval->str = ""; return TOK_STRING; }
+<INITIAL>\"\" { yylval->str = strdup(""); return TOK_STRING; }
<INITIAL>\" BEGIN(STRING);
-<STRING>[^"]* { yylval->str = yytext; return TOK_STRING; }
+<STRING>[^"]+ { yylval->str = strdup(yytext); return TOK_STRING; }
<STRING>\" BEGIN(INITIAL);
<INITIAL>\[ BEGIN(ADDR6);
@@ -62,13 +61,12 @@ tun { yylval->str = yytext; return TOK_TUN; }
}
<ADDR6>\] BEGIN(INITIAL);
-<INITIAL>#.* {}
-<INITIAL>\/\/.* {}
+<INITIAL>#.* /* ignore */
+<INITIAL>\/\/.* /* ignore */
<INITIAL>\/\* BEGIN(COMMENT);
<COMMENT>\*\/ BEGIN(INITIAL);
-<COMMENT>. {}
-<COMMENT>\n {}
+<COMMENT>.|\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 <num> TOK_INTEGER
%token <str> TOK_STRING
-%token <str> TOK_IDENTIFIER
-
-%token <str> TOK_INTERFACE
-%token <str> TOK_BIND
-%token <str> TOK_MTU
-%token <str> TOK_MODE
-%token <str> TOK_PROTOCOL
-%token <str> TOK_PEER
-%token <str> TOK_ADDRESS
-%token <str> TOK_SECRET
-%token <str> TOK_KEY
-%token <str> 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 <addr> TOK_ADDR
%token <addr6> TOK_ADDR6
-%token <str> TOK_ANY
-%token <str> TOK_TAP
-%token <str> TOK_TUN
%code {
#include <config.h>
@@ -59,8 +62,13 @@
%type <num> port
%type <num> maybe_port
%type <num> maybe_port_default
+%type <str> 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);