From 5f9e9271b2a6d9bc5541e5bb79315cc7170aaec8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 6 Jan 2015 14:46:20 +0000 Subject: [PATCH] Add support for LZS decompression in DTLS Signed-off-by: David Woodhouse --- cstp.c | 19 +++++++++++++++---- dtls.c | 10 ++++++++++ openconnect-internal.h | 2 ++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/cstp.c b/cstp.c index 7b5de67e..a3d5d489 100644 --- a/cstp.c +++ b/cstp.c @@ -218,9 +218,11 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) _("CRITICAL ERROR: DTLS master secret is uninitialised. Please report this.\n")); return -EINVAL; } - - buf_append(reqbuf, "\r\nX-DTLS-CipherSuite: %s\r\n\r\n", + buf_append(reqbuf, "\r\nX-DTLS-CipherSuite: %s\r\n", vpninfo->dtls_ciphers ? : DEFAULT_CIPHER_LIST); + if (vpninfo->req_compr & COMPR_LZS) + buf_append(reqbuf, "X-DTLS-Accept-Encoding: lzs\r\n"); + buf_append(reqbuf, "\r\n"); if (buf_error(reqbuf)) { vpn_progress(vpninfo, PRG_ERR, @@ -353,6 +355,15 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) if (dtls_sessid_changed && vpninfo->dtls_state > DTLS_SLEEPING) vpninfo->dtls_need_reconnect = 1; + } else if (!strcmp(buf + 7, "Content-Encoding")) { + if (!strcmp(colon, "lzs")) + vpninfo->dtls_compr = COMPR_LZS; + else { + vpn_progress(vpninfo, PRG_ERR, + _("Unknown DTLS-Content-Encoding %s\n"), + colon); + return -EINVAL; + } } continue; } @@ -663,8 +674,8 @@ static int cstp_reconnect(struct openconnect_info *vpninfo) return 0; } -static int decompress_and_queue_packet(struct openconnect_info *vpninfo, - unsigned char *buf, int len) +int decompress_and_queue_packet(struct openconnect_info *vpninfo, + unsigned char *buf, int len) { struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->ip_info.mtu); const char *comprtype; diff --git a/dtls.c b/dtls.c index e965af3b..4363940e 100644 --- a/dtls.c +++ b/dtls.c @@ -754,6 +754,15 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) vpn_progress(vpninfo, PRG_DEBUG, _("Got DTLS Keepalive\n")); break; + case AC_PKT_COMPRESSED: + if (!vpninfo->dtls_compr) { + vpn_progress(vpninfo, PRG_ERR, + _("Compressed DTLS packet received when compression not enabled\n")); + goto unknown_pkt; + } + decompress_and_queue_packet(vpninfo, vpninfo->dtls_pkt->data, + len - 1); + break; default: vpn_progress(vpninfo, PRG_ERR, _("Unknown DTLS packet type %02x, len %d\n"), @@ -766,6 +775,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) * the appropriate length of garbage. So don't abort... for now. */ break; } else { + unknown_pkt: vpninfo->quit_reason = "Unknown packet received"; return 1; } diff --git a/openconnect-internal.h b/openconnect-internal.h index 8e8b0e03..1a3f31d2 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -631,6 +631,8 @@ void dtls_shutdown(struct openconnect_info *vpninfo); int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout); int cstp_bye(struct openconnect_info *vpninfo, const char *reason); void cstp_free_splits(struct openconnect_info *vpninfo); +int decompress_and_queue_packet(struct openconnect_info *vpninfo, + unsigned char *buf, int len); /* lzs.c */ int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen);