From 118ebb9d65b44fb734aee3ebd31ecdaffd38c615 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 16 Oct 2013 18:33:51 +0200 Subject: Initiate handshake when a packet can't be sent because the local address is invalid --- src/dlist.h | 4 ++++ src/fastd.h | 4 ++-- src/handshake.c | 2 +- src/peer.h | 4 ++++ src/protocol_ec25519_fhmqvc.c | 10 +++++----- src/send.c | 15 ++++++++++----- 6 files changed, 26 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/dlist.h b/src/dlist.h index 98b7fd3..d689ad3 100644 --- a/src/dlist.h +++ b/src/dlist.h @@ -40,6 +40,10 @@ struct fastd_dlist_head { }; +static inline bool fastd_dlist_linked(fastd_dlist_head_t *elem) { + return elem->prev; +} + static inline void fastd_dlist_insert(fastd_dlist_head_t *list, fastd_dlist_head_t *elem) { elem->prev = list; elem->next = list->next; diff --git a/src/fastd.h b/src/fastd.h index 1fe639e..17ae0fa 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -327,9 +327,9 @@ struct fastd_string_stack { }; -void fastd_send(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer, size_t stat_size); +void fastd_send(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer, size_t stat_size); void fastd_send_all(fastd_context_t *ctx, fastd_peer_t *source_peer, fastd_buffer_t buffer); -void fastd_send_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer); +void fastd_send_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer); void fastd_receive(fastd_context_t *ctx, fastd_socket_t *sock); void fastd_handle_receive(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer_t buffer); diff --git a/src/handshake.c b/src/handshake.c index 10dafa0..5400828 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -301,7 +301,7 @@ void fastd_handshake_handle(fastd_context_t *ctx, fastd_socket_t *sock, const fa fastd_handshake_add_uint8(ctx, &reply_buffer, RECORD_REPLY_CODE, reply_code); fastd_handshake_add_uint8(ctx, &reply_buffer, RECORD_ERROR_DETAIL, error_detail); - fastd_send_handshake(ctx, sock, local_addr, remote_addr, reply_buffer); + fastd_send_handshake(ctx, sock, local_addr, remote_addr, peer, reply_buffer); } else { ctx->conf->protocol->handshake_handle(ctx, sock, local_addr, remote_addr, peer, &handshake, method); diff --git a/src/peer.h b/src/peer.h index 4d87e3a..12f591d 100644 --- a/src/peer.h +++ b/src/peer.h @@ -148,6 +148,10 @@ static inline void fastd_peer_unschedule_handshake(fastd_context_t *ctx UNUSED, fastd_dlist_remove(&peer->handshake_entry); } +static inline bool fastd_peer_handshake_scheduled(fastd_context_t *ctx UNUSED, fastd_peer_t *peer) { + return fastd_dlist_linked(&peer->handshake_entry); +} + const fastd_eth_addr_t* fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer); const fastd_eth_addr_t* fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer); diff --git a/src/protocol_ec25519_fhmqvc.c b/src/protocol_ec25519_fhmqvc.c index 62e9303..ad65ca7 100644 --- a/src/protocol_ec25519_fhmqvc.c +++ b/src/protocol_ec25519_fhmqvc.c @@ -292,7 +292,7 @@ static void protocol_handshake_init(fastd_context_t *ctx, const fastd_socket_t * fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, ctx->protocol_state->handshake_key.key1.public.p); - fastd_send_handshake(ctx, sock, local_addr, remote_addr, buffer); + fastd_send_handshake(ctx, sock, local_addr, remote_addr, peer, buffer); } @@ -363,7 +363,7 @@ static void clear_shared_handshake_key(fastd_context_t *ctx UNUSED, const fastd_ memset(&peer->protocol_state->peer_handshake_key, 0, sizeof(peer->protocol_state->peer_handshake_key)); } -static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, const fastd_peer_t *peer, +static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const handshake_key_t *handshake_key, const aligned_int256_t *peer_handshake_key, const fastd_handshake_t *handshake, const fastd_method_t *method) { pr_debug(ctx, "responding handshake with %P[%I]...", peer, remote_addr); @@ -381,7 +381,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key->p); fastd_handshake_add(ctx, &buffer, RECORD_T, HASHBYTES, hmacbuf.b); - fastd_send_handshake(ctx, sock, local_addr, remote_addr, buffer); + fastd_send_handshake(ctx, sock, local_addr, remote_addr, peer, buffer); } static bool establish(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_method_t *method, fastd_socket_t *sock, @@ -519,7 +519,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key->p); fastd_handshake_add(ctx, &buffer, RECORD_T, HASHBYTES, hmacbuf.b); - fastd_send_handshake(ctx, sock, local_addr, remote_addr, buffer); + fastd_send_handshake(ctx, sock, local_addr, remote_addr, peer, buffer); } static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, @@ -834,7 +834,7 @@ static void session_send(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer_ return; } - fastd_send(ctx, peer->sock, &peer->local_address, &peer->address, send_buffer, stat_size); + fastd_send(ctx, peer->sock, &peer->local_address, &peer->address, peer, send_buffer, stat_size); peer->last_send = ctx->now; } diff --git a/src/send.c b/src/send.c index 0b3f59c..2f0fb98 100644 --- a/src/send.c +++ b/src/send.c @@ -71,7 +71,7 @@ static inline void count_stat(fastd_stats_t *stats, size_t stat_size) { } } -static void send_type(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, uint8_t packet_type, fastd_buffer_t buffer, size_t stat_size) { +static void send_type(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, uint8_t packet_type, fastd_buffer_t buffer, size_t stat_size) { if (!sock) exit_bug(ctx, "send: sock == NULL"); @@ -124,12 +124,17 @@ static void send_type(fastd_context_t *ctx, const fastd_socket_t *sock, const fa if (ret < 0 && errno == EINVAL && msg.msg_controllen) { pr_debug2(ctx, "sendmsg failed, trying again without pktinfo"); + + if (peer && !fastd_peer_handshake_scheduled(ctx, peer)) + fastd_peer_schedule_handshake(ctx, peer, 0); + msg.msg_control = NULL; msg.msg_controllen = 0; do { ret = sendmsg(sock->fd, &msg, 0); } while (ret < 0 && errno == EINTR); + } if (ret < 0) { @@ -161,12 +166,12 @@ static void send_type(fastd_context_t *ctx, const fastd_socket_t *sock, const fa fastd_buffer_free(buffer); } -void fastd_send(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer, size_t stat_size) { - send_type(ctx, sock, local_addr, remote_addr, PACKET_DATA, buffer, stat_size); +void fastd_send(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer, size_t stat_size) { + send_type(ctx, sock, local_addr, remote_addr, peer, PACKET_DATA, buffer, stat_size); } -void fastd_send_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer) { - send_type(ctx, sock, local_addr, remote_addr, PACKET_HANDSHAKE, buffer, 0); +void fastd_send_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer) { + send_type(ctx, sock, local_addr, remote_addr, peer, PACKET_HANDSHAKE, buffer, 0); } void fastd_send_all(fastd_context_t *ctx, fastd_peer_t *source_peer, fastd_buffer_t buffer) { -- cgit v1.2.3