Skip to content
Snippets Groups Projects
Commit f6b30425 authored by Matt Johnston's avatar Matt Johnston
Browse files

Try using writev() for writing packets out to tcp

parent 36526700
No related merge requests found
......@@ -211,7 +211,7 @@ AC_ARG_ENABLE(shadow,
# 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_PROG_GCC_TRADITIONAL
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))
......
......@@ -120,6 +120,10 @@
#include <libgen.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef BUNDLED_LIBTOM
#include "libtomcrypt/src/headers/tomcrypt.h"
#include "libtommath/tommath.h"
......
......@@ -55,10 +55,60 @@ void write_packet() {
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 @@ void write_packet() {
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 @@ void write_packet() {
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"))
}
......
......@@ -36,7 +36,7 @@ struct Queue {
struct Link* head;
struct Link* tail;
unsigned int count; /* safety value */
unsigned int count;
};
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment