comparison packet.c @ 906:4696755c4cac

A few fixes for cases where compression increases payload sizes, and be more precise about maximum channel sizes
author Matt Johnston <matt@ucc.asn.au>
date Sat, 22 Feb 2014 18:02:09 +0800
parents 220f55d540ae
children b8208506322e
comparison
equal deleted inserted replaced
905:f98618496f82 906:4696755c4cac
39 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state, 39 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
40 buffer * clear_buf, unsigned int clear_len, 40 buffer * clear_buf, unsigned int clear_len,
41 unsigned char *output_mac); 41 unsigned char *output_mac);
42 static int checkmac(); 42 static int checkmac();
43 43
44 #define ZLIB_COMPRESS_INCR 100 44 /* For exact details see http://www.zlib.net/zlib_tech.html
45 * 5 bytes per 16kB block, plus 6 bytes for the stream.
46 * We might allocate 5 unnecessary bytes here if it's an
47 * exact multiple. */
48 #define ZLIB_COMPRESS_EXPANSION (((RECV_MAX_PAYLOAD_LEN/16384)+1)*5 + 6)
45 #define ZLIB_DECOMPRESS_INCR 1024 49 #define ZLIB_DECOMPRESS_INCR 1024
46 #ifndef DISABLE_ZLIB 50 #ifndef DISABLE_ZLIB
47 static buffer* buf_decompress(buffer* buf, unsigned int len); 51 static buffer* buf_decompress(buffer* buf, unsigned int len);
48 static void buf_compress(buffer * dest, buffer * src, unsigned int len); 52 static void buf_compress(buffer * dest, buffer * src, unsigned int len);
49 #endif 53 #endif
331 padlen = buf_getbyte(ses.readbuf); 335 padlen = buf_getbyte(ses.readbuf);
332 336
333 /* payload length */ 337 /* payload length */
334 /* - 4 - 1 is for LEN and PADLEN values */ 338 /* - 4 - 1 is for LEN and PADLEN values */
335 len = ses.readbuf->len - padlen - 4 - 1 - macsize; 339 len = ses.readbuf->len - padlen - 4 - 1 - macsize;
336 if ((len > RECV_MAX_PAYLOAD_LEN) || (len < 1)) { 340 if ((len > RECV_MAX_PAYLOAD_LEN+ZLIB_COMPRESS_EXPANSION) || (len < 1)) {
337 dropbear_exit("Bad packet size %d", len); 341 dropbear_exit("Bad packet size %d", len);
338 } 342 }
339 343
340 buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF); 344 buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF);
341 345
420 } 424 }
421 425
422 if (zstream->avail_out == 0) { 426 if (zstream->avail_out == 0) {
423 int new_size = 0; 427 int new_size = 0;
424 if (ret->size >= RECV_MAX_PAYLOAD_LEN) { 428 if (ret->size >= RECV_MAX_PAYLOAD_LEN) {
429 /* Already been increased as large as it can go,
430 * yet didn't finish up the decompression */
425 dropbear_exit("bad packet, oversized decompressed"); 431 dropbear_exit("bad packet, oversized decompressed");
426 } 432 }
427 new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR); 433 new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR);
428 buf_resize(ret, new_size); 434 buf_resize(ret, new_size);
429 } 435 }
524 + MAX(MIN_PACKET_LEN, blocksize) + 3 530 + MAX(MIN_PACKET_LEN, blocksize) + 3
525 /* add space for the MAC at the end */ 531 /* add space for the MAC at the end */
526 + mac_size 532 + mac_size
527 #ifndef DISABLE_ZLIB 533 #ifndef DISABLE_ZLIB
528 /* some extra in case 'compression' makes it larger */ 534 /* some extra in case 'compression' makes it larger */
529 + ZLIB_COMPRESS_INCR 535 + ZLIB_COMPRESS_EXPANSION
530 #endif 536 #endif
531 /* and an extra cleartext (stripped before transmission) byte for the 537 /* and an extra cleartext (stripped before transmission) byte for the
532 * packet type */ 538 * packet type */
533 + 1; 539 + 1;
534 540
537 buf_setpos(writebuf, PACKET_PAYLOAD_OFF); 543 buf_setpos(writebuf, PACKET_PAYLOAD_OFF);
538 544
539 #ifndef DISABLE_ZLIB 545 #ifndef DISABLE_ZLIB
540 /* compression */ 546 /* compression */
541 if (is_compress_trans()) { 547 if (is_compress_trans()) {
542 int compress_delta;
543 buf_compress(writebuf, ses.writepayload, ses.writepayload->len); 548 buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
544 compress_delta = (writebuf->len - PACKET_PAYLOAD_OFF) - ses.writepayload->len;
545
546 /* Handle the case where 'compress' increased the size. */
547 if (compress_delta > ZLIB_COMPRESS_INCR) {
548 buf_resize(writebuf, writebuf->size + compress_delta);
549 }
550 } else 549 } else
551 #endif 550 #endif
552 { 551 {
553 memcpy(buf_getwriteptr(writebuf, ses.writepayload->len), 552 memcpy(buf_getwriteptr(writebuf, ses.writepayload->len),
554 buf_getptr(ses.writepayload, ses.writepayload->len), 553 buf_getptr(ses.writepayload, ses.writepayload->len),
692 dropbear_assert(ses.keys->trans.zstream->avail_out == 0); 691 dropbear_assert(ses.keys->trans.zstream->avail_out == 0);
693 692
694 /* the buffer has been filled, we must extend. This only happens in 693 /* the buffer has been filled, we must extend. This only happens in
695 * unusual circumstances where the data grows in size after deflate(), 694 * unusual circumstances where the data grows in size after deflate(),
696 * but it is possible */ 695 * but it is possible */
697 buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR); 696 buf_resize(dest, dest->size + ZLIB_COMPRESS_EXPANSION);
698 697
699 } 698 }
700 TRACE2(("leave buf_compress")) 699 TRACE2(("leave buf_compress"))
701 } 700 }
702 #endif 701 #endif