summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fastd.c10
-rw-r--r--src/fastd.h4
-rw-r--r--src/handshake.c134
-rw-r--r--src/handshake.h37
-rw-r--r--src/packet.h25
-rw-r--r--src/peer.c6
-rw-r--r--src/peer.h12
-rw-r--r--src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c16
-rw-r--r--src/protocol_null.c69
-rw-r--r--src/task.c3
-rw-r--r--src/task.h7
-rw-r--r--src/types.h5
12 files changed, 179 insertions, 149 deletions
diff --git a/src/fastd.c b/src/fastd.c
index 350e6f3..0083dcd 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -206,14 +206,14 @@ static void handle_tasks(fastd_context *ctx) {
break;
case TASK_HANDSHAKE:
- if (task->peer->state != STATE_WAIT && task->peer->state != STATE_TEMP && !task->handshake.force)
+ if (task->peer->state != STATE_WAIT && task->peer->state != STATE_TEMP)
break;
pr_debug(ctx, "Sending handshake to %P...", task->peer);
- fastd_handshake_send(ctx, task->peer);
+ ctx->conf->protocol->handshake_init(ctx, task->peer);
if (task->peer->state == STATE_WAIT)
- fastd_task_schedule_handshake(ctx, task->peer, 20000, false);
+ fastd_task_schedule_handshake(ctx, task->peer, 20000);
break;
default:
@@ -321,12 +321,10 @@ static void handle_socket(fastd_context *ctx, int sockfd) {
if (peer) {
switch (packet_type) {
case PACKET_DATA:
- peer->seen = ctx->now;
ctx->conf->protocol->handle_recv(ctx, peer, buffer);
break;
case PACKET_HANDSHAKE:
- peer->seen = ctx->now;
fastd_handshake_handle(ctx, peer, buffer);
break;
@@ -341,8 +339,6 @@ static void handle_socket(fastd_context *ctx, int sockfd) {
peer = fastd_peer_add_temp(ctx, (fastd_peer_address*)&recvaddr);
ctx->conf->protocol->handle_recv(ctx, peer, buffer);
- pr_debug(ctx, "Requesting re-handshake from %P", peer);
- fastd_handshake_rehandshake(ctx, peer);
break;
case PACKET_HANDSHAKE:
diff --git a/src/fastd.h b/src/fastd.h
index ba5aed0..4db53e4 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -64,7 +64,8 @@ struct _fastd_protocol {
size_t (*min_encrypt_head_space)(fastd_context *ctx);
size_t (*min_decrypt_head_space)(fastd_context *ctx);
- void (*init_peer)(fastd_context *ctx, fastd_peer *peer);
+ void (*handshake_init)(fastd_context *ctx, fastd_peer *peer);
+ void (*handshake_handle)(fastd_context *ctx, fastd_peer *peer, const fastd_handshake *handshake);
void (*handle_recv)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
void (*send)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
@@ -123,7 +124,6 @@ struct _fastd_context {
fastd_peer_eth_addr *eth_addr;
};
-
void fastd_printf(const fastd_context *ctx, const char *format, ...);
void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *dir, int depth);
diff --git a/src/handshake.c b/src/handshake.c
index 53224b0..fcec5af 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -47,7 +47,7 @@ static const char const *REPLY_TYPES[REPLY_MAX] = {
"unacceptable value",
};
-#define AS_UINT8(ptr) (*(uint8_t*)(ptr))
+#define AS_UINT8(ptr) (*(uint8_t*)(ptr).data)
static inline void handshake_add(fastd_context *ctx, fastd_buffer *buffer, fastd_handshake_record_type type, size_t len, const void *data) {
if ((uint8_t*)buffer->data + buffer->len + 2 + len > (uint8_t*)buffer->base + buffer->base_len)
@@ -75,48 +75,53 @@ static inline void handshake_add_uint8(fastd_context *ctx, fastd_buffer *buffer,
buffer->len += 3;
}
-void fastd_handshake_send(fastd_context *ctx, fastd_peer *peer) {
+fastd_buffer fastd_handshake_new_init(fastd_context *ctx, fastd_peer *peer, size_t tail_space) {
size_t protocol_len = strlen(ctx->conf->protocol->name);
fastd_buffer buffer = fastd_buffer_alloc(sizeof(fastd_packet), 0,
2*3 + /* handshake type, mode */
- 2+protocol_len /* protocol name */
+ 2+protocol_len+ /* protocol name */
+ tail_space
);
fastd_packet *request = buffer.data;
request->req_id = ++peer->last_req_id;
request->rsv = 0;
- handshake_add_uint8(ctx, &buffer, RECORD_HANDSHAKE_TYPE, HANDSHAKE_REQUEST);
+ handshake_add_uint8(ctx, &buffer, RECORD_HANDSHAKE_TYPE, 1);
handshake_add_uint8(ctx, &buffer, RECORD_MODE, ctx->conf->mode);
handshake_add(ctx, &buffer, RECORD_PROTOCOL_NAME, protocol_len, ctx->conf->protocol->name);
- fastd_task_put_send_handshake(ctx, peer, buffer);
+ return buffer;
}
-void fastd_handshake_rehandshake(fastd_context *ctx, fastd_peer *peer) {
- size_t protocol_len = strlen(ctx->conf->protocol->name);
- fastd_buffer buffer = fastd_buffer_alloc(sizeof(fastd_packet), 0, 3 /* handshake type */);
+fastd_buffer fastd_handshake_new_reply(fastd_context *ctx, fastd_peer *peer, const fastd_handshake *handshake, size_t tail_space) {
+ fastd_buffer buffer = fastd_buffer_alloc(sizeof(fastd_packet), 0,
+ 2*3 + /* handshake type, reply code */
+ tail_space
+ );
fastd_packet *request = buffer.data;
- request->req_id = ++peer->last_req_id;
+ request->req_id = handshake->req_id;
request->rsv = 0;
- handshake_add_uint8(ctx, &buffer, RECORD_HANDSHAKE_TYPE, HANDSHAKE_REHANDSHAKE_REQUEST);
+ handshake_add_uint8(ctx, &buffer, RECORD_HANDSHAKE_TYPE, AS_UINT8(handshake->records[RECORD_HANDSHAKE_TYPE])+1);
+ handshake_add_uint8(ctx, &buffer, RECORD_REPLY_CODE, 0);
- fastd_task_put_send_handshake(ctx, peer, buffer);
+ return buffer;
}
+
void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
if (buffer.len < sizeof(fastd_packet)) {
pr_warn(ctx, "received a short handshake from %P", peer);
goto end_free;
}
- fastd_packet *packet = buffer.data;
+ fastd_handshake handshake;
+ memset(&handshake, 0, sizeof(handshake));
- size_t lengths[RECORD_MAX];
- void *records[RECORD_MAX] = { 0 };
+ fastd_packet *packet = buffer.data;
uint8_t *ptr = packet->tlv_data;
while (true) {
@@ -129,103 +134,94 @@ void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer b
if (ptr+2+len > (uint8_t*)buffer.data + buffer.len)
break;
- lengths[type] = len;
- records[type] = ptr+2;
+ handshake.records[type].length = len;
+ handshake.records[type].data = ptr+2;
ptr += 2+len;
}
- if (!records[RECORD_HANDSHAKE_TYPE]) {
- pr_warn(ctx, "received a handshake without type from %P", peer);
- goto end_free;
- }
-
- fastd_buffer reply_buffer;
- fastd_packet *reply;
+ handshake.req_id = packet->req_id;
- uint8_t reply_code;
- uint8_t error_detail;
- const char *error_field_str;
+ if (handshake.records[RECORD_HANDSHAKE_TYPE].length != 1)
+ goto end_free;
- switch (AS_UINT8(records[RECORD_HANDSHAKE_TYPE])) {
- case HANDSHAKE_REQUEST:
- reply_code = REPLY_SUCCESS;
- error_detail = 0;
+ if (AS_UINT8(handshake.records[RECORD_HANDSHAKE_TYPE]) == 1) {
+ uint8_t reply_code = REPLY_SUCCESS;
+ uint8_t error_detail = 0;
- if (!records[RECORD_MODE]) {
+ if (!handshake.records[RECORD_MODE].data) {
reply_code = REPLY_MANDATORY_MISSING;
error_detail = RECORD_MODE;
goto send_reply;
}
- if (lengths[RECORD_MODE] != 1 || AS_UINT8(records[RECORD_MODE]) != ctx->conf->mode) {
+ if (handshake.records[RECORD_MODE].length != 1 || AS_UINT8(handshake.records[RECORD_MODE]) != ctx->conf->mode) {
reply_code = REPLY_UNACCEPTABLE_VALUE;
error_detail = RECORD_MODE;
goto send_reply;
}
- if (!records[RECORD_PROTOCOL_NAME]) {
+ if (!handshake.records[RECORD_PROTOCOL_NAME].data) {
reply_code = REPLY_MANDATORY_MISSING;
error_detail = RECORD_PROTOCOL_NAME;
goto send_reply;
}
- if (lengths[RECORD_PROTOCOL_NAME] != strlen(ctx->conf->protocol->name)
- || strncmp((char*)records[RECORD_PROTOCOL_NAME], ctx->conf->protocol->name, lengths[RECORD_PROTOCOL_NAME])) {
+ if (handshake.records[RECORD_PROTOCOL_NAME].length != strlen(ctx->conf->protocol->name)
+ || strncmp((char*)handshake.records[RECORD_PROTOCOL_NAME].data, ctx->conf->protocol->name, handshake.records[RECORD_PROTOCOL_NAME].length)) {
reply_code = REPLY_UNACCEPTABLE_VALUE;
error_detail = RECORD_PROTOCOL_NAME;
goto send_reply;
}
send_reply:
- reply_buffer = fastd_buffer_alloc(sizeof(fastd_packet), 0, 3*3 /* enough space for handshake type, reply code and error detail */);
- reply = reply_buffer.data;
-
- reply->req_id = packet->req_id;
- reply->rsv = 0;
+ if (reply_code) {
+ fastd_buffer reply_buffer = fastd_buffer_alloc(sizeof(fastd_packet), 0, 3*3 /* enough space for handshake type, reply code and error detail */);
+ fastd_packet *reply = reply_buffer.data;
- handshake_add_uint8(ctx, &reply_buffer, RECORD_HANDSHAKE_TYPE, HANDSHAKE_REPLY);
- handshake_add_uint8(ctx, &reply_buffer, RECORD_REPLY_CODE, reply_code);
+ reply->req_id = packet->req_id;
+ reply->rsv = 0;
- if (reply_code)
+ handshake_add_uint8(ctx, &reply_buffer, RECORD_HANDSHAKE_TYPE, 2);
+ handshake_add_uint8(ctx, &reply_buffer, RECORD_REPLY_CODE, reply_code);
handshake_add_uint8(ctx, &reply_buffer, RECORD_ERROR_DETAIL, error_detail);
-
- fastd_task_put_send_handshake(ctx, peer, reply_buffer);
-
- break;
-
- case HANDSHAKE_REPLY:
- if (packet->req_id != peer->last_req_id) {
- pr_warn(ctx, "received handshake reply with request ID %u from %P while %u was expected", packet->req_id, peer, peer->last_req_id);
- goto end_free;
+ }
+ else {
+ ctx->conf->protocol->handshake_handle(ctx, peer, &handshake);
+ }
+ }
+ else {
+ if ((AS_UINT8(handshake.records[RECORD_HANDSHAKE_TYPE]) & 1) == 0) {
+ if (packet->req_id != peer->last_req_id) {
+ pr_warn(ctx, "received handshake reply with request ID %u from %P while %u was expected", packet->req_id, peer, peer->last_req_id);
+ goto end_free;
+ }
}
- if (!records[RECORD_REPLY_CODE] || lengths[RECORD_REPLY_CODE] != 1) {
+ if (handshake.records[RECORD_REPLY_CODE].length != 1) {
pr_warn(ctx, "received handshake reply without reply code from %P", peer);
goto end_free;
}
- reply_code = AS_UINT8(records[RECORD_REPLY_CODE]);
+ uint8_t reply_code = AS_UINT8(handshake.records[RECORD_REPLY_CODE]);
- switch (reply_code) {
- case REPLY_SUCCESS:
- pr_info(ctx, "Handshake with %P successful.", peer);
- fastd_peer_set_established(peer);
- ctx->conf->protocol->init_peer(ctx, peer);
- break;
+ if (reply_code == REPLY_SUCCESS) {
+ ctx->conf->protocol->handshake_handle(ctx, peer, &handshake);
+ }
+ else {
+ const char *error_field_str;
- default:
if (reply_code >= REPLY_MAX) {
pr_warn(ctx, "Handshake with %P failed with unknown code %i", peer, reply_code);
- break;
+ goto end_free;
}
- if (!records[RECORD_ERROR_DETAIL] || lengths[RECORD_ERROR_DETAIL] != 1) {
+ if (handshake.records[RECORD_ERROR_DETAIL].length != 1) {
pr_warn(ctx, "Handshake with %P failed with code %s", peer, REPLY_TYPES[reply_code]);
- break;
+ goto end_free;
}
- error_detail = AS_UINT8(records[RECORD_ERROR_DETAIL]);
+ uint8_t error_detail = AS_UINT8(handshake.records[RECORD_ERROR_DETAIL]);
if (error_detail >= RECORD_MAX)
error_field_str = "<unknown>";
else
@@ -244,14 +240,6 @@ void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer b
break;
}
}
- break;
-
- case HANDSHAKE_REHANDSHAKE_REQUEST:
- fastd_task_schedule_handshake(ctx, peer, 0, true);
- break;
-
- default:
- pr_warn(ctx, "received a handshake with unknown type from %P", peer);
}
end_free:
diff --git a/src/handshake.h b/src/handshake.h
index 5e5e67f..064e167 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -28,9 +28,42 @@
#define _FASTD_HANDSHAKE_H_
#include "fastd.h"
+#include "packet.h"
+
+
+typedef enum _fastd_handshake_record_type {
+ RECORD_HANDSHAKE_TYPE = 0,
+ RECORD_REPLY_CODE,
+ RECORD_ERROR_DETAIL,
+ RECORD_FLAGS,
+ RECORD_MODE,
+ RECORD_PROTOCOL_NAME,
+ RECORD_MAX,
+} fastd_handshake_record_type;
+
+typedef enum _fastd_reply_code {
+ REPLY_SUCCESS = 0,
+ REPLY_MANDATORY_MISSING,
+ REPLY_UNACCEPTABLE_VALUE,
+ REPLY_MAX,
+} fastd_reply_code;
+
+
+typedef struct _fastd_handshake_record {
+ size_t length;
+ void *data;
+} fastd_handshake_record;
+
+struct _fastd_handshake {
+ uint8_t req_id;
+ fastd_handshake_record records[RECORD_MAX];
+};
+
+
+fastd_buffer fastd_handshake_new_init(fastd_context *ctx, fastd_peer *peer, size_t tail_space);
+fastd_buffer fastd_handshake_new_reply(fastd_context *ctx, fastd_peer *peer, const fastd_handshake *handshake, size_t tail_space);
-void fastd_handshake_send(fastd_context *ctx, fastd_peer *peer);
-void fastd_handshake_rehandshake(fastd_context *ctx, fastd_peer *peer);
void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
+
#endif /* _FASTD_HANDSHAKE_H_ */
diff --git a/src/packet.h b/src/packet.h
index 4da0110..76a64d1 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -36,31 +36,6 @@ typedef enum _fastd_packet_type {
PACKET_DATA,
} fastd_packet_type;
-typedef enum _fastd_handshake_record_type {
- RECORD_HANDSHAKE_TYPE = 0,
- RECORD_REPLY_CODE,
- RECORD_ERROR_DETAIL,
- RECORD_FLAGS,
- RECORD_MODE,
- RECORD_PROTOCOL_NAME,
- RECORD_MAX,
-} fastd_handshake_record_type;
-
-typedef enum _fastd_handshake_type {
- HANDSHAKE_REQUEST = 0,
- HANDSHAKE_REPLY,
- HANDSHAKE_REHANDSHAKE_REQUEST,
- HANDSHAKE_MAX,
-} fastd_handshake_type;
-
-typedef enum _fastd_reply_code {
- REPLY_SUCCESS = 0,
- REPLY_MANDATORY_MISSING,
- REPLY_UNACCEPTABLE_VALUE,
- REPLY_MAX,
-} fastd_reply_code;
-
-
typedef struct __attribute__ ((__packed__)) _fastd_packet {
uint8_t req_id;
uint16_t rsv;
diff --git a/src/peer.c b/src/peer.c
index 8fbc598..ea53e95 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -59,7 +59,7 @@ static inline void setup_peer(fastd_context *ctx, fastd_peer *peer) {
peer->seen = (struct timespec){0, 0};
if (!fastd_peer_is_floating(peer))
- fastd_task_schedule_handshake(ctx, peer, 0, false);
+ fastd_task_schedule_handshake(ctx, peer, 0);
}
static void delete_peer(fastd_context *ctx, fastd_peer *peer) {
@@ -148,13 +148,13 @@ fastd_peer* fastd_peer_add_temp(fastd_context *ctx, const fastd_peer_address *ad
return peer;
}
-fastd_peer* fastd_peer_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_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);
ctx->conf->protocol->free_peer_state(ctx, perm_peer);
perm_peer->address = temp_peer->address;
- perm_peer->state = fastd_peer_is_established(temp_peer) ? STATE_ESTABLISHED : STATE_WAIT;
+ perm_peer->state = STATE_ESTABLISHED;
perm_peer->seen = temp_peer->seen;
perm_peer->protocol_state = temp_peer->protocol_state;
diff --git a/src/peer.h b/src/peer.h
index 725ea9a..0e258a0 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -75,7 +75,7 @@ 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);
-fastd_peer* fastd_peer_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_peer);
+fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *perm_peer, fastd_peer *temp_peer);
const fastd_eth_addr* fastd_get_source_address(const fastd_context *ctx, fastd_buffer buffer);
const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buffer buffer);
@@ -89,22 +89,22 @@ static inline bool fastd_peer_is_floating(const fastd_peer *peer) {
}
static inline bool fastd_peer_is_temporary(const fastd_peer *peer) {
- return (peer->state == STATE_TEMP || peer->state == STATE_TEMP_ESTABLISHED);
+ return (peer->state == STATE_TEMP);
}
static inline bool fastd_peer_is_established(const fastd_peer *peer) {
- return (peer->state == STATE_ESTABLISHED || peer->state == STATE_TEMP_ESTABLISHED);
+ return (peer->state == STATE_ESTABLISHED);
}
-static inline void fastd_peer_set_established(fastd_peer *peer) {
+static inline void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer) {
switch(peer->state) {
case STATE_WAIT:
+ pr_info(ctx, "Connection with %P established.", peer);
peer->state = STATE_ESTABLISHED;
break;
case STATE_TEMP:
- peer->state = STATE_TEMP_ESTABLISHED;
- break;
+ exit_bug(ctx, "tried to set a temporary connection to established");
default:
return;
diff --git a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c
index 9d7eaa7..449a1c6 100644
--- a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c
+++ b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c
@@ -275,6 +275,13 @@ static void new_handshake(fastd_context *ctx, fastd_peer *peer, const fastd_peer
ecc_25519_store(&(*handshake)->public_key, &work);
}
+static void protocol_handshake_init(fastd_context *ctx, fastd_peer *peer) {
+}
+
+static void protocol_handshake_handle(fastd_context *ctx, fastd_peer *peer, const fastd_handshake *handshake) {
+}
+
+#if 0
static void protocol_init_peer(fastd_context *ctx, fastd_peer *peer) {
pr_info(ctx, "Initializing session with %P...", peer);
@@ -303,6 +310,7 @@ static void protocol_init_peer(fastd_context *ctx, fastd_peer *peer) {
fastd_task_put_send(ctx, peer, buffer);
}
+#endif
static void respond_handshake(fastd_context *ctx, fastd_peer *peer) {
pr_info(ctx, "Responding protocol handshake with %P...", peer);
@@ -383,7 +391,7 @@ static void establish(fastd_context *ctx, fastd_peer *peer, const fastd_peer_con
fastd_peer *perm_peer;
for (perm_peer = ctx->peers; perm_peer; perm_peer = perm_peer->next) {
if (perm_peer->config == peer_config) {
- fastd_peer_merge(ctx, perm_peer, peer);
+ fastd_peer_set_established_merge(ctx, perm_peer, peer);
break;
}
}
@@ -552,7 +560,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
new_handshake(ctx, peer, peer_config, false);
memcpy(peer->protocol_state->accepting_handshake->peer_key.p, packet->init.handshake_key, PUBLICKEYBYTES);
- fastd_peer_set_established(peer);
+ fastd_peer_set_established(ctx, peer);
respond_handshake(ctx, peer);
break;
@@ -733,7 +741,9 @@ const fastd_protocol fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305 = {
.min_encrypt_head_space = protocol_min_encrypt_head_space,
.min_decrypt_head_space = protocol_min_decrypt_head_space,
- .init_peer = protocol_init_peer,
+ .handshake_init = protocol_handshake_init,
+ .handshake_handle = protocol_handshake_handle,
+
.handle_recv = protocol_handle_recv,
.send = protocol_send,
diff --git a/src/protocol_null.c b/src/protocol_null.c
index 7ed4cd3..3a85e6c 100644
--- a/src/protocol_null.c
+++ b/src/protocol_null.c
@@ -29,10 +29,14 @@
#include "fastd.h"
#include "task.h"
#include "peer.h"
+#include "handshake.h"
#include <arpa/inet.h>
+#define AS_UINT8(ptr) (*(uint8_t*)(ptr).data)
+
+
static void protocol_init(fastd_context *ctx, fastd_config *conf) {
if (conf->n_floating > 1)
exit_error(ctx, "with protocol `null' use can't define more than one floating peer");
@@ -46,20 +50,12 @@ static size_t protocol_min_head_space(fastd_context *ctx) {
return 0;
}
-static void protocol_init_peer(fastd_context *ctx, fastd_peer *peer) {
- pr_info(ctx, "Connection with %P established.", peer);
-
- if (!fastd_peer_is_temporary(peer))
- fastd_task_put_send(ctx, peer, fastd_buffer_alloc(0, 0, 0));
+static void protocol_handshake_init(fastd_context *ctx, fastd_peer *peer) {
+ fastd_buffer buffer = fastd_handshake_new_init(ctx, peer, 0);
+ fastd_task_put_send_handshake(ctx, peer, buffer);
}
-static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
- if (!fastd_peer_is_established(peer)) {
- pr_info(ctx, "Connection with %P established.", peer);
-
- fastd_peer_set_established(peer);
- }
-
+static void establish(fastd_context *ctx, fastd_peer *peer) {
if (fastd_peer_is_temporary(peer)) {
fastd_peer *perm_peer;
for (perm_peer = ctx->peers; perm_peer; perm_peer = perm_peer->next) {
@@ -68,17 +64,52 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf
}
if (!perm_peer) {
- fastd_buffer_free(buffer);
return;
}
- peer = fastd_peer_merge(ctx, perm_peer, peer);
+ fastd_peer_set_established_merge(ctx, perm_peer, peer);
+ }
+ else {
+ fastd_peer_set_established(ctx, peer);
+ }
+}
+
+static void protocol_handshake_handle(fastd_context *ctx, fastd_peer *peer, const fastd_handshake *handshake) {
+ fastd_buffer buffer;
+
+ switch(AS_UINT8(handshake->records[RECORD_HANDSHAKE_TYPE])) {
+ case 1:
+ buffer = fastd_handshake_new_reply(ctx, peer, handshake, 0);
+ fastd_task_put_send_handshake(ctx, peer, buffer);
+ break;
+
+ case 2:
+ peer->seen = ctx->now;
+ establish(ctx, peer);
+ buffer = fastd_handshake_new_reply(ctx, peer, handshake, 0);
+ fastd_task_put_send_handshake(ctx, peer, buffer);
+ break;
+
+ case 3:
+ peer->seen = ctx->now;
+ establish(ctx, peer);
+ break;
+
+ default:
+ pr_debug(ctx, "received handshake reply with unknown type %u", AS_UINT8(handshake->records[RECORD_HANDSHAKE_TYPE]));
+ break;
}
-
- if (buffer.len)
+
+}
+
+static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
+ if (fastd_peer_is_established(peer) && buffer.len) {
+ peer->seen = ctx->now;
fastd_task_put_handle_recv(ctx, peer, buffer);
- else
+ }
+ else {
fastd_buffer_free(buffer);
+ }
}
static void protocol_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) {
@@ -101,7 +132,9 @@ const fastd_protocol fastd_protocol_null = {
.min_encrypt_head_space = protocol_min_head_space,
.min_decrypt_head_space = protocol_min_head_space,
- .init_peer = protocol_init_peer,
+ .handshake_init = protocol_handshake_init,
+ .handshake_handle = protocol_handshake_handle,
+
.handle_recv = protocol_handle_recv,
.send = protocol_send,
diff --git a/src/task.c b/src/task.c
index 48da733..62afd4f 100644
--- a/src/task.c
+++ b/src/task.c
@@ -60,12 +60,11 @@ void fastd_task_put_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buff
fastd_queue_put(ctx, &ctx->task_queue, &task->entry, 0);
}
-void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int timeout, bool force) {
+void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int timeout) {
fastd_task *task = malloc(sizeof(fastd_task));
task->type = TASK_HANDSHAKE;
task->peer = peer;
- task->handshake.force = force;
fastd_queue_put(ctx, &ctx->task_queue, &task->entry, timeout);
}
diff --git a/src/task.h b/src/task.h
index 951f30a..23400d3 100644
--- a/src/task.h
+++ b/src/task.h
@@ -51,10 +51,6 @@ typedef struct _fastd_task_handle_recv {
fastd_buffer buffer;
} fastd_task_handle_recv;
-typedef struct _fastd_task_handshake {
- bool force;
-} fastd_task_handshake;
-
typedef struct _fastd_task {
fastd_queue_entry entry;
@@ -64,7 +60,6 @@ typedef struct _fastd_task {
union {
fastd_task_send send;
fastd_task_handle_recv handle_recv;
- fastd_task_handshake handshake;
};
} fastd_task;
@@ -81,7 +76,7 @@ void fastd_task_put_send_handshake(fastd_context *ctx, fastd_peer *peer, fastd_b
void fastd_task_put_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
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, bool force);
+void fastd_task_schedule_handshake(fastd_context *ctx, fastd_peer *peer, int timeout);
void fastd_task_delete_peer(fastd_context *ctx, fastd_peer *peer);
diff --git a/src/types.h b/src/types.h
index 9828c8f..1730459 100644
--- a/src/types.h
+++ b/src/types.h
@@ -48,9 +48,8 @@ typedef enum _fastd_mode {
typedef enum _fastd_peer_state {
STATE_WAIT,
- STATE_ESTABLISHED,
STATE_TEMP,
- STATE_TEMP_ESTABLISHED,
+ STATE_ESTABLISHED,
} fastd_peer_state;
@@ -67,6 +66,8 @@ typedef struct _fastd_context fastd_context;
typedef struct _fastd_protocol fastd_protocol;
+typedef struct _fastd_handshake fastd_handshake;
+
/* May be defined by the protocol however it likes */
typedef struct _fastd_protocol_config fastd_protocol_config;
typedef struct _fastd_protocol_peer_config fastd_protocol_peer_config;