# HG changeset patch # User Matt Johnston # Date 1364742935 -28800 # Node ID f27058078d61a8c3a057530d3ddcd19bd5062569 # Parent 00bc3df3a9c33a5a36e51d1097603d4c1015159f Try using writev() for writing packets out to tcp diff -r 00bc3df3a9c3 -r f27058078d61 configure.ac --- a/configure.ac Sun Mar 31 21:38:17 2013 +0800 +++ b/configure.ac Sun Mar 31 23:15:35 2013 +0800 @@ -211,7 +211,7 @@ # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h pam/pam_appl.h netinet/in_systm.h]) +AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h pam/pam_appl.h netinet/in_systm.h, sys/uio.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -616,7 +616,7 @@ AC_FUNC_MEMCMP AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL -AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork]) +AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork writev]) AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME)) diff -r 00bc3df3a9c3 -r f27058078d61 includes.h --- a/includes.h Sun Mar 31 21:38:17 2013 +0800 +++ b/includes.h Sun Mar 31 23:15:35 2013 +0800 @@ -120,6 +120,10 @@ #include #endif +#ifdef HAVE_SYS_UIO_H +#include +#endif + #ifdef BUNDLED_LIBTOM #include "libtomcrypt/src/headers/tomcrypt.h" #include "libtommath/tommath.h" diff -r 00bc3df3a9c3 -r f27058078d61 packet.c --- 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")) } diff -r 00bc3df3a9c3 -r f27058078d61 queue.h --- a/queue.h Sun Mar 31 21:38:17 2013 +0800 +++ b/queue.h Sun Mar 31 23:15:35 2013 +0800 @@ -36,7 +36,7 @@ struct Link* head; struct Link* tail; - unsigned int count; /* safety value */ + unsigned int count; };