diff packet.c @ 592:afb089e70892

Don't reset last_packet_time when we're transmitting SSH_MSG_IGNORE packets (from keepalives)
author Matt Johnston <matt@ucc.asn.au>
date Wed, 23 Feb 2011 15:10:28 +0000
parents 005530560594
children a98a2138364a
line wrap: on
line diff
--- a/packet.c	Wed Jul 21 13:53:29 2010 +0000
+++ b/packet.c	Wed Feb 23 15:10:28 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);