Detect increases in PMTU.
Tinc never restarts PMTU discovery unless a node becomes unreachable. However, it can be that the PMTU was very low during the initial discovery, but has increased later. To detect this, tinc now tries to send an extra packet every PingInterval, with a size slightly higher than the currently known PMTU. If this packet is succesfully received back, we partially restart PMTU discovery to find out the new maximum. Conflicts: src/net_packet.c
This commit is contained in:
parent
87416bcd8b
commit
42b222ecb6
1 changed files with 23 additions and 7 deletions
|
@ -70,11 +70,15 @@ bool localdiscovery = false;
|
||||||
mtuprobes == 32: send 1 burst, sleep pingtimeout second
|
mtuprobes == 32: send 1 burst, sleep pingtimeout second
|
||||||
mtuprobes == 33: no response from other side, restart PMTU discovery process
|
mtuprobes == 33: no response from other side, restart PMTU discovery process
|
||||||
|
|
||||||
Probes are sent in batches of three, with random sizes between the lower and
|
Probes are sent in batches of at least three, with random sizes between the
|
||||||
upper boundaries for the MTU thus far discovered.
|
lower and upper boundaries for the MTU thus far discovered.
|
||||||
|
|
||||||
In case local discovery is enabled, a fourth packet is added to each batch,
|
After the initial discovery, a fourth packet is added to each batch with a
|
||||||
|
size larger than the currently known PMTU, to test if the PMTU has increased.
|
||||||
|
|
||||||
|
In case local discovery is enabled, another packet is added to each batch,
|
||||||
which will be broadcast to the local network.
|
which will be broadcast to the local network.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void send_mtu_probe_handler(void *data) {
|
static void send_mtu_probe_handler(void *data) {
|
||||||
|
@ -125,13 +129,18 @@ static void send_mtu_probe_handler(void *data) {
|
||||||
timeout = pingtimeout;
|
timeout = pingtimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 3 + localdiscovery; i++) {
|
for(int i = 0; i < 4 + localdiscovery; i++) {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if(n->maxmtu <= n->minmtu)
|
if(i == 0) {
|
||||||
|
if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU)
|
||||||
|
continue;
|
||||||
|
len = n->maxmtu + 8;
|
||||||
|
} else if(n->maxmtu <= n->minmtu) {
|
||||||
len = n->maxmtu;
|
len = n->maxmtu;
|
||||||
else
|
} else {
|
||||||
len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
|
len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
|
||||||
|
}
|
||||||
|
|
||||||
if(len < 64)
|
if(len < 64)
|
||||||
len = 64;
|
len = 64;
|
||||||
|
@ -140,7 +149,7 @@ static void send_mtu_probe_handler(void *data) {
|
||||||
memset(packet.data, 0, 14);
|
memset(packet.data, 0, 14);
|
||||||
randomize(packet.data + 14, len - 14);
|
randomize(packet.data + 14, len - 14);
|
||||||
packet.len = len;
|
packet.len = len;
|
||||||
if(i >= 3 && n->mtuprobes <= 10)
|
if(i >= 4 && n->mtuprobes <= 10)
|
||||||
packet.priority = -1;
|
packet.priority = -1;
|
||||||
else
|
else
|
||||||
packet.priority = 0;
|
packet.priority = 0;
|
||||||
|
@ -199,6 +208,13 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
|
||||||
/* If we haven't established the PMTU yet, restart the discovery process. */
|
/* If we haven't established the PMTU yet, restart the discovery process. */
|
||||||
|
|
||||||
if(n->mtuprobes > 30) {
|
if(n->mtuprobes > 30) {
|
||||||
|
if (len == 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->mtuprobes = 10;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(n->minmtu)
|
if(n->minmtu)
|
||||||
n->mtuprobes = 30;
|
n->mtuprobes = 30;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue