No subject
Mon Sep 20 15:00:41 CEST 2010
+0100
From: Daniel Schall <tinc-devel at mon-clan.de>
Date: Thu, 6 Jan 2011 17:00:35 +0100
Subject: [PATCH] Improved PMTU discovery
diff --git a/lib/dropin.c b/lib/dropin.c
index 52fb5b8..2b803b1 100644
--- a/lib/dropin.c
+++ b/lib/dropin.c
@@ -165,8 +165,8 @@
#endif
=20
#ifdef HAVE_MINGW
-int usleep(long usec) {
- Sleep(usec / 1000);
- return 0;
-}
+//int usleep(long usec) {
+// Sleep(usec / 1000);
+// return 0;
+//}
#endif
diff --git a/lib/dropin.h b/lib/dropin.h
index d5cf6d2..61326fe 100644
--- a/lib/dropin.h
+++ b/lib/dropin.h
@@ -42,7 +42,7 @@
#endif
=20
#ifdef HAVE_MINGW
-extern int usleep(long);
+//extern int usleep(long);
#endif
=20
#endif /* __DROPIN_H__ */
diff --git a/src/net.c b/src/net.c
index 08e3cad..9d170d0 100644
--- a/src/net.c
+++ b/src/net.c
@@ -280,6 +280,9 @@
int result, i;
socklen_t len =3D sizeof(result);
vpn_packet_t packet;
+ packet.flag_bits =3D 0;
+ packet.flags.compress =3D 1;
+
static int errors =3D 0;
=20
/* check input from kernel */
diff --git a/src/net.h b/src/net.h
index ab6bd41..7e05d09 100644
--- a/src/net.h
+++ b/src/net.h
@@ -79,11 +79,16 @@
typedef struct vpn_packet_t {
length_t len; /* the actual number of bytes in the `data' field */
int priority; /* priority or TOS */
- struct {
- uint32_t local:1; /* is this packet sent to a local interface? */
- uint32_t pmtud:1; /* is this packet used for PMTU discovery? */
- uint32_t unused:30; /* unused bits */
- } flags;
+ union {
+ struct {
+ uint32_t local:1; /* is this packet sent to a local interface? */
+ uint32_t pmtud:1; /* is this packet used for PMTU discovery? */
+ uint32_t pmtur:1; /* is this packet used for PMTU reply? */
+ uint32_t compress:1; /* is this packet compressed? */
+ uint32_t unused:28; /* unused bits */
+ } flags;
+ uint32_t flag_bits; /* to easily zero out and access flag bits */
+ };
uint32_t seqno; /* 32 bits sequence number (network byte order of =
course) */
uint8_t data[MAXSIZE];
} vpn_packet_t;
diff --git a/src/net_packet.c b/src/net_packet.c
index 5556326..4258599 100644
--- a/src/net_packet.c
+++ b/src/net_packet.c
@@ -72,7 +72,9 @@
=20
void send_mtu_probe(node_t *n) {
vpn_packet_t packet;
- memset(&packet.flags, 0, sizeof(packet.flags));
+ packet.flag_bits =3D 0;
+ packet.flags.pmtud =3D 1;
+
int len, i;
int timeout =3D 1;
=09
@@ -120,21 +122,22 @@
timeout =3D pingtimeout;
}
=20
- for(i =3D 0; i < 3; i++) {
+ const int nbPackets =3D 3;
+ for(i =3D 0; i < nbPackets; i++) {
if(n->maxmtu <=3D n->minmtu)
len =3D n->maxmtu;
else
- len =3D n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
+ len =3D n->minmtu + 1 + (n->maxmtu + 1 - n->minmtu) / (double) =
nbPackets * i;
=20
if(len < 64)
len =3D 64;
=09
- memset(packet.data, 0, 14);
- RAND_pseudo_bytes(packet.data + 14, len - 14);
+ //RAND_pseudo_bytes(packet.data, len);
+ memset(packet.data, 0x0, len);
packet.len =3D len;
packet.priority =3D 0;
=20
- ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s =
(%s)", len, n->name, n->hostname);
+ ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s =
(%s) from interval [%d - %d]", len, n->name, n->hostname, n->minmtu, =
n->maxmtu);
=20
send_udppacket(n, &packet);
}
@@ -147,24 +150,26 @@
event_add(n->mtuevent);
}
=20
-void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
- ifdebug(TRAFFIC) logger(LOG_INFO, "Got MTU probe length %d from %s =
(%s)", packet->len, n->name, n->hostname);
+void mtu_probe_h(node_t *n, vpn_packet_t *packet) {
+ length_t len =3D packet->len;
+ ifdebug(TRAFFIC) logger(LOG_INFO, "Got PMTU %s (length %d) from %s =
(%s)", (packet->flags.pmtur) ? "reply" : "probe", packet->len, n->name, =
n->hostname);
=20
- if(!packet->data[0]) {
- packet->data[0] =3D 1;
- send_udppacket(n, packet);
- } else {
- if(n->mtuprobes > 30) {
- if(n->minmtu)
- n->mtuprobes =3D 30;
- else
- n->mtuprobes =3D 1;
+ if(n->mtuprobes > 30) {
+ if(n->minmtu)
+ n->mtuprobes =3D 30;
+ else
+ n->mtuprobes =3D 1;
}
+ if(len > n->maxmtu)
+ len =3D n->maxmtu;
+ if(n->minmtu < len)
+ n->minmtu =3D len;
=20
- if(len > n->maxmtu)
- len =3D n->maxmtu;
- if(n->minmtu < len)
- n->minmtu =3D len;
+ if(!packet->flags.pmtur) {
+ /* PMTU Probe --> reply */
+
+ packet->flags.pmtur =3D 1;
+ send_udppacket(n, packet);
}
}
=20
@@ -264,11 +269,12 @@
=20
/* Remove flags */
=20
- inpkt->len -=3D sizeof(inpkt->flags);
+ inpkt->flag_bits =3D ntohl(inpkt->flag_bits);
+ inpkt->len -=3D sizeof(inpkt->flag_bits);
=20
/* Check packet length */
=20
- if(inpkt->len < sizeof(inpkt->seqno) + n->inmaclength) {
+ if(inpkt->len < sizeof(inpkt->flag_bits) + sizeof(inpkt->seqno) + =
n->inmaclength) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got too short packet from %s =
(%s)",
n->name, n->hostname);
return;
@@ -302,6 +308,7 @@
return;
}
=09
+ outpkt->flag_bits =3D inpkt->flag_bits;
outpkt->len =3D outlen + outpad;
inpkt =3D outpkt;
}
@@ -346,9 +353,7 @@
=20
/* Decompress the packet */
=20
- length_t origlen =3D inpkt->len;
-
- if(n->incompression) {
+ if(n->incompression && inpkt->flags.compress) {
outpkt =3D pkt[nextpkt++];
=20
if((outpkt->len =3D uncompress_packet(outpkt->data, inpkt->data, =
inpkt->len, n->incompression)) < 0) {
@@ -357,22 +362,21 @@
return;
}
=20
+ outpkt->flag_bits =3D inpkt->flag_bits;
inpkt =3D outpkt;
-
- origlen -=3D MTU/64 + 20;
}
=20
inpkt->priority =3D 0;
=20
- if(!inpkt->data[12] && !inpkt->data[13])
- mtu_probe_h(n, inpkt, origlen);
+ if(inpkt->flags.pmtud)
+ mtu_probe_h(n, inpkt);
else
receive_packet(n, inpkt);
}
=20
void receive_tcppacket(connection_t *c, char *buffer, int len) {
vpn_packet_t outpkt;
- memset(&outpkt.flags, 0, sizeof(outpkt.flags));
+ outpkt.flag_bits =3D 0;
=20
outpkt.len =3D len;
if(c->options & OPTION_TCPONLY)
@@ -420,10 +424,12 @@
return;
}
=20
- if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && =
(inpkt->data[12] | inpkt->data[13])) {
+ /* Decide to send using UDP or TCP */
+
+ if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && =
!origpkt->flags.pmtud) {
ifdebug(TRAFFIC) logger(LOG_INFO,
- "Packet for %s (%s) larger than minimum MTU, forwarding via %s",
- n->name, n->hostname, n !=3D n->nexthop ? n->nexthop->name : =
"TCP");
+ "Packet for %s (%s) larger than minimum MTU (=3D%d), forwarding via =
%s",
+ n->name, n->hostname, n->minmtu, n !=3D n->nexthop ? =
n->nexthop->name : "TCP");
=20
if(n !=3D n->nexthop)
send_packet(n->nexthop, origpkt);
@@ -438,7 +444,7 @@
=20
/* Compress the packet */
=20
- if(n->outcompression) {
+ if(n->outcompression && inpkt->flags.compress) {
outpkt =3D pkt[nextpkt++];
=20
if((outpkt->len =3D compress_packet(outpkt->data, inpkt->data, =
inpkt->len, n->outcompression)) < 0) {
@@ -447,7 +453,12 @@
return;
}
=20
- inpkt =3D outpkt;
+ if(outpkt->len < inpkt->len) {
+ outpkt->flag_bits =3D inpkt->flag_bits;
+ inpkt =3D outpkt;
+ }else{
+ outpkt->flags.compress =3D 0;
+ }
}
=20
/* Add sequence number */
@@ -469,6 +480,7 @@
goto end;
}
=20
+ outpkt->flag_bits =3D inpkt->flag_bits;
outpkt->len =3D outlen + outpad;
inpkt =3D outpkt;
}
@@ -483,7 +495,8 @@
=20
/* Add flags (not encrypted) */
=20
- inpkt->len +=3D sizeof(inpkt->flags);
+ inpkt->len +=3D sizeof(inpkt->flag_bits);
+ inpkt->flag_bits =3D htonl(inpkt->flag_bits);
=20
/* Determine which socket we have to use */
=20
@@ -506,7 +519,7 @@
}
#endif
=20
- if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, =
0, &(n->address.sa), SALEN(n->address.sa)) < 0 && =
!sockwouldblock(sockerrno)) {
+ if(sendto(listen_socket[sock].udp, (char *) &inpkt->flags, inpkt->len, =
0, &(n->address.sa), SALEN(n->address.sa)) < 0 && =
!sockwouldblock(sockerrno)) {
if(sockmsgsize(sockerrno)) {
if(n->maxmtu >=3D origlen)
n->maxmtu =3D origlen - 1;
diff --git a/src/process.c b/src/process.c
index 0007943..073f5c0 100644
--- a/src/process.c
+++ b/src/process.c
@@ -494,10 +494,10 @@
saved_debug_level =3D -1;
} else {
logger(LOG_NOTICE,
- "Temporarily setting debug level to 5. Kill me with SIGINT again to =
go back to level %d.",
- debug_level);
+ "Temporarily setting debug level to %d. Kill me with SIGINT again =
to go back to level %d.",
+ DEBUG_SCARY_THINGS, debug_level);
saved_debug_level =3D debug_level;
- debug_level =3D 5;
+ debug_level =3D DEBUG_SCARY_THINGS;
}
}
=20
diff --git a/src/protocol.h b/src/protocol.h
index 2aed26d..251e847 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -25,7 +25,7 @@
incompatible version have different protocols.
*/
=20
-#define PROT_CURRENT 17
+#define PROT_CURRENT 18
=20
/* Silly Windows */
=20
diff --git a/src/protocol_key.c b/src/protocol_key.c
index e2e4be5..1dc694d 100644
--- a/src/protocol_key.c
+++ b/src/protocol_key.c
@@ -310,8 +310,16 @@
update_node_udp(from, &sa);
}
=20
- if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuevent)
- send_mtu_probe(from);
-
+ if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuevent) {
+ //if(strcmp(from->name, myself->name) > 0) {
+ // // delay mtu discovery to prevent synchronous bursts
+ // from->mtuevent =3D new_event();
+ // from->mtuevent->handler =3D (event_handler_t)send_mtu_probe;
+ // from->mtuevent->data =3D from;
+ // from->mtuevent->time =3D now + 1;
+ // event_add(from->mtuevent);
+ //}else
+ send_mtu_probe(from);
+ }
return true;
}
diff --git a/src/route.c b/src/route.c
index 1caf738..b1a6389 100644
--- a/src/route.c
+++ b/src/route.c
@@ -317,6 +317,7 @@
static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) {
struct ip ip;
vpn_packet_t fragment;
+ fragment.flag_bits =3D packet->flag_bits;
int len, maxlen, todo;
uint8_t *offset;
uint16_t ip_off, origf;
------=_NextPart_000_0001_01CBADF1.BD635B80--
More information about the tinc-devel
mailing list