summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c11
-rw-r--r--src/config.l14
-rw-r--r--src/config.y35
-rw-r--r--src/fastd.h21
-rw-r--r--src/types.h2
5 files changed, 56 insertions, 27 deletions
diff --git a/src/config.c b/src/config.c
index 964c2d6..7c1b62f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -183,13 +183,22 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
else
token = START_CONFIG;
+ fastd_config_str *strings = NULL;
+
while(fastd_config_push_parse(ps, token, &token_val, &loc, ctx, conf, filename, depth+1) == 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.str, filename, loc.first_line, loc.first_column);
+ exit_error(ctx, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column);
+
+ if (token == TOK_STRING) {
+ token_val.str->next = strings;
+ strings = token_val.str;
+ }
}
+ fastd_config_str_free(strings);
+
fastd_config_pstate_delete(ps);
fastd_config_yylex_destroy(scanner);
diff --git a/src/config.l b/src/config.l
index f2a9002..546bd8d 100644
--- a/src/config.l
+++ b/src/config.l
@@ -88,7 +88,7 @@ no { UPDATE_LOCATION; return TOK_NO; }
UPDATE_LOCATION;
if (!inet_pton(AF_INET, yytext, &yylval->addr)) {
- yylval->str = "invalid address";
+ yylval->error = "invalid address";
return -1;
}
@@ -116,7 +116,7 @@ no { UPDATE_LOCATION; return TOK_NO; }
yytext[i-esc] = yytext[i];
}
yytext[yyleng-esc-1] = 0;
- yylval->str = strdup(yytext);
+ yylval->str = fastd_config_str_dup(yytext);
BEGIN(INITIAL);
yylloc->last_column++;
return TOK_STRING;
@@ -127,7 +127,7 @@ no { UPDATE_LOCATION; return TOK_NO; }
<ADDR6>[0-9a-fA-F:]+ {
yylloc->last_column += yyleng;
if (!inet_pton(AF_INET6, yytext, &yylval->addr6)) {
- yylval->str = "invalid address";
+ yylval->error = "invalid address";
return -1;
}
}
@@ -144,12 +144,12 @@ no { UPDATE_LOCATION; return TOK_NO; }
. {
yylloc->first_line = yylloc->last_line;
yylloc->first_column = yylloc->last_column+1;
- yylval->str = "invalid character";
+ yylval->error = "invalid character";
return -1;
}
<INITIAL><<EOF>> { return 0; }
-<COMMENT><<EOF>> { yylval->str = "unterminated block comment"; return -1; }
-<STRING><<EOF>> { yylval->str = "unterminated string"; return -1; }
-<ADDR6><<EOF>> { yylval->str = "unterminated address"; return -1; }
+<COMMENT><<EOF>> { yylval->error = "unterminated block comment"; return -1; }
+<STRING><<EOF>> { yylval->error = "unterminated string"; return -1; }
+<ADDR6><<EOF>> { yylval->error = "unterminated address"; return -1; }
%%
diff --git a/src/config.y b/src/config.y
index be30ab0..cbb58c7 100644
--- a/src/config.y
+++ b/src/config.y
@@ -43,7 +43,8 @@
%union {
int num;
- char* str;
+ fastd_config_str *str;
+ char *error;
bool boolean;
struct in_addr addr;
struct in6_addr addr6;
@@ -144,7 +145,7 @@ log_level: TOK_FATAL { conf->loglevel = LOG_FATAL; }
| TOK_DEBUG { conf->loglevel = LOG_DEBUG; }
;
-interface: TOK_STRING { free(conf->ifname); conf->ifname = $1; }
+interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1->str); }
;
bind: TOK_ADDR maybe_port {
@@ -173,34 +174,32 @@ mode: TOK_TAP { conf->mode = MODE_TAP; }
;
protocol: TOK_STRING {
- if (!strcmp($1, "null"))
+ if (!strcmp($1->str, "null"))
conf->protocol = &fastd_protocol_null;
#ifdef WITH_PROTOCOL_ECFXP
- else if (!strcmp($1, "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);
-
- free($1);
+ exit_error(ctx, "config error: invalid protocol `%s'", $1->str);
}
;
-secret: TOK_STRING { free(conf->secret); conf->secret = $1; }
+secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); }
;
on_up: TOK_STRING {
free(conf->on_up);
free(conf->on_up_dir);
- conf->on_up = $1;
+ conf->on_up = strdup($1->str);
conf->on_up_dir = get_current_dir_name();
}
;
peer: maybe_string {
fastd_peer_config_new(ctx, conf);
- conf->peers->name = $1;
+ conf->peers->name = strdup($1->str);
}
;
@@ -225,10 +224,10 @@ peer_address: TOK_ADDR ':' port {
}
;
-peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = $1; }
+peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = strdup($1->str); }
;
-peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1, true, depth); free($1); }
+peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1->str, true, depth); }
;
@@ -238,16 +237,14 @@ peer_to_peer: boolean { conf->peer_to_peer = $1; }
include: TOK_PEER TOK_STRING maybe_as {
fastd_peer_config_new(ctx, conf);
- conf->peers->name = $3;
+ conf->peers->name = strdup($3->str);
- fastd_read_config(ctx, conf, $2, true, depth);
- free($2);
+ fastd_read_config(ctx, conf, $2->str, true, depth);
}
| TOK_PEERS TOK_FROM TOK_STRING {
- fastd_read_config_dir(ctx, conf, $3, depth);
- free($3);
+ fastd_read_config_dir(ctx, conf, $3->str, depth);
}
- | TOK_STRING { fastd_read_config(ctx, conf, $1, false, depth); free($1); }
+ | TOK_STRING { fastd_read_config(ctx, conf, $1->str, false, depth); }
;
@@ -269,7 +266,7 @@ boolean: TOK_YES { $$ = true; }
port: TOK_INTEGER {
if ($1 < 0 || $1 > 65635)
- exit_error(ctx, "invalid port %i", $1);
+ exit_error(ctx, "config error: invalid port %i", $1);
$$ = htons($1);
}
;
diff --git a/src/fastd.h b/src/fastd.h
index 5e62fb0..f402be8 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -132,6 +132,11 @@ struct _fastd_context {
unsigned int randseed;
};
+struct _fastd_config_str {
+ fastd_config_str *next;
+ char 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);
@@ -225,6 +230,22 @@ static inline size_t fastd_max_packet_size(const fastd_context *ctx) {
}
}
+static inline fastd_config_str* fastd_config_str_dup(const char *str) {
+ fastd_config_str *ret = malloc(sizeof(fastd_config_str) + strlen(str) + 1);
+ ret->next = NULL;
+ strcpy(ret->str, str);
+
+ return ret;
+}
+
+static inline void fastd_config_str_free(fastd_config_str *str) {
+ while(str) {
+ fastd_config_str *next = str->next;
+ free(str);
+ str = next;
+ }
+}
+
static inline bool timespec_after(const struct timespec *tp1, const struct timespec *tp2) {
return (tp1->tv_sec > tp2->tv_sec ||
(tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec));
diff --git a/src/types.h b/src/types.h
index 684fe4a..390b145 100644
--- a/src/types.h
+++ b/src/types.h
@@ -69,6 +69,8 @@ typedef struct _fastd_protocol fastd_protocol;
typedef struct _fastd_handshake fastd_handshake;
+typedef struct _fastd_config_str fastd_config_str;
+
/* May be defined by the protocol however it likes */
typedef struct _fastd_protocol_config fastd_protocol_config;
typedef struct _fastd_protocol_peer_config fastd_protocol_peer_config;