Mercurial > dropbear
diff packet.c @ 728:f27058078d61
Try using writev() for writing packets out to tcp
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 31 Mar 2013 23:15:35 +0800 |
parents | f4232b65b316 |
children | 9a5438271556 |
line wrap: on
line diff
--- a/packet.c Sun Mar 31 21:38:17 2013 +0800 +++ b/packet.c Sun Mar 31 23:15:35 2013 +0800 @@ -55,10 +55,60 @@ buffer * writebuf = NULL; time_t now; unsigned packet_type; + int all_ignore = 1; +#ifdef HAVE_WRITEV + struct iovec *iov = NULL; + int i; + struct Link *l; +#endif TRACE(("enter write_packet")) dropbear_assert(!isempty(&ses.writequeue)); +#ifdef HAVE_WRITEV + iov = m_malloc(sizeof(*iov) * ses.writequeue.count); + for (l = ses.writequeue.head, i = 0; l; l = l->link, i++) + { + writebuf = (buffer*)l->item; + packet_type = writebuf->data[writebuf->len-1]; + len = writebuf->len - 1 - writebuf->pos; + dropbear_assert(len > 0); + all_ignore &= (packet_type == SSH_MSG_IGNORE); + iov[i].iov_base = buf_getptr(writebuf, len); + iov[i].iov_len = len; + } + written = writev(ses.sock_out, iov, ses.writequeue.count); + if (written < 0) { + if (errno == EINTR) { + m_free(iov); + TRACE(("leave writepacket: EINTR")) + return; + } else { + dropbear_exit("Error writing"); + } + } + + if (written == 0) { + ses.remoteclosed(); + } + + while (written > 0) { + writebuf = (buffer*)examine(&ses.writequeue); + len = writebuf->len - 1 - writebuf->pos; + if (len > written) { + // partial buffer write + buf_incrpos(writebuf, written); + written = 0; + } else { + written -= len; + dequeue(&ses.writequeue); + buf_free(writebuf); + } + } + + m_free(iov); + +#else /* Get the next buffer in the queue of encrypted packets to write*/ writebuf = (buffer*)examine(&ses.writequeue); @@ -78,13 +128,7 @@ dropbear_exit("Error writing"); } } - - now = time(NULL); - ses.last_trx_packet_time = now; - - if (packet_type != SSH_MSG_IGNORE) { - ses.last_packet_time = now; - } + all_ignore = (packet_type == SSH_MSG_IGNORE); if (written == 0) { ses.remoteclosed(); @@ -100,6 +144,14 @@ buf_incrpos(writebuf, written); } +#endif + now = time(NULL); + ses.last_trx_packet_time = now; + + if (!all_ignore) { + ses.last_packet_time = now; + } + TRACE(("leave write_packet")) }