diff options
-rw-r--r-- | src/config.c | 2 | ||||
-rw-r--r-- | src/fastd.c | 4 | ||||
-rw-r--r-- | src/fastd.h | 4 | ||||
-rw-r--r-- | src/peer.c | 3 | ||||
-rw-r--r-- | src/peer.h | 2 | ||||
-rw-r--r-- | src/protocol_ec25519_fhmqvc.c | 2 | ||||
-rw-r--r-- | src/resolve.c | 32 |
7 files changed, 41 insertions, 8 deletions
diff --git a/src/config.c b/src/config.c index d017325..64903cb 100644 --- a/src/config.c +++ b/src/config.c @@ -63,6 +63,8 @@ static void default_config(fastd_config *conf) { conf->reorder_count = 64; conf->reorder_time = 10; + conf->min_resolve_interval = 15; + conf->ifname = NULL; memset(&conf->bind_addr_in, 0, sizeof(struct sockaddr_in)); diff --git a/src/fastd.c b/src/fastd.c index afa36eb..1f5c2bf 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -416,7 +416,7 @@ static void handle_tasks(fastd_context *ctx) { switch (task->type) { case TASK_HANDSHAKE: if (fastd_peer_is_dynamic(task->peer)) - fastd_resolve_peer(ctx, task->peer->config); + fastd_resolve_peer(ctx, task->peer); else send_handshake(ctx, task->peer); break; @@ -576,6 +576,8 @@ static void handle_resolv_returns(fastd_context *ctx) { if (!fastd_peer_config_matches_dynamic(peer->config, &resolve_return.constraints)) continue; + peer->last_resolve_return = ctx->now; + if (fastd_peer_claim_address(ctx, peer, &resolve_return.addr)) { send_handshake(ctx, peer); } diff --git a/src/fastd.h b/src/fastd.h index c586eed..add22f2 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -136,6 +136,8 @@ struct _fastd_config { unsigned reorder_count; unsigned reorder_time; + unsigned min_resolve_interval; + char *ifname; struct sockaddr_in bind_addr_in; @@ -222,7 +224,7 @@ void fastd_send(fastd_context *ctx, const fastd_peer_address *address, fastd_buf void fastd_send_handshake(fastd_context *ctx, const fastd_peer_address *address, fastd_buffer buffer); void fastd_handle_receive(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); -void fastd_resolve_peer(fastd_context *ctx, const fastd_peer_config *peer); +void fastd_resolve_peer(fastd_context *ctx, fastd_peer *peer); int fastd_vsnprintf(const fastd_context *ctx, char *buffer, size_t size, const char *format, va_list ap); void fastd_logf(const fastd_context *ctx, int level, const char *format, ...); @@ -176,6 +176,8 @@ static inline void setup_peer(fastd_context *ctx, fastd_peer *peer) { peer->address = peer->config->address; peer->established = false; + peer->last_resolve = (struct timespec){0, 0}; + peer->last_resolve_return = (struct timespec){0, 0}; peer->seen = (struct timespec){0, 0}; peer->protocol_state = NULL; @@ -284,6 +286,7 @@ bool fastd_peer_claim_address(fastd_context *ctx, fastd_peer *new_peer, const fa break; } else { + memset(&new_peer->address, 0, sizeof(fastd_peer_address)); return false; } } @@ -39,6 +39,8 @@ struct _fastd_peer { bool established; + struct timespec last_resolve; + struct timespec last_resolve_return; struct timespec seen; fastd_protocol_peer_state *protocol_state; diff --git a/src/protocol_ec25519_fhmqvc.c b/src/protocol_ec25519_fhmqvc.c index 1772f4b..75360b7 100644 --- a/src/protocol_ec25519_fhmqvc.c +++ b/src/protocol_ec25519_fhmqvc.c @@ -511,7 +511,7 @@ static const fastd_peer_config* match_sender_key(fastd_context *ctx, const fastd return config; } else { /* matches dynamic */ - fastd_resolve_peer(ctx, config); + fastd_resolve_peer(ctx, get_peer(ctx, config)); return NULL; } } diff --git a/src/resolve.c b/src/resolve.c index 2a913d8..8faffe2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -85,7 +85,7 @@ static void* resolve_peer(void *varg) { } if (write(arg->ctx->resolvewfd, &ret, sizeof(ret)) < 0) - exit_errno(arg->ctx, "write"); + pr_error_errno(arg->ctx, "can't write resolve return"); freeaddrinfo(res); free(arg); @@ -93,15 +93,37 @@ static void* resolve_peer(void *varg) { return NULL; } -void fastd_resolve_peer(fastd_context *ctx, const fastd_peer_config *peer) { - pr_verbose(ctx, "resolving host `%s' for peer `%s'...", peer->hostname, peer->name); +void fastd_resolve_peer(fastd_context *ctx, fastd_peer *peer) { + if (timespec_after(&peer->last_resolve, &peer->last_resolve_return)) { + pr_debug(ctx, "not resolving %P as there is already a resolve running", peer); + return; + } + + if (timespec_diff(&ctx->now, &peer->last_resolve) < ctx->conf->min_resolve_interval*1000) { + pr_debug(ctx, "not resolving %P as it has been resolved a short time ago", peer); + + fastd_resolve_return ret; + memset(&ret, 0, sizeof(ret)); + + ret.hostname = strdup(peer->config->hostname); + ret.constraints = peer->config->address; + ret.addr = peer->address; + + if (write(ctx->resolvewfd, &ret, sizeof(ret)) < 0) + pr_error_errno(ctx, "can't write resolve return"); + + return; + } + + pr_verbose(ctx, "resolving host `%s' for peer %P...", peer->config->hostname, peer); + peer->last_resolve = ctx->now; resolv_arg *arg = malloc(sizeof(resolv_arg)); arg->ctx = ctx; arg->master_thread = pthread_self(); - arg->hostname = strdup(peer->hostname); - arg->constraints = peer->address; + arg->hostname = strdup(peer->config->hostname); + arg->constraints = peer->config->address; pthread_t thread; if (pthread_create(&thread, NULL, resolve_peer, arg) != 0) { |