# HG changeset patch # User Matt Johnston # Date 1298473831 0 # Node ID ea103e4476cedf01688d63cd6c04effe8fc8ae9d # Parent 345aaed42ef46d5236c5652124542bf9911b9e1e# Parent afb089e708923651f2d2290173261d8f1bbb6ac9 merge of '8849ec659cb45b924158cc3322390a1d3d48daef' and 'a46ca9204de0df58d8701df0d79b6b8ec601b9ce' diff -r 345aaed42ef4 -r ea103e4476ce packet.c --- a/packet.c Wed Jul 21 14:07:13 2010 +0000 +++ b/packet.c Wed Feb 23 15:10:31 2011 +0000 @@ -53,6 +53,8 @@ int len, written; buffer * writebuf = NULL; + time_t now; + unsigned packet_type; TRACE(("enter write_packet")) dropbear_assert(!isempty(&ses.writequeue)); @@ -60,7 +62,10 @@ /* Get the next buffer in the queue of encrypted packets to write*/ writebuf = (buffer*)examine(&ses.writequeue); - len = writebuf->len - writebuf->pos; + /* The last byte of the buffer is not to be transmitted, but is + * a cleartext packet_type indicator */ + packet_type = writebuf->data[writebuf->len-1]; + len = writebuf->len - 1 - writebuf->pos; dropbear_assert(len > 0); /* Try to write as much as possible */ written = write(ses.sock_out, buf_getptr(writebuf, len), len); @@ -74,8 +79,12 @@ } } - ses.last_trx_packet_time = time(NULL); - ses.last_packet_time = time(NULL); + now = time(NULL); + ses.last_trx_packet_time = now; + + if (packet_type != SSH_MSG_IGNORE) { + ses.last_packet_time = now; + } if (written == 0) { ses.remoteclosed(); @@ -420,17 +429,21 @@ unsigned char blocksize, mac_size; buffer * writebuf; /* the packet which will go on the wire. This is encrypted in-place. */ - unsigned char type; + unsigned char packet_type; unsigned int len, encrypt_buf_size; unsigned char mac_bytes[MAX_MAC_LEN]; - type = ses.writepayload->data[0]; TRACE(("enter encrypt_packet()")) - TRACE(("encrypt_packet type is %d", type)) + + buf_setpos(ses.writepayload, 0); + packet_type = buf_getbyte(ses.writepayload); + buf_setpos(ses.writepayload, 0); + + TRACE(("encrypt_packet type is %d", packet_type)) - if (!ses.dataallowed && !packet_is_okay_kex(type)) { + if (!ses.dataallowed && !packet_is_okay_kex(packet_type)) { /* During key exchange only particular packets are allowed. - Since this type isn't OK we just enqueue it to send + Since this packet_type isn't OK we just enqueue it to send after the KEX, see maybe_flush_reply_queue */ enqueue_reply_packet(); return; @@ -442,19 +455,21 @@ /* Encrypted packet len is payload+5, then worst case is if we are 3 away * from a blocksize multiple. In which case we need to pad to the * multiple, then add another blocksize (or MIN_PACKET_LEN) */ - encrypt_buf_size = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3; + encrypt_buf_size = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3 /* add space for the MAC at the end */ - encrypt_buf_size += mac_size; + + mac_size +#ifndef DISABLE_ZLIB + /* zlib compression could lengthen the payload in some cases */ + + ZLIB_COMPRESS_INCR +#endif + /* and an extra cleartext (stripped before transmission) byte for the + * packet type */ + + 1; -#ifndef DISABLE_ZLIB - encrypt_buf_size += ZLIB_COMPRESS_INCR; /* bit of a kludge, but we can't know len*/ -#endif writebuf = buf_new(encrypt_buf_size); buf_setlen(writebuf, PACKET_PAYLOAD_OFF); buf_setpos(writebuf, PACKET_PAYLOAD_OFF); - buf_setpos(ses.writepayload, 0); - #ifndef DISABLE_ZLIB /* compression */ if (is_compress_trans()) { @@ -512,6 +527,9 @@ /* stick the MAC on it */ buf_putbytes(writebuf, mac_bytes, mac_size); + /* The last byte of the buffer stores the cleartext packet_type. It is not + * transmitted but is used for transmit timeout purposes */ + buf_putbyte(writebuf, packet_type); /* enqueue the packet for sending. It will get freed after transmission. */ buf_setpos(writebuf, 0); enqueue(&ses.writequeue, (void*)writebuf); diff -r 345aaed42ef4 -r ea103e4476ce process-packet.c --- a/process-packet.c Wed Jul 21 14:07:13 2010 +0000 +++ b/process-packet.c Wed Feb 23 15:10:31 2011 +0000 @@ -52,6 +52,8 @@ ses.lastpacket = type; + ses.last_packet_time = time(NULL); + /* These packets we can receive at any time */ switch(type) { @@ -70,8 +72,6 @@ dropbear_close("Disconnect received"); } - ses.last_packet_time = time(NULL); - /* This applies for KEX, where the spec says the next packet MUST be * NEWKEYS */ if (ses.requirenext != 0) {