diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 39 |
1 files changed, 27 insertions, 12 deletions
@@ -58,8 +58,13 @@ void write_packet() { ssize_t written; #ifdef HAVE_WRITEV - struct iovec *iov = NULL; - int iov_count; + /* 50 is somewhat arbitrary */ + unsigned int iov_count = 50; + struct iovec iov[50]; +#else + int len; + buffer* writebuf; + int packet_type; #endif TRACE2(("enter write_packet")) @@ -67,7 +72,7 @@ void write_packet() { #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV)) - iov = packet_queue_to_iovec(&ses.writequeue, &iov_count); + packet_queue_to_iovec(&ses.writequeue, iov, &iov_count); /* This may return EAGAIN. The main loop sometimes calls write_packet() without bothering to test with select() since it's likely to be necessary */ @@ -75,15 +80,14 @@ void write_packet() { if (written < 0) { if (errno == EINTR || errno == EAGAIN) { TRACE2(("leave write_packet: EINTR")) - m_free(iov); return; } else { dropbear_exit("Error writing: %s", strerror(errno)); } } - m_free(iov); packet_queue_consume(&ses.writequeue, written); + ses.writequeue_len -= written; if (written == 0) { ses.remoteclosed(); @@ -97,6 +101,8 @@ void write_packet() { * a cleartext packet_type indicator */ packet_type = writebuf->data[writebuf->len-1]; len = writebuf->len - 1 - writebuf->pos; + TRACE2(("write_packet type %d len %d/%d", packet_type, + len, writebuf->len-1)) dropbear_assert(len > 0); /* Try to write as much as possible */ written = write(ses.sock_out, buf_getptr(writebuf, len), len); @@ -114,6 +120,8 @@ void write_packet() { ses.remoteclosed(); } + ses.writequeue_len -= written; + if (written == len) { /* We've finished with the packet, free it */ dequeue(&ses.writequeue); @@ -571,15 +579,12 @@ void encrypt_packet() { /* 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); - /* Update counts */ ses.kexstate.datatrans += writebuf->len; + + writebuf_enqueue(writebuf, packet_type); + + /* Update counts */ ses.transseq++; now = monotonic_now(); @@ -597,6 +602,16 @@ void encrypt_packet() { TRACE2(("leave encrypt_packet()")) } +void writebuf_enqueue(buffer * writebuf, unsigned char packet_type) { + /* 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); + ses.writequeue_len += writebuf->len-1; +} + /* Create the packet mac, and append H(seqno|clearbuf) to the output */ /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */ |