diff dbutil.c @ 1046:b8f4b7027191 coverity

merge
author Matt Johnston <matt@ucc.asn.au>
date Tue, 24 Feb 2015 22:48:34 +0800
parents d3925ed45a85
children 01eea88963f3
line wrap: on
line diff
--- a/dbutil.c	Tue Feb 10 21:47:43 2015 +0800
+++ b/dbutil.c	Tue Feb 24 22:48:34 2015 +0800
@@ -150,18 +150,44 @@
 
 
 #ifdef DEBUG_TRACE
+
+static double debug_start_time = -1;
+
+void debug_start_net()
+{
+	if (getenv("DROPBEAR_DEBUG_NET_TIMESTAMP"))
+	{
+    	/* Timestamps start from first network activity */
+	    struct timeval tv;
+	    gettimeofday(&tv, NULL);
+	    debug_start_time = tv.tv_sec + (tv.tv_usec / 1000000.0);
+	    TRACE(("Resetting Dropbear TRACE timestamps"))
+	}
+}
+
+static double time_since_start()
+{
+    double nowf;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    nowf = tv.tv_sec + (tv.tv_usec / 1000000.0);
+    if (debug_start_time < 0)
+    {
+        debug_start_time = nowf;
+        return 0;
+    }
+    return nowf - debug_start_time;
+}
+
 void dropbear_trace(const char* format, ...) {
 	va_list param;
-	struct timeval tv;
 
 	if (!debug_trace) {
 		return;
 	}
 
-	gettimeofday(&tv, NULL);
-
 	va_start(param, format);
-	fprintf(stderr, "TRACE  (%d) %d.%d: ", getpid(), (int)tv.tv_sec, (int)tv.tv_usec);
+	fprintf(stderr, "TRACE  (%d) %f: ", getpid(), time_since_start());
 	vfprintf(stderr, format, param);
 	fprintf(stderr, "\n");
 	va_end(param);
@@ -170,7 +196,6 @@
 void dropbear_trace2(const char* format, ...) {
 	static int trace_env = -1;
 	va_list param;
-	struct timeval tv;
 
 	if (trace_env == -1) {
 		trace_env = getenv("DROPBEAR_TRACE2") ? 1 : 0;
@@ -180,10 +205,8 @@
 		return;
 	}
 
-	gettimeofday(&tv, NULL);
-
 	va_start(param, format);
-	fprintf(stderr, "TRACE2 (%d) %d.%d: ", getpid(), (int)tv.tv_sec, (int)tv.tv_usec);
+	fprintf(stderr, "TRACE2 (%d) %f: ", getpid(), time_since_start());
 	vfprintf(stderr, format, param);
 	fprintf(stderr, "\n");
 	va_end(param);
@@ -390,13 +413,29 @@
 }
 #endif
 
+#if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
+static void set_piggyback_ack(int sock) {
+	/* Undocumented Linux feature - set TCP_DEFER_ACCEPT and data will be piggybacked
+	on the 3rd packet (ack) of the TCP handshake. Saves a IP packet.
+	http://thread.gmane.org/gmane.linux.network/224627/focus=224727
+	"Piggyback the final ACK of the three way TCP connection establishment with the data" */
+	int val = 1;
+	/* No error checking, this is opportunistic */
+	int err = setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (void*)&val, sizeof(val));
+	if (err)
+	{
+		TRACE(("Failed setsockopt TCP_DEFER_ACCEPT: %s", strerror(errno)))
+	}
+}
+#endif
+
+
 /* Connect via TCP to a host. Connection will try ipv4 or ipv6, will
  * return immediately if nonblocking is set. On failure, if errstring
  * wasn't null, it will be a newly malloced error message */
 
 /* TODO: maxfd */
-int connect_remote(const char* remotehost, const char* remoteport,
-		int nonblocking, char ** errstring) {
+int connect_remote(const char* remotehost, const char* remoteport, char ** errstring) {
 
 	struct addrinfo *res0 = NULL, *res = NULL, hints;
 	int sock;
@@ -435,12 +474,14 @@
 			continue;
 		}
 
-		if (nonblocking) {
-			setnonblocking(sock);
-		}
+		setnonblocking(sock);
+
+#if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
+		set_piggyback_ack(sock);
+#endif
 
 		if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
-			if (errno == EINPROGRESS && nonblocking) {
+			if (errno == EINPROGRESS) {
 				TRACE(("Connect in progress"))
 				break;
 			} else {
@@ -454,7 +495,7 @@
 		break; /* Success */
 	}
 
-	if (sock < 0 && !(errno == EINPROGRESS && nonblocking)) {
+	if (sock < 0 && !(errno == EINPROGRESS)) {
 		/* Failed */
 		if (errstring != NULL && *errstring == NULL) {
 			int len;
@@ -827,12 +868,12 @@
 
 /* make sure that the socket closes */
 void m_close(int fd) {
+	int val;
 
 	if (fd == -1) {
 		return;
 	}
 
-	int val;
 	do {
 		val = close(fd);
 	} while (val < 0 && errno == EINTR);