X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnet_packet.c;h=e50135ec42f264c026e6ca7a293da5ba9f875156;hb=d30b9e1272fef18070d37d10b2b3e4bb2fc07f59;hp=dbf361fd38fe2c41b4484763045d266545c7be84;hpb=f57129ce3439f3826c12f15feb5df05e5ad8cab9;p=tinc diff --git a/src/net_packet.c b/src/net_packet.c index dbf361fd..e50135ec 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -164,11 +164,26 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); if(!packet->data[0]) { + /* It's a probe request, send back a reply */ + packet->data[0] = 1; + + /* Temporarily set udp_confirmed, so that the reply is sent + back exactly the way it came in. */ + + bool udp_confirmed = n->status.udp_confirmed; + n->status.udp_confirmed = true; send_udppacket(n, packet); + n->status.udp_confirmed = udp_confirmed; } else { + /* It's a valid reply: now we know bidirectional communication + is possible using the address and socket that the reply + packet used. */ + n->status.udp_confirmed = true; + /* If we haven't established the PMTU yet, restart the discovery process. */ + if(n->mtuprobes > 30) { if(n->minmtu) n->mtuprobes = 30; @@ -176,6 +191,8 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { n->mtuprobes = 1; } + /* If applicable, raise the minimum supported MTU */ + if(len > n->maxmtu) len = n->maxmtu; if(n->minmtu < len) @@ -447,24 +464,28 @@ static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock if(n->status.udp_confirmed) return; - /* Otherwise, go through the list of known addresses of - this node. The first address we try is always the - one in n->address; that could be set to the node's - reflexive UDP address discovered during key - exchange. The other known addresses are those found - in edges to this node. */ + /* Send every third packet to n->address; that could be set + to the node's reflexive UDP address discovered during key + exchange. */ + static int x = 0; + if(++x >= 3) { + x = 0; + return; + } + + /* Otherwise, address are found in edges to this node. + So we pick a random edge and a random socket. */ int i = 0; int j = rand() % n->edge_tree->count; edge_t *candidate = NULL; - for splay_each(edge_t, e, edge_weight_tree) { - if(e->to != n) - continue; - i++; - if(!candidate || i == j) - candidate = e; + for splay_each(edge_t, e, n->edge_tree) { + if(i++ == j) { + candidate = e->reverse; + break; + } } if(candidate) {