From 3c83faaa1660a70932c14b0fb1f9175b531cdf10 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 2 Apr 2012 01:28:34 +0200 Subject: Add sending of keep-alive packets --- src/config.c | 1 + src/fastd.c | 7 ++++- src/fastd.h | 1 + src/peer.c | 4 --- src/peer.h | 1 - src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c | 7 ++++- src/protocol_null.c | 7 ++++- src/task.c | 40 +++++++++++++++++++++++-- src/task.h | 3 ++ 9 files changed, 61 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/config.c b/src/config.c index 358a785..1842891 100644 --- a/src/config.c +++ b/src/config.c @@ -51,6 +51,7 @@ extern fastd_protocol fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; static void default_config(fastd_config *conf) { conf->loglevel = LOG_INFO; + conf->keepalive_interval = 60; conf->peer_stale_time = 300; conf->peer_stale_time_temp = 30; conf->eth_addr_stale_time = 300; diff --git a/src/fastd.c b/src/fastd.c index 311af08..373277d 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -207,7 +207,7 @@ static void handle_tasks(fastd_context *ctx) { break; case TASK_HANDSHAKE: - pr_debug(ctx, "Sending handshake to %P...", task->peer); + pr_debug(ctx, "sending handshake to %P...", task->peer); ctx->conf->protocol->handshake_init(ctx, task->peer); if (fastd_peer_is_established(task->peer)) @@ -216,6 +216,11 @@ static void handle_tasks(fastd_context *ctx) { fastd_task_schedule_handshake(ctx, task->peer, 20000); break; + case TASK_KEEPALIVE: + pr_debug(ctx, "sending keepalive to %P", task->peer); + ctx->conf->protocol->send(ctx, task->peer, fastd_buffer_alloc(0, ctx->conf->protocol->min_encrypt_head_space(ctx), 0)); + break; + default: exit_bug(ctx, "invalid task type"); } diff --git a/src/fastd.h b/src/fastd.h index 8f53409..2c1b02c 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -79,6 +79,7 @@ struct _fastd_protocol { struct _fastd_config { fastd_loglevel loglevel; + unsigned keepalive_interval; unsigned peer_stale_time; unsigned peer_stale_time_temp; unsigned eth_addr_stale_time; diff --git a/src/peer.c b/src/peer.c index a86a0d2..c88152d 100644 --- a/src/peer.c +++ b/src/peer.c @@ -148,10 +148,6 @@ fastd_peer* fastd_peer_add_temp(fastd_context *ctx, const fastd_peer_address *ad return peer; } -void fastd_peer_clean_handshakes(fastd_context *ctx, fastd_peer *peer) { - fastd_task_delete_peer_handshakes(ctx, peer); -} - fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_peer) { pr_debug(ctx, "merging peer %P into %P", temp_peer, perm_peer); diff --git a/src/peer.h b/src/peer.h index f3b9a93..1ffa18b 100644 --- a/src/peer.h +++ b/src/peer.h @@ -75,7 +75,6 @@ fastd_peer_config* fastd_peer_config_new(fastd_context *ctx, fastd_config *conf) void fastd_peer_reset(fastd_context *ctx, fastd_peer *peer); fastd_peer* fastd_peer_add(fastd_context *ctx, fastd_peer_config *conf); fastd_peer* fastd_peer_add_temp(fastd_context *ctx, const fastd_peer_address *address); -void fastd_peer_clean_handshakes(fastd_context *ctx, fastd_peer *peer); fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_peer); void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer); diff --git a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c index 8988778..913ac48 100644 --- a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c +++ b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c @@ -414,6 +414,8 @@ static void establish(fastd_context *ctx, fastd_peer *peer, const fastd_peer_con fastd_peer_set_established(ctx, peer); } + fastd_task_schedule_keepalive(ctx, peer, ctx->conf->keepalive_interval*1000); + if (!initiator) protocol_send(ctx, peer, fastd_buffer_alloc(0, protocol_min_encrypt_head_space(ctx), 0)); } @@ -712,7 +714,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf if (crypto_secretbox_xsalsa20poly1305_open(recv_buffer.data, buffer.data, buffer.len, nonce, session->key) == 0) { if (!session->handshakes_cleaned) { pr_debug(ctx, "cleaning left handshakes with %P", peer); - fastd_peer_clean_handshakes(ctx, peer); + fastd_task_delete_peer_handshakes(ctx, peer); session->handshakes_cleaned = true; } @@ -784,6 +786,9 @@ static void protocol_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buf fastd_task_put_send(ctx, peer, send_buffer); increment_nonce(session->send_nonce); + + fastd_task_delete_peer_keepalives(ctx, peer); + fastd_task_schedule_keepalive(ctx, peer, ctx->conf->keepalive_interval*1000); } static void protocol_free_peer_state(fastd_context *ctx, fastd_peer *peer) { diff --git a/src/protocol_null.c b/src/protocol_null.c index 163d164..cc08877 100644 --- a/src/protocol_null.c +++ b/src/protocol_null.c @@ -71,6 +71,8 @@ static void establish(fastd_context *ctx, fastd_peer *peer) { else { fastd_peer_set_established(ctx, peer); } + + fastd_task_schedule_keepalive(ctx, peer, ctx->conf->keepalive_interval*1000); } static void protocol_handshake_handle(fastd_context *ctx, fastd_peer *peer, const fastd_handshake *handshake) { @@ -101,10 +103,13 @@ static void protocol_handshake_handle(fastd_context *ctx, fastd_peer *peer, cons static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { if (fastd_peer_is_established(peer) && buffer.len) { /* this could be optimized a bit */ - fastd_peer_clean_handshakes(ctx, peer); + fastd_task_delete_peer_handshakes(ctx, peer); fastd_peer_seen(ctx, peer); fastd_task_put_handle_recv(ctx, peer, buffer); + + fastd_task_delete_peer_keepalives(ctx, peer); + fastd_task_schedule_keepalive(ctx, peer, ctx->conf->keepalive_interval*1000); } else { fastd_buffer_free(buffer); diff --git a/src/task.c b/src/task.c index c45bbcc..bd3ee7a 100644 --- a/src/task.c +++ b/src/task.c @@ -86,6 +86,30 @@ void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int tim fastd_queue_put(ctx, &ctx->task_queue, &task->entry, timeout); } +static bool is_keepalive(fastd_queue_entry *data, void *extra) { + fastd_task *task = container_of(data, fastd_task, entry); + fastd_peer *peer = extra; + + if (task->peer != peer) + return true; + + return (task->type == TASK_KEEPALIVE); +} + +void fastd_task_schedule_keepalive(fastd_context *ctx, fastd_peer *peer, int timeout) { + if (fastd_queue_has_entry(ctx, &ctx->task_queue, is_keepalive, peer)) { + pr_debug(ctx, "not sending a keepalive to %P, there still is one queued", peer); + return; + } + + fastd_task *task = malloc(sizeof(fastd_task)); + + task->type = TASK_KEEPALIVE; + task->peer = peer; + + fastd_queue_put(ctx, &ctx->task_queue, &task->entry, timeout); +} + typedef struct _replace_peer_extra { fastd_peer *old_peer; fastd_peer *new_peer; @@ -112,6 +136,7 @@ void fastd_task_replace_peer(fastd_context *ctx, fastd_peer *old_peer, fastd_pee typedef struct _delete_task_extra { fastd_peer *peer; bool handshake_only; + bool keepalive_only; } delete_task_extra; static bool delete_task(fastd_queue_entry *data, void *extra) { @@ -125,6 +150,9 @@ static bool delete_task(fastd_queue_entry *data, void *extra) { if (e->handshake_only && task->type != TASK_HANDSHAKE) return true; + if (e->keepalive_only && task->type != TASK_KEEPALIVE) + return true; + switch (task->type) { case TASK_SEND: fastd_buffer_free(task->send.buffer); @@ -136,6 +164,9 @@ static bool delete_task(fastd_queue_entry *data, void *extra) { case TASK_HANDSHAKE: break; + + case TASK_KEEPALIVE: + break; } free(task); @@ -144,11 +175,16 @@ static bool delete_task(fastd_queue_entry *data, void *extra) { } void fastd_task_delete_peer(fastd_context *ctx, fastd_peer *peer) { - delete_task_extra extra = {peer, false}; + delete_task_extra extra = {peer, false, false}; fastd_queue_filter(ctx, &ctx->task_queue, delete_task, &extra); } void fastd_task_delete_peer_handshakes(fastd_context *ctx, fastd_peer *peer) { - delete_task_extra extra = {peer, true}; + delete_task_extra extra = {peer, true, false}; + fastd_queue_filter(ctx, &ctx->task_queue, delete_task, &extra); +} + +void fastd_task_delete_peer_keepalives(fastd_context *ctx, fastd_peer *peer) { + delete_task_extra extra = {peer, false, true}; fastd_queue_filter(ctx, &ctx->task_queue, delete_task, &extra); } diff --git a/src/task.h b/src/task.h index 312c8f9..259ccfc 100644 --- a/src/task.h +++ b/src/task.h @@ -37,6 +37,7 @@ typedef enum _fastd_task_type { TASK_SEND, TASK_HANDLE_RECV, TASK_HANDSHAKE, + TASK_KEEPALIVE, } fastd_task_type; typedef struct _fastd_task_any { @@ -77,9 +78,11 @@ void fastd_task_put_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buff void fastd_task_put_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int timeout); +void fastd_task_schedule_keepalive(fastd_context *ctx, fastd_peer *peer, int timeout); void fastd_task_replace_peer(fastd_context *ctx, fastd_peer *old_peer, fastd_peer *new_peer); void fastd_task_delete_peer(fastd_context *ctx, fastd_peer *peer); void fastd_task_delete_peer_handshakes(fastd_context *ctx, fastd_peer *peer); +void fastd_task_delete_peer_keepalives(fastd_context *ctx, fastd_peer *peer); #endif /* _FASTD_TASK_H_ */ -- cgit v1.2.3