summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2015-02-19 00:32:00 +0800
committerMatt Johnston <matt@ucc.asn.au>2015-02-19 00:32:00 +0800
commitd275e08165dda61c6ce2263cdfd8f5684d8a6b55 (patch)
tree94ae7b933f8ea0ba18edb429d7988565bdc5684f
parent2213944b126c167ffaed53152b973a28c746bab7 (diff)
downloaddropbear-d275e08165dda61c6ce2263cdfd8f5684d8a6b55.tar.gz
In theory TFO should work. Needs platform cleanup and testing
-rw-r--r--cli-main.c5
-rw-r--r--cli-session.c7
-rw-r--r--dbutil.c46
-rw-r--r--dbutil.h3
-rw-r--r--packet.c2
-rw-r--r--packet.h5
-rw-r--r--session.h2
7 files changed, 60 insertions, 10 deletions
diff --git a/cli-main.c b/cli-main.c
index 6834d1d..80ff557 100644
--- a/cli-main.c
+++ b/cli-main.c
@@ -47,6 +47,7 @@ int main(int argc, char ** argv) {
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 @@ int main(int argc, char ** argv) {
} 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;
diff --git a/cli-session.c b/cli-session.c
index a5ae728..c2e4863 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -102,15 +102,20 @@ void cli_connected(int result, int sock, void* userdata, const char *errstring)
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;
diff --git a/dbutil.c b/dbutil.c
index 7b3a664..01b541c 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -1049,9 +1049,11 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
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 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
}
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 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
c->res_iter = c->res;
- /* Set one going */
- connect_try_next(c);
-
return c;
}
@@ -1202,3 +1236,7 @@ void handle_connect_fds(fd_set *writefd) {
}
TRACE(("leave handle_connect_fds - end iter"))
}
+
+void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) {
+ c->writequeue = writequeue;
+}
diff --git a/dbutil.h b/dbutil.h
index e05b249..c82e494 100644
--- a/dbutil.h
+++ b/dbutil.h
@@ -28,6 +28,7 @@
#include "includes.h"
#include "buffer.h"
+#include "queue.h"
#ifndef DISABLE_SYSLOG
void startsyslog();
@@ -132,4 +133,6 @@ void handle_connect_fds(fd_set *writefd);
/* 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_ */
diff --git a/packet.c b/packet.c
index 7b2b865..bdc3613 100644
--- a/packet.c
+++ b/packet.c
@@ -108,8 +108,6 @@ void write_packet() {
unsigned packet_type;
#ifdef HAVE_WRITEV
struct iovec *iov = NULL;
- int i;
- struct Link *l;
int iov_count;
#endif
diff --git a/packet.h b/packet.h
index 4645b14..ac14eca 100644
--- a/packet.h
+++ b/packet.h
@@ -27,6 +27,7 @@
#define _PACKET_H_
#include "includes.h"
+#include "queue.h"
void write_packet();
void read_packet();
@@ -46,4 +47,8 @@ typedef struct PacketType {
#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_ */
diff --git a/session.h b/session.h
index 3786346..28c2cae 100644
--- a/session.h
+++ b/session.h
@@ -60,7 +60,7 @@ void svr_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_N
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);