diff options
Diffstat (limited to 'src/or/eventdns.c')
-rw-r--r-- | src/or/eventdns.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 60f08265cd..6e4e5e25b4 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -2203,6 +2203,23 @@ evdns_clear_nameservers_and_suspend(void) return 0; } +static struct sockaddr_storage global_bind_address; +static socklen_t global_bind_addrlen = 0; +static int global_bind_addr_is_set = 0; +void +evdns_set_default_outgoing_bind_address(const struct sockaddr *addr, + socklen_t addrlen) +{ + memset(&global_bind_address, 0, sizeof(global_bind_address)); + if (addr) { + assert(addrlen <= sizeof(global_bind_address)); + memcpy(&global_bind_address, addr, addrlen); + global_bind_addrlen = addrlen; + global_bind_addr_is_set = 1; + } else { + global_bind_addr_is_set = 0; + } +} /* exported function */ int @@ -2251,6 +2268,15 @@ _evdns_nameserver_add_impl(const struct sockaddr *address, fcntl(ns->socket, F_SETFL, O_NONBLOCK); #endif + if (global_bind_addr_is_set) { + if (bind(ns->socket, (struct sockaddr *)&global_bind_address, + global_bind_addrlen) < 0) { + log(EVDNS_LOG_DEBUG, "Couldn't bind to outgoing address."); + err = 2; + goto out2; + } + } + if (connect(ns->socket, address, addrlen) != 0) { log(EVDNS_LOG_DEBUG, "Couldn't open socket to nameserver."); err = 2; |