+void send_mtu_probe(node_t *n)
+{
+ vpn_packet_t packet;
+ int len, i;
+
+ cp();
+
+ n->mtuprobes++;
+ n->mtuevent = NULL;
+
+ if(n->mtuprobes >= 10 && !n->minmtu) {
+ ifdebug(TRAFFIC) logger(LOG_INFO, _("No response to MTU probes from %s (%s)"), n->name, n->hostname);
+ return;
+ }
+
+ for(i = 0; i < 3; i++) {
+ if(n->mtuprobes >= 30 || n->minmtu >= n->maxmtu) {
+ n->mtu = n->minmtu;
+ ifdebug(TRAFFIC) logger(LOG_INFO, _("Fixing MTU of %s (%s) to %d after %d probes"), n->name, n->hostname, n->mtu, n->mtuprobes);
+ return;
+ }
+
+ len = n->minmtu + 1 + random() % (n->maxmtu - n->minmtu);
+ if(len < 64)
+ len = 64;
+
+ memset(packet.data, 0, 14);
+ RAND_pseudo_bytes(packet.data + 14, len - 14);
+ packet.len = len;
+
+ ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
+
+ send_udppacket(n, &packet);
+ }
+
+ n->mtuevent = new_event();
+ n->mtuevent->handler = (event_handler_t)send_mtu_probe;
+ n->mtuevent->data = n;
+ n->mtuevent->time = now + 1;
+ event_add(n->mtuevent);
+}
+
+void mtu_probe_h(node_t *n, vpn_packet_t *packet) {
+ ifdebug(TRAFFIC) logger(LOG_INFO, _("Got MTU probe length %d from %s (%s)"), packet->len, n->name, n->hostname);
+
+ if(!packet->data[0]) {
+ packet->data[0] = 1;
+ send_packet(n, packet);
+ } else {
+ if(n->minmtu < packet->len)
+ n->minmtu = packet->len;
+ }
+}
+