]> git.meshlink.io Git - meshlink/blobdiff - src/pmtu.c
Don't send UDP probes to tiny nodes.
[meshlink] / src / pmtu.c
index d91919eed40f9e95a653f00d7cad55389cd293a7..179d89665ef3d41a46a099e6a9d14538c2249442 100644 (file)
@@ -91,6 +91,7 @@ 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;
 
@@ -122,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;
 }
@@ -133,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 */
@@ -161,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);
@@ -212,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;
@@ -293,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
@@ -387,7 +410,7 @@ static void try_pmtu(meshlink_handle_t *mesh, node_t *n) {
  */
 
 void keepalive(meshlink_handle_t *mesh, node_t *n, bool traffic) {
-       if(!n->status.reachable || !n->status.validkey) {
+       if(!n->status.reachable || !n->status.validkey || n->status.tiny) {
                return;
        }