[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) {