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;