pMTU discovery

David Woodhouse dwmw2 at infradead.org
Fri Jun 8 08:02:19 EDT 2012


On Thu, 2012-05-31 at 11:44 +0200, Bernhard Schmidt wrote:
> we're currently testing OpenConnect 3.20 against our new shiny ASA Beta 
> which finally does IPv6 transport. However, when we do use that, we have 
> MTU problems on the link. The official AnyConnect client works fine.

It'd be very interesting to know where the Cisco client gets its numbers
from. How does this compare?

diff --git a/cstp.c b/cstp.c
index dbc24b9..5910940 100644
--- a/cstp.c
+++ b/cstp.c
@@ -32,6 +32,9 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <netinet/tcp.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <openssl/ssl.h>
 #include <openssl/err.h>
@@ -86,6 +89,48 @@ static int  __attribute__ ((format (printf, 3, 4)))
 	return ret;
 }
 
+static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *mtu)
+{
+#ifdef TCP_MAXSEG
+	int mss;
+	socklen_t mss_size = sizeof(mss);
+#endif
+#ifdef TCP_INFO
+	struct tcp_info ti;
+	socklen_t ti_size = sizeof(ti);
+#endif
+	if (vpninfo->mtu) {
+		/* User override */
+		*base_mtu = 0;
+		*mtu = vpninfo->mtu;
+	}
+#ifdef TCP_INFO
+	else if (!getsockopt(vpninfo->ssl_fd, SOL_TCP, TCP_INFO, &ti, &ti_size)) {
+		vpn_progress(vpninfo, PRG_TRACE,
+			     _("TCP_INFO rcv mss %d, snd mss %d, adv mss %d, pmtu %d\n"),
+			     ti.tcpi_rcv_mss, ti.tcpi_snd_mss, ti.tcpi_advmss, ti.tcpi_pmtu);
+		*base_mtu = ti.tcpi_pmtu;
+		if (ti.tcpi_rcv_mss < ti.tcpi_snd_mss)
+			*mtu = ti.tcpi_rcv_mss;
+		else
+			*mtu = ti.tcpi_snd_mss;
+	}
+#endif
+#ifdef TCP_MAXSEG
+	else if (!getsockopt(vpninfo->ssl_fd, SOL_TCP, TCP_MAXSEG, &mss, &mss_size)) {
+		vpn_progress(vpninfo, PRG_TRACE, _("TCP_MAXSEG %d\n"), mss);
+		*mtu = mss;
+		/* Erm, how do we sanely find the base MTU? */
+		*base_mtu = 1500;
+	}
+#endif
+	else {
+		/* Default */
+		*base_mtu = 0;
+		*mtu = 1406;
+	}
+}
+
 static int start_cstp_connection(struct openconnect_info *vpninfo)
 {
 	char buf[65536];
@@ -100,6 +145,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
 	const char *old_addr6 = vpninfo->vpn_addr6;
 	const char *old_netmask6 = vpninfo->vpn_netmask6;
 	struct split_include *inc;
+	int base_mtu, mtu;
 
 	/* Clear old options which will be overwritten */
 	vpninfo->vpn_addr = vpninfo->vpn_netmask = NULL;
@@ -132,6 +178,8 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
 	}
 
  retry:
+	calculate_mtu(vpninfo, &base_mtu, &mtu);
+
 	buf[0] = 0;
 	buf_append(buf, sizeof(buf), "CONNECT /CSCOSSLC/tunnel HTTP/1.1\r\n");
 	buf_append(buf, sizeof(buf), "Host: %s\r\n", vpninfo->hostname);
@@ -141,7 +189,9 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
 	buf_append(buf, sizeof(buf), "X-CSTP-Hostname: %s\r\n", vpninfo->localname);
 	if (vpninfo->deflate && i < sizeof(buf))
 		buf_append(buf, sizeof(buf), "X-CSTP-Accept-Encoding: deflate;q=1.0\r\n");
-	buf_append(buf, sizeof(buf), "X-CSTP-MTU: %d\r\n", vpninfo->mtu);
+	if (base_mtu)
+		buf_append(buf, sizeof(buf), "X-CSTP-Base-MTU: %d\r\n", base_mtu);
+	buf_append(buf, sizeof(buf), "X-CSTP-MTU: %d\r\n", mtu);
 	buf_append(buf, sizeof(buf), "X-CSTP-Address-Type: %s\r\n",
 			       vpninfo->disable_ipv6?"IPv4":"IPv6,IPv4");
 	buf_append(buf, sizeof(buf), "X-DTLS-Master-Secret: ");
diff --git a/main.c b/main.c
index 6f7f86c..9f52ed1 100644
--- a/main.c
+++ b/main.c
@@ -412,7 +412,7 @@ int main(int argc, char **argv)
 	/* Set up some defaults */
 	vpninfo->tun_fd = vpninfo->ssl_fd = vpninfo->dtls_fd = vpninfo->new_dtls_fd = -1;
 	vpninfo->useragent = openconnect_create_useragent("Open AnyConnect VPN Agent");
-	vpninfo->mtu = 1406;
+	vpninfo->mtu = 0;
 	vpninfo->deflate = 1;
 	vpninfo->dtls_attempt_period = 60;
 	vpninfo->max_qlen = 10;

-- 
dwmw2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20120608/00ab415f/attachment.bin>


More information about the openconnect-devel mailing list