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

[or-cvs] r9194: Add client-side caching for reverse DNS. (in tor/trunk: . doc src/or)



Author: nickm
Date: 2006-12-26 17:41:43 -0500 (Tue, 26 Dec 2006)
New Revision: 9194

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/src/or/connection_edge.c
Log:
 r11718@Kushana:  nickm | 2006-12-26 16:57:44 -0500
 Add client-side caching for reverse DNS.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r11718] on c95137ef-5f19-0410-b913-86e773d04f59

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2006-12-25 04:37:53 UTC (rev 9193)
+++ tor/trunk/ChangeLog	2006-12-26 22:41:43 UTC (rev 9194)
@@ -65,6 +65,7 @@
     - Report X-Your-Address-Is correctly from tunneled directory connections;
       don't report X-Your-Address-Is is when it's an internal address; and
       never believe reported remote addresses when they're internal.
+    - Add client-side caching for reverse DNS lookups.
 
   o Security bugfixes:
     - Stop sending the HttpProxyAuthenticator string to directory

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2006-12-25 04:37:53 UTC (rev 9193)
+++ tor/trunk/doc/TODO	2006-12-26 22:41:43 UTC (rev 9194)
@@ -97,7 +97,7 @@
       . Add client-side interface
         o SOCKS interface: specify
         o SOCKS interface: implement
-d       - Cache answers client-side
+        o Cache answers client-side
         o Add to Tor-resolve.py
         - Add to tor-resolve
 d   - Be a DNS proxy.

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2006-12-25 04:37:53 UTC (rev 9193)
+++ tor/trunk/src/or/connection_edge.c	2006-12-26 22:41:43 UTC (rev 9194)
@@ -664,6 +664,7 @@
 {
   addressmap_entry_t *ent;
   int rewrites;
+  char *cp;
 
   for (rewrites = 0; rewrites < 16; rewrites++) {
     ent = strmap_get(addressmap, address);
@@ -671,8 +672,10 @@
     if (!ent || !ent->new_address)
       return; /* done, no rewrite needed */
 
+    cp = tor_strdup(escaped_safe_str(ent->new_address));
     log_info(LD_APP, "Addressmap: rewriting '%s' to '%s'",
-             safe_str(address), safe_str(ent->new_address));
+             escaped_safe_str(address), cp);
+    tor_free(cp);
     strlcpy(address, ent->new_address, maxlen);
   }
   log_warn(LD_CONFIG,
@@ -681,6 +684,28 @@
   /* it's fine to rewrite a rewrite, but don't loop forever */
 }
 
+/* DOCDOC */
+static int
+addressmap_rewrite_reverse(char *address, size_t maxlen)
+{
+  size_t len = maxlen + 16;
+  char *s = tor_malloc(len), *cp;
+  addressmap_entry_t *ent;
+  int r = 0;
+  tor_snprintf(s, len, "REVERSE[%s]", address);
+  ent = strmap_get(addressmap, s);
+  if (ent) {
+    cp = tor_strdup(escaped_safe_str(ent->new_address));
+    log_info(LD_APP, "Rewrote reverse lookup '%s' -> '%s'",
+             escaped_safe_str(s), cp);
+    tor_free(cp);
+    strlcpy(address, ent->new_address, maxlen);
+    r = 1;
+  }
+  tor_free(s);
+  return r;
+}
+
 /** Return 1 if <b>address</b> is already registered, else return 0 */
 int
 addressmap_have_mapping(const char *address)
@@ -775,7 +800,7 @@
     ent->num_resolve_failures = 0;
 }
 
-/** Record the fact that <b>address</b> resolved to <b>val</b>.
+/** Record the fact that <b>address</b> resolved to <b>name</b>.
  * We can now use this in subsequent streams via addressmap_rewrite()
  * so we can more correctly choose an exit that will allow <b>address</b>.
  *
@@ -785,30 +810,24 @@
  * If <b>ttl</b> is nonnegative, the mapping will be valid for
  * <b>ttl</b>seconds; otherwise, we use the default.
  */
-void
-client_dns_set_addressmap(const char *address, uint32_t val,
-                          const char *exitname,
-                          int ttl)
+static void
+client_dns_set_addressmap_impl(const char *address, const char *name,
+                               const char *exitname,
+                               int ttl)
 {
-  struct in_addr in;
   /* <address>.<hex or nickname>.exit\0  or just  <address>\0 */
   char extendedaddress[MAX_SOCKS_ADDR_LEN+MAX_VERBOSE_NICKNAME_LEN+10];
   /* 123.123.123.123.<hex or nickname>.exit\0  or just  123.123.123.123\0 */
   char extendedval[INET_NTOA_BUF_LEN+MAX_VERBOSE_NICKNAME_LEN+10];
-  char valbuf[INET_NTOA_BUF_LEN];
 
   tor_assert(address);
-  tor_assert(val);
+  tor_assert(name);
 
   if (ttl<0)
     ttl = DEFAULT_DNS_TTL;
   else
     ttl = dns_clip_ttl(ttl);
 
-  if (tor_inet_aton(address, &in))
-    return; /* If address was an IP address already, don't add a mapping. */
-  in.s_addr = htonl(val);
-  tor_inet_ntoa(&in,valbuf,sizeof(valbuf));
   if (exitname) {
     /* XXXX fails to ever get attempts to get an exit address of
      * google.com.digest[=~]nickname.exit; we need a syntax for this that
@@ -816,17 +835,58 @@
     tor_snprintf(extendedaddress, sizeof(extendedaddress),
                  "%s.%s.exit", address, exitname);
     tor_snprintf(extendedval, sizeof(extendedval),
-                 "%s.%s.exit", valbuf, exitname);
+                 "%s.%s.exit", name, exitname);
   } else {
     tor_snprintf(extendedaddress, sizeof(extendedaddress),
                  "%s", address);
     tor_snprintf(extendedval, sizeof(extendedval),
-                 "%s", valbuf);
+                 "%s", name);
   }
   addressmap_register(extendedaddress, tor_strdup(extendedval),
                       time(NULL) + ttl);
 }
 
+/** Record the fact that <b>address</b> resolved to <b>val</b>.
+ * We can now use this in subsequent streams via addressmap_rewrite()
+ * so we can more correctly choose an exit that will allow <b>address</b>.
+ *
+ * If <b>exitname</b> is defined, then append the addresses with
+ * ".exitname.exit" before registering the mapping.
+ *
+ * If <b>ttl</b> is nonnegative, the mapping will be valid for
+ * <b>ttl</b>seconds; otherwise, we use the default.
+ */
+void
+client_dns_set_addressmap(const char *address, uint32_t val,
+                          const char *exitname,
+                          int ttl)
+{
+  struct in_addr in;
+  char valbuf[INET_NTOA_BUF_LEN];
+
+  tor_assert(address);
+
+  if (tor_inet_aton(address, &in))
+    return; /* If address was an IP address already, don't add a mapping. */
+  in.s_addr = htonl(val);
+  tor_inet_ntoa(&in,valbuf,sizeof(valbuf));
+
+  client_dns_set_addressmap_impl(address, valbuf, exitname, ttl);
+}
+
+/** DOCDOC */
+static void
+client_dns_set_reverse_addressmap(const char *address, const char *v,
+                                  const char *exitname,
+                                  int ttl)
+{
+  size_t len = strlen(address) + 16;
+  char *s = tor_malloc(len);
+  tor_snprintf(s, len, "REVERSE[%s]", address);
+  client_dns_set_addressmap_impl(s, v, exitname, ttl);
+  tor_free(s);
+}
+
 /* By default, we hand out 127.192.0.1 through 127.254.254.254.
  * These addresses should map to localhost, so even if the
  * application accidentally tried to connect to them directly (not
@@ -1103,8 +1163,19 @@
             safe_str(socks->address),
             socks->port);
 
-  /* For address map controls, remap the address */
-  addressmap_rewrite(socks->address, 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,
+                                             strlen(socks->address),
+                                             socks->address, -1);
+      connection_mark_unattached_ap(conn,
+                                    END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
+      return 0;
+    }
+  } else {
+    /* For address map controls, remap the address */
+    addressmap_rewrite(socks->address, sizeof(socks->address));
+  }
 
   if (address_is_in_virtual_range(socks->address)) {
     /* This address was probably handed out by client_dns_get_unmapped_address,
@@ -1826,11 +1897,19 @@
   char buf[384];
   size_t replylen;
 
-  if (answer_type == RESOLVED_TYPE_IPV4) {
-    uint32_t a = ntohl(get_uint32(answer));
-    if (a)
-      client_dns_set_addressmap(conn->socks_request->address, a,
-                                conn->chosen_exit_name, ttl);
+  if (ttl >= 0) {
+    if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
+      uint32_t a = ntohl(get_uint32(answer));
+      if (a)
+        client_dns_set_addressmap(conn->socks_request->address, a,
+                                  conn->chosen_exit_name, ttl);
+    } else if (answer_type == RESOLVED_TYPE_HOSTNAME && answer_len < 256) {
+      char *cp = tor_strndup(answer, answer_len);
+      client_dns_set_reverse_addressmap(conn->socks_request->address,
+                                        cp,
+                                        conn->chosen_exit_name, ttl);
+      tor_free(cp);
+    }
   }
 
   if (conn->socks_request->socks_version == 4) {