From: Etienne Dechamps Date: Sun, 21 Sep 2014 09:38:41 +0000 (+0200) Subject: Preemptively mirror REQ_PUBKEY messages from nodes with unknown keys. X-Git-Tag: release-1.1pre11~42 X-Git-Url: https://tinc-vpn.org/git/browse?a=commitdiff_plain;h=daf65919d1ccc40f6c11f3f723f325de9021c422;p=tinc Preemptively mirror REQ_PUBKEY messages from nodes with unknown keys. In this commit, if a node receives a REQ_PUBKEY message from a node it doesn't have the key for, it will send a REQ_PUBKEY message in return *before* sending its own key. The rationale is to prevent delays when establishing communication between two nodes that see each other for the first time. These delays are caused by the first SPTPS packet being dropped on the floor, as shown in the following typical exchange: node1: No Ed25519 key known for node2 REQ_PUBKEY -> <- ANS_PUBKEY node1: Learned Ed25519 public key from node2 REQ_SPTPS_START -> node2: No Ed25519 key known for zyklos <- REQ_PUBKEY ANS_PUBKEY -> node2: Learned Ed25519 public key from node1 -- 10-second delay -- node1: No key from node2 after 10 seconds, restarting SPTPS REQ_SPTPS_START -> <- SPTPS -> node1: SPTPS key exchange with node2 succesful node2: SPTPS key exchange with node1 succesful With this patch, the following happens instead: node1: No Ed25519 key known for node2 REQ_PUBKEY -> node2: Preemptively requesting Ed25519 key for node1 <- REQ_PUBKEY <- ANS_PUBKEY ANS_PUBKEY -> node2: Learned Ed25519 public key from node1 node1: Learned Ed25519 public key from node2 REQ_SPTPS_START -> <- SPTPS -> node1: SPTPS key exchange with node2 succesful node2: SPTPS key exchange with node1 succesful --- diff --git a/src/protocol_key.c b/src/protocol_key.c index fcb748f4..abde7772 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -124,6 +124,11 @@ bool send_req_key(node_t *to) { static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) { switch(reqno) { case REQ_PUBKEY: { + if(!node_read_ecdsa_public_key(from)) { + /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ + logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); + } char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); free(pubkey);