Commit bdd670b6 authored by David Woodhouse's avatar David Woodhouse

Factor out compress_packet() function to be used for both CSTP and DTLS

Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 08476c2f
......@@ -734,6 +734,56 @@ int decompress_and_queue_packet(struct openconnect_info *vpninfo,
return 0;
}
int compress_packet(struct openconnect_info *vpninfo, int compr_type, struct pkt *this)
{
int ret;
if (compr_type == COMPR_DEFLATE) {
unsigned char *adler;
vpninfo->deflate_strm.next_in = this->data;
vpninfo->deflate_strm.avail_in = this->len;
vpninfo->deflate_strm.next_out = (void *)vpninfo->deflate_pkt->data;
vpninfo->deflate_strm.avail_out = vpninfo->deflate_pkt_size - 4;
vpninfo->deflate_strm.total_out = 0;
ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
if (ret) {
vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
/* Things are going to go horribly wrong if we try to do any
more compression. Give up entirely. */
vpninfo->cstp_compr = 0;
return -EIO;
}
/* Add ongoing adler32 to tail of compressed packet */
vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
this->data, this->len);
adler = &vpninfo->deflate_pkt->data[vpninfo->deflate_strm.total_out];
*(adler++) = vpninfo->deflate_adler32 >> 24;
*(adler++) = (vpninfo->deflate_adler32 >> 16) & 0xff;
*(adler++) = (vpninfo->deflate_adler32 >> 8) & 0xff;
*(adler) = vpninfo->deflate_adler32 & 0xff;
vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
return 0;
} else if (vpninfo->cstp_compr == COMPR_LZS) {
if (this->len < 40)
return -EFBIG;
ret = lzs_compress(vpninfo->deflate_pkt->data, this->len,
this->data, this->len);
if (ret < 0)
return ret;
vpninfo->deflate_pkt->len = ret;
return 0;
} else
return -EINVAL;
return 0;
}
#if defined(OPENCONNECT_OPENSSL)
static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
{
......@@ -1065,49 +1115,10 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
vpninfo->outgoing_queue = this->next;
vpninfo->outgoing_qlen--;
if (vpninfo->cstp_compr == COMPR_DEFLATE) {
unsigned char *adler;
vpninfo->deflate_strm.next_in = this->data;
vpninfo->deflate_strm.avail_in = this->len;
vpninfo->deflate_strm.next_out = (void *)vpninfo->deflate_pkt->data;
vpninfo->deflate_strm.avail_out = vpninfo->deflate_pkt_size - 4;
vpninfo->deflate_strm.total_out = 0;
ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
if (ret) {
vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
goto uncompr;
}
/* Add ongoing adler32 to tail of compressed packet */
vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
this->data, this->len);
adler = &vpninfo->deflate_pkt->data[vpninfo->deflate_strm.total_out];
*(adler++) = vpninfo->deflate_adler32 >> 24;
*(adler++) = (vpninfo->deflate_adler32 >> 16) & 0xff;
*(adler++) = (vpninfo->deflate_adler32 >> 8) & 0xff;
*(adler) = vpninfo->deflate_adler32 & 0xff;
vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
vpninfo->deflate_pkt->hdr[4] = (vpninfo->deflate_pkt->len) >> 8;
vpninfo->deflate_pkt->hdr[5] = (vpninfo->deflate_pkt->len) & 0xff;
vpn_progress(vpninfo, PRG_TRACE,
_("Sending deflate compressed data packet of %d bytes (was %d)\n"),
vpninfo->deflate_pkt->len, this->len);
vpninfo->pending_deflated_pkt = this;
vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
} else if (vpninfo->cstp_compr == COMPR_LZS) {
ret = lzs_compress(vpninfo->deflate_pkt->data, this->len,
this->data, this->len);
if (vpninfo->cstp_compr) {
ret = compress_packet(vpninfo, vpninfo->cstp_compr, this);
if (ret < 0)
goto uncompr; /* It only ever returns -EFBIG */
vpninfo->deflate_pkt->len = ret;
goto uncompr;
vpninfo->deflate_pkt->hdr[4] = (vpninfo->deflate_pkt->len) >> 8;
vpninfo->deflate_pkt->hdr[5] = (vpninfo->deflate_pkt->len) & 0xff;
......@@ -1116,8 +1127,8 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
vpninfo->deflate_pkt->hdr[7] = 0;
vpn_progress(vpninfo, PRG_TRACE,
_("Sending LZS compressed data packet of %d bytes (was %d)\n"),
ret, this->len);
_("Sending compressed data packet of %d bytes (was %d)\n"),
vpninfo->deflate_pkt->len, this->len);
vpninfo->pending_deflated_pkt = this;
vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
......
......@@ -854,19 +854,14 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
/* One byte of header */
this->hdr[7] = AC_PKT_DATA;
/* We can just use vpninfo->deflate_pkt unless CSTP currently
* has a compressed packet pending — which it shouldn't if
* DTLS is active. */
if (vpninfo->dtls_compr & COMPR_LZS && this->len > 0x40 &&
vpninfo->current_ssl_pkt != vpninfo->deflate_pkt) {
ret = lzs_compress(vpninfo->deflate_pkt->data, this->len,
this->data, this->len);
if (ret > 0) {
/* We can compress into vpninfo->deflate_pkt unless CSTP
* currently has a compressed packet pending — which it
* shouldn't if DTLS is active. */
if (vpninfo->dtls_compr &&
vpninfo->current_ssl_pkt != vpninfo->deflate_pkt &&
!compress_packet(vpninfo, vpninfo->dtls_compr, this)) {
send_pkt = vpninfo->deflate_pkt;
send_pkt->hdr[7] = AC_PKT_COMPRESSED;
send_pkt->len = ret;
}
}
#if defined(DTLS_OPENSSL)
......
......@@ -633,6 +633,7 @@ 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);
int compress_packet(struct openconnect_info *vpninfo, int compr_type, struct pkt *this);
/* lzs.c */
int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment