changeset 1033:ca71904cf3ee fastopen

Fixes for backwards compatibility
author Matt Johnston <matt@ucc.asn.au>
date Fri, 20 Feb 2015 23:38:05 +0800
parents 0da8ba489c23
children 107b013e9d9d
files configure.ac dbutil.h netio.c netio.h sysoptions.h
diffstat 5 files changed, 55 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Fri Feb 20 23:16:38 2015 +0800
+++ b/configure.ac	Fri Feb 20 23:38:05 2015 +0800
@@ -632,7 +632,7 @@
 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))
 
--- a/dbutil.h	Fri Feb 20 23:16:38 2015 +0800
+++ b/dbutil.h	Fri Feb 20 23:38:05 2015 +0800
@@ -65,18 +65,6 @@
 
 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);
--- a/netio.c	Fri Feb 20 23:16:38 2015 +0800
+++ b/netio.c	Fri Feb 20 23:38:05 2015 +0800
@@ -68,6 +68,11 @@
 
 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 @@
 		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 {
--- a/netio.h	Fri Feb 20 23:16:38 2015 +0800
+++ b/netio.h	Fri Feb 20 23:38:05 2015 +0800
@@ -42,5 +42,17 @@
 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
+
--- a/sysoptions.h	Fri Feb 20 23:16:38 2015 +0800
+++ b/sysoptions.h	Fri Feb 20 23:38:05 2015 +0800
@@ -259,4 +259,9 @@
 /* Use this string since some implementations might special-case it */
 #define DROPBEAR_KEEPALIVE_STRING "[email protected]"
 
+/* 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 */