]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Make outgoing DNS requests respect OutboundBindAddress.
authorNick Mathewson <nickm@torproject.org>
Tue, 6 Jan 2009 20:50:55 +0000 (20:50 +0000)
committerNick Mathewson <nickm@torproject.org>
Tue, 6 Jan 2009 20:50:55 +0000 (20:50 +0000)
Fixes the bug part of bug 789.

svn:r17983

ChangeLog
src/or/dns.c
src/or/dnsserv.c
src/or/eventdns.c
src/or/eventdns.h

index 7681dd8d6924818189772f2bce6606d4dbe2f823..f04b6cb0be72c89044d8ba15595ba6b633b0ff82 100644 (file)
--- 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:
index 3266cf99dc9659910e8484daa2e381de25897dca..f8191679bf088bd22352b9cda348b3cb098bcc80 100644 (file)
@@ -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)) {
index 11002e9d7fed1ce3f87a6871754ee699a836623d..36d072110de0fe0205e614fbdddf1dce53945013 100644 (file)
@@ -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,
index 60f08265cd55b69a6721f1d85a9ed844c1f9741a..6e4e5e25b4cae118f1b30ce1b859facec6fbd933 100644 (file)
@@ -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;
index 8d9a0b8fb83bad416ae080d9e48f3bd3b33976b5..d3d359d2fbde62c30ecfd33a4bec336cf0026095 100644 (file)
@@ -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;