Currently, tinc sends MTU probes in batches of three every second. This
commit changes that to send one packet every 333 milliseconds instead.
This change brings two benefits:
- It makes MTU probing faster, because MTU probe lengths are calculated
based on minmtu, and minmtu is adjusted based on the replies. When
sending batches of three packets, all three packets are based on the
same minmtu estimation; in contrast, by sending one packet more
frequently, each subsequent packet can benefit from the replies that
have been received since the last packet was sent. As a result, MTU
discovery converges much faster (2-3 times as fast, typically).
- It reduces network spikiness - it's more network-friendly to send
one packet from time to time as opposed to sending bursts.
if(n->mtuprobes < 0)
return;
if(n->mtuprobes < 0)
return;
- if(n->mtuprobes == 30 || n->minmtu >= n->maxmtu) {
+ if(n->mtuprobes == 90 || n->minmtu >= n->maxmtu) {
if(n->minmtu > n->maxmtu)
n->minmtu = n->maxmtu;
else
if(n->minmtu > n->maxmtu)
n->minmtu = n->maxmtu;
else
if(probelen >= n->maxmtu + 8) {
logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
n->maxmtu = MTU;
if(probelen >= n->maxmtu + 8) {
logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
n->maxmtu = MTU;
n->rtt = diff.tv_sec + diff.tv_usec * 1e-6;
n->probe_time = probe_timestamp;
} else if(n->probe_counter == 3) {
n->rtt = diff.tv_sec + diff.tv_usec * 1e-6;
n->probe_time = probe_timestamp;
} else if(n->probe_counter == 3) {
- /* TODO: this will never fire after initial MTU discovery. */
+ /* TODO: this will never fire - we're not sending batches of three anymore. */
struct timeval probe_timestamp_diff;
timersub(&probe_timestamp, &n->probe_time, &probe_timestamp_diff);
n->bandwidth = 2.0 * probelen / (probe_timestamp_diff.tv_sec + probe_timestamp_diff.tv_usec * 1e-6);
struct timeval probe_timestamp_diff;
timersub(&probe_timestamp, &n->probe_time, &probe_timestamp_diff);
n->bandwidth = 2.0 * probelen / (probe_timestamp_diff.tv_sec + probe_timestamp_diff.tv_usec * 1e-6);
- /* mtuprobes == 0..29: initial discovery, send bursts with 1 second interval, mtuprobes++
- mtuprobes == 30: fix MTU, and go to -1
+ /* mtuprobes == 0..89: initial discovery, send bursts with 1 second interval, mtuprobes++
+ mtuprobes == 90: fix MTU, and go to -1
mtuprobes == -1: send one >maxmtu probe every pingtimeout */
struct timeval now;
mtuprobes == -1: send one >maxmtu probe every pingtimeout */
struct timeval now;
struct timeval elapsed;
timersub(&now, &n->probe_sent_time, &elapsed);
if(n->mtuprobes >= 0) {
struct timeval elapsed;
timersub(&now, &n->probe_sent_time, &elapsed);
if(n->mtuprobes >= 0) {
- if(n->mtuprobes != 0 && elapsed.tv_sec < 1)
+ if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333)
return;
} else {
if(elapsed.tv_sec < pingtimeout)
return;
} else {
if(elapsed.tv_sec < pingtimeout)
if(n->maxmtu + 8 < MTU)
send_udp_probe_packet(n, n->maxmtu + 8);
} else {
if(n->maxmtu + 8 < MTU)
send_udp_probe_packet(n, n->maxmtu + 8);
} else {
- /* Probes are sent in batches of three, with random sizes between the
+ /* Probes are sent with random sizes between the
lower and upper boundaries for the MTU thus far discovered. */
lower and upper boundaries for the MTU thus far discovered. */
- for (int i = 0; i < 3; i++) {
- int len = n->maxmtu;
- if(n->minmtu < n->maxmtu)
- len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
-
- send_udp_probe_packet(n, MAX(len, 64));
- }
+ int len = n->maxmtu;
+ if(n->minmtu < n->maxmtu)
+ len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
+ send_udp_probe_packet(n, MAX(len, 64));
if(n->mtuprobes >= 0)
n->mtuprobes++;
if(n->mtuprobes >= 0)
n->mtuprobes++;