summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-01-06 20:50:55 +0000
committerNick Mathewson <nickm@torproject.org>2009-01-06 20:50:55 +0000
commit462f64b6b993d46f5b61c7e2333cc526d15ba884 (patch)
treee5c9ff1ec2a7a77da5a46fc7016d5cad79ff0a4d
parent585d4a12b50aa0151411c777a6c7d266d71fb46f (diff)
downloadtor-462f64b6b993d46f5b61c7e2333cc526d15ba884.tar.gz
tor-462f64b6b993d46f5b61c7e2333cc526d15ba884.zip
Make outgoing DNS requests respect OutboundBindAddress.
Fixes the bug part of bug 789. svn:r17983
-rw-r--r--ChangeLog4
-rw-r--r--src/or/dns.c19
-rw-r--r--src/or/dnsserv.c2
-rw-r--r--src/or/eventdns.c26
-rw-r--r--src/or/eventdns.h1
5 files changed, 50 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 7681dd8d69..f04b6cb0be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
Changes in version 0.2.1.11-alpha - 2009-01-??
-
+ o Minor bugfixes:
+ - Make outbound DNS packets respect the OutboundBindAddress setting.
+ Fixes the bug part of bug 798.
Changes in version 0.2.1.10-alpha - 2009-01-06
o Major bugfixes:
diff --git a/src/or/dns.c b/src/or/dns.c
index 3266cf99dc..f8191679bf 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1102,6 +1102,25 @@ configure_nameservers(int force)
conf_fname = "/etc/resolv.conf";
#endif
+ if (options->OutboundBindAddress) {
+ tor_addr_t addr;
+ if (tor_addr_from_str(&addr, options->OutboundBindAddress) < 0) {
+ log_warn(LD_CONFIG,"Outbound bind address '%s' didn't parse. Ignoring.",
+ options->OutboundBindAddress);
+ } else {
+ int socklen;
+ struct sockaddr_storage ss;
+ socklen = tor_addr_to_sockaddr(&addr, 0,
+ (struct sockaddr *)&ss, sizeof(ss));
+ if (socklen < 0) {
+ log_warn(LD_BUG, "Couldn't convert outboung bind address to sockaddr."
+ " Ignoring.");
+ } else {
+ evdns_set_default_outgoing_bind_address((struct sockaddr *)&ss,socklen);
+ }
+ }
+ }
+
evdns_set_log_fn(evdns_log_cb);
if (conf_fname) {
if (stat(conf_fname, &st)) {
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c
index 11002e9d7f..36d072110d 100644
--- a/src/or/dnsserv.c
+++ b/src/or/dnsserv.c
@@ -294,7 +294,7 @@ void
dnsserv_configure_listener(connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->s);
+ tor_assert(conn->s >= 0);
tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER);
conn->dns_server_port = evdns_add_server_port(conn->s, 0,
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;
diff --git a/src/or/eventdns.h b/src/or/eventdns.h
index 8d9a0b8fb8..d3d359d2fb 100644
--- a/src/or/eventdns.h
+++ b/src/or/eventdns.h
@@ -264,6 +264,7 @@ int evdns_clear_nameservers_and_suspend(void);
int evdns_resume(void);
int evdns_nameserver_ip_add(const char *ip_as_string);
int evdns_nameserver_sockaddr_add(const struct sockaddr *sa, socklen_t len);
+void evdns_set_default_outgoing_bind_address(const struct sockaddr *addr, socklen_t addrlen);
int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr);
int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr);
struct in_addr;