changeset 1027:daf21fd50abf fastopen

In theory TFO should work. Needs platform cleanup and testing
author Matt Johnston <matt@ucc.asn.au>
date Thu, 19 Feb 2015 00:32:00 +0800
parents 59a1146e8b9d
children 5ad81aa19c2d ea4676b840ef
files cli-main.c cli-session.c dbutil.c dbutil.h packet.c packet.h session.h
diffstat 7 files changed, 60 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/cli-main.c	Wed Feb 18 23:02:49 2015 +0800
+++ b/cli-main.c	Thu Feb 19 00:32:00 2015 +0800
@@ -47,6 +47,7 @@
 
 	int sock_in, sock_out;
 	char* error = NULL;
+	struct dropbear_progress_connection *progress = NULL;
 
 	_dropbear_exit = cli_dropbear_exit;
 	_dropbear_log = cli_dropbear_log;
@@ -72,11 +73,11 @@
 	} else
 #endif
 	{
-		connect_remote(cli_opts.remotehost, cli_opts.remoteport, cli_connected, NULL);
+		progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport, cli_connected, NULL);
 		sock_in = sock_out = -1;
 	}
 
-	cli_session(sock_in, sock_out);
+	cli_session(sock_in, sock_out, progress);
 
 	/* not reached */
 	return -1;
--- a/cli-session.c	Wed Feb 18 23:02:49 2015 +0800
+++ b/cli-session.c	Thu Feb 19 00:32:00 2015 +0800
@@ -102,15 +102,20 @@
 	ses.sock_in = ses.sock_out = sock;
 }
 
-void cli_session(int sock_in, int sock_out) {
+void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection *progress) {
 
 	common_session_init(sock_in, sock_out);
 
+	if (progress) {
+		connect_set_writequeue(progress, &ses.writequeue);
+	}
+
 	chaninitialise(cli_chantypes);
 
 	/* Set up cli_ses vars */
 	cli_session_init();
 
+
 	/* Ready to go */
 	sessinitdone = 1;
 
--- a/dbutil.c	Wed Feb 18 23:02:49 2015 +0800
+++ b/dbutil.c	Thu Feb 19 00:32:00 2015 +0800
@@ -1049,9 +1049,11 @@
 		setnonblocking(c->sock);
 
 #if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
-		set_piggyback_ack(sock);
+		//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"))
@@ -1065,8 +1067,43 @@
 		}
 
 		break; /* Success. Treated the same as EINPROGRESS */
+#endif
+#else
+		{
+			struct msghdr message = {0};
+			int flags;
+			int res;
+			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;
+				}
+			}
+
+			if (!c->writequeue) {
+				res = connect(c->sock, r->ai_addr, r->ai_addrlen);
+			}
+			if (res < 0 && errno != EINPROGRESS) {
+				err = errno;
+				close(c->sock);
+				c->sock = -1;
+				continue;
+			} else {
+				break;
+			}
+		}
+#endif
 	}
 
+
 	if (r) {
 		c->res_iter = r->ai_next;
 	} else {
@@ -1130,9 +1167,6 @@
 
 	c->res_iter = c->res;
 
-	/* Set one going */
-	connect_try_next(c);
-
 	return c;
 }
 
@@ -1202,3 +1236,7 @@
 	}
 	TRACE(("leave handle_connect_fds - end iter"))
 }
+
+void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) {
+	c->writequeue = writequeue;
+}
--- a/dbutil.h	Wed Feb 18 23:02:49 2015 +0800
+++ b/dbutil.h	Thu Feb 19 00:32:00 2015 +0800
@@ -28,6 +28,7 @@
 
 #include "includes.h"
 #include "buffer.h"
+#include "queue.h"
 
 #ifndef DISABLE_SYSLOG
 void startsyslog();
@@ -132,4 +133,6 @@
 /* Doesn't actually stop the connect, but adds a dummy callback instead */
 void cancel_connect(struct dropbear_progress_connection *c);
 
+void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue);
+
 #endif /* _DBUTIL_H_ */
--- a/packet.c	Wed Feb 18 23:02:49 2015 +0800
+++ b/packet.c	Thu Feb 19 00:32:00 2015 +0800
@@ -108,8 +108,6 @@
 	unsigned packet_type;
 #ifdef HAVE_WRITEV
 	struct iovec *iov = NULL;
-	int i;
-	struct Link *l;
 	int iov_count;
 #endif
 	
--- a/packet.h	Wed Feb 18 23:02:49 2015 +0800
+++ b/packet.h	Thu Feb 19 00:32:00 2015 +0800
@@ -27,6 +27,7 @@
 #define _PACKET_H_
 
 #include "includes.h"
+#include "queue.h"
 
 void write_packet();
 void read_packet();
@@ -46,4 +47,8 @@
 
 #define INIT_READBUF 128
 
+/* TODO: writev #ifdef guard */
+struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count);
+void packet_queue_consume(struct Queue *queue, ssize_t written);
+
 #endif /* _PACKET_H_ */
--- a/session.h	Wed Feb 18 23:02:49 2015 +0800
+++ b/session.h	Thu Feb 19 00:32:00 2015 +0800
@@ -60,7 +60,7 @@
 void svr_dropbear_log(int priority, const char* format, va_list param);
 
 /* Client */
-void cli_session(int sock_in, int sock_out);
+void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection *progress);
 void cli_connected(int result, int sock, void* userdata, const char *errstring);
 void cleantext(unsigned char* dirtytext);