diff --git a/changes/bug1090-launch-warning b/changes/bug1090-launch-warning new file mode 100644 index 0000000000..3f3fbcb4d8 --- /dev/null +++ b/changes/bug1090-launch-warning @@ -0,0 +1,5 @@ + o Minor features: + - Keep track of how many times we launch a new circuit to handle + a given stream. Too many launches could indicate an inconsistency + between our "launch a circuit to handle this stream" logic and our + "attach our stream to one of the available circuits" logic. diff --git a/src/or/circuituse.c b/src/or/circuituse.c index cc4a739a90..fd1cf6b9b7 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1409,7 +1409,18 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, extend_info_free(extend_info); - if (desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL) { + if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) { + /* We just caused a circuit to get built because of this stream. + * If this stream has caused a _lot_ of circuits to be built, that's + * a bad sign: we should tell the user. */ + if (conn->num_circuits_launched < NUM_CIRCUITS_LAUNCHED_THRESHOLD && + ++conn->num_circuits_launched == NUM_CIRCUITS_LAUNCHED_THRESHOLD) + log_warn(LD_BUG, "The application request to %s:%d has launched " + "%d circuits without finding one it likes.", + escaped_safe_str_client(conn->socks_request->address), + conn->socks_request->port, + conn->num_circuits_launched); + } else { /* help predict this next time */ rep_hist_note_used_internal(time(NULL), need_uptime, 1); if (circ) { diff --git a/src/or/or.h b/src/or/or.h index 50a1223f3c..7d354c8fe1 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1151,6 +1151,13 @@ typedef struct edge_connection_t { * already retried several times. */ uint8_t num_socks_retries; +#define NUM_CIRCUITS_LAUNCHED_THRESHOLD 10 + /** Number of times we've launched a circuit to handle this stream. If + * it gets too high, that could indicate an inconsistency between our + * "launch a circuit to handle this stream" logic and our "attach our + * stream to one of the available circuits" logic. */ + unsigned int num_circuits_launched:4; + /** True iff this connection is for a DNS request only. */ unsigned int is_dns_request:1;