From f04a3a2cfa6a2787e84b07d6d22cb1e9837ff6af Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Fri, 20 Feb 2015 23:38:05 +0800 Subject: [PATCH] Fixes for backwards compatibility --HG-- branch : fastopen --- configure.ac | 2 +- dbutil.h | 12 -------- netio.c | 83 +++++++++++++++++++++++----------------------------- netio.h | 12 ++++++++ sysoptions.h | 5 ++++ 5 files changed, 55 insertions(+), 59 deletions(-) diff --git a/configure.ac b/configure.ac index b952d7e..b0e85e5 100644 --- a/configure.ac +++ b/configure.ac @@ -632,7 +632,7 @@ fi AC_PROG_GCC_TRADITIONAL AC_FUNC_MEMCMP AC_FUNC_SELECT_ARGTYPES -AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork writev sendmsg]) +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 --git a/dbutil.h b/dbutil.h index a7b6897..f5c57b3 100644 --- a/dbutil.h +++ b/dbutil.h @@ -65,18 +65,6 @@ extern int debug_trace; char * stripcontrol(const char * text); -#if defined(__linux__) && HAVE_SENDMSG -#define DROPBEAR_TCP_FAST_OPEN -void set_listen_fast_open(int sock); -/* may be supported by kernel but not libc */ -#ifndef TCP_FASTOPEN -#define TCP_FASTOPEN 23 -#endif -#ifndef MSG_FASTOPEN -#define MSG_FASTOPEN 0x20000000 -#endif -#endif - int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, int *writefd, int *readfd, int *errfd, pid_t *pid); void run_shell_command(const char* cmd, unsigned int maxfd, char* usershell); diff --git a/netio.c b/netio.c index 8dd8060..b86c85b 100644 --- a/netio.c +++ b/netio.c @@ -68,6 +68,11 @@ void cancel_connect(struct dropbear_progress_connection *c) { static void connect_try_next(struct dropbear_progress_connection *c) { struct addrinfo *r; + int res = 0; + int fastopen = 0; +#ifdef DROPBEAR_TCP_FAST_OPEN + struct msghdr message; +#endif if (!c->res_iter) { return; @@ -89,60 +94,46 @@ static void connect_try_next(struct dropbear_progress_connection *c) { set_piggyback_ack(c->sock); #endif -#ifdef PROGRESS_CONNECT_FALLBACK -#if 0 - if (connect(c->sock, r->ai_addr, r->ai_addrlen) < 0) { - if (errno == EINPROGRESS) { - TRACE(("Connect in progress")) - break; - } else { - close(c->sock); - c->sock = -1; - continue; - } - } +#ifdef DROPBEAR_TCP_FAST_OPEN + fastopen = (c->writequeue != NULL); - break; /* Success. Treated the same as EINPROGRESS */ -#endif -#else - { - struct msghdr message; - int res = 0; - memset(&message, 0x0, sizeof(message)); - message.msg_name = r->ai_addr; - message.msg_namelen = r->ai_addrlen; + memset(&message, 0x0, sizeof(message)); + message.msg_name = r->ai_addr; + message.msg_namelen = r->ai_addrlen; - if (c->writequeue) { - int iovlen; /* Linux msg_iovlen is a size_t */ - message.msg_iov = packet_queue_to_iovec(c->writequeue, &iovlen); - message.msg_iovlen = iovlen; - res = sendmsg(c->sock, &message, MSG_FASTOPEN); - if (res < 0 && errno == EOPNOTSUPP) { - TRACE(("Fastopen not supported")); - /* No kernel MSG_FASTOPEN support. Fall back below */ - c->writequeue = NULL; - } - m_free(message.msg_iov); - if (res > 0) { - packet_queue_consume(c->writequeue, res); - } + if (c->writequeue) { + int iovlen; /* Linux msg_iovlen is a size_t */ + message.msg_iov = packet_queue_to_iovec(c->writequeue, &iovlen); + message.msg_iovlen = iovlen; + res = sendmsg(c->sock, &message, MSG_FASTOPEN); + if (res < 0 && errno == EOPNOTSUPP) { + TRACE(("Fastopen not supported")); + /* No kernel MSG_FASTOPEN support. Fall back below */ + fastopen = 0; + /* Set to NULL to avoid trying again */ + c->writequeue = NULL; } - - if (!c->writequeue) { - res = connect(c->sock, r->ai_addr, r->ai_addrlen); - } - if (res < 0 && errno != EINPROGRESS) { - close(c->sock); - c->sock = -1; - continue; - } else { - break; + m_free(message.msg_iov); + if (res > 0) { + packet_queue_consume(c->writequeue, res); } } #endif + + /* Normal connect(), used as fallback for TCP fastopen too */ + if (!fastopen) { + res = connect(c->sock, r->ai_addr, r->ai_addrlen); + } + + if (res < 0 && errno != EINPROGRESS) { + close(c->sock); + c->sock = -1; + continue; + } else { + break; + } } - if (r) { c->res_iter = r->ai_next; } else { diff --git a/netio.h b/netio.h index 3c98d6c..280ccaf 100644 --- a/netio.h +++ b/netio.h @@ -42,5 +42,17 @@ void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count); void packet_queue_consume(struct Queue *queue, ssize_t written); +#ifdef DROPBEAR_TCP_FAST_OPEN +/* Try for any Linux builds, will fall back if the kernel doesn't support it */ +void set_listen_fast_open(int sock); +/* Define values which may be supported by the kernel even if the libc is too old */ +#ifndef TCP_FASTOPEN +#define TCP_FASTOPEN 23 +#endif +#ifndef MSG_FASTOPEN +#define MSG_FASTOPEN 0x20000000 +#endif +#endif + #endif diff --git a/sysoptions.h b/sysoptions.h index bec7246..092eb7e 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -259,4 +259,9 @@ /* Use this string since some implementations might special-case it */ #define DROPBEAR_KEEPALIVE_STRING "keepalive@openssh.com" +/* Linux will attempt TCP fast open, falling back if not supported by the kernel */ +#ifdef __linux__ +#define DROPBEAR_TCP_FAST_OPEN 1 +#endif + /* no include guard for this file */