Commit 9c3df07b authored by Nick Mathewson's avatar Nick Mathewson 🐻
Browse files

r12687@Kushana: nickm | 2007-04-09 17:05:57 -0400

 Try to fix bug 410: move responsibility for attaching/detaching initial streams from circuits into dns_resolve.  Needs refactoring a little.


svn:r9931
parent 32506ad2
...@@ -66,7 +66,8 @@ Changes in version 0.2.0.1-alpha - 2007-??-?? ...@@ -66,7 +66,8 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
- Drop the old code to choke directory connections when the corresponding - Drop the old code to choke directory connections when the corresponding
or connections got full: thanks to the cell queue feature, or conns or connections got full: thanks to the cell queue feature, or conns
don't get full any more. don't get full any more.
- Make dns_resolve handle attaching connections to circuits properly,
so the caller doesn't have to.
Changes in version 0.1.2.12-rc - 2007-03-16 Changes in version 0.1.2.12-rc - 2007-03-16
o Major bugfixes: o Major bugfixes:
......
...@@ -70,8 +70,11 @@ Things we'd like to do in 0.2.0.x: ...@@ -70,8 +70,11 @@ Things we'd like to do in 0.2.0.x:
o When making a circuit active on a connection with an empty buf, o When making a circuit active on a connection with an empty buf,
we need to "prime" the buffer, so that we can trigger the "I flushed we need to "prime" the buffer, so that we can trigger the "I flushed
some" test. some" test.
- Change how directory-bridge-choking works: choke when circuit queue X Change how directory-bridge-choking works: choke when circuit queue
is full, not when the orconn is "too full". is full, not when the orconn is "too full".
[No need to do this: the edge-connection choking will already take
care of this a bit, and rewriting the 'bridged connection' code
to not use socketpairs will give us even more control.]
- Do we switch to arena-allocation for cells? - Do we switch to arena-allocation for cells?
- Can we stop doing so many memcpys on cells? - Can we stop doing so many memcpys on cells?
o Also, only package data from exitconns when there is space on the o Also, only package data from exitconns when there is space on the
......
...@@ -2245,12 +2245,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) ...@@ -2245,12 +2245,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
/* send it off to the gethostbyname farm */ /* send it off to the gethostbyname farm */
switch (dns_resolve(n_stream)) { switch (dns_resolve(n_stream)) {
case 1: /* resolve worked */ case 1: /* resolve worked */
/* add it into the linked list of n_streams on this circuit */
n_stream->next_stream = TO_OR_CIRCUIT(circ)->n_streams;
TO_OR_CIRCUIT(circ)->n_streams = n_stream;
assert_circuit_ok(circ); assert_circuit_ok(circ);
log_debug(LD_EXIT,"about to call connection_exit_connect()."); log_debug(LD_EXIT,"about to call connection_exit_connect().");
connection_exit_connect(n_stream); connection_exit_connect(n_stream);
return 0; return 0;
...@@ -2262,8 +2257,6 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) ...@@ -2262,8 +2257,6 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
break; break;
case 0: /* resolve added to pending list */ case 0: /* resolve added to pending list */
/* add it into the linked list of resolving_streams on this circuit */ /* add it into the linked list of resolving_streams on this circuit */
n_stream->next_stream = TO_OR_CIRCUIT(circ)->resolving_streams;
TO_OR_CIRCUIT(circ)->resolving_streams = n_stream;
assert_circuit_ok(circ); assert_circuit_ok(circ);
; ;
} }
...@@ -2310,8 +2303,6 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ) ...@@ -2310,8 +2303,6 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
connection_free(TO_CONN(dummy_conn)); connection_free(TO_CONN(dummy_conn));
return 0; return 0;
case 0: /* resolve added to pending list */ case 0: /* resolve added to pending list */
dummy_conn->next_stream = circ->resolving_streams;
circ->resolving_streams = dummy_conn;
assert_circuit_ok(TO_CIRCUIT(circ)); assert_circuit_ok(TO_CIRCUIT(circ));
break; break;
} }
......
...@@ -509,14 +509,22 @@ parse_inaddr_arpa_address(const char *address, struct in_addr *in) ...@@ -509,14 +509,22 @@ parse_inaddr_arpa_address(const char *address, struct in_addr *in)
* do that for us.) * do that for us.)
* *
* If we have a cached answer, send the answer back along <b>exitconn</b>'s * If we have a cached answer, send the answer back along <b>exitconn</b>'s
* attached circuit. * circuit.
* *
* Else, if seen before and pending, add conn to the pending list, * Else, if seen before and pending, add conn to the pending list,
* and return 0. * and return 0.
* *
* Else, if not seen before, add conn to pending list, hand to * Else, if not seen before, add conn to pending list, hand to
* dns farm, and return 0. * dns farm, and return 0.
*
* Exitconn's on_circuit field must be set, but exitconn should not
* yet be linked onto the n_streams/resolving_streams list of that circuit.
* On success, link the connection to n_streams if it's an exit connection.
* On "pending", link the connection to resolving streams. Otherwise,
* clear its on_circuit field.
*/ */
/* XXXX020 Split this into a helper that checks whether there is an answer,
* and a caller that takes appropriate action based on what happened. */
int int
dns_resolve(edge_connection_t *exitconn) dns_resolve(edge_connection_t *exitconn)
{ {
...@@ -530,6 +538,7 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -530,6 +538,7 @@ dns_resolve(edge_connection_t *exitconn)
assert_connection_ok(TO_CONN(exitconn), 0); assert_connection_ok(TO_CONN(exitconn), 0);
tor_assert(exitconn->_base.s == -1); tor_assert(exitconn->_base.s == -1);
assert_cache_ok(); assert_cache_ok();
tor_assert(oncirc);
is_resolve = exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE; is_resolve = exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE;
...@@ -538,8 +547,12 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -538,8 +547,12 @@ dns_resolve(edge_connection_t *exitconn)
if (tor_inet_aton(exitconn->_base.address, &in) != 0) { if (tor_inet_aton(exitconn->_base.address, &in) != 0) {
exitconn->_base.addr = ntohl(in.s_addr); exitconn->_base.addr = ntohl(in.s_addr);
exitconn->address_ttl = DEFAULT_DNS_TTL; exitconn->address_ttl = DEFAULT_DNS_TTL;
if (is_resolve) if (is_resolve) {
send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4); send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
} else {
exitconn->next_stream = oncirc->n_streams;
oncirc->n_streams = exitconn;
}
return 1; return 1;
} }
if (address_is_invalid_destination(exitconn->_base.address, 0)) { if (address_is_invalid_destination(exitconn->_base.address, 0)) {
...@@ -548,7 +561,8 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -548,7 +561,8 @@ dns_resolve(edge_connection_t *exitconn)
escaped_safe_str(exitconn->_base.address)); escaped_safe_str(exitconn->_base.address));
if (is_resolve) if (is_resolve)
send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR); send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR);
circuit_detach_stream(TO_CIRCUIT(oncirc), exitconn); //circuit_detach_stream(TO_CIRCUIT(oncirc), exitconn);
exitconn->on_circuit = NULL;
if (!exitconn->_base.marked_for_close) if (!exitconn->_base.marked_for_close)
connection_free(TO_CONN(exitconn)); connection_free(TO_CONN(exitconn));
return -1; return -1;
...@@ -581,7 +595,8 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -581,7 +595,8 @@ dns_resolve(edge_connection_t *exitconn)
if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE) if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR); send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR);
circuit_detach_stream(TO_CIRCUIT(oncirc), exitconn); //circuit_detach_stream(TO_CIRCUIT(oncirc), exitconn);
exitconn->on_circuit = NULL;
if (!exitconn->_base.marked_for_close) if (!exitconn->_base.marked_for_close)
connection_free(TO_CONN(exitconn)); connection_free(TO_CONN(exitconn));
return -1; return -1;
...@@ -606,6 +621,9 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -606,6 +621,9 @@ dns_resolve(edge_connection_t *exitconn)
"resolve of %s", exitconn->_base.s, "resolve of %s", exitconn->_base.s,
escaped_safe_str(exitconn->_base.address)); escaped_safe_str(exitconn->_base.address));
exitconn->_base.state = EXIT_CONN_STATE_RESOLVING; exitconn->_base.state = EXIT_CONN_STATE_RESOLVING;
exitconn->next_stream = oncirc->resolving_streams;
oncirc->resolving_streams = exitconn;
return 0; return 0;
case CACHE_STATE_CACHED_VALID: case CACHE_STATE_CACHED_VALID:
log_debug(LD_EXIT,"Connection (fd %d) found cached answer for %s", log_debug(LD_EXIT,"Connection (fd %d) found cached answer for %s",
...@@ -621,6 +639,12 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -621,6 +639,12 @@ dns_resolve(edge_connection_t *exitconn)
if (is_resolve) if (is_resolve)
send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4); send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
} }
if (!is_resolve) {
/* It's a connect; add it into the linked list of n_streams on this
circuit */
exitconn->next_stream = oncirc->n_streams;
oncirc->n_streams = exitconn;
}
return 1; return 1;
case CACHE_STATE_CACHED_FAILED: case CACHE_STATE_CACHED_FAILED:
log_debug(LD_EXIT,"Connection (fd %d) found cached error for %s", log_debug(LD_EXIT,"Connection (fd %d) found cached error for %s",
...@@ -628,7 +652,8 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -628,7 +652,8 @@ dns_resolve(edge_connection_t *exitconn)
escaped_safe_str(exitconn->_base.address)); escaped_safe_str(exitconn->_base.address));
if (is_resolve) if (is_resolve)
send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR); send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR);
circuit_detach_stream(TO_CIRCUIT(oncirc), exitconn); // circuit_detach_stream(TO_CIRCUIT(oncirc), exitconn);
exitconn->on_circuit = NULL;
if (!exitconn->_base.marked_for_close) if (!exitconn->_base.marked_for_close)
connection_free(TO_CONN(exitconn)); connection_free(TO_CONN(exitconn));
return -1; return -1;
...@@ -658,7 +683,18 @@ dns_resolve(edge_connection_t *exitconn) ...@@ -658,7 +683,18 @@ dns_resolve(edge_connection_t *exitconn)
log_debug(LD_EXIT,"Launching %s.", log_debug(LD_EXIT,"Launching %s.",
escaped_safe_str(exitconn->_base.address)); escaped_safe_str(exitconn->_base.address));
assert_cache_ok(); assert_cache_ok();
return launch_resolve(exitconn);
r = launch_resolve(exitconn);
if (r == 0) {
exitconn->next_stream = oncirc->resolving_streams;
oncirc->resolving_streams = exitconn;
} else {
tor_assert(r<0);
exitconn->on_circuit = NULL;
if (!exitconn->_base.marked_for_close)
connection_free(TO_CONN(exitconn));
}
return r;
} }
/** Log an error and abort if conn is waiting for a DNS resolve. /** Log an error and abort if conn is waiting for a DNS resolve.
...@@ -1160,7 +1196,7 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses, ...@@ -1160,7 +1196,7 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses,
} }
/** For eventdns: start resolving as necessary to find the target for /** For eventdns: start resolving as necessary to find the target for
* <b>exitconn</b> */ * <b>exitconn</b>. Returns -1 on error, 0 on "resolve launched." */
static int static int
launch_resolve(edge_connection_t *exitconn) launch_resolve(edge_connection_t *exitconn)
{ {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment