[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r8562: Backport 8478: fix long-standing server-side DNS bug. (in tor/branches/tor-0_1_1-patches: . src/or)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r8562: Backport 8478: fix long-standing server-side DNS bug. (in tor/branches/tor-0_1_1-patches: . src/or)
- From: nickm@xxxxxxxx
- Date: Sun, 1 Oct 2006 14:13:18 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Sun, 01 Oct 2006 14:13:28 -0400
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Author: nickm
Date: 2006-10-01 14:13:16 -0400 (Sun, 01 Oct 2006)
New Revision: 8562
Modified:
tor/branches/tor-0_1_1-patches/ChangeLog
tor/branches/tor-0_1_1-patches/src/or/connection_edge.c
tor/branches/tor-0_1_1-patches/src/or/dns.c
tor/branches/tor-0_1_1-patches/src/or/or.h
Log:
Backport 8478: fix long-standing server-side DNS bug.
Modified: tor/branches/tor-0_1_1-patches/ChangeLog
===================================================================
--- tor/branches/tor-0_1_1-patches/ChangeLog 2006-10-01 07:53:17 UTC (rev 8561)
+++ tor/branches/tor-0_1_1-patches/ChangeLog 2006-10-01 18:13:16 UTC (rev 8562)
@@ -8,6 +8,9 @@
This should improve client CPU usage by 25-50%.
- Don't crash if, after a server has been running for a while,
it can't resolve its hostname.
+ - When a client asks us to resolve (not connect to) an address,
+ and we have a cached answer, give them the cached answer.
+ Previously, we would give them no answer at all.
o Minor bugfixes:
- Allow Tor to start when RunAsDaemon is set but no logs are set.
Modified: tor/branches/tor-0_1_1-patches/src/or/connection_edge.c
===================================================================
--- tor/branches/tor-0_1_1-patches/src/or/connection_edge.c 2006-10-01 07:53:17 UTC (rev 8561)
+++ tor/branches/tor-0_1_1-patches/src/or/connection_edge.c 2006-10-01 18:13:16 UTC (rev 8562)
@@ -1669,7 +1669,7 @@
}
/* send it off to the gethostbyname farm */
- switch (dns_resolve(n_stream)) {
+ switch (dns_resolve(n_stream, NULL)) {
case 1: /* resolve worked */
/* add it into the linked list of n_streams on this circuit */
@@ -1723,7 +1723,7 @@
dummy_conn->purpose = EXIT_PURPOSE_RESOLVE;
/* send it off to the gethostbyname farm */
- switch (dns_resolve(dummy_conn)) {
+ switch (dns_resolve(dummy_conn, circ)) {
case -1: /* Impossible to resolve; a resolved cell was sent. */
/* Connection freed; don't touch it. */
return 0;
Modified: tor/branches/tor-0_1_1-patches/src/or/dns.c
===================================================================
--- tor/branches/tor-0_1_1-patches/src/or/dns.c 2006-10-01 07:53:17 UTC (rev 8561)
+++ tor/branches/tor-0_1_1-patches/src/or/dns.c 2006-10-01 18:13:16 UTC (rev 8562)
@@ -71,13 +71,14 @@
} cached_resolve_t;
static void purge_expired_resolves(uint32_t now);
-static int assign_to_dnsworker(connection_t *exitconn);
+static int assign_to_dnsworker(connection_t *exitconn, circuit_t *oncirc);
static void dns_purge_resolve(cached_resolve_t *resolve);
static void dns_found_answer(char *address, uint32_t addr, char outcome);
static int dnsworker_main(void *data);
static int spawn_dnsworker(void);
static int spawn_enough_dnsworkers(void);
-static void send_resolved_cell(connection_t *conn, uint8_t answer_type);
+static void send_resolved_cell(connection_t *conn, circuit_t *circ,
+ uint8_t answer_type);
/** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root;
@@ -199,7 +200,7 @@
/** Send a response to the RESOVLE request of a connection. answer_type must
* be one of RESOLVED_TYPE_(IPV4|ERROR|ERROR_TRANSIENT) */
static void
-send_resolved_cell(connection_t *conn, uint8_t answer_type)
+send_resolved_cell(connection_t *conn, circuit_t *circ, uint8_t answer_type)
{
char buf[RELAY_PAYLOAD_SIZE];
size_t buflen;
@@ -229,7 +230,12 @@
default:
tor_assert(0);
}
- connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
+
+ if (circ == NULL) {
+ circ = circuit_get_by_edge_conn(conn);
+ }
+
+ connection_edge_send_command(conn, circ,
RELAY_COMMAND_RESOLVED, buf, buflen,
conn->cpath_layer);
}
@@ -261,7 +267,7 @@
* dns farm, and return 0.
*/
int
-dns_resolve(connection_t *exitconn)
+dns_resolve(connection_t *exitconn, circuit_t *oncirc)
{
cached_resolve_t *resolve;
cached_resolve_t search;
@@ -277,7 +283,7 @@
if (tor_inet_aton(exitconn->address, &in) != 0) {
exitconn->addr = ntohl(in.s_addr);
if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
- send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
+ send_resolved_cell(exitconn, oncirc, RESOLVED_TYPE_IPV4);
return 1;
}
@@ -310,13 +316,13 @@
log_debug(LD_EXIT,"Connection (fd %d) found cached answer for %s",
exitconn->s, escaped_safe_str(exitconn->address));
if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
- send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
+ send_resolved_cell(exitconn, oncirc, RESOLVED_TYPE_IPV4);
return 1;
case CACHE_STATE_FAILED:
log_debug(LD_EXIT,"Connection (fd %d) found cached error for %s",
exitconn->s, escaped_safe_str(exitconn->address));
if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
- send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR);
+ send_resolved_cell(exitconn, oncirc, RESOLVED_TYPE_ERROR);
circ = circuit_get_by_edge_conn(exitconn);
if (circ)
circuit_detach_stream(circ, exitconn);
@@ -339,14 +345,14 @@
exitconn->state = EXIT_CONN_STATE_RESOLVING;
insert_resolve(resolve);
- return assign_to_dnsworker(exitconn);
+ return assign_to_dnsworker(exitconn, oncirc);
}
/** Find or spawn a dns worker process to handle resolving
* <b>exitconn</b>-\>address; tell that dns worker to begin resolving.
*/
static int
-assign_to_dnsworker(connection_t *exitconn)
+assign_to_dnsworker(connection_t *exitconn, circuit_t *oncirc)
{
connection_t *dnsconn;
unsigned char len;
@@ -365,7 +371,7 @@
if (!dnsconn) {
log_warn(LD_EXIT,"no idle dns workers. Failing.");
if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
- send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR_TRANSIENT);
+ send_resolved_cell(exitconn, oncirc, RESOLVED_TYPE_ERROR_TRANSIENT);
goto err;
}
@@ -631,7 +637,7 @@
/* This detach must happen after we send the end cell. */
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
} else {
- send_resolved_cell(pendconn, RESOLVED_TYPE_ERROR);
+ send_resolved_cell(pendconn, NULL, RESOLVED_TYPE_ERROR);
/* This detach must happen after we send the resolved cell. */
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
}
@@ -655,7 +661,7 @@
/* prevent double-remove. This isn't really an accurate state,
* but it does the right thing. */
pendconn->state = EXIT_CONN_STATE_RESOLVEFAILED;
- send_resolved_cell(pendconn, RESOLVED_TYPE_IPV4);
+ send_resolved_cell(pendconn, NULL, RESOLVED_TYPE_IPV4);
circ = circuit_get_by_edge_conn(pendconn);
tor_assert(circ);
circuit_detach_stream(circ, pendconn);
Modified: tor/branches/tor-0_1_1-patches/src/or/or.h
===================================================================
--- tor/branches/tor-0_1_1-patches/src/or/or.h 2006-10-01 07:53:17 UTC (rev 8561)
+++ tor/branches/tor-0_1_1-patches/src/or/or.h 2006-10-01 18:13:16 UTC (rev 8562)
@@ -1961,7 +1961,7 @@
void assert_connection_edge_not_dns_pending(connection_t *conn);
void assert_all_pending_dns_resolves_ok(void);
void dns_cancel_pending_resolve(char *question);
-int dns_resolve(connection_t *exitconn);
+int dns_resolve(connection_t *exitconn, circuit_t *oncirc);
/********************************* hibernate.c **********************/