[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r10324: Add an AutomapHostsOnResolve option. It seems to work. (in tor/trunk: . doc src/or)



Author: nickm
Date: 2007-05-25 10:48:16 -0400 (Fri, 25 May 2007)
New Revision: 10324

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/src/or/config.c
   tor/trunk/src/or/connection_edge.c
   tor/trunk/src/or/or.h
Log:
 r12946@catbus:  nickm | 2007-05-25 10:46:50 -0400
 Add an AutomapHostsOnResolve option.  It seems to work.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r12946] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-05-25 14:48:12 UTC (rev 10323)
+++ tor/trunk/ChangeLog	2007-05-25 14:48:16 UTC (rev 10324)
@@ -130,6 +130,12 @@
     - More unit tests.
     - Warn when using a version of libevent before 1.3b to run a server on
       OSX or BSD: these versions interact badly with userspace threads.
+    - Add a new AutomapHostsOnResolve option: when it is enabled, any
+      resolve request for hosts matching a given pattern causes Tor to
+      generate an internal virtual address mapping for that host.  This
+      allows DNSPort to work sensibly with hidden service users.  By
+      default, .exit and .onion addresses are remapped; the list of
+      patterns can be reconfigured with AutomapHostsSuffixes.
 
   o Removed features:
     - Removed support for the old binary "version 0" controller protocol.

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-05-25 14:48:12 UTC (rev 10323)
+++ tor/trunk/doc/TODO	2007-05-25 14:48:16 UTC (rev 10324)
@@ -199,8 +199,8 @@
       o Make a listener type.
       o Hook into connection_edge logic.
       o Hook into evdns_server_* logic
-      - Actually send back a useful answer.
-      - Make i
+      o Actually send back a useful answer.
+      o Make it handle .onion and .exit correctly.
       - Document.
     - Add a way to request DNS resolves from the controller.
     - A better UI for authority ops.

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-05-25 14:48:12 UTC (rev 10323)
+++ tor/trunk/src/or/config.c	2007-05-25 14:48:16 UTC (rev 10324)
@@ -67,6 +67,8 @@
   PLURAL(StrictExitNode),
   { "l", "Log", 1, 0},
   { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
+  { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
+  { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
   { "BandwidthRateBytes", "BandwidthRate", 0, 0},
   { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
   { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
@@ -133,6 +135,8 @@
   VAR("AuthDirRejectUnlisted",BOOL,    AuthDirRejectUnlisted,"0"),
   VAR("AuthDirListBadExits", BOOL,     AuthDirListBadExits,  "0"),
   VAR("AuthoritativeDirectory",BOOL,   AuthoritativeDir,     "0"),
+  VAR("AutomapHostsOnResolve",BOOL,    AutomapHostsOnResolve,"0"),
+  VAR("AutomapHostsSuffixes",CSV,      AutomapHostsSuffixes, ".onion,.exit"),
   VAR("AvoidDiskWrites",     BOOL,     AvoidDiskWrites,      "0"),
   VAR("BandwidthBurst",      MEMUNIT,  BandwidthBurst,       "6 MB"),
   VAR("BandwidthRate",       MEMUNIT,  BandwidthRate,        "3 MB"),
@@ -2909,6 +2913,15 @@
   if (options->PreferTunneledDirConns && !options->TunnelDirConns)
     REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
 
+  if (options->AutomapHostsSuffixes) {
+    SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
+    {
+      size_t len = strlen(suf);
+      if (len && suf[len-1] == '.')
+        suf[len-1] = '\0';
+    });
+  }
+
   return 0;
 #undef REJECT
 #undef COMPLAIN

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2007-05-25 14:48:12 UTC (rev 10323)
+++ tor/trunk/src/or/connection_edge.c	2007-05-25 14:48:16 UTC (rev 10324)
@@ -669,7 +669,7 @@
       return (rewrites > 0); /* done, no rewrite needed */
 
     cp = tor_strdup(escaped_safe_str(ent->new_address));
-    log_info(LD_APP, "Addressmap: rewriting %s to %s",
+    log_notice(LD_APP, "Addressmap: rewriting %s to %s",
              escaped_safe_str(address), cp);
     tor_free(cp);
     strlcpy(address, ent->new_address, maxlen);
@@ -1009,7 +1009,7 @@
 
       ++next_virtual_addr;
       --available;
-      log_notice(LD_CONFIG, "%d addrs available", (int)available);
+      log_info(LD_CONFIG, "%d addrs available", (int)available);
       if (! --available) {
         log_warn(LD_CONFIG, "Ran out of virtual addresses!");
         return NULL;
@@ -1067,6 +1067,7 @@
 
   tor_free(*addrp);
   *addrp = addressmap_get_virtual_address(type);
+  log_info(LD_APP, "Registering map from %s to %s", *addrp, new_address);
   addressmap_register(*addrp, new_address, 2);
 
 #if 0
@@ -1081,7 +1082,7 @@
     tor_assert(!strcasecmp(*addrp,
                            (type == RESOLVED_TYPE_IPV4) ?
                            vent->ipv4_address : vent->hostname_address));
-    log_fn(LOG_INFO, "Map from %s to %s okay.",
+    log_info(LD_APP, "Map from %s to %s okay.",
            safe_str(*addrp),safe_str(new_address));
   }
 #endif
@@ -1176,12 +1177,34 @@
 {
   socks_request_t *socks = conn->socks_request;
   hostname_type_t addresstype;
+  or_options_t *options = get_options();
+  struct in_addr addr_tmp;
+  int automap = 0;
 
   tor_strlower(socks->address); /* normalize it */
   log_debug(LD_APP,"Client asked for %s:%d",
             safe_str(socks->address),
             socks->port);
 
+  if (socks->command == SOCKS_COMMAND_RESOLVE &&
+      !tor_inet_aton(socks->address, &addr_tmp) &&
+      options->AutomapHostsOnResolve && options->AutomapHostsSuffixes) {
+    SMARTLIST_FOREACH(options->AutomapHostsSuffixes, const char *, cp,
+                      if (!strcasecmpend(socks->address, cp)) {
+                        automap = 1;
+                        break;
+                      });
+    if (automap) {
+      const char *new_addr;
+      new_addr = addressmap_register_virtual_address(
+                              RESOLVED_TYPE_IPV4, tor_strdup(socks->address));
+      tor_assert(new_addr);
+      log_info(LD_APP, "Automapping %s to %s",
+               escaped_safe_str(socks->address), safe_str(new_addr));
+      strlcpy(socks->address, new_addr, sizeof(socks->address));
+    }
+  }
+
   if (socks->command == SOCKS_COMMAND_RESOLVE_PTR) {
     if (addressmap_rewrite_reverse(socks->address, sizeof(socks->address))) {
       connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_HOSTNAME,
@@ -1192,15 +1215,15 @@
                                  END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
       return 0;
     }
-  } else {
-    /* For address map controls, remap the address */
+  } else if (!automap) {
+    /* For address map controls, remap the address. */
     if (addressmap_rewrite(socks->address, sizeof(socks->address))) {
       control_event_stream_status(conn, STREAM_EVENT_REMAP,
                                   REMAP_STREAM_SOURCE_CACHE);
     }
   }
 
-  if (address_is_in_virtual_range(socks->address)) {
+  if (!automap && address_is_in_virtual_range(socks->address)) {
     /* This address was probably handed out by client_dns_get_unmapped_address,
      * but the mapping was discarded for some reason.  We *don't* want to send
      * the address through Tor; that's likely to fail, and may leak
@@ -1229,6 +1252,7 @@
     /* foo.exit -- modify conn->chosen_exit_node to specify the exit
      * node, and conn->address to hold only the address portion.*/
     char *s = strrchr(socks->address,'.');
+    tor_assert(!automap);
     if (s) {
       if (s[1] != '\0') {
         conn->chosen_exit_name = tor_strdup(s+1);
@@ -1294,8 +1318,10 @@
                                 END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
         return 0;
       }
+      tor_assert(!automap);
       rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
     } else if (socks->command == SOCKS_COMMAND_CONNECT) {
+      tor_assert(!automap);
       if (socks->port == 0) {
         log_notice(LD_APP,"Application asked to connect to port 0. Refusing.");
         connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
@@ -1340,7 +1366,7 @@
     /* it's a hidden-service request */
     rend_cache_entry_t *entry;
     int r;
-
+    tor_assert(!automap);
     if (SOCKS_COMMAND_IS_RESOLVE(socks->command)) {
       /* if it's a resolve request, fail it right now, rather than
        * building all the circuits and then realizing it won't work. */

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-05-25 14:48:12 UTC (rev 10323)
+++ tor/trunk/src/or/or.h	2007-05-25 14:48:16 UTC (rev 10324)
@@ -1822,6 +1822,8 @@
   int TrackHostExitsExpire; /**< Number of seconds until we expire an
                              * addressmap */
   config_line_t *AddressMap; /**< List of address map directives. */
+  int AutomapHostsOnResolve; /**< DOCDOC */
+  smartlist_t *AutomapHostsSuffixes; /**< DOCDOC */
   int RendPostPeriod; /**< How often do we post each rendezvous service
                        * descriptor? Remember to publish them independently. */
   int KeepalivePeriod; /**< How often do we send padding cells to keep