summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-10-16 18:33:51 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-10-16 18:33:51 +0200
commit118ebb9d65b44fb734aee3ebd31ecdaffd38c615 (patch)
treecfb4e9f8ad1364dbfe411e6c6dc6c5139b08016c
parent4c188ac86175422bc44e88e037b01acaba781cb7 (diff)
downloadfastd-118ebb9d65b44fb734aee3ebd31ecdaffd38c615.tar
fastd-118ebb9d65b44fb734aee3ebd31ecdaffd38c615.zip
Initiate handshake when a packet can't be sent because the local address is invalid
-rw-r--r--src/dlist.h4
-rw-r--r--src/fastd.h4
-rw-r--r--src/handshake.c2
-rw-r--r--src/peer.h4
-rw-r--r--src/protocol_ec25519_fhmqvc.c10
-rw-r--r--src/send.c15
6 files changed, 26 insertions, 13 deletions
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) {