From 70238e30d240966fbfcda1a07ff9cd93f062865c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 5 Jan 2015 14:34:20 +0000 Subject: [PATCH] Change vpninfo->deflate to three separate bitmasks for requested/CSTP/DTLS As we support more compression methods, and also need to separately keep track of what was negotiated for CSTP and DTLS, this will be needed. We will also want to look a library API and command-line options for enabling and disabling specific compression methods. Signed-off-by: David Woodhouse --- cstp.c | 27 +++++++++++++++++---------- library.c | 2 +- main.c | 6 +++--- openconnect-internal.h | 8 +++++++- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/cstp.c b/cstp.c index 55225f49..17427fd1 100644 --- a/cstp.c +++ b/cstp.c @@ -188,8 +188,15 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) buf_append(reqbuf, "Cookie: webvpn=%s\r\n", vpninfo->cookie); buf_append(reqbuf, "X-CSTP-Version: 1\r\n"); buf_append(reqbuf, "X-CSTP-Hostname: %s\r\n", vpninfo->localname); - if (vpninfo->deflate && i < sizeof(buf)) - buf_append(reqbuf, "X-CSTP-Accept-Encoding: deflate;q=1.0\r\n"); + if (vpninfo->req_compr) { + char sep = ' '; + buf_append(reqbuf, "X-CSTP-Accept-Encoding:"); + if (vpninfo->req_compr & COMPR_DEFLATE) { + buf_append(reqbuf, "%cdeflate", sep); + sep = ','; + } + buf_append(reqbuf, "\r\n"); + } if (base_mtu) buf_append(reqbuf, "X-CSTP-Base-MTU: %d\r\n", base_mtu); buf_append(reqbuf, "X-CSTP-MTU: %d\r\n", mtu); @@ -267,7 +274,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) vpn_progress(vpninfo, PRG_INFO, _("Got CONNECT response: %s\n"), buf); /* We may have advertised it, but we only do it if the server agrees */ - vpninfo->deflate = 0; + vpninfo->cstp_compr = vpninfo->dtls_compr = 0; mtu = 0; while ((i = vpninfo->ssl_gets(vpninfo, buf, sizeof(buf)))) { @@ -367,7 +374,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) vpninfo->ssl_times.rekey_method = REKEY_NONE; } else if (!strcmp(buf + 7, "Content-Encoding")) { if (!strcmp(colon, "deflate")) - vpninfo->deflate = 1; + vpninfo->cstp_compr = COMPR_DEFLATE; else { vpn_progress(vpninfo, PRG_ERR, _("Unknown CSTP-Content-Encoding %s\n"), @@ -546,7 +553,7 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo) if (ret) return ret; - if (vpninfo->deflate) { + if (vpninfo->req_compr & COMPR_DEFLATE) { vpninfo->deflate_adler32 = 1; vpninfo->inflate_adler32 = 1; @@ -554,7 +561,7 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo) deflateInit2(&vpninfo->deflate_strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY)) { vpn_progress(vpninfo, PRG_ERR, _("Compression setup failed\n")); - vpninfo->deflate = 0; + vpninfo->req_compr &= ~COMPR_DEFLATE; } if (!vpninfo->deflate_pkt) { @@ -564,7 +571,7 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo) _("Allocation of deflate buffer failed\n")); inflateEnd(&vpninfo->inflate_strm); deflateEnd(&vpninfo->deflate_strm); - vpninfo->deflate = 0; + vpninfo->req_compr &= ~COMPR_DEFLATE; } else { memset(vpninfo->deflate_pkt, 0, sizeof(struct pkt)); memcpy(vpninfo->deflate_pkt->hdr, data_hdr, 8); @@ -587,7 +594,7 @@ static int cstp_reconnect(struct openconnect_info *vpninfo) openconnect_close_https(vpninfo, 0); - if (vpninfo->deflate) { + if (vpninfo->cstp_compr == COMPR_DEFLATE) { /* Requeue the original packet that was deflated */ if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt) { vpninfo->current_ssl_pkt = NULL; @@ -824,7 +831,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) return -EPIPE; } case AC_PKT_COMPRESSED: - if (!vpninfo->deflate) { + if (!vpninfo->cstp_compr) { vpn_progress(vpninfo, PRG_ERR, _("Compressed packet received in !deflate mode\n")); goto unknown_pkt; @@ -975,7 +982,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) vpninfo->outgoing_queue = this->next; vpninfo->outgoing_qlen--; - if (vpninfo->deflate) { + if (vpninfo->cstp_compr == COMPR_DEFLATE) { unsigned char *adler; int ret; diff --git a/library.c b/library.c index e9c28ffc..add732e2 100644 --- a/library.c +++ b/library.c @@ -72,7 +72,7 @@ struct openconnect_info *openconnect_vpninfo_new(const char *useragent, vpninfo->ssl_fd = vpninfo->dtls_fd = -1; vpninfo->cmd_fd = vpninfo->cmd_fd_write = -1; vpninfo->cert_expire_warning = 60 * 86400; - vpninfo->deflate = 1; + vpninfo->req_compr = COMPR_ALL; vpninfo->max_qlen = 10; vpninfo->localname = strdup("localhost"); vpninfo->useragent = openconnect_create_useragent(useragent); diff --git a/main.c b/main.c index 2bd9faf7..e26838b5 100644 --- a/main.c +++ b/main.c @@ -1132,10 +1132,10 @@ int main(int argc, char **argv) vpninfo->sslkey = dup_config_arg(); break; case 'd': - vpninfo->deflate = 1; + vpninfo->req_compr = COMPR_ALL; break; case 'D': - vpninfo->deflate = 0; + vpninfo->req_compr = 0; break; case 'g': free(urlpath); @@ -1429,7 +1429,7 @@ int main(int argc, char **argv) (ip_info->netmask6 && ip_info->addr) ? " + " : "", ip_info->netmask6 ? : "", (vpninfo->dtls_state != DTLS_CONNECTED) ? - (vpninfo->deflate ? "SSL + deflate" : "SSL") + (vpninfo->cstp_compr == COMPR_DEFLATE) ? "SSL + deflate" : "SSL" : "DTLS"); if (!vpninfo->vpnc_script) { diff --git a/openconnect-internal.h b/openconnect-internal.h index 33f42e29..e4fc124c 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -140,6 +140,9 @@ struct pkt { #define DTLS_CONNECTING 3 #define DTLS_CONNECTED 4 +#define COMPR_DEFLATE (1<<0) +#define COMPR_ALL (COMPR_DEFLATE) + struct keepalive_info { int dpd; int keepalive; @@ -438,7 +441,10 @@ struct openconnect_info { int dtls_local_port; - int deflate; + int req_compr; /* What we requested */ + int cstp_compr; /* Accepted for CSTP */ + int dtls_compr; /* Accepted for DTLS */ + int is_dyndns; /* Attempt to redo DNS lookup on each CSTP reconnect */ char *useragent;