diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2013-08-28 23:34:55 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2013-08-29 00:45:13 +0200 |
commit | dcaf41a18e1bd9014d1cf3ca7a7129a1be76e811 (patch) | |
tree | 024ee42fb7f76ed8e2fb4c1a5ec66031cdcc26b6 /src/fastd.c | |
parent | 2343f5329c0d5e7d8073810e56577d944b7c518e (diff) | |
download | fastd-dcaf41a18e1bd9014d1cf3ca7a7129a1be76e811.tar fastd-dcaf41a18e1bd9014d1cf3ca7a7129a1be76e811.zip |
Simplify keepalive sending
By using a global keepalive timer, the O(n) keepalive queue purge operation on
every send operation is avoided.
Diffstat (limited to 'src/fastd.c')
-rw-r--r-- | src/fastd.c | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/src/fastd.c b/src/fastd.c index 173e5f3..786f158 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -425,37 +425,27 @@ static void send_handshake(fastd_context_t *ctx, fastd_peer_t *peer) { static void handle_tasks(fastd_context_t *ctx) { fastd_task_t *task; while ((task = fastd_task_get(ctx)) != NULL) { - switch (task->type) { - case TASK_HANDSHAKE: - fastd_peer_schedule_handshake(ctx, task->peer); + fastd_peer_schedule_handshake(ctx, task->peer); - if(!fastd_peer_may_connect(ctx, task->peer)) { - task->peer->next_remote = task->peer->remotes; - break; - } - - send_handshake(ctx, task->peer); - - if (fastd_peer_is_established(task->peer)) - break; - - task->peer->next_remote = task->peer->next_remote->next; - if (!task->peer->next_remote) - task->peer->next_remote = task->peer->remotes; + if(!fastd_peer_may_connect(ctx, task->peer)) { + task->peer->next_remote = task->peer->remotes; + free(task); + continue; + } - if (fastd_remote_is_dynamic(task->peer->next_remote)) - fastd_resolve_peer(ctx, task->peer, task->peer->next_remote); + send_handshake(ctx, task->peer); - break; + if (fastd_peer_is_established(task->peer)) { + free(task); + continue; + } - case TASK_KEEPALIVE: - pr_debug2(ctx, "sending keepalive to %P", task->peer); - ctx->conf->protocol->send(ctx, task->peer, fastd_buffer_alloc(ctx, 0, ctx->conf->min_encrypt_head_space, ctx->conf->min_encrypt_tail_space)); - break; + task->peer->next_remote = task->peer->next_remote->next; + if (!task->peer->next_remote) + task->peer->next_remote = task->peer->remotes; - default: - exit_bug(ctx, "invalid task type"); - } + if (fastd_remote_is_dynamic(task->peer->next_remote)) + fastd_resolve_peer(ctx, task->peer, task->peer->next_remote); free(task); } @@ -557,10 +547,14 @@ static void handle_input(fastd_context_t *ctx) { if (i != n_fds) exit_bug(ctx, "fd count mismatch"); - int timeout = fastd_task_timeout(ctx); + int keepalive_timeout = timespec_diff(&ctx->next_keepalives, &ctx->now); - if (timeout < 0 || timeout > 60000) - timeout = 60000; /* call maintenance at least once a minute */ + if (keepalive_timeout < 0) + keepalive_timeout = 0; + + int timeout = fastd_task_timeout(ctx); + if (timeout < 0 || timeout > keepalive_timeout) + timeout = keepalive_timeout; int ret = poll(fds, n_fds, timeout); if (ret < 0) { @@ -628,6 +622,22 @@ static void maintenance(fastd_context_t *ctx) { fastd_peer_eth_addr_cleanup(ctx); fastd_socket_handle_binds(ctx); + + if (timespec_after(&ctx->now, &ctx->next_keepalives)) { + fastd_peer_t *peer; + for (peer = ctx->peers; peer; peer = peer->next) { + if (!fastd_peer_is_established(peer)) + continue; + + if (timespec_diff(&ctx->now, &peer->last_send) < (int)ctx->conf->keepalive_timeout*1000) + continue; + + pr_debug2(ctx, "sending keepalive to %P", peer); + ctx->conf->protocol->send(ctx, peer, fastd_buffer_alloc(ctx, 0, ctx->conf->min_encrypt_head_space, ctx->conf->min_encrypt_tail_space)); + } + + ctx->next_keepalives.tv_sec += ctx->conf->keepalive_interval; + } } @@ -748,6 +758,9 @@ int main(int argc, char *argv[]) { update_time(&ctx); + ctx.next_keepalives = ctx.now; + ctx.next_keepalives.tv_sec += conf.keepalive_interval; + pr_info(&ctx, "fastd " FASTD_VERSION " starting"); fastd_cap_init(&ctx); |