+end:
+ timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval){timeout, rand() % 100000});
+}
+
+void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
+ timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0});
+ send_mtu_probe_handler(&mesh->loop, n);
+}
+
+static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
+ logger(mesh, MESHLINK_DEBUG, "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(mesh, 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 (len == n->maxmtu + 8) {
+ logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
+ n->maxmtu = MTU;
+ n->mtuprobes = 10;
+ return;
+ }
+
+ if(n->minmtu)
+ n->mtuprobes = 30;
+ else
+ n->mtuprobes = 1;