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);
+ /* Some servers send us packets that are larger than
+ negotiated MTU after decompression. We reserve some extra
+ space to handle that */
+ int receive_mtu = MAX(16384, vpninfo->ip_info.mtu);
+ struct pkt *new = malloc(sizeof(struct pkt) + receive_mtu);
const char *comprname = "";
if (!new)
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 = receive_mtu;
vpninfo->inflate_strm.total_out = 0;
if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
} 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, receive_mtu, buf, len);
if (new->len < 0) {
len = new->len;
if (len == 0)
#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, receive_mtu);
if (new->len <= 0) {
len = new->len;
if (len == 0)