Bladeren bron

Merge remote-tracking branch 'public/bug2822'

Nick Mathewson 12 jaren geleden
bovenliggende
commit
a925fc9189
5 gewijzigde bestanden met toevoegingen van 46 en 9 verwijderingen
  1. 5 0
      changes/bug2822.1
  2. 6 0
      changes/bug2822.2
  3. 9 0
      src/common/address.c
  4. 2 0
      src/common/address.h
  5. 24 9
      src/or/connection_edge.c

+ 5 - 0
changes/bug2822.1

@@ -0,0 +1,5 @@
+  o Minor features:
+
+    - Rate-limit log messages when asked to connect anonymously to a private
+      address. When these hit, they tended to hit fast and often. Partial
+      fix for bug 2822.

+ 6 - 0
changes/bug2822.2

@@ -0,0 +1,6 @@
+  o Minor features:
+
+    - Don't bother trying to connect to addresses that we are sure will
+      resolve to 127.0.0.1: Getting 127.0.0.1 in a reply makes us think
+      we have been lied to, even when the address the client tried to
+      connect to was "localhost." Partial fix for bug 2822.

+ 9 - 0
src/common/address.c

@@ -1687,3 +1687,12 @@ get_interface_address(int severity, uint32_t *addr)
   return r;
 }
 
+/** Return true if we can tell that <b>name</b> is a canonical name for the
+ * loopback address. */
+int
+tor_addr_hostname_is_local(const char *name)
+{
+  return !strcasecmp(name, "localhost") ||
+    !strcasecmp(name, "local") ||
+    !strcasecmpend(name, ".local");
+}

+ 2 - 0
src/common/address.h

@@ -200,6 +200,8 @@ int tor_addr_is_loopback(const tor_addr_t *addr);
 int tor_addr_port_split(int severity, const char *addrport,
                         char **address_out, uint16_t *port_out);
 
+int tor_addr_hostname_is_local(const char *name);
+
 /* IPv4 helpers */
 int is_internal_IP(uint32_t ip, int for_listening);
 int addr_port_lookup(int severity, const char *addrport, char **address,

+ 24 - 9
src/or/connection_edge.c

@@ -2000,20 +2000,35 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
       if (options->ClientRejectInternalAddresses &&
           !conn->use_begindir && !conn->chosen_exit_name && !circ) {
         tor_addr_t addr;
-        if (tor_addr_parse(&addr, socks->address) >= 0 &&
-            tor_addr_is_internal(&addr, 0)) {
+        if (tor_addr_hostname_is_local(socks->address) ||
+            (tor_addr_parse(&addr, socks->address) >= 0 &&
+             tor_addr_is_internal(&addr, 0))) {
           /* If this is an explicit private address with no chosen exit node,
            * then we really don't want to try to connect to it.  That's
            * probably an error. */
           if (conn->is_transparent_ap) {
-            log_warn(LD_NET,
-                     "Rejecting request for anonymous connection to private "
-                     "address %s on a TransPort or NATDPort.  Possible loop "
-                     "in your NAT rules?", safe_str_client(socks->address));
+#define WARN_INTERVAL_LOOP 300
+            static ratelim_t loop_warn_limit = RATELIM_INIT(WARN_INTERVAL_LOOP);
+            char *m;
+            if ((m = rate_limit_log(&loop_warn_limit, approx_time()))) {
+              log_warn(LD_NET,
+                       "Rejecting request for anonymous connection to private "
+                       "address %s on a TransPort or NATDPort.  Possible loop "
+                       "in your NAT rules?%s", safe_str_client(socks->address),
+                       m);
+              tor_free(m);
+            }
           } else {
-            log_warn(LD_NET,
-                     "Rejecting SOCKS request for anonymous connection to "
-                     "private address %s", safe_str_client(socks->address));
+#define WARN_INTERVAL_PRIV 300
+            static ratelim_t priv_warn_limit = RATELIM_INIT(WARN_INTERVAL_PRIV);
+            char *m;
+            if ((m = rate_limit_log(&priv_warn_limit, approx_time()))) {
+              log_warn(LD_NET,
+                       "Rejecting SOCKS request for anonymous connection to "
+                       "private address %s.%s",
+                       safe_str_client(socks->address),m);
+              tor_free(m);
+            }
           }
           connection_mark_unattached_ap(conn, END_STREAM_REASON_PRIVATE_ADDR);
           return -1;