summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config.c1
-rw-r--r--src/fastd.c7
-rw-r--r--src/fastd.h1
-rw-r--r--src/peer.c4
-rw-r--r--src/peer.h1
-rw-r--r--src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c7
-rw-r--r--src/protocol_null.c7
-rw-r--r--src/task.c40
-rw-r--r--src/task.h3
9 files changed, 61 insertions, 10 deletions
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_ */