summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-03-21 06:33:57 +0000
committerNick Mathewson <nickm@torproject.org>2004-03-21 06:33:57 +0000
commitd44e3ad809e287fa0e2134bf1846b6322110b32b (patch)
tree24b86a047e220f4175470ea46be3847a00f05070
parentb3f6b55ea11e548c4febcaf946e7d66ee8b9b7ee (diff)
downloadtor-d44e3ad809e287fa0e2134bf1846b6322110b32b.tar.gz
tor-d44e3ad809e287fa0e2134bf1846b6322110b32b.zip
Remove unused open circuits when there are too many, not when they are too old.
svn:r1332
-rw-r--r--src/or/circuit.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index 225c8e37cb..80b38dba23 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -18,6 +18,7 @@ unsigned long stats_n_relay_cells_delivered = 0;
/********* START VARIABLES **********/
+static int circuitlist_len=0;
static circuit_t *global_circuitlist=NULL;
char *circuit_state_to_string[] = {
"doing handshakes", /* 0 */
@@ -36,6 +37,7 @@ void circuit_add(circuit_t *circ) {
circ->next = global_circuitlist;
global_circuitlist = circ;
}
+ ++circuitlist_len;
}
void circuit_remove(circuit_t *circ) {
@@ -45,12 +47,14 @@ void circuit_remove(circuit_t *circ) {
if(global_circuitlist == circ) {
global_circuitlist = global_circuitlist->next;
+ --circuitlist_len;
return;
}
for(tmpcirc = global_circuitlist;tmpcirc->next;tmpcirc = tmpcirc->next) {
if(tmpcirc->next == circ) {
tmpcirc->next = circ->next;
+ --circuitlist_len;
return;
}
}
@@ -59,9 +63,8 @@ void circuit_remove(circuit_t *circ) {
void circuit_close_all_marked()
{
circuit_t *tmp,*m;
-
+
while (global_circuitlist && global_circuitlist->marked_for_close) {
-
tmp = global_circuitlist->next;
circuit_free(global_circuitlist);
global_circuitlist = tmp;
@@ -325,8 +328,8 @@ int circuit_count_building(void) {
int num=0;
for(circ=global_circuitlist;circ;circ = circ->next) {
- if(circ->cpath
- && circ->state != CIRCUIT_STATE_OPEN
+ if(circ->cpath
+ && circ->state != CIRCUIT_STATE_OPEN
&& !circ->marked_for_close)
num++;
}
@@ -343,7 +346,7 @@ int circuit_stream_is_being_handled(connection_t *conn) {
int num=0;
for(circ=global_circuitlist;circ;circ = circ->next) {
- if(circ->cpath && circ->state != CIRCUIT_STATE_OPEN &&
+ if(circ->cpath && circ->state != CIRCUIT_STATE_OPEN &&
!circ->marked_for_close) {
exitrouter = router_get_by_nickname(circ->build_state->chosen_exit);
if(exitrouter && connection_ap_can_use_exit(conn, exitrouter) != ADDR_POLICY_REJECTED)
@@ -907,34 +910,44 @@ void circuit_dump_by_conn(connection_t *conn, int severity) {
}
}
-/* Expire unused testing circuits after 10 minutes. */
-#define TESTING_CIRCUIT_MAX_AGE 600
+/* Don't keep more than 10 unused open circuits around. */
+#define MAX_UNUSED_OPEN_CIRCUITS 10
void circuit_expire_unused_circuits(void) {
- circuit_t *circ, *tmpcirc;
+ circuit_t *circ;
time_t now = time(NULL);
+ smartlist_t *unused_open_circs;
+ int i;
- circ = global_circuitlist;
- while(circ) {
- tmpcirc = circ;
- circ = circ->next;
+ unused_open_circs = smartlist_create(circuitlist_len);
+
+ for (circ = global_circuitlist; circ; circ = circ->next) {
+ if (circ->marked_for_close)
+ continue;
/* If the circuit has been dirty for too long, and there are no streams
* on it, mark it for close.
- * If we are creating test circuits, and the circuit is old, and has
- * no streams, shut it down even if it isn't dirty.
*/
- if(((tmpcirc->timestamp_dirty &&
- tmpcirc->timestamp_dirty + options.NewCircuitPeriod < now) ||
- (options.RunTesting &&
- tmpcirc->cpath &&
- tmpcirc->timestamp_created + TESTING_CIRCUIT_MAX_AGE < now))
- && !tmpcirc->p_conn
- && !tmpcirc->p_streams
- && !tmpcirc->marked_for_close) {
- log_fn(LOG_DEBUG,"Closing n_circ_id %d",tmpcirc->n_circ_id);
- circuit_mark_for_close(tmpcirc);
+ if (circ->timestamp_dirty &&
+ circ->timestamp_dirty + options.NewCircuitPeriod < now &&
+ !circ->p_conn &&
+ !circ->p_streams) {
+ log_fn(LOG_DEBUG,"Closing n_circ_id %d",circ->n_circ_id);
+ circuit_mark_for_close(circ);
+ } else if (!circ->timestamp_dirty && circ->cpath &&
+ circ->state == CIRCUIT_STATE_OPEN) {
+ /* Also, gather a list of open unused circuits that we created.
+ * Because we add elements to the front of global_circuitlist,
+ * the last elements of unused_open_circs will be the oldest
+ * ones.
+ */
+ smartlist_add(unused_open_circs, circ);
}
}
+ for (i = MAX_UNUSED_OPEN_CIRCUITS; i < unused_open_circs->num_used; ++i) {
+ circuit_t *circ=(circuit_t*)(unused_open_circs->list[i]);
+ circuit_mark_for_close(circ);
+ }
+ smartlist_free(unused_open_circs);
}
/* Number of consecutive failures so far; should only be touched by
@@ -1351,7 +1364,7 @@ void assert_circuit_ok(const circuit_t *c)
if (c->cpath) {
assert(!c->n_crypto);
assert(!c->p_crypto);
- assert(!c->n_digest);
+ assert(!c->n_digest);
assert(!c->p_digest);
} else {
assert(c->n_crypto);