Clarify the send_mtu_probe() function.

This cleans up the PMTU probing function a little bit. It moves the
low-level sending of packets to a separate function, so that the code
reads naturally instead of using a weird for loop with "special
indexes". In addition, comments are moved inside the body of the
function for additional context.

This shouldn't introduce any change of behavior, except for local
discovery which has some minor logic fixes and which now always uses
small packets (16 bytes) because there's no need for a full-length
probe just to try the local network.
This commit is contained in:
Etienne Dechamps 2014-10-12 19:44:33 +01:00
parent d28f332286
commit 950edc0744

View file

@ -46,6 +46,10 @@
#include "utils.h" #include "utils.h"
#include "xalloc.h" #include "xalloc.h"
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
int keylifetime = 0; int keylifetime = 0;
#ifdef HAVE_LZO #ifdef HAVE_LZO
static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS]; static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
@ -58,27 +62,21 @@ bool localdiscovery = true;
#define MAX_SEQNO 1073741824 #define MAX_SEQNO 1073741824
/* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval static void send_mtu_probe_packet(node_t *n, int len) {
mtuprobes == 31: sleep pinginterval seconds vpn_packet_t packet;
mtuprobes == 32: send 1 burst, sleep pingtimeout second packet.offset = DEFAULT_PACKET_OFFSET;
mtuprobes == 33: no response from other side, restart PMTU discovery process memset(DATA(&packet), 0, 14);
randomize(DATA(&packet) + 14, len - 14);
packet.len = len;
packet.priority = 0;
Probes are sent in batches of at least three, with random sizes between the logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
lower and upper boundaries for the MTU thus far discovered.
After the initial discovery, a fourth packet is added to each batch with a send_udppacket(n, &packet);
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.
*/
static void send_mtu_probe_handler(void *data) { static void send_mtu_probe_handler(void *data) {
node_t *n = data; node_t *n = data;
int timeout = 1;
n->mtuprobes++;
if(!n->status.reachable || !n->status.validkey) { if(!n->status.reachable || !n->status.validkey) {
logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname); logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname);
@ -86,6 +84,14 @@ static void send_mtu_probe_handler(void *data) {
return; return;
} }
/* 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 */
n->mtuprobes++;
int timeout = 1;
if(n->mtuprobes > 32) { if(n->mtuprobes > 32) {
if(!n->minmtu) { if(!n->minmtu) {
n->mtuprobes = 31; n->mtuprobes = 31;
@ -122,36 +128,29 @@ static void send_mtu_probe_handler(void *data) {
timeout = pingtimeout; timeout = pingtimeout;
} }
for(int i = 0; i < 4 + localdiscovery; i++) { /* After the initial discovery, a fourth packet is added to each batch with a
int len; size larger than the currently known PMTU, to test if the PMTU has increased. */
if (n->mtuprobes >= 30 && n->maxmtu + 8 < MTU)
send_mtu_probe_packet(n, n->maxmtu + 8);
if(i == 0) { /* Probes are sent in batches of three, with random sizes between the
if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) lower and upper boundaries for the MTU thus far discovered. */
continue; for (int i = 0; i < 3; i++) {
len = n->maxmtu + 8; int len = n->maxmtu;
} else if(n->maxmtu <= n->minmtu) { if(n->minmtu < n->maxmtu)
len = n->maxmtu;
} else {
len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu); len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
}
if(len < 64) send_mtu_probe_packet(n, MAX(len, 64));
len = 64; }
vpn_packet_t packet; /* In case local discovery is enabled, another packet is added to each batch,
packet.offset = DEFAULT_PACKET_OFFSET; which will be broadcast to the local network. */
memset(DATA(&packet), 0, 14); if(localdiscovery && n->mtuprobes <= 10 && n->prevedge) {
randomize(DATA(&packet) + 14, len - 14); n->status.send_locally = true;
packet.len = len; send_mtu_probe_packet(n, 16);
packet.priority = 0; n->status.send_locally = false;
n->status.send_locally = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
send_udppacket(n, &packet);
} }
n->status.send_locally = false;
n->probe_counter = 0; n->probe_counter = 0;
gettimeofday(&n->probe_time, NULL); gettimeofday(&n->probe_time, NULL);