aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2003-12-12 23:03:25 +0000
committerRoger Dingledine <arma@torproject.org>2003-12-12 23:03:25 +0000
commit9c66e2bf9a9ced671a18c967d08f8a2320105bbe (patch)
treec25141330384689d1f285d0f147d9ad70e6bac25
parentd23c66b04124432561771c95cebc8dd324d035c5 (diff)
downloadtor-9c66e2bf9a9ced671a18c967d08f8a2320105bbe.tar
tor-9c66e2bf9a9ced671a18c967d08f8a2320105bbe.tar.gz
if >=2 circs are being built that handle a given stream,
no need to have new circs handle it too. svn:r896
-rw-r--r--src/or/circuit.c20
-rw-r--r--src/or/onion.c6
-rw-r--r--src/or/or.h1
-rw-r--r--src/or/routerlist.c2
4 files changed, 26 insertions, 3 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index c2bf75500..09f20580d 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -275,6 +275,26 @@ int circuit_count_building(void) {
return num;
}
+#define MIN_CIRCUITS_HANDLING_STREAM 2
+/* return 1 if at least MIN_CIRCUITS_HANDLING_STREAM non-open circuits
+ * will have an acceptable exit node for conn. Else return 0.
+ */
+int circuit_stream_is_being_handled(connection_t *conn) {
+ circuit_t *circ;
+ routerinfo_t *exitrouter;
+ int num=0;
+
+ for(circ=global_circuitlist;circ;circ = circ->next) {
+ if(circ->cpath && circ->state != CIRCUIT_STATE_OPEN) {
+ exitrouter = router_get_by_nickname(circ->build_state->chosen_exit);
+ if(exitrouter && connection_ap_can_use_exit(conn, exitrouter) >= 0)
+ if(++num >= MIN_CIRCUITS_HANDLING_STREAM)
+ return 1;
+ }
+ }
+ return 0;
+}
+
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction, crypt_path_t *layer_hint) {
connection_t *conn=NULL;
diff --git a/src/or/onion.c b/src/or/onion.c
index ca4f678f8..40b36685d 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -233,7 +233,8 @@ static routerinfo_t *choose_good_exit_server(routerlist_t *dir)
for (i = 0; i < n_connections; ++i) {
if (carray[i]->type == CONN_TYPE_AP &&
carray[i]->state == AP_CONN_STATE_CIRCUIT_WAIT &&
- !carray[i]->marked_for_close)
+ !carray[i]->marked_for_close &&
+ !circuit_stream_is_being_handled(carray[i]))
++n_pending_connections;
}
log_fn(LOG_DEBUG, "Choosing exit node; %d connections are pending",
@@ -265,7 +266,8 @@ static routerinfo_t *choose_good_exit_server(routerlist_t *dir)
for (j = 0; j < n_connections; ++j) { /* iterate over connections */
if (carray[j]->type != CONN_TYPE_AP ||
carray[j]->state != AP_CONN_STATE_CIRCUIT_WAIT ||
- carray[j]->marked_for_close)
+ carray[j]->marked_for_close ||
+ circuit_stream_is_being_handled(carray[j]))
continue; /* Skip everything but APs in CIRCUIT_WAIT */
switch (connection_ap_can_use_exit(carray[j], dir->routers[i]))
{
diff --git a/src/or/or.h b/src/or/or.h
index 09be6c398..41b0627eb 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -517,6 +517,7 @@ circuit_t *circuit_get_newest(connection_t *conn, int must_be_open);
void circuit_expire_building(void);
int circuit_count_building(void);
+int circuit_stream_is_being_handled(connection_t *conn);
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction, crypt_path_t *layer_hint);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 4dd52fdee..602ae27e8 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -698,7 +698,7 @@ router_get_list_from_string_impl(const char **s, routerlist_t **dest,
/* Helper function: reads a single router entry from *s, and advances
- * updates *s so it points to just after the router it just read.
+ * *s so it points to just after the router it just read.
* mallocs a new router and returns it if all goes well, else returns
* NULL.
*/