On Fri, 2018-01-05 at 11:31 -0500, Chaskiel Grundman wrote:
> It turns out I was mistaken. The gateway does *not* split the packet
> into 2 DTLS packets. It sends one large DTLS packet and openconnect
> reads the first 1290 bytes of plaintext as one packet and the rest as
> another.
> 
> I do not use official anyconnect clients myself except on windows,
> which I have gotten a capture from. The ciphersuites are identical.
> the captures include the dtls handshake, and the largest data packet
> sent during setup. The linux capture also includes the packets
> corresponding to a >1290 byte ping (I used 1391 instead of 1291, so
> there's extra stuff coming back from the gateway corresponding to the
> IP fragmentation, but that does not obscure the fact that the gateway
> sends a packet with a 1344 byte DTLS payload, but the max that
> openconnect sends is 1328)

The openconnect client is quite strict with the data received by the
peer. It expects that the peer will have the same view on its
calculated MTU. Could you try this (untested) patch on client? Does it
improve the situation?

regards,
Nikos
From ecf04b64be1fc835d5688a815e3ef40851242ffc Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <[email protected]>
Date: Sat, 6 Jan 2018 09:46:06 +0100
Subject: [PATCH] Allow the server to exceed the calculate MTU size by
 MTU_SLACK

That works around the issue that if we have an asymmetric MTU (different
for sending and receiving), that is not visible to either party. For that,
allow larger than MTU packets to be received.

Signed-off-by: Nikos Mavrogiannopoulos <[email protected]>
---
 cstp.c                 | 9 +++++----
 dtls.c                 | 3 ++-
 openconnect-internal.h | 4 ++++
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/cstp.c b/cstp.c
index 5477c5c..5395446 100644
--- a/cstp.c
+++ b/cstp.c
@@ -729,7 +729,8 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
 int decompress_and_queue_packet(struct openconnect_info *vpninfo, int compr_type,
 				unsigned char *buf, int len)
 {
-	struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->ip_info.mtu);
+	unsigned max = vpninfo->ip_info.mtu+MTU_SLACK;
+	struct pkt *new = malloc(sizeof(struct pkt) + max);
 	const char *comprname = "";
 
 	if (!new)
@@ -746,7 +747,7 @@ int decompress_and_queue_packet(struct openconnect_info *vpninfo, int compr_type
 		vpninfo->inflate_strm.avail_in = len - 4;
 
 		vpninfo->inflate_strm.next_out = new->data;
-		vpninfo->inflate_strm.avail_out = vpninfo->ip_info.mtu;
+		vpninfo->inflate_strm.avail_out = max;
 		vpninfo->inflate_strm.total_out = 0;
 
 		if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
@@ -768,7 +769,7 @@ int decompress_and_queue_packet(struct openconnect_info *vpninfo, int compr_type
 	} else if (compr_type == COMPR_LZS) {
 		comprname = "LZS";
 
-		new->len = lzs_decompress(new->data, vpninfo->ip_info.mtu, buf, len);
+		new->len = lzs_decompress(new->data, max, buf, len);
 		if (new->len < 0) {
 			len = new->len;
 			if (len == 0)
@@ -781,7 +782,7 @@ int decompress_and_queue_packet(struct openconnect_info *vpninfo, int compr_type
 #ifdef HAVE_LZ4
 	} else if (compr_type == COMPR_LZ4) {
 		comprname = "LZ4";
-		new->len = LZ4_decompress_safe((void *)buf, (void *)new->data, len, vpninfo->ip_info.mtu);
+		new->len = LZ4_decompress_safe((void *)buf, (void *)new->data, len, max);
 		if (new->len <= 0) {
 			len = new->len;
 			if (len == 0)
diff --git a/dtls.c b/dtls.c
index 80d6c05..13c2553 100644
--- a/dtls.c
+++ b/dtls.c
@@ -273,7 +273,8 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
 	}
 
 	while (1) {
-		int len = vpninfo->ip_info.mtu;
+		/* Allow the peer sending larger than MTU packets */
+		int len = vpninfo->ip_info.mtu + MTU_SLACK;
 		unsigned char *buf;
 
 		if (!vpninfo->dtls_pkt) {
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 5b9a8d6..a91b8d1 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -118,6 +118,10 @@
 #define SHA1_SIZE 20
 #define MD5_SIZE 16
 
+/* The amount of bytes which the peer can exceed the MTU on its
+ * packets. */
+#define MTU_SLACK 256
+
 /* FreeBSD provides this in <sys/param.h>  */
 #ifndef MAX
 #define MAX(x,y) ((x)>(y))?(x):(y)
-- 
2.11.0

_______________________________________________
openconnect-devel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/openconnect-devel

Reply via email to