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