diff options
-rw-r--r-- | changes/bug2822.1 | 5 | ||||
-rw-r--r-- | changes/bug2822.2 | 6 | ||||
-rw-r--r-- | src/common/address.c | 9 | ||||
-rw-r--r-- | src/common/address.h | 2 | ||||
-rw-r--r-- | src/or/connection_edge.c | 33 |
5 files changed, 46 insertions, 9 deletions
diff --git a/changes/bug2822.1 b/changes/bug2822.1 new file mode 100644 index 0000000000..9c4016d059 --- /dev/null +++ b/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. diff --git a/changes/bug2822.2 b/changes/bug2822.2 new file mode 100644 index 0000000000..373741ca75 --- /dev/null +++ b/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. diff --git a/src/common/address.c b/src/common/address.c index 7f78d1e4d3..e444ef1934 100644 --- a/src/common/address.c +++ b/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"); +} diff --git a/src/common/address.h b/src/common/address.h index 761eed661c..2afec564be 100644 --- a/src/common/address.h +++ b/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, diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 5ef56a63b0..3b053c7cc3 100644 --- a/src/or/connection_edge.c +++ b/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; |