diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-03-30 02:26:30 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-03-30 02:26:30 +0200 |
commit | ca127fccb899627e9e9a69d139bd27d79b30cd54 (patch) | |
tree | d6aba2530629cf805fc279dcb2702a3f66cdd177 | |
parent | 4d696a973af61e716959801c88b3ddbeca582e89 (diff) | |
download | fastd-ca127fccb899627e9e9a69d139bd27d79b30cd54.tar fastd-ca127fccb899627e9e9a69d139bd27d79b30cd54.zip |
Rework handshake... again. ecfxp protocol broken, will be fixed with next commit.
-rw-r--r-- | src/fastd.c | 10 | ||||
-rw-r--r-- | src/fastd.h | 4 | ||||
-rw-r--r-- | src/handshake.c | 134 | ||||
-rw-r--r-- | src/handshake.h | 37 | ||||
-rw-r--r-- | src/packet.h | 25 | ||||
-rw-r--r-- | src/peer.c | 6 | ||||
-rw-r--r-- | src/peer.h | 12 | ||||
-rw-r--r-- | src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c | 16 | ||||
-rw-r--r-- | src/protocol_null.c | 69 | ||||
-rw-r--r-- | src/task.c | 3 | ||||
-rw-r--r-- | src/task.h | 7 | ||||
-rw-r--r-- | src/types.h | 5 |
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; @@ -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; @@ -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, @@ -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); } @@ -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; |