summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c94
-rw-r--r--src/config.l2
-rw-r--r--src/config.y2
-rw-r--r--src/fastd.c4
-rw-r--r--src/fastd.h21
-rw-r--r--src/peer.c1
-rw-r--r--src/types.h2
7 files changed, 74 insertions, 52 deletions
diff --git a/src/config.c b/src/config.c
index b745251..aa10b10 100644
--- a/src/config.c
+++ b/src/config.c
@@ -102,51 +102,61 @@ void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *d
char *oldcwd = get_current_dir_name();
- if (chdir(dir))
- exit_error(ctx, "change from directory `%s' to `%s' failed: %s", oldcwd, dir, strerror(errno));
-
- DIR *dirh = opendir(".");
+ if (!chdir(dir)) {
+ char *newdir = get_current_dir_name();
+ conf->peer_dirs = fastd_string_stack_push(conf->peer_dirs, newdir);
+ free(newdir);
+
+ DIR *dirh = opendir(".");
+
+ if (dirh) {
+ while (true) {
+ struct dirent entry, *result;
+ int ret;
+
+ ret = readdir_r(dirh, &entry, &result);
+ if (ret) {
+ pr_error(ctx, "readdir_r: %s", strerror(ret));
+ break;
+ }
- if (!dirh)
- exit_error(ctx, "opendir for `%s' failed: %s", dir, strerror(errno));
+ if (!result)
+ break;
+ if (result->d_name[0] == '.')
+ continue;
- while (true) {
- struct dirent entry, *result;
- int ret;
+ struct stat statbuf;
+ if (stat(result->d_name, &statbuf)) {
+ pr_warn(ctx, "ignoring file `%s': stat failed: %s", result->d_name, strerror(errno));
+ continue;
+ }
+ if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
+ pr_info(ctx, "ignoring file `%s': no regular file", result->d_name);
+ continue;
+ }
- ret = readdir_r(dirh, &entry, &result);
- if (ret)
- exit_error(ctx, "readdir_r: %s", strerror(ret));
+ fastd_peer_config_new(ctx, conf);
+ conf->peers->name = strdup(result->d_name);
+ conf->peers->config_source_dir = strdup(dir);
- if (!result)
- break;
- if (result->d_name[0] == '.')
- continue;
+ 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);
+ }
+ }
- struct stat statbuf;
- if (stat(result->d_name, &statbuf)) {
- pr_info(ctx, "ignoring file `%s': stat failed: %s", result->d_name, strerror(errno));
- continue;
+ closedir(dirh);
}
- if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
- pr_info(ctx, "ignoring file `%s': no regular file", result->d_name);
- continue;
+ else {
+ pr_error(ctx, "opendir for `%s' failed: %s", dir, strerror(errno));
}
- fastd_peer_config_new(ctx, conf);
- conf->peers->name = strdup(result->d_name);
- conf->peers->config_source_dir = strdup(dir);
-
- 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);
- }
+ chdir(oldcwd);
+ free(oldcwd);
+ }
+ else {
+ pr_error(ctx, "change from directory `%s' to `%s' failed: %s", oldcwd, dir, strerror(errno));
}
-
- closedir(dirh);
-
- chdir(oldcwd);
- free(oldcwd);
}
bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth) {
@@ -160,7 +170,7 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
FILE *file;
yyscan_t scanner;
fastd_config_pstate *ps;
- fastd_config_str *strings = NULL;
+ fastd_string_stack *strings = NULL;
fastd_config_yylex_init(&scanner);
ps = fastd_config_pstate_new();
@@ -222,7 +232,7 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
ret = false;
end_free:
- fastd_config_str_free(strings);
+ fastd_string_stack_free(strings);
fastd_config_pstate_delete(ps);
fastd_config_yylex_destroy(scanner);
@@ -491,8 +501,12 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
}
}
- if (conf->mode == MODE_TUN && (!conf->peers || conf->peers->next))
- exit_error(ctx, "config error: for tun mode exactly one peer must be configured");
+ if (conf->mode == MODE_TUN) {
+ if (!conf->peers || conf->peers->next)
+ exit_error(ctx, "config error: for tun mode exactly one peer must be configured");
+ if (conf->peer_dirs)
+ exit_error(ctx, "config error: for tun mode peer directories can't be used");
+ }
conf->protocol->init(ctx, conf);
}
diff --git a/src/config.l b/src/config.l
index 546bd8d..49c0117 100644
--- a/src/config.l
+++ b/src/config.l
@@ -116,7 +116,7 @@ no { UPDATE_LOCATION; return TOK_NO; }
yytext[i-esc] = yytext[i];
}
yytext[yyleng-esc-1] = 0;
- yylval->str = fastd_config_str_dup(yytext);
+ yylval->str = fastd_string_stack_dup(yytext);
BEGIN(INITIAL);
yylloc->last_column++;
return TOK_STRING;
diff --git a/src/config.y b/src/config.y
index df46f20..8b5e49e 100644
--- a/src/config.y
+++ b/src/config.y
@@ -43,7 +43,7 @@
%union {
int num;
- fastd_config_str *str;
+ fastd_string_stack *str;
char *error;
bool boolean;
struct in_addr addr;
diff --git a/src/fastd.c b/src/fastd.c
index 939c651..3185186 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -81,10 +81,10 @@ static void init_socket(fastd_context *ctx) {
struct sockaddr_in6 addr_in6 = ctx->conf->bind_addr_in6;
if (addr_in.sin_family == AF_UNSPEC && addr_in6.sin6_family == AF_UNSPEC) {
- if (ctx->conf->n_floating || ctx->conf->n_v4)
+ if (ctx->conf->n_floating || ctx->conf->peer_dirs || ctx->conf->n_v4)
addr_in.sin_family = AF_INET;
- if (ctx->conf->n_floating || ctx->conf->n_v6)
+ if (ctx->conf->n_floating || ctx->conf->peer_dirs || ctx->conf->n_v6)
addr_in6.sin6_family = AF_INET6;
}
diff --git a/src/fastd.h b/src/fastd.h
index 6eab856..4a4bd49 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -99,6 +99,7 @@ struct _fastd_config {
unsigned key_valid;
unsigned key_refresh;
+ fastd_string_stack *peer_dirs;
fastd_peer_config *peers;
unsigned n_floating;
@@ -132,8 +133,8 @@ struct _fastd_context {
unsigned int randseed;
};
-struct _fastd_config_str {
- fastd_config_str *next;
+struct _fastd_string_stack {
+ fastd_string_stack *next;
char str[];
};
@@ -230,17 +231,25 @@ 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);
+static inline fastd_string_stack* fastd_string_stack_dup(const char *str) {
+ fastd_string_stack *ret = malloc(sizeof(fastd_string_stack) + strlen(str) + 1);
ret->next = NULL;
strcpy(ret->str, str);
return ret;
}
-static inline void fastd_config_str_free(fastd_config_str *str) {
+static inline fastd_string_stack* fastd_string_stack_push(fastd_string_stack *stack, const char *str) {
+ fastd_string_stack *ret = malloc(sizeof(fastd_string_stack) + strlen(str) + 1);
+ ret->next = stack;
+ strcpy(ret->str, str);
+
+ return ret;
+}
+
+static inline void fastd_string_stack_free(fastd_string_stack *str) {
while(str) {
- fastd_config_str *next = str->next;
+ fastd_string_stack *next = str->next;
free(str);
str = next;
}
diff --git a/src/peer.c b/src/peer.c
index d0375ae..415358e 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -118,7 +118,6 @@ void fastd_peer_reset(fastd_context *ctx, fastd_peer *peer) {
}
-
static fastd_peer* add_peer(fastd_context *ctx) {
fastd_peer *peer = malloc(sizeof(fastd_peer));
diff --git a/src/types.h b/src/types.h
index 390b145..504b6dd 100644
--- a/src/types.h
+++ b/src/types.h
@@ -69,7 +69,7 @@ typedef struct _fastd_protocol fastd_protocol;
typedef struct _fastd_handshake fastd_handshake;
-typedef struct _fastd_config_str fastd_config_str;
+typedef struct _fastd_string_stack fastd_string_stack;
/* May be defined by the protocol however it likes */
typedef struct _fastd_protocol_config fastd_protocol_config;