summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2006-07-18 00:59:46 +0000
committerRoger Dingledine <arma@torproject.org>2006-07-18 00:59:46 +0000
commit4e72d6b4dcc43a4a2509e184253dc587baec36cc (patch)
treeaf9fd60ad238433526dc9946ebedb406ab2b7ce4
parentf6923640e694dcf0d1a01138b9716891e47ce74a (diff)
downloadtor-4e72d6b4dcc43a4a2509e184253dc587baec36cc.tar.gz
tor-4e72d6b4dcc43a4a2509e184253dc587baec36cc.zip
If we are using an exit enclave and we can't connect, e.g. because
its webserver is misconfigured to not listen on localhost, then back off and try connecting from somewhere else before we fail. svn:r6783
-rw-r--r--trunk/doc/TODO2
-rw-r--r--trunk/src/or/circuituse.c35
-rw-r--r--trunk/src/or/connection_edge.c1
-rw-r--r--trunk/src/or/or.h2
-rw-r--r--trunk/src/or/relay.c18
5 files changed, 48 insertions, 10 deletions
diff --git a/trunk/doc/TODO b/trunk/doc/TODO
index 9881a74243..e8312b28ff 100644
--- a/trunk/doc/TODO
+++ b/trunk/doc/TODO
@@ -108,7 +108,7 @@ R - remember the last time we saw one of our entry guards labelled with
- If the client's clock is too far in the past, it will drop (or
just not try to get) descriptors, so it'll never build circuits.
R - Failed rend desc fetches sometimes don't get retried.
- - If we fail to connect via an exit enclave, (warn and) try again
+ o If we fail to connect via an exit enclave, (warn and) try again
without demanding that exit node.
R - non-v1 authorities should not accept rend descs.
- We need a separate list of "hidserv authorities" if we want to
diff --git a/trunk/src/or/circuituse.c b/trunk/src/or/circuituse.c
index b6ceafd700..0c7198a7bf 100644
--- a/trunk/src/or/circuituse.c
+++ b/trunk/src/or/circuituse.c
@@ -963,10 +963,16 @@ circuit_get_open_circ_or_launch(connection_t *conn,
if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) {
if (conn->chosen_exit_name) {
routerinfo_t *r;
+ int opt = conn->chosen_exit_optional;
if (!(r = router_get_by_nickname(conn->chosen_exit_name, 1))) {
- log_notice(LD_APP,
- "Requested exit point '%s' is not known. Closing.",
- conn->chosen_exit_name);
+ log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
+ "Requested exit point '%s' is not known. %s.",
+ conn->chosen_exit_name, opt ? "Trying others" : "Closing");
+ if (opt) {
+ conn->chosen_exit_optional = 0;
+ tor_free(conn->chosen_exit_name);
+ return 0;
+ }
return -1;
}
extend_info = extend_info_from_router(r);
@@ -1151,16 +1157,27 @@ connection_ap_handshake_attach_circuit(connection_t *conn)
if (conn->chosen_exit_name) {
routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
+ int opt = conn->chosen_exit_optional;
if (!router) {
- log_warn(LD_APP,
- "Requested exit point '%s' is not known. Closing.",
- conn->chosen_exit_name);
+ log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
+ "Requested exit point '%s' is not known. %s.",
+ conn->chosen_exit_name, opt ? "Trying others" : "Closing");
+ if (opt) {
+ conn->chosen_exit_optional = 0;
+ tor_free(conn->chosen_exit_name);
+ return 0;
+ }
return -1;
}
if (!connection_ap_can_use_exit(conn, router)) {
- log_warn(LD_APP,
- "Requested exit point '%s' would refuse request. Closing.",
- conn->chosen_exit_name);
+ log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
+ "Requested exit point '%s' would refuse request. %s.",
+ conn->chosen_exit_name, opt ? "Trying others" : "Closing");
+ if (opt) {
+ conn->chosen_exit_optional = 0;
+ tor_free(conn->chosen_exit_name);
+ return 0;
+ }
return -1;
}
}
diff --git a/trunk/src/or/connection_edge.c b/trunk/src/or/connection_edge.c
index 41948e055c..45620e2a3b 100644
--- a/trunk/src/or/connection_edge.c
+++ b/trunk/src/or/connection_edge.c
@@ -1126,6 +1126,7 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn,
routers with this nickname */
conn->chosen_exit_name =
tor_strdup(hex_str(r->cache_info.identity_digest, DIGEST_LEN));
+ conn->chosen_exit_optional = 1;
}
}
diff --git a/trunk/src/or/or.h b/trunk/src/or/or.h
index 5700221fa1..ff3a26e65b 100644
--- a/trunk/src/or/or.h
+++ b/trunk/src/or/or.h
@@ -656,6 +656,8 @@ struct connection_t {
/** Nickname of planned exit node -- used with .exit support. */
char *chosen_exit_name;
+ /** If 1, and we fail to reach the chosen exit, stop requiring it. */
+ unsigned int chosen_exit_optional:1;
/* Used only by OR connections: */
tor_tls_t *tls; /**< TLS connection state (OR only.) */
diff --git a/trunk/src/or/relay.c b/trunk/src/or/relay.c
index 95b999c726..7dc7d3b7b5 100644
--- a/trunk/src/or/relay.c
+++ b/trunk/src/or/relay.c
@@ -696,11 +696,21 @@ connection_edge_process_end_not_open(
/* rewrite it to an IP if we learned one. */
addressmap_rewrite(conn->socks_request->address,
sizeof(conn->socks_request->address));
+ if (conn->chosen_exit_optional) { /* stop wanting a specific exit */
+ conn->chosen_exit_optional = 0;
+ tor_free(conn->chosen_exit_name);
+ }
if (connection_ap_detach_retriable(conn, circ) >= 0)
return 0;
/* else, conn will get closed below */
break;
+ case END_STREAM_REASON_CONNECTREFUSED:
+ if (!conn->chosen_exit_optional)
+ break; /* break means it'll close, below */
+ /* Else fall through: expire this circuit, clear the
+ * chosen_exit_name field, and try again. */
case END_STREAM_REASON_RESOLVEFAILED:
+ case END_STREAM_REASON_TIMEOUT:
case END_STREAM_REASON_MISC:
if (client_dns_incr_failures(conn->socks_request->address)
< MAX_RESOLVE_FAILURES) {
@@ -709,6 +719,10 @@ connection_edge_process_end_not_open(
tor_assert(circ->timestamp_dirty);
circ->timestamp_dirty -= get_options()->MaxCircuitDirtiness;
+ if (conn->chosen_exit_optional) { /* stop wanting a specific exit */
+ conn->chosen_exit_optional = 0;
+ tor_free(conn->chosen_exit_name);
+ }
if (connection_ap_detach_retriable(conn, circ) >= 0)
return 0;
/* else, conn will get closed below */
@@ -729,6 +743,10 @@ connection_edge_process_end_not_open(
exitrouter->exit_policy =
router_parse_addr_policy_from_string("reject *:*", -1);
}
+ if (conn->chosen_exit_optional) { /* stop wanting a specific exit */
+ conn->chosen_exit_optional = 0;
+ tor_free(conn->chosen_exit_name);
+ }
if (connection_ap_detach_retriable(conn, circ) >= 0)
return 0;
/* else, will close below */