summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-06-25 11:10:43 -0400
committerNick Mathewson <nickm@torproject.org>2015-06-25 11:10:43 -0400
commit68eaaed7982b63abedfcfba33f7e2656c68e3e4a (patch)
treee42a25dde274264a3caf9fe121f733a31687a3c8
parent75388f67c07d1a48c6fb9c5d1c4441ab66b644c0 (diff)
downloadtor-68eaaed7982b63abedfcfba33f7e2656c68e3e4a.tar.gz
tor-68eaaed7982b63abedfcfba33f7e2656c68e3e4a.zip
Avoid crashing on busy/NEWNYM+hidden service clients
When we ran out of intro points for a hidden service (which could happen on a newnym), we would change the connection's state back to "waiting for hidden service descriptor." But this would make an assertion fail if we went on to call circuit_get_open_circ_or_launch again. This fixes bug 16013; I believe the bug was introduced in 38be533c69417aacf28cedec1c3bae808ce29f4, where we made it possible for circuit_get_open_circ_or_launch() to change the connection's state.
-rw-r--r--changes/bug160135
-rw-r--r--src/or/circuituse.c12
2 files changed, 17 insertions, 0 deletions
diff --git a/changes/bug16013 b/changes/bug16013
new file mode 100644
index 0000000000..d194c609f8
--- /dev/null
+++ b/changes/bug16013
@@ -0,0 +1,5 @@
+ o Major bugfixes (hidden service, stability):
+ - Stop randomly crashing with an assertion failure when connecting to a
+ busy hidden service, or connecting to a hidden service while a NEWNYM
+ is in progress. Fixes bug 16013; bugfix on 0.1.0.1-rc.
+
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 714754a672..75cd4fec56 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -2346,6 +2346,18 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
return 1;
}
+ /* At this point we need to re-check the state, since it's possible that
+ * our call to circuit_get_open_circ_or_launch() changed the connection's
+ * state from "CIRCUIT_WAIT" to "RENDDESC_WAIT" because we decided to
+ * re-fetch the descriptor.
+ */
+ if (ENTRY_TO_CONN(conn)->state != AP_CONN_STATE_CIRCUIT_WAIT) {
+ log_info(LD_REND, "This connection is no longer ready to attach; its "
+ "state changed."
+ "(We probably have to re-fetch its descriptor.)");
+ return 0;
+ }
+
if (rendcirc && (rendcirc->base_.purpose ==
CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED)) {
log_info(LD_REND,