summaryrefslogtreecommitdiffhomepage
path: root/netio.c
diff options
context:
space:
mode:
authorhouseofkodai <karthik@houseofkodai.in>2017-05-01 08:26:15 +0530
committerMatt Johnston <matt@ucc.asn.au>2018-01-26 00:28:25 +0800
commit9c7ecf6d14a82c1b1a97e1b4a328460ba8762299 (patch)
treea4cce47cf5ff76f239ff832965822c2e0164cd05 /netio.c
parent917722257d11ea7a33990c170542aeff2b6061b1 (diff)
cli_bind_address_connect
* replaces -b dummy option in dbclient to be similar with openssh -b option * useful in multi-wan connections
Diffstat (limited to 'netio.c')
-rw-r--r--netio.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/netio.c b/netio.c
index 2f37e70..b594e84 100644
--- a/netio.c
+++ b/netio.c
@@ -19,6 +19,7 @@ struct dropbear_progress_connection {
int sock;
char* errstring;
+ struct addrinfo *bind_addrinfo;
};
/* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
@@ -30,6 +31,7 @@ static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *
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 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
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 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
/* 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 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
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 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
} 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;
}