summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config.c88
-rw-r--r--src/config.h19
-rw-r--r--src/config.y59
-rw-r--r--src/options.c12
-rw-r--r--src/peer.c15
-rw-r--r--src/peer.h3
-rw-r--r--src/types.h1
7 files changed, 105 insertions, 92 deletions
diff --git a/src/config.c b/src/config.c
index 21c30c4..1e6cff7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -143,22 +143,22 @@ void fastd_config_bind_address(const fastd_peer_address_t *address, const char *
}
/** Handles the start of a peer group configuration */
-void fastd_config_peer_group_push(const char *name) {
+void fastd_config_peer_group_push(fastd_parser_state_t *state, const char *name) {
fastd_peer_group_t *group = calloc(1, sizeof(fastd_peer_group_t));
group->name = strdup(name);
group->max_connections = -1;
- group->parent = conf.peer_group;
+ group->parent = state->peer_group;
group->next = group->parent->children;
group->parent->children = group;
- conf.peer_group = group;
+ state->peer_group = group;
}
/** Handles the end of a peer group configuration */
-void fastd_config_peer_group_pop(void) {
- conf.peer_group = conf.peer_group->parent;
+void fastd_config_peer_group_pop(fastd_parser_state_t *state) {
+ state->peer_group = state->peer_group->parent;
}
/** Frees a peer group and its children */
@@ -189,7 +189,7 @@ static bool has_peer_group_peer_dirs(const fastd_peer_group_t *group) {
}
/** Reads and processes all peer definitions in the current directory (which must also be supplied as the argument) */
-static void read_peer_dir(const char *dir) {
+static void read_peer_dir(fastd_peer_config_t **peers, fastd_peer_group_t *group, const char *dir) {
DIR *dirh = opendir(".");
if (dirh) {
@@ -221,13 +221,17 @@ static void read_peer_dir(const char *dir) {
continue;
}
- fastd_peer_config_new();
- conf.peers->name = strdup(result->d_name);
- conf.peers->config_source_dir = dir;
+ fastd_peer_config_t *peer = fastd_peer_config_new(group);
+ peer->name = strdup(result->d_name);
+ peer->config_source_dir = dir;
- if (!fastd_read_config(result->d_name, true, 0)) {
+ if (fastd_config_read(result->d_name, group, peer, 0)) {
+ peer->next = *peers;
+ *peers = peer;
+ }
+ else {
pr_warn("peer config `%s' will be ignored", result->d_name);
- fastd_peer_config_delete();
+ fastd_peer_config_free(peer);
}
}
@@ -240,14 +244,14 @@ static void read_peer_dir(const char *dir) {
}
}
-/** Reads all peer configured directories */
-static void read_peer_dirs(void) {
+/** Reads all configured peer directories for a peer grup */
+static void read_peer_dirs(fastd_peer_config_t **peers, fastd_peer_group_t *group) {
char *oldcwd = get_current_dir_name();
fastd_string_stack_t *dir;
- for (dir = conf.peer_group->peer_dirs; dir; dir = dir->next) {
+ for (dir = group->peer_dirs; dir; dir = dir->next) {
if (!chdir(dir->str))
- read_peer_dir(dir->str);
+ read_peer_dir(peers, group, dir->str);
else
pr_error("change from directory `%s' to `%s' failed: %s", oldcwd, dir->str, strerror(errno));
}
@@ -259,15 +263,15 @@ static void read_peer_dirs(void) {
}
/** Adds a peer directory to the configuration */
-void fastd_add_peer_dir(const char *dir) {
+void fastd_config_add_peer_dir(fastd_peer_group_t *group, const char *dir) {
char *oldcwd = get_current_dir_name();
if (!chdir(dir)) {
char *newdir = get_current_dir_name();
- conf.peer_group->peer_dirs = fastd_string_stack_push(conf.peer_group->peer_dirs, newdir);
+ group->peer_dirs = fastd_string_stack_push(group->peer_dirs, newdir);
free(newdir);
- if(chdir(oldcwd))
+ if (chdir(oldcwd))
pr_error("can't chdir to `%s': %s", oldcwd, strerror(errno));
}
else {
@@ -278,7 +282,7 @@ void fastd_add_peer_dir(const char *dir) {
}
/** Reads and processes a configuration file */
-bool fastd_read_config(const char *filename, bool peer_config, int depth) {
+bool fastd_config_read(const char *filename, fastd_peer_group_t *peer_group, fastd_peer_config_t *peer_config, int depth) {
if (depth >= MAX_CONFIG_DEPTH)
exit_error("maximum config include depth exceeded");
@@ -321,15 +325,21 @@ bool fastd_read_config(const char *filename, bool peer_config, int depth) {
int token;
YYSTYPE token_val;
YYLTYPE loc = {1, 0, 1, 0};
+ fastd_parser_state_t state = {
+ .peer_group = peer_group,
+ .peer = peer_config,
+ .filename = filename,
+ .depth = depth+1,
+ };
if (peer_config)
token = START_PEER_CONFIG;
else
- token = conf.peer_group->parent ? START_PEER_GROUP_CONFIG : START_CONFIG;
+ token = peer_group->parent ? START_PEER_GROUP_CONFIG : START_CONFIG;
- int parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, filename, depth+1);
+ int parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, &state);
- while(parse_ret == YYPUSH_MORE) {
+ while (parse_ret == YYPUSH_MORE) {
token = fastd_lex(&token_val, &loc, lex);
if (token < 0) {
@@ -343,7 +353,7 @@ bool fastd_read_config(const char *filename, bool peer_config, int depth) {
strings = token_val.str;
}
- parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, filename, depth+1);
+ parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, &state);
}
if (parse_ret)
@@ -559,17 +569,13 @@ void fastd_config_verify(void) {
conf.protocol->peer_verify(peer);
}
-/** Reads the peer dirs of the current peer group and its children */
-static void peer_dirs_read_peer_group(void) {
- read_peer_dirs();
-
- fastd_peer_group_t *base = conf.peer_group, *group;
- for (group = conf.peer_group->children; group; group = group->next) {
- conf.peer_group = group;
- peer_dirs_read_peer_group();
- }
+/** Reads the peer dirs of a peer group and its children */
+static void peer_dirs_read_peer_group(fastd_peer_config_t **peers, fastd_peer_group_t *group) {
+ read_peer_dirs(peers, group);
- conf.peer_group = base;
+ fastd_peer_group_t *child;
+ for (child = group->children; child; child = child->next)
+ peer_dirs_read_peer_group(peers, child);
}
/** Deletes peer configs that have disappeared from a peer dir on reconfiguration */
@@ -632,13 +638,8 @@ static void peer_dirs_handle_new_peers(fastd_peer_config_t **peers, fastd_peer_c
/** Refreshes the peer configurations from the configured peer dirs */
void fastd_config_load_peer_dirs(void) {
- fastd_peer_config_t *old_peers = conf.peers;
- conf.peers = NULL;
-
- peer_dirs_read_peer_group();
-
- fastd_peer_config_t *new_peers = conf.peers;
- conf.peers = old_peers;
+ fastd_peer_config_t *new_peers = NULL;
+ peer_dirs_read_peer_group(&new_peers, conf.peer_group);
peer_dirs_handle_old_peers(&conf.peers, &new_peers);
peer_dirs_handle_new_peers(&conf.peers, new_peers);
@@ -648,8 +649,11 @@ void fastd_config_load_peer_dirs(void) {
/** Frees all resources used by the global configuration */
void fastd_config_release(void) {
- while (conf.peers)
- fastd_peer_config_delete();
+ while (conf.peers) {
+ fastd_peer_config_t *peer = conf.peers, *next = peer->next;
+ fastd_peer_config_free(peer);
+ conf.peers = next;
+ }
while (conf.bind_addrs) {
fastd_bind_address_t *next = conf.bind_addrs->next;
diff --git a/src/config.h b/src/config.h
index 3231f6d..f4e1de5 100644
--- a/src/config.h
+++ b/src/config.h
@@ -35,20 +35,31 @@
#include "fastd.h"
+/** State of the config parser */
+struct fastd_parser_state {
+ fastd_peer_group_t *peer_group; /**< The current peer group */
+ fastd_peer_config_t *peer; /**< The peer currently being loaded */
+
+ const char *const filename; /**< The filename of the currently parsed file */
+ const int depth; /**< The include depth */
+};
+
+
void fastd_config_protocol(const char *name);
void fastd_config_method(const char *name);
void fastd_config_cipher(const char *name, const char *impl);
void fastd_config_mac(const char *name, const char *impl);
void fastd_config_bind_address(const fastd_peer_address_t *address, const char *bindtodev, bool default_v4, bool default_v6);
-void fastd_config_peer_group_push(const char *name);
-void fastd_config_peer_group_pop(void);
void fastd_config_release(void);
void fastd_config_handle_options(int argc, char *const argv[]);
void fastd_config_verify(void);
+bool fastd_config_read(const char *filename, fastd_peer_group_t *peer_group, fastd_peer_config_t *peer_config, int depth);
+void fastd_config_peer_group_push(fastd_parser_state_t *state, const char *name);
+void fastd_config_peer_group_pop(fastd_parser_state_t *state);
+void fastd_config_add_peer_dir(fastd_peer_group_t *group, const char *dir);
+
void fastd_configure(int argc, char *const argv[]);
void fastd_config_check(void);
void fastd_config_load_peer_dirs(void);
-void fastd_add_peer_dir(const char *dir);
-bool fastd_read_config(const char *filename, bool peer_config, int depth);
diff --git a/src/config.y b/src/config.y
index 88d6f53..a2e14e3 100644
--- a/src/config.y
+++ b/src/config.y
@@ -28,8 +28,7 @@
%define api.push-pull push
%name-prefix "fastd_config_"
%locations
-%parse-param {const char *filename}
-%parse-param {int depth}
+%parse-param {fastd_parser_state_t *state}
%code requires {
#include <src/fastd.h>
@@ -138,7 +137,7 @@
#include <limits.h>
- void fastd_config_error(YYLTYPE *loc, const char *filename, int depth, const char *s);
+ void fastd_config_error(YYLTYPE *loc, fastd_parser_state_t *state, const char *s);
}
@@ -349,7 +348,7 @@ packet_mark: TOK_UINT {
mtu: TOK_UINT {
if ($1 < 576 || $1 > 65535) {
- fastd_config_error(&@$, filename, depth, "invalid MTU");
+ fastd_config_error(&@$, state, "invalid MTU");
YYERROR;
}
@@ -416,15 +415,19 @@ on_verify: sync_def_async TOK_STRING {
#ifdef WITH_VERIFY
fastd_shell_command_set(&conf.on_verify, $2->str, $1);
#else
- fastd_config_error(&@$, filename, depth, "`on verify' is not supported by this version of fastd");
+ fastd_config_error(&@$, state, "`on verify' is not supported by this version of fastd");
YYERROR;
#endif
}
;
peer: TOK_STRING {
- fastd_peer_config_new();
- conf.peers->name = strdup($1->str);
+ fastd_peer_config_t *peer = fastd_peer_config_new(state->peer_group);
+ peer->name = strdup($1->str);
+ peer->next = conf.peers;
+
+ conf.peers = peer;
+ state->peer = peer;
}
;
@@ -439,7 +442,7 @@ peer_statement: TOK_REMOTE peer_remote ';'
;
peer_remote: TOK_ADDR4 port {
- fastd_remote_config_t **remote = &conf.peers->remotes;
+ fastd_remote_config_t **remote = &state->peer->remotes;
while (*remote)
remote = &(*remote)->next;
@@ -451,7 +454,7 @@ peer_remote: TOK_ADDR4 port {
fastd_peer_address_simplify(&(*remote)->address);
}
| TOK_ADDR6 port {
- fastd_remote_config_t **remote = &conf.peers->remotes;
+ fastd_remote_config_t **remote = &state->peer->remotes;
while (*remote)
remote = &(*remote)->next;
@@ -465,7 +468,7 @@ peer_remote: TOK_ADDR4 port {
| TOK_ADDR6_SCOPED port {
char addrbuf[INET6_ADDRSTRLEN];
size_t addrlen;
- fastd_remote_config_t **remote = &conf.peers->remotes;
+ fastd_remote_config_t **remote = &state->peer->remotes;
while (*remote)
remote = &(*remote)->next;
@@ -483,7 +486,7 @@ peer_remote: TOK_ADDR4 port {
(*remote)->address.in.sin_port = htons($2);
}
| maybe_af TOK_STRING port {
- fastd_remote_config_t **remote = &conf.peers->remotes;
+ fastd_remote_config_t **remote = &state->peer->remotes;
while (*remote)
remote = &(*remote)->next;
@@ -496,40 +499,40 @@ peer_remote: TOK_ADDR4 port {
;
peer_float: boolean {
- conf.peers->floating = $1;
+ state->peer->floating = $1;
}
;
peer_key: TOK_STRING {
- free(conf.peers->key); conf.peers->key = strdup($1->str);
+ free(state->peer->key); state->peer->key = strdup($1->str);
}
;
peer_include: TOK_STRING {
- if (!fastd_read_config($1->str, true, depth))
+ if (!fastd_config_read($1->str, state->peer_group, state->peer, state->depth))
YYERROR;
}
;
peer_group: TOK_STRING {
- fastd_config_peer_group_push($1->str);
+ fastd_config_peer_group_push(state, $1->str);
}
;
peer_group_after:
{
- fastd_config_peer_group_pop();
+ fastd_config_peer_group_pop(state);
}
;
peer_limit: TOK_UINT {
if ($1 > INT_MAX) {
- fastd_config_error(&@$, filename, depth, "invalid peer limit");
+ fastd_config_error(&@$, state, "invalid peer limit");
YYERROR;
}
- conf.peer_group->max_connections = $1;
+ state->peer_group->max_connections = $1;
}
;
@@ -538,18 +541,20 @@ forward: boolean { conf.forward = $1; }
include: TOK_PEER TOK_STRING maybe_as {
- fastd_peer_config_new();
+ fastd_peer_config_t *peer = fastd_peer_config_new(state->peer_group);
if ($3)
- conf.peers->name = strdup($3->str);
-
- if (!fastd_read_config($2->str, true, depth))
+ peer->name = strdup($3->str);
+ if (!fastd_config_read($2->str, state->peer_group, peer, state->depth))
YYERROR;
+
+ peer->next = conf.peers;
+ conf.peers = peer;
}
| TOK_PEERS TOK_FROM TOK_STRING {
- fastd_add_peer_dir($3->str);
+ fastd_config_add_peer_dir(state->peer_group, $3->str);
}
| TOK_STRING {
- if (!fastd_read_config($1->str, false, depth))
+ if (!fastd_config_read($1->str, state->peer_group, NULL, state->depth))
YYERROR;
}
;
@@ -595,7 +600,7 @@ colon_or_port: ':'
port: colon_or_port TOK_UINT {
if ($2 < 1 || $2 > 65535) {
- fastd_config_error(&@$, filename, depth, "invalid port");
+ fastd_config_error(&@$, state, "invalid port");
YYERROR;
}
$$ = $2;
@@ -603,6 +608,6 @@ port: colon_or_port TOK_UINT {
;
%%
-void fastd_config_error(YYLTYPE *loc, const char *filename, int depth UNUSED, const char *s) {
- pr_error("config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column);
+void fastd_config_error(YYLTYPE *loc, fastd_parser_state_t *state, const char *s) {
+ pr_error("config error: %s at %s:%i:%i", s, state->filename, loc->first_line, loc->first_column);
}
diff --git a/src/options.c b/src/options.c
index 7ac026e..63115ef 100644
--- a/src/options.c
+++ b/src/options.c
@@ -111,21 +111,25 @@ static void option_config(const char *arg) {
if (!strcmp(arg, "-"))
arg = NULL;
- if (!fastd_read_config(arg, false, 0))
+ if (!fastd_config_read(arg, conf.peer_group, NULL, 0))
exit(1);
}
/** Handles the --config-peer option */
static void option_config_peer(const char *arg) {
- fastd_peer_config_new();
+ fastd_peer_config_t *peer = fastd_peer_config_new(conf.peer_group);
- if(!fastd_read_config(arg, true, 0))
+ if(!fastd_config_read(arg, conf.peer_group, peer, 0))
exit(1);
+
+ peer->next = conf.peers;
+ conf.peers = peer;
+
}
/** Handles the --config-peer-dir option */
static void option_config_peer_dir(const char *arg) {
- fastd_add_peer_dir(arg);
+ fastd_config_add_peer_dir(conf.peer_group, arg);
}
diff --git a/src/peer.c b/src/peer.c
index fd123f7..5de7831 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -431,13 +431,9 @@ static void delete_peer(fastd_peer_t *peer) {
/** Allocates a new peer config */
-fastd_peer_config_t* fastd_peer_config_new(void) {
+fastd_peer_config_t* fastd_peer_config_new(fastd_peer_group_t *group) {
fastd_peer_config_t *peer = calloc(1, sizeof(fastd_peer_config_t));
-
- peer->group = conf.peer_group;
-
- peer->next = conf.peers;
- conf.peers = peer;
+ peer->group = group;
return peer;
}
@@ -458,13 +454,6 @@ void fastd_peer_config_free(fastd_peer_config_t *peer) {
free(peer);
}
-/** Deletes the peer config created last */
-void fastd_peer_config_delete(void) {
- fastd_peer_config_t *peer = conf.peers, *next = peer->next;
- fastd_peer_config_free(peer);
- conf.peers = next;
-}
-
/** Deletes a peer config, and removes the peer assiciated with the peer config */
void fastd_peer_config_purge(fastd_peer_config_t *config) {
size_t i;
diff --git a/src/peer.h b/src/peer.h
index 9da5f3c..7fcb092 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -165,9 +165,8 @@ static inline uint16_t fastd_peer_address_get_port(const fastd_peer_address_t *a
}
}
-fastd_peer_config_t* fastd_peer_config_new(void);
+fastd_peer_config_t* fastd_peer_config_new(fastd_peer_group_t *group);
void fastd_peer_config_free(fastd_peer_config_t *peer);
-void fastd_peer_config_delete(void);
void fastd_peer_config_purge(fastd_peer_config_t *config);
bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_config_t *peer2);
diff --git a/src/types.h b/src/types.h
index d13828c..3ab03a6 100644
--- a/src/types.h
+++ b/src/types.h
@@ -107,6 +107,7 @@ typedef struct fastd_mac fastd_mac_t;
typedef struct fastd_handshake fastd_handshake_t;
typedef struct fastd_lex fastd_lex_t;
+typedef struct fastd_parser_state fastd_parser_state_t;
typedef struct fastd_string_stack fastd_string_stack_t;
typedef struct fastd_shell_command fastd_shell_command_t;