aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2003-11-18 07:48:00 +0000
committerRoger Dingledine <arma@torproject.org>2003-11-18 07:48:00 +0000
commita3e39b0ceb4478339f9903ab6e01a3984e208d42 (patch)
treea020d00d6914aef7d85afb17d4256203e4667dce /src
parentbb0e409fbd9416c17b8a4a071b6c8404580077ea (diff)
downloadtor-a3e39b0ceb4478339f9903ab6e01a3984e208d42.tar
tor-a3e39b0ceb4478339f9903ab6e01a3984e208d42.tar.gz
don't build too many circs at once
expire circs that have been building for too long svn:r835
Diffstat (limited to 'src')
-rw-r--r--src/or/circuit.c42
-rw-r--r--src/or/command.c4
-rw-r--r--src/or/main.c21
-rw-r--r--src/or/or.h4
4 files changed, 62 insertions, 9 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index 47911f2dd..5c2a26356 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -250,6 +250,46 @@ circuit_t *circuit_get_newest(connection_t *conn, int must_be_open) {
return NULL;
}
+#define MIN_SECONDS_BEFORE_EXPIRING_CIRC 2
+/* circuits that were born at the end of their second might be expired
+ * after 2.1 seconds; circuits born at the beginning might be expired
+ * after closer to 3 seconds.
+ */
+
+/* close all circuits that start at us, aren't open, and were born
+ * at least MIN_SECONDS_BEFORE_EXPIRING_CIRC seconds ago */
+void circuit_expire_building(void) {
+ circuit_t *circ;
+ int now = time(NULL);
+
+ for(circ=global_circuitlist;circ;circ = circ->next) {
+ if(circ->cpath &&
+ circ->state != CIRCUIT_STATE_OPEN &&
+ circ->timestamp_created + MIN_SECONDS_BEFORE_EXPIRING_CIRC+1 < now) {
+ if(circ->n_conn)
+ log_fn(LOG_INFO,"Abandoning circ %s:%d:%d (state %d:%s)",
+ circ->n_conn->address, circ->n_port, circ->n_circ_id,
+ circ->state, circuit_state_to_string[circ->state]);
+ else
+ log_fn(LOG_INFO,"Abandoning circ %d (state %d:%s)", circ->n_circ_id,
+ circ->state, circuit_state_to_string[circ->state]);
+ circuit_close(circ);
+ }
+ }
+}
+
+/* count the number of circs starting at us that aren't open */
+int circuit_count_building(void) {
+ circuit_t *circ;
+ int num=0;
+
+ for(circ=global_circuitlist;circ;circ = circ->next) {
+ if(circ->cpath && circ->state != CIRCUIT_STATE_OPEN)
+ num++;
+ }
+ return num;
+}
+
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction, crypt_path_t *layer_hint) {
connection_t *conn=NULL;
@@ -818,7 +858,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
connection_ap_attach_pending();
return 0;
} else if (r<0) {
- log_fn(LOG_WARN,"Unable to extend circuit path.");
+ log_fn(LOG_INFO,"Unable to extend circuit path.");
return -1;
}
hop = circ->cpath->prev;
diff --git a/src/or/command.c b/src/or/command.c
index b3302a301..fa83d23c8 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -146,8 +146,8 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) {
}
log_fn(LOG_DEBUG,"Moving to next skin.");
if(circuit_send_next_onion_skin(circ) < 0) {
- log_fn(LOG_WARN,"circuit_send_next_onion_skin failed.");
- circuit_close(circ);
+ log_fn(LOG_INFO,"circuit_send_next_onion_skin failed.");
+ circuit_close(circ); /* XXX push this circuit_close lower */
return;
}
} else { /* pack it into an extended relay cell, and send it. */
diff --git a/src/or/main.c b/src/or/main.c
index 19aae3044..d0e945921 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -335,7 +335,14 @@ static void run_scheduled_events(time_t now) {
time_to_fetch_directory = now + options.DirFetchPostPeriod;
}
- /* 2. Every second, we try a new circuit if there are no valid
+ /* 2. Every second, we examine pending circuits and prune the
+ * ones which have been pending for more than 2 seconds.
+ * We do this before step 3, so it can try building more if
+ * it's not comfortable with the number of available circuits.
+ */
+ circuit_expire_building();
+
+ /* 3. Every second, we try a new circuit if there are no valid
* circuits. Every NewCircuitPeriod seconds, we expire circuits
* that became dirty more than NewCircuitPeriod seconds ago,
* and we make a new circ if there are no clean circuits.
@@ -356,11 +363,15 @@ static void run_scheduled_events(time_t now) {
}
time_to_new_circuit = now + options.NewCircuitPeriod;
}
- if(!circ)
+#define CIRCUIT_MIN_BUILDING 3
+ if(!circ && circuit_count_building() < CIRCUIT_MIN_BUILDING)
+ /* if there's no open circ, and less than 3 are on the way,
+ * go ahead and try another.
+ */
circuit_launch_new(1);
}
- /* 3. Every second, we check how much bandwidth we've consumed and
+ /* 4. Every second, we check how much bandwidth we've consumed and
* increment global_read_bucket.
*/
stats_n_bytes_read += stats_prev_global_read_bucket-global_read_bucket;
@@ -370,12 +381,12 @@ static void run_scheduled_events(time_t now) {
}
stats_prev_global_read_bucket = global_read_bucket;
- /* 4. We do houskeeping for each connection... */
+ /* 5. We do housekeeping for each connection... */
for(i=0;i<nfds;i++) {
run_connection_housekeeping(i, now);
}
- /* 5. and blow away any connections that need to die. can't do this later
+ /* 6. and blow away any connections that need to die. can't do this later
* because we might open up a circuit and not realize we're about to cull
* the connection it's running over.
* XXX we can remove this step once we audit circuit-building to make sure
diff --git a/src/or/or.h b/src/or/or.h
index fe9196e08..81aae7d10 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -110,7 +110,6 @@
#define CIRC_ID_TYPE_LOWER 0
#define CIRC_ID_TYPE_HIGHER 1
-#define CIRC_ID_TYPE_BOTH 2
#define _CONN_TYPE_MIN 3
#define CONN_TYPE_OR_LISTENER 3
@@ -518,6 +517,9 @@ circuit_t *circuit_get_by_circ_id_conn(circ_id_t circ_id, connection_t *conn);
circuit_t *circuit_get_by_conn(connection_t *conn);
circuit_t *circuit_get_newest(connection_t *conn, int must_be_open);
+void circuit_expire_building(void);
+int circuit_count_building(void);
+
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction, crypt_path_t *layer_hint);
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,