From fa90b359694a0b3aa967dec97b1286e0dd695a78 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 27 Aug 2020 22:32:07 +0200 Subject: [PATCH] Fast retries and timeout of UDP probes. When the previous probe hasn't been replied to, try the next UDP probe faster. After three probes without a reply, consider the UDP connection timed out. --- src/node.h | 3 ++- src/pmtu.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/node.h b/src/node.h index 24f78dcf..0131e359 100644 --- a/src/node.h +++ b/src/node.h @@ -73,7 +73,8 @@ typedef struct node_t { timeout_t udp_ping_timeout; /* UDP probe event */ struct timespec last_mtu_probe_sent; /* Time that the last MTU probe was sent */ struct timespec last_udp_probe_sent; /* Time that the last UDP probe was sent */ - int mtuprobes; /* Number of probes */ + int8_t mtuprobes; /* MTU probes counter */ + int8_t udpprobes; /* UDP probes counter */ uint16_t last_mtu_len; /* Size of the last sent probe */ uint16_t mtu; /* Maximum size of packets to send to this node */ uint16_t maxmtu; /* Probed maximum MTU */ diff --git a/src/pmtu.c b/src/pmtu.c index d91919ee..5220a737 100644 --- a/src/pmtu.c +++ b/src/pmtu.c @@ -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; @@ -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); @@ -219,14 +222,21 @@ static void send_udp_probe_packet(meshlink_handle_t *mesh, node_t *n, int len) { static void try_udp(meshlink_handle_t *mesh, node_t *n) { /* Probe request */ + if(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 = (n->status.udp_confirmed && n->udpprobes >= 0) ? 10 : 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; -- 2.39.2