summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fastd.c8
-rw-r--r--src/fastd.h2
-rw-r--r--src/peer.c89
-rw-r--r--src/peer.h3
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h2
-rw-r--r--src/protocols/ec25519_fhmqvc/handshake.c2
-rw-r--r--src/protocols/ec25519_fhmqvc/util.c8
-rw-r--r--src/shell.c128
-rw-r--r--src/shell.h9
-rw-r--r--src/types.h1
10 files changed, 161 insertions, 91 deletions
diff --git a/src/fastd.c b/src/fastd.c
index c9f03f0..2b08a7e 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -276,19 +276,19 @@ void fastd_handle_receive(fastd_peer_t *peer, fastd_buffer_t buffer) {
}
static inline void on_pre_up(void) {
- fastd_shell_command_exec(&conf.on_pre_up, NULL, NULL, NULL);
+ fastd_shell_command_exec(&conf.on_pre_up, NULL);
}
static inline void on_up(void) {
- fastd_shell_command_exec(&conf.on_up, NULL, NULL, NULL);
+ fastd_shell_command_exec(&conf.on_up, NULL);
}
static inline void on_down(void) {
- fastd_shell_command_exec(&conf.on_down, NULL, NULL, NULL);
+ fastd_shell_command_exec(&conf.on_down, NULL);
}
static inline void on_post_down(void) {
- fastd_shell_command_exec(&conf.on_post_down, NULL, NULL, NULL);
+ fastd_shell_command_exec(&conf.on_post_down, NULL);
}
static fastd_peer_group_t* init_peer_group(const fastd_peer_group_config_t *config, fastd_peer_group_t *parent) {
diff --git a/src/fastd.h b/src/fastd.h
index f12d036..838ce94 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -70,7 +70,7 @@ struct fastd_protocol {
void (*generate_key)(void);
void (*show_key)(void);
- void (*set_shell_env)(const fastd_peer_t *peer);
+ void (*set_shell_env)(fastd_shell_env_t *env, const fastd_peer_t *peer);
bool (*describe_peer)(const fastd_peer_t *peer, char *buf, size_t len);
};
diff --git a/src/peer.c b/src/peer.c
index 879d3a7..860cf1d 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -32,12 +32,88 @@
#include <sys/wait.h>
+void fastd_peer_set_shell_env(fastd_shell_env_t *env, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr) {
+ /* both INET6_ADDRSTRLEN and IFNAMESIZE already include space for the zero termination, so there is no need to add space for the '%' here. */
+ char buf[INET6_ADDRSTRLEN+IF_NAMESIZE];
+
+ fastd_shell_env_set(env, "PEER_NAME", (peer && peer->config) ? peer->config->name : NULL);
+
+ switch(local_addr ? local_addr->sa.sa_family : AF_UNSPEC) {
+ case AF_INET:
+ inet_ntop(AF_INET, &local_addr->in.sin_addr, buf, sizeof(buf));
+ fastd_shell_env_set(env, "LOCAL_ADDRESS", buf);
+
+ snprintf(buf, sizeof(buf), "%u", ntohs(local_addr->in.sin_port));
+ fastd_shell_env_set(env, "LOCAL_PORT", buf);
+
+ break;
+
+ case AF_INET6:
+ inet_ntop(AF_INET6, &local_addr->in6.sin6_addr, buf, sizeof(buf));
+
+ if (IN6_IS_ADDR_LINKLOCAL(&local_addr->in6.sin6_addr)) {
+ if (if_indextoname(local_addr->in6.sin6_scope_id, buf+strlen(buf)+1))
+ buf[strlen(buf)] = '%';
+ }
+
+ fastd_shell_env_set(env, "LOCAL_ADDRESS", buf);
+
+ snprintf(buf, sizeof(buf), "%u", ntohs(local_addr->in6.sin6_port));
+ fastd_shell_env_set(env, "LOCAL_PORT", buf);
+
+ break;
+
+ default:
+ fastd_shell_env_set(env, "LOCAL_ADDRESS", NULL);
+ fastd_shell_env_set(env, "LOCAL_PORT", NULL);
+ }
+
+ switch(peer_addr ? peer_addr->sa.sa_family : AF_UNSPEC) {
+ case AF_INET:
+ inet_ntop(AF_INET, &peer_addr->in.sin_addr, buf, sizeof(buf));
+ fastd_shell_env_set(env, "PEER_ADDRESS", buf);
+
+ snprintf(buf, sizeof(buf), "%u", ntohs(peer_addr->in.sin_port));
+ fastd_shell_env_set(env, "PEER_PORT", buf);
+
+ break;
+
+ case AF_INET6:
+ inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, buf, sizeof(buf));
+
+ if (IN6_IS_ADDR_LINKLOCAL(&peer_addr->in6.sin6_addr)) {
+ if (if_indextoname(peer_addr->in6.sin6_scope_id, buf+strlen(buf)+1))
+ buf[strlen(buf)] = '%';
+ }
+
+ fastd_shell_env_set(env, "PEER_ADDRESS", buf);
+
+ snprintf(buf, sizeof(buf), "%u", ntohs(peer_addr->in6.sin6_port));
+ fastd_shell_env_set(env, "PEER_PORT", buf);
+
+ break;
+
+ default:
+ fastd_shell_env_set(env, "PEER_ADDRESS", NULL);
+ fastd_shell_env_set(env, "PEER_PORT", NULL);
+ }
+
+ conf.protocol->set_shell_env(env, peer);
+}
+
+void fastd_peer_exec_shell_command(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr) {
+ fastd_shell_env_t *env = fastd_shell_env_alloc();
+ fastd_peer_set_shell_env(env, peer, local_addr, peer_addr);
+ fastd_shell_command_exec(command, env);
+ fastd_shell_env_free(env);
+}
+
static inline void on_establish(const fastd_peer_t *peer) {
- fastd_shell_command_exec(&conf.on_establish, peer, &peer->local_address, &peer->address);
+ fastd_peer_exec_shell_command(&conf.on_establish, peer, &peer->local_address, &peer->address);
}
static inline void on_disestablish(const fastd_peer_t *peer) {
- fastd_shell_command_exec(&conf.on_disestablish, peer, &peer->local_address, &peer->address);
+ fastd_peer_exec_shell_command(&conf.on_disestablish, peer, &peer->local_address, &peer->address);
}
static int peer_id_cmp(fastd_peer_t *const *a, fastd_peer_t *const *b) {
@@ -631,8 +707,15 @@ bool fastd_peer_verify_temporary(fastd_peer_t *peer, const fastd_peer_address_t
/* TODO: async not supported yet */
+ fastd_shell_env_t *env = fastd_shell_env_alloc();
+ fastd_peer_set_shell_env(env, peer, local_addr, peer_addr);
+
int ret;
- if (!fastd_shell_command_exec_sync(&conf.on_verify, peer, local_addr, peer_addr, &ret))
+ bool ok = fastd_shell_command_exec_sync(&conf.on_verify, env, &ret);
+
+ fastd_shell_env_free(env);
+
+ if (!ok)
return false;
if (WIFSIGNALED(ret)) {
diff --git a/src/peer.h b/src/peer.h
index 36a2b10..c7cf603 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -139,6 +139,9 @@ void fastd_peer_reset_socket(fastd_peer_t *peer);
void fastd_peer_schedule_handshake(fastd_peer_t *peer, int delay);
fastd_peer_t* fastd_peer_find_by_id(uint64_t id);
+void fastd_peer_set_shell_env(fastd_shell_env_t *env, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr);
+void fastd_peer_exec_shell_command(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr);
+
static inline void fastd_peer_schedule_handshake_default(fastd_peer_t *peer) {
fastd_peer_schedule_handshake(peer, fastd_rand(17500, 22500));
}
diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
index e7c80e0..fcf9b56 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
@@ -95,7 +95,7 @@ void fastd_protocol_ec25519_fhmqvc_send_empty(fastd_peer_t *peer, protocol_sessi
void fastd_protocol_ec25519_fhmqvc_generate_key(void);
void fastd_protocol_ec25519_fhmqvc_show_key(void);
-void fastd_protocol_ec25519_fhmqvc_set_shell_env(const fastd_peer_t *peer);
+void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const fastd_peer_t *peer);
bool fastd_protocol_ec25519_fhmqvc_describe_peer(const fastd_peer_t *peer, char *buf, size_t len);
diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c
index 37c753f..c4177b4 100644
--- a/src/protocols/ec25519_fhmqvc/handshake.c
+++ b/src/protocols/ec25519_fhmqvc/handshake.c
@@ -524,7 +524,7 @@ void fastd_protocol_ec25519_fhmqvc_handshake_init(const fastd_socket_t *sock, co
fastd_handshake_add(&buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, &ctx.protocol_state->handshake_key.key.public);
if (!peer || !fastd_peer_is_established(peer))
- fastd_shell_command_exec(&conf.on_connect, peer, (local_addr && local_addr->sa.sa_family) ? local_addr : sock->bound_addr, remote_addr);
+ fastd_peer_exec_shell_command(&conf.on_connect, peer, (local_addr && local_addr->sa.sa_family) ? local_addr : sock->bound_addr, remote_addr);
fastd_send_handshake(sock, local_addr, remote_addr, peer, buffer);
}
diff --git a/src/protocols/ec25519_fhmqvc/util.c b/src/protocols/ec25519_fhmqvc/util.c
index 8d11eeb..a53513f 100644
--- a/src/protocols/ec25519_fhmqvc/util.c
+++ b/src/protocols/ec25519_fhmqvc/util.c
@@ -64,18 +64,18 @@ void fastd_protocol_ec25519_fhmqvc_show_key(void) {
print_hexdump("Public: ", conf.protocol_config->key.public.u8);
}
-void fastd_protocol_ec25519_fhmqvc_set_shell_env(const fastd_peer_t *peer) {
+void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const fastd_peer_t *peer) {
char buf[65];
hexdump(buf, conf.protocol_config->key.public.u8);
- setenv("LOCAL_KEY", buf, 1);
+ fastd_shell_env_set(env, "LOCAL_KEY", buf);
if (peer && peer->protocol_config) {
hexdump(buf, peer->protocol_config->public_key.u8);
- setenv("PEER_KEY", buf, 1);
+ fastd_shell_env_set(env, "PEER_KEY", buf);
}
else {
- unsetenv("PEER_KEY");
+ fastd_shell_env_set(env, "PEER_KEY", NULL);
}
}
diff --git a/src/shell.c b/src/shell.c
index e35e986..3b2644b 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -25,16 +25,48 @@
#include "shell.h"
-#include "peer.h"
+#include "fastd.h"
-#include <arpa/inet.h>
#include <net/if.h>
#include <sys/wait.h>
-static void shell_command_setenv(pid_t pid, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr) {
- /* both INET6_ADDRSTRLEN and IFNAMESIZE already include space for the zero termination, so there is no need to add space for the '%' here. */
- char buf[INET6_ADDRSTRLEN+IF_NAMESIZE];
+typedef struct shell_env_entry {
+ const char *key;
+ char *value;
+} shell_env_entry_t;
+
+
+struct fastd_shell_env {
+ VECTOR(shell_env_entry_t) entries;
+};
+
+
+fastd_shell_env_t * fastd_shell_env_alloc(void) {
+ fastd_shell_env_t *env = malloc(sizeof(fastd_shell_env_t));
+ VECTOR_ALLOC(env->entries, 0);
+
+ return env;
+}
+
+void fastd_shell_env_set(fastd_shell_env_t *env, const char *key, const char *value) {
+ shell_env_entry_t entry = {.key = key, .value = value ? strdup(value) : NULL};
+ VECTOR_ADD(env->entries, entry);
+}
+
+void fastd_shell_env_free(fastd_shell_env_t *env) {
+ size_t i;
+ for (i = 0; i < VECTOR_LEN(env->entries); i++) {
+ shell_env_entry_t *entry = &VECTOR_INDEX(env->entries, i);
+ free(entry->value);
+ }
+
+ VECTOR_FREE(env->entries);
+ free(env);
+}
+
+static void shell_command_setenv(pid_t pid, const fastd_shell_env_t *env) {
+ char buf[20];
snprintf(buf, sizeof(buf), "%u", (unsigned)pid);
setenv("FASTD_PID", buf, 1);
@@ -57,75 +89,21 @@ static void shell_command_setenv(pid_t pid, const fastd_peer_t *peer, const fast
snprintf(buf, sizeof(buf), "%u", conf.mtu);
setenv("INTERFACE_MTU", buf, 1);
- if (peer && peer->config && peer->config->name)
- setenv("PEER_NAME", peer->config->name, 1);
- else
- unsetenv("PEER_NAME");
-
- switch(local_addr ? local_addr->sa.sa_family : AF_UNSPEC) {
- case AF_INET:
- inet_ntop(AF_INET, &local_addr->in.sin_addr, buf, sizeof(buf));
- setenv("LOCAL_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(local_addr->in.sin_port));
- setenv("LOCAL_PORT", buf, 1);
-
- break;
-
- case AF_INET6:
- inet_ntop(AF_INET6, &local_addr->in6.sin6_addr, buf, sizeof(buf));
-
- if (IN6_IS_ADDR_LINKLOCAL(&local_addr->in6.sin6_addr)) {
- if (if_indextoname(local_addr->in6.sin6_scope_id, buf+strlen(buf)+1))
- buf[strlen(buf)] = '%';
- }
-
- setenv("LOCAL_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(local_addr->in6.sin6_port));
- setenv("LOCAL_PORT", buf, 1);
-
- break;
-
- default:
- unsetenv("LOCAL_ADDRESS");
- unsetenv("LOCAL_PORT");
- }
-
- switch(peer_addr ? peer_addr->sa.sa_family : AF_UNSPEC) {
- case AF_INET:
- inet_ntop(AF_INET, &peer_addr->in.sin_addr, buf, sizeof(buf));
- setenv("PEER_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(peer_addr->in.sin_port));
- setenv("PEER_PORT", buf, 1);
-
- break;
-
- case AF_INET6:
- inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, buf, sizeof(buf));
-
- if (IN6_IS_ADDR_LINKLOCAL(&peer_addr->in6.sin6_addr)) {
- if (if_indextoname(peer_addr->in6.sin6_scope_id, buf+strlen(buf)+1))
- buf[strlen(buf)] = '%';
- }
-
- setenv("PEER_ADDRESS", buf, 1);
-
- snprintf(buf, sizeof(buf), "%u", ntohs(peer_addr->in6.sin6_port));
- setenv("PEER_PORT", buf, 1);
+ if (!env)
+ return;
- break;
+ size_t i;
+ for (i = 0; i < VECTOR_LEN(env->entries); i++) {
+ shell_env_entry_t *entry = &VECTOR_INDEX(env->entries, i);
- default:
- unsetenv("PEER_ADDRESS");
- unsetenv("PEER_PORT");
+ if (entry->value)
+ setenv(entry->key, entry->value, 1);
+ else
+ unsetenv(entry->key);
}
-
- conf.protocol->set_shell_env(peer);
}
-static bool shell_command_do_exec(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, pid_t *pid_ret) {
+static bool shell_command_do_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env, pid_t *pid_ret) {
pid_t parent = getpid();
pid_t pid = fork();
@@ -145,7 +123,7 @@ static bool shell_command_do_exec(const fastd_shell_command_t *command, const fa
if (chdir(command->dir))
_exit(126);
- shell_command_setenv(parent, peer, local_addr, peer_addr);
+ shell_command_setenv(parent, env);
/* unblock SIGCHLD */
sigset_t set;
@@ -157,7 +135,7 @@ static bool shell_command_do_exec(const fastd_shell_command_t *command, const fa
_exit(127);
}
-bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, int *ret) {
+bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const fastd_shell_env_t *env, int *ret) {
if (!fastd_shell_command_isset(command))
return true;
@@ -168,7 +146,7 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f
pthread_sigmask(SIG_BLOCK, &set, &oldset);
pid_t pid;
- if (!shell_command_do_exec(command, peer, local_addr, peer_addr, &pid))
+ if (!shell_command_do_exec(command, env, &pid))
return false;
int status;
@@ -195,12 +173,12 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f
}
-void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr) {
+void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env) {
if (!fastd_shell_command_isset(command))
return;
if (command->sync)
- fastd_shell_command_exec_sync(command, peer, local_addr, peer_addr, NULL);
+ fastd_shell_command_exec_sync(command, env, NULL);
else
- shell_command_do_exec(command, peer, local_addr, peer_addr, NULL);
+ shell_command_do_exec(command, env, NULL);
}
diff --git a/src/shell.h b/src/shell.h
index 30de630..9b66477 100644
--- a/src/shell.h
+++ b/src/shell.h
@@ -38,6 +38,7 @@ struct fastd_shell_command {
bool sync;
};
+
static inline void fastd_shell_command_unset(fastd_shell_command_t *command) {
free(command->command);
command->command = NULL;
@@ -58,5 +59,9 @@ static inline bool fastd_shell_command_isset(const fastd_shell_command_t *comman
return command->command;
}
-bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, int *ret);
-void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr);
+fastd_shell_env_t * fastd_shell_env_alloc(void);
+void fastd_shell_env_set(fastd_shell_env_t *env, const char *key, const char *value);
+void fastd_shell_env_free(fastd_shell_env_t *env);
+
+bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const fastd_shell_env_t *env, int *ret);
+void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env);
diff --git a/src/types.h b/src/types.h
index 37560b1..8a80d19 100644
--- a/src/types.h
+++ b/src/types.h
@@ -132,6 +132,7 @@ typedef struct fastd_lex fastd_lex_t;
typedef struct fastd_string_stack fastd_string_stack_t;
typedef struct fastd_shell_command fastd_shell_command_t;
+typedef struct fastd_shell_env fastd_shell_env_t;
typedef struct fastd_async_resolve_return fastd_async_resolve_return_t;