diff options
author | houseofkodai <karthik@houseofkodai.in> | 2017-05-01 08:26:15 +0530 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2018-01-26 00:28:25 +0800 |
commit | 9c7ecf6d14a82c1b1a97e1b4a328460ba8762299 (patch) | |
tree | a4cce47cf5ff76f239ff832965822c2e0164cd05 /netio.c | |
parent | 917722257d11ea7a33990c170542aeff2b6061b1 (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.c | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -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; } |