X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fpmtu.c;h=0d5e8fd528ba59821ce43ed10bba555104924685;hb=e57f522ee2fef5a229a59f8fa08f94555fe3ec32;hp=4073825cfdc56f65d722395f257516fb81fed820;hpb=322eef8bc2ca53e1b7778f33bc9fb3af498cb9bc;p=meshlink diff --git a/src/pmtu.c b/src/pmtu.c index 4073825c..0d5e8fd5 100644 --- a/src/pmtu.c +++ b/src/pmtu.c @@ -91,8 +91,16 @@ static void udp_probe_timeout_handler(event_loop_t *loop, void *data) { logger(mesh, MESHLINK_INFO, "Too much time has elapsed since last UDP ping response from %s, stopping UDP communication", n->name); n->status.udp_confirmed = false; n->mtuprobes = 0; + n->udpprobes = 0; n->minmtu = 0; n->maxmtu = MTU; + + // If we also have a meta-connection to this node, send a PING on it as well + connection_t *c = n->connection; + + if(c && !c->status.pinged) { + send_ping(mesh, c); + } } static void send_udp_probe_reply(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) { @@ -115,7 +123,7 @@ static void send_udp_probe_reply(meshlink_handle_t *mesh, node_t *n, vpn_packet_ bool udp_confirmed = n->status.udp_confirmed; n->status.udp_confirmed = true; logger(mesh, MESHLINK_DEBUG, "Sending UDP reply length %d to %s", packet->len, n->name); - n->out_meta += packet->len; + n->out_meta += packet->len + SPTPS_DATAGRAM_OVERHEAD; send_udppacket(mesh, n, packet); n->status.udp_confirmed = udp_confirmed; } @@ -126,7 +134,7 @@ void udp_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint1 return; } - n->in_meta += packet->len; + n->in_meta += packet->len + SPTPS_DATAGRAM_OVERHEAD; if(!packet->data[0]) { /* It's a probe request, send back a reply */ @@ -154,6 +162,8 @@ void udp_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint1 n->status.udp_confirmed = true; } + n->udpprobes = 0; + // Reset the UDP ping timer. timeout_del(&mesh->loop, &n->udp_ping_timeout); @@ -205,21 +215,40 @@ static void send_udp_probe_packet(meshlink_handle_t *mesh, node_t *n, int len) { logger(mesh, MESHLINK_DEBUG, "Sending UDP probe length %d to %s", len, n->name); - n->out_meta += packet.len; + n->out_meta += packet.len + SPTPS_DATAGRAM_OVERHEAD; send_udppacket(mesh, n, &packet); } static void try_udp(meshlink_handle_t *mesh, node_t *n) { /* Probe request */ + if(n->status.udp_confirmed && n->udpprobes < -3) { + /* We lost three UDP probes, UDP status is no longer unconfirmed */ + udp_probe_timeout_handler(&mesh->loop, n); + } + struct timespec elapsed; + timespec_sub(&mesh->loop.now, &n->last_udp_probe_sent, &elapsed); - int interval = n->status.udp_confirmed ? 10 : 2; + int interval; + + if(n->status.udp_confirmed && n->udpprobes >= 0) { + // UDP confirmed and no lost probes, default interval + interval = 10; + } else if(n->udpprobes <= -15) { + // Many probes lost in a row, slow probing interval + n->udpprobes = -15; + interval = 10; + } else { + // Fast probing if we don't know the state of UDP connectivity yet + interval = 2; + } if(elapsed.tv_sec >= interval) { n->last_udp_probe_sent = mesh->loop.now; send_udp_probe_packet(mesh, n, MIN_PROBE_SIZE); + n->udpprobes--; if(!n->status.udp_confirmed && n->prevedge) { n->status.broadcast = true; @@ -286,6 +315,7 @@ static uint16_t choose_initial_maxmtu(meshlink_handle_t *mesh, node_t *n) { return mtu; #else + (void)mesh; (void)n; return MTU; #endif