}
static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
-
if(!packet->data[0]) {
+ logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe request %d from %s (%s)", packet->len, n->name, n->hostname);
+
/* It's a probe request, send back a reply */
- packet->data[0] = 1;
+ /* Type 2 probe replies were introduced in protocol 17.3 */
+ if ((n->options >> 24) == 3) {
+ uint8_t* data = packet->data;
+ *data++ = 2;
+ uint16_t len16 = htons(len); memcpy(data, &len16, 2); data += 2;
+ } else {
+ /* Legacy protocol: n won't understand type 2 probe replies. */
+ packet->data[0] = 1;
+ }
/* Temporarily set udp_confirmed, so that the reply is sent
back exactly the way it came in. */
send_udppacket(n, packet);
n->status.udp_confirmed = udp_confirmed;
} else {
+ length_t probelen = len;
+ if (packet->data[0] == 2) {
+ if (len < 3)
+ logger(DEBUG_TRAFFIC, LOG_WARNING, "Received invalid (too short) MTU probe reply from %s (%s)", n->name, n->hostname);
+ else {
+ uint16_t probelen16; memcpy(&probelen16, packet->data + 1, 2); probelen = ntohs(probelen16);
+ }
+ }
+ logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d MTU probe reply %d from %s (%s)", packet->data[0], probelen, n->name, n->hostname);
+
/* It's a valid reply: now we know bidirectional communication
is possible using the address and socket that the reply
packet used. */
/* If we haven't established the PMTU yet, restart the discovery process. */
if(n->mtuprobes > 30) {
- if (len == n->maxmtu + 8) {
+ 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->mtuprobes = 10;
/* If applicable, raise the minimum supported MTU */
- if(len > n->maxmtu)
- len = n->maxmtu;
- if(n->minmtu < len)
- n->minmtu = len;
+ if(probelen > n->maxmtu)
+ probelen = n->maxmtu;
+ if(n->minmtu < probelen)
+ n->minmtu = probelen;
/* Calculate RTT and bandwidth.
The RTT is the time between the MTU probe burst was sent and the first
n->rtt = diff.tv_sec + diff.tv_usec * 1e-6;
n->probe_time = now;
} else if(n->probe_counter == 3) {
- n->bandwidth = 2.0 * len / (diff.tv_sec + diff.tv_usec * 1e-6);
+ n->bandwidth = 2.0 * probelen / (diff.tv_sec + diff.tv_usec * 1e-6);
logger(DEBUG_TRAFFIC, LOG_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2);
}
}