comparison 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
comparison
equal deleted inserted replaced
590:a34a6a2e7c72 592:afb089e70892
51 /* non-blocking function writing out a current encrypted packet */ 51 /* non-blocking function writing out a current encrypted packet */
52 void write_packet() { 52 void write_packet() {
53 53
54 int len, written; 54 int len, written;
55 buffer * writebuf = NULL; 55 buffer * writebuf = NULL;
56 time_t now;
57 unsigned packet_type;
56 58
57 TRACE(("enter write_packet")) 59 TRACE(("enter write_packet"))
58 dropbear_assert(!isempty(&ses.writequeue)); 60 dropbear_assert(!isempty(&ses.writequeue));
59 61
60 /* Get the next buffer in the queue of encrypted packets to write*/ 62 /* Get the next buffer in the queue of encrypted packets to write*/
61 writebuf = (buffer*)examine(&ses.writequeue); 63 writebuf = (buffer*)examine(&ses.writequeue);
62 64
63 len = writebuf->len - writebuf->pos; 65 /* The last byte of the buffer is not to be transmitted, but is
66 * a cleartext packet_type indicator */
67 packet_type = writebuf->data[writebuf->len-1];
68 len = writebuf->len - 1 - writebuf->pos;
64 dropbear_assert(len > 0); 69 dropbear_assert(len > 0);
65 /* Try to write as much as possible */ 70 /* Try to write as much as possible */
66 written = write(ses.sock_out, buf_getptr(writebuf, len), len); 71 written = write(ses.sock_out, buf_getptr(writebuf, len), len);
67 72
68 if (written < 0) { 73 if (written < 0) {
72 } else { 77 } else {
73 dropbear_exit("error writing"); 78 dropbear_exit("error writing");
74 } 79 }
75 } 80 }
76 81
77 ses.last_trx_packet_time = time(NULL); 82 now = time(NULL);
78 ses.last_packet_time = time(NULL); 83 ses.last_trx_packet_time = now;
84
85 if (packet_type != SSH_MSG_IGNORE) {
86 ses.last_packet_time = now;
87 }
79 88
80 if (written == 0) { 89 if (written == 0) {
81 ses.remoteclosed(); 90 ses.remoteclosed();
82 } 91 }
83 92
418 427
419 unsigned char padlen; 428 unsigned char padlen;
420 unsigned char blocksize, mac_size; 429 unsigned char blocksize, mac_size;
421 buffer * writebuf; /* the packet which will go on the wire. This is 430 buffer * writebuf; /* the packet which will go on the wire. This is
422 encrypted in-place. */ 431 encrypted in-place. */
423 unsigned char type; 432 unsigned char packet_type;
424 unsigned int len, encrypt_buf_size; 433 unsigned int len, encrypt_buf_size;
425 unsigned char mac_bytes[MAX_MAC_LEN]; 434 unsigned char mac_bytes[MAX_MAC_LEN];
426 435
427 type = ses.writepayload->data[0];
428 TRACE(("enter encrypt_packet()")) 436 TRACE(("enter encrypt_packet()"))
429 TRACE(("encrypt_packet type is %d", type)) 437
430 438 buf_setpos(ses.writepayload, 0);
431 if (!ses.dataallowed && !packet_is_okay_kex(type)) { 439 packet_type = buf_getbyte(ses.writepayload);
440 buf_setpos(ses.writepayload, 0);
441
442 TRACE(("encrypt_packet type is %d", packet_type))
443
444 if (!ses.dataallowed && !packet_is_okay_kex(packet_type)) {
432 /* During key exchange only particular packets are allowed. 445 /* During key exchange only particular packets are allowed.
433 Since this type isn't OK we just enqueue it to send 446 Since this packet_type isn't OK we just enqueue it to send
434 after the KEX, see maybe_flush_reply_queue */ 447 after the KEX, see maybe_flush_reply_queue */
435 enqueue_reply_packet(); 448 enqueue_reply_packet();
436 return; 449 return;
437 } 450 }
438 451
440 mac_size = ses.keys->trans.algo_mac->hashsize; 453 mac_size = ses.keys->trans.algo_mac->hashsize;
441 454
442 /* Encrypted packet len is payload+5, then worst case is if we are 3 away 455 /* Encrypted packet len is payload+5, then worst case is if we are 3 away
443 * from a blocksize multiple. In which case we need to pad to the 456 * from a blocksize multiple. In which case we need to pad to the
444 * multiple, then add another blocksize (or MIN_PACKET_LEN) */ 457 * multiple, then add another blocksize (or MIN_PACKET_LEN) */
445 encrypt_buf_size = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3; 458 encrypt_buf_size = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3
446 /* add space for the MAC at the end */ 459 /* add space for the MAC at the end */
447 encrypt_buf_size += mac_size; 460 + mac_size
448
449 #ifndef DISABLE_ZLIB 461 #ifndef DISABLE_ZLIB
450 encrypt_buf_size += ZLIB_COMPRESS_INCR; /* bit of a kludge, but we can't know len*/ 462 /* zlib compression could lengthen the payload in some cases */
463 + ZLIB_COMPRESS_INCR
451 #endif 464 #endif
465 /* and an extra cleartext (stripped before transmission) byte for the
466 * packet type */
467 + 1;
468
452 writebuf = buf_new(encrypt_buf_size); 469 writebuf = buf_new(encrypt_buf_size);
453 buf_setlen(writebuf, PACKET_PAYLOAD_OFF); 470 buf_setlen(writebuf, PACKET_PAYLOAD_OFF);
454 buf_setpos(writebuf, PACKET_PAYLOAD_OFF); 471 buf_setpos(writebuf, PACKET_PAYLOAD_OFF);
455
456 buf_setpos(ses.writepayload, 0);
457 472
458 #ifndef DISABLE_ZLIB 473 #ifndef DISABLE_ZLIB
459 /* compression */ 474 /* compression */
460 if (is_compress_trans()) { 475 if (is_compress_trans()) {
461 buf_compress(writebuf, ses.writepayload, ses.writepayload->len); 476 buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
510 buf_incrpos(writebuf, len); 525 buf_incrpos(writebuf, len);
511 526
512 /* stick the MAC on it */ 527 /* stick the MAC on it */
513 buf_putbytes(writebuf, mac_bytes, mac_size); 528 buf_putbytes(writebuf, mac_bytes, mac_size);
514 529
530 /* The last byte of the buffer stores the cleartext packet_type. It is not
531 * transmitted but is used for transmit timeout purposes */
532 buf_putbyte(writebuf, packet_type);
515 /* enqueue the packet for sending. It will get freed after transmission. */ 533 /* enqueue the packet for sending. It will get freed after transmission. */
516 buf_setpos(writebuf, 0); 534 buf_setpos(writebuf, 0);
517 enqueue(&ses.writequeue, (void*)writebuf); 535 enqueue(&ses.writequeue, (void*)writebuf);
518 536
519 /* Update counts */ 537 /* Update counts */