summaryrefslogtreecommitdiffstats
path: root/src/fastd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fastd.c')
-rw-r--r--src/fastd.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/src/fastd.c b/src/fastd.c
index 59e5c54..ee7f03a 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -55,6 +55,9 @@ static void on_terminate(int signo) {
}
static void on_sigusr1(int signo, siginfo_t *siginfo, void *context) {
+ if (siginfo->si_code != SI_QUEUE || !siginfo->si_value.sival_ptr)
+ return;
+
fastd_resolve_return *ret = siginfo->si_value.sival_ptr;
ret->next = ret->ctx->resolve_returns;
@@ -133,10 +136,10 @@ static void init_sockets(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->peer_dirs || ctx->conf->n_v4)
+ if (ctx->conf->peer_dirs || ctx->conf->n_floating || ctx->conf->n_v4 || ctx->conf->n_dynamic || ctx->conf->n_dynamic_v4)
addr_in.sin_family = AF_INET;
- if (ctx->conf->n_floating || ctx->conf->peer_dirs || ctx->conf->n_v6)
+ if (ctx->conf->peer_dirs || ctx->conf->n_floating || ctx->conf->n_v6 || ctx->conf->n_dynamic || ctx->conf->n_dynamic_v6)
addr_in6.sin6_family = AF_INET6;
}
@@ -362,13 +365,15 @@ static void delete_peers(fastd_context *ctx) {
}
}
-static void update_time(fastd_context *ctx) {
+static inline void update_time(fastd_context *ctx) {
clock_gettime(CLOCK_MONOTONIC, &ctx->now);
}
-static void send_handshake(fastd_context *ctx, fastd_peer *peer) {
- pr_debug(ctx, "sending handshake to %P...", peer);
- ctx->conf->protocol->handshake_init(ctx, peer);
+static inline void send_handshake(fastd_context *ctx, fastd_peer *peer) {
+ if (peer->address.sa.sa_family != AF_UNSPEC) {
+ pr_debug(ctx, "sending handshake to %P...", peer);
+ ctx->conf->protocol->handshake_init(ctx, peer);
+ }
fastd_task_schedule_handshake(ctx, peer, fastd_rand(ctx, 17500, 22500));
}
@@ -379,7 +384,7 @@ static void handle_tasks(fastd_context *ctx) {
switch (task->type) {
case TASK_HANDSHAKE:
if (task->peer->state == STATE_RESOLVE)
- fastd_resolve_peer_handshake(ctx, task->peer);
+ fastd_resolve_peer(ctx, task->peer->config);
else
send_handshake(ctx, task->peer);
break;
@@ -516,7 +521,9 @@ static void handle_socket(fastd_context *ctx, int sockfd) {
fastd_buffer_free(buffer);
}
}
- else if(ctx->conf->n_floating) {
+ else if(ctx->conf->n_floating || ctx->conf->n_dynamic ||
+ (recvaddr.sa.sa_family == AF_INET && ctx->conf->n_dynamic_v4) ||
+ (recvaddr.sa.sa_family == AF_INET6 && ctx->conf->n_dynamic_v6)) {
switch (packet_type) {
case PACKET_DATA:
peer = fastd_peer_add_temp(ctx, (fastd_peer_address*)&recvaddr);
@@ -570,25 +577,51 @@ static void handle_input(fastd_context *ctx) {
handle_socket(ctx, ctx->sock6fd);
}
+static void cleanup_peers(fastd_context *ctx) {
+ fastd_peer *peer, *next;
+
+ for (peer = ctx->peers; peer; peer = next) {
+ next = peer->next;
+
+ if (fastd_peer_is_temporary(peer)) {
+ if (timespec_diff(&ctx->now, &peer->seen) > ctx->conf->peer_stale_time_temp*1000)
+ fastd_peer_reset(ctx, peer);
+ }
+ else if (fastd_peer_is_established(peer)) {
+ if (timespec_diff(&ctx->now, &peer->seen) > ctx->conf->peer_stale_time*1000)
+ fastd_peer_reset(ctx, peer);
+ }
+ }
+}
+
+static void cleanup_peer_with_address(fastd_context *ctx, const fastd_peer_address *addr) {
+ fastd_peer *peer;
+ for (peer = ctx->peers; peer; peer = peer->next) {
+ if (fastd_peer_is_temporary(peer) && fastd_peer_addr_equal(&peer->address, addr)) {
+ fastd_peer_reset(ctx, peer);
+ return;
+ }
+ }
+}
+
static void handle_resolv_returns(fastd_context *ctx) {
while (ctx->resolve_returns) {
fastd_peer *peer;
for (peer = ctx->peers; peer; peer = peer->next) {
- if (peer->state != STATE_RESOLVE)
+ if (!peer->config)
continue;
if (!strequal(peer->config->hostname, ctx->resolve_returns->hostname))
continue;
- if (peer->config->address.sa.sa_family != AF_UNSPEC &&
- peer->config->address.sa.sa_family != ctx->resolve_returns->addr.sa.sa_family)
- continue;
-
- if (peer->config->address.in.sin_port != htons(ctx->resolve_returns->port))
+ if (!fastd_peer_config_matches_dynamic(peer->config, &ctx->resolve_returns->constraints))
continue;
+ cleanup_peer_with_address(ctx, &ctx->resolve_returns->addr);
peer->address = ctx->resolve_returns->addr;
- send_handshake(ctx, peer);
+
+ if (peer->state == STATE_RESOLVE)
+ send_handshake(ctx, peer);
break;
}
@@ -599,23 +632,6 @@ static void handle_resolv_returns(fastd_context *ctx) {
}
}
-static void cleanup_peers(fastd_context *ctx) {
- fastd_peer *peer, *next;
-
- for (peer = ctx->peers; peer; peer = next) {
- next = peer->next;
-
- if (fastd_peer_is_temporary(peer)) {
- if (timespec_diff(&ctx->now, &peer->seen) > ctx->conf->peer_stale_time_temp*1000)
- fastd_peer_reset(ctx, peer);
- }
- else if (fastd_peer_is_established(peer)) {
- if (timespec_diff(&ctx->now, &peer->seen) > ctx->conf->peer_stale_time*1000)
- fastd_peer_reset(ctx, peer);
- }
- }
-}
-
static void maintenance(fastd_context *ctx) {
cleanup_peers(ctx);