diff netio.c @ 1465:f7a53832501d

cli_bind_address_connect * replaces -b dummy option in dbclient to be similar with openssh -b option * useful in multi-wan connections
author houseofkodai <karthik@houseofkodai.in>
date Mon, 01 May 2017 08:26:15 +0530
parents ad637c9e0f6f
children f787f60f8e45
line wrap: on
line diff
--- a/netio.c	Thu Jan 25 19:51:41 2018 +0530
+++ b/netio.c	Mon May 01 08:26:15 2017 +0530
@@ -19,6 +19,7 @@
 	int sock;
 
 	char* errstring;
+	struct addrinfo *bind_addrinfo;
 };
 
 /* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
@@ -30,6 +31,7 @@
 	m_free(c->remotehost);
 	m_free(c->remoteport);
 	m_free(c->errstring);
+	if (c->bind_addrinfo) freeaddrinfo(c->bind_addrinfo);
 	m_free(c);
 
 	if (iter) {
@@ -66,6 +68,17 @@
 			continue;
 		}
 
+		if (c->bind_addrinfo) {
+			if (bind(c->sock, c->bind_addrinfo->ai_addr, c->bind_addrinfo->ai_addrlen) < 0) {
+				/* failure */
+				m_free(c->errstring);
+				c->errstring = m_strdup(strerror(errno));
+				close(c->sock);
+				c->sock = -1;
+				continue;
+			}
+		}
+
 		ses.maxfd = MAX(ses.maxfd, c->sock);
 		set_sock_nodelay(c->sock);
 		setnonblocking(c->sock);
@@ -130,7 +143,7 @@
 
 /* Connect via TCP to a host. */
 struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport,
-	connect_callback cb, void* cb_data)
+	connect_callback cb, void* cb_data, char* bind_address)
 {
 	struct dropbear_progress_connection *c = NULL;
 	int err;
@@ -142,6 +155,7 @@
 	c->sock = -1;
 	c->cb = cb;
 	c->cb_data = cb_data;
+	c->bind_addrinfo = NULL;
 
 	list_append(&ses.conn_pending, c);
 
@@ -160,6 +174,22 @@
 	} else {
 		c->res_iter = c->res;
 	}
+	
+	if (NULL != bind_address) {
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_family = AF_UNSPEC;
+		err = getaddrinfo(bind_address, NULL, &hints, &c->bind_addrinfo);
+		if (err) {
+			int len;
+			len = 100 + strlen(gai_strerror(err));
+			c->errstring = (char*)m_malloc(len);
+			snprintf(c->errstring, len, "Error resolving '%s'. %s", 
+					bind_address, gai_strerror(err));
+			TRACE(("Error resolving: %s", gai_strerror(err)))
+			c->res_iter = NULL;
+		}
+	}
 
 	return c;
 }