From ffda069e617db34c12321b438964e4c369053466 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 31 Oct 2019 22:26:25 +0100 Subject: [PATCH] Allow nodes to learn their own reflexive UDP address. When a node gets a succesful UDP probe reply, it informs the peer of the UDP address and port that it has. The peer can then use this information to inform other nodes it wants to communicate with. Currently, this is only done to close the time window where two nodes have established an SPTPS session via a third node, while the third node hasn't learned of the two nodes' UDP addresses, in which case it was too late for the third node to assist with hole punching. --- src/net_packet.c | 9 ++++++++- src/protocol_key.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/net_packet.c b/src/net_packet.c index 0510b54b..a2709553 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -185,7 +185,14 @@ static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet is possible using the address and socket that the reply packet used. */ - n->status.udp_confirmed = true; + if(!n->status.udp_confirmed) { + char *address, *port; + sockaddr2str(&n->address, &address, &port); + send_request(mesh, n->nexthop->connection, NULL, "%d %s %s . -1 -1 -1 0 %s %s", ANS_KEY, n->name, n->name, address, port); + free(address); + free(port); + n->status.udp_confirmed = true; + } /* If we haven't established the PMTU yet, restart the discovery process. */ diff --git a/src/protocol_key.c b/src/protocol_key.c index f912c0fb..641e2b96 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -324,6 +324,12 @@ bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { return true; } + if(from == to) { + logger(mesh, MESHLINK_WARNING, "Got %s from %s from %s to %s", + "ANS_KEY", c->name, from_name, to_name); + return true; + } + /* Append the known UDP address of the from node, if we have a confirmed one */ if(!*address && from->status.udp_confirmed && from->address.sa.sa_family != AF_UNSPEC) { char *address, *port; @@ -338,6 +344,37 @@ bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { return send_request(mesh, to->nexthop->connection, NULL, "%s", request); } + /* Is this an ANS_KEY informing us of our own reflexive UDP address? */ + + if(from == mesh->self) { + if(*key == '.' && *address && *port) { + logger(mesh, MESHLINK_DEBUG, "Learned our own reflexive UDP address from %s: %s port %s", c->name, address, port); + + /* Inform all other nodes we want to communicate with and which are reachable via this connection */ + for splay_each(node_t, n, mesh->nodes) { + if(n->nexthop == c->node) { + continue; + } + + if(n->status.udp_confirmed) { + continue; + } + + if(!n->status.waitingforkey && !n->status.validkey) { + continue; + } + + logger(mesh, MESHLINK_DEBUG, "Forwarding our own reflexive UDP address to %s", n->name); + send_request(mesh, c, NULL, "%d %s %s . -1 -1 -1 0 %s %s", ANS_KEY, mesh->self->name, n->name, address, port); + } + } else { + logger(mesh, MESHLINK_WARNING, "Got %s from %s from %s to %s", + "ANS_KEY", c->name, from_name, to_name); + } + + return true; + } + /* Process SPTPS data if present */ if(*key != '.') { -- 2.39.5