summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
927064e)
This keeps NAT mappings for UDP alive, and will also detect when a node is not
reachable via UDP anymore or if the path MTU is decreasing. Tinc will fall back
to TCP if the node has become unreachable.
If UDP communication is impossible, we stop sending probes, but we retry if it
changes its keys.
We also decouple the UDP and TCP ping mechanisms completely, to ensure tinc
properly detects failure of either method.
- c->last_ping_time = now;
-
#define MAX_SEQNO 1073741824
#define MAX_SEQNO 1073741824
+// mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
+// mtuprobes == 31: sleep pinginterval seconds
+// mtuprobes == 32: send 1 burst, sleep pingtimeout second
+// mtuprobes == 33: no response from other side, restart PMTU discovery process
+
void send_mtu_probe(node_t *n) {
vpn_packet_t packet;
int len, i;
void send_mtu_probe(node_t *n) {
vpn_packet_t packet;
int len, i;
n->mtuprobes++;
n->mtuevent = NULL;
n->mtuprobes++;
n->mtuevent = NULL;
- if(!n->status.reachable) {
+ if(!n->status.reachable || !n->status.validkey) {
logger(LOG_DEBUG, "Trying to send MTU probe to unreachable node %s (%s)", n->name, n->hostname);
logger(LOG_DEBUG, "Trying to send MTU probe to unreachable node %s (%s)", n->name, n->hostname);
+ if(n->mtuprobes > 32) {
+ ifdebug(TRAFFIC) logger(LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
+ n->mtuprobes = 1;
+ n->minmtu = 0;
+ n->maxmtu = MTU;
+ }
+
if(n->mtuprobes >= 10 && !n->minmtu) {
ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
if(n->mtuprobes >= 10 && !n->minmtu) {
ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
+ if(n->mtuprobes == 30 || (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);
+ n->mtuprobes = 31;
+ }
+
+ if(n->mtuprobes == 31) {
+ timeout = pinginterval;
+ goto end;
+ } else if(n->mtuprobes == 32) {
+ timeout = pingtimeout;
+ }
+
- 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;
- }
+ if(n->maxmtu <= n->minmtu)
+ len = n->maxmtu;
+ else
+ len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
- len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
send_udppacket(n, &packet);
}
send_udppacket(n, &packet);
}
n->mtuevent = new_event();
n->mtuevent->handler = (event_handler_t)send_mtu_probe;
n->mtuevent->data = n;
n->mtuevent = new_event();
n->mtuevent->handler = (event_handler_t)send_mtu_probe;
n->mtuevent->data = n;
- n->mtuevent->time = now + 1;
+ n->mtuevent->time = now + timeout;
event_add(n->mtuevent);
}
event_add(n->mtuevent);
}
packet->data[0] = 1;
send_packet(n, packet);
} else {
packet->data[0] = 1;
send_packet(n, packet);
} else {
+ if(len > n->maxmtu)
+ len = n->maxmtu;
if(n->minmtu < len)
n->minmtu = len;
if(n->minmtu < len)
n->minmtu = len;
+ if(n->mtuprobes > 30)
+ n->mtuprobes = 30;
- if(n->connection)
- n->connection->last_ping_time = now;
-
if(!inpkt->data[12] && !inpkt->data[13])
mtu_probe_h(n, inpkt, origlen);
else
if(!inpkt->data[12] && !inpkt->data[13])
mtu_probe_h(n, inpkt, origlen);
else