summaryrefslogtreecommitdiff
path: root/src/or/circuit.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-04-13 05:20:52 +0000
committerRoger Dingledine <arma@torproject.org>2004-04-13 05:20:52 +0000
commite0ce205a763fbddc9d87d305fc0ec79c333394bc (patch)
tree69916bff4c50b5e298b6eae599631366faf4c4f5 /src/or/circuit.c
parenta3c072e579aae88df1246453c28471af0ec3ab54 (diff)
downloadtor-e0ce205a763fbddc9d87d305fc0ec79c333394bc.tar.gz
tor-e0ce205a763fbddc9d87d305fc0ec79c333394bc.zip
clean up circuit rebuilding some; fix some bugs we hadn't hit yet
svn:r1606
Diffstat (limited to 'src/or/circuit.c')
-rw-r--r--src/or/circuit.c83
1 files changed, 52 insertions, 31 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index ca9c503aa1..7b51905329 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -16,6 +16,7 @@ static void circuit_free_cpath_node(crypt_path_t *victim);
static uint16_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type);
static void circuit_rep_hist_note_result(circuit_t *circ);
+void circuit_expire_old_circuits(void);
static void circuit_is_open(circuit_t *circ);
static void circuit_build_failed(circuit_t *circ);
static circuit_t *circuit_establish_circuit(uint8_t purpose, const char *exit_nickname);
@@ -293,10 +294,6 @@ static int circuit_is_acceptable(circuit_t *circ,
if(conn) {
/* decide if this circ is suitable for this conn */
-// if(circ->state == CIRCUIT_STATE_OPEN && circ->n_conn) /* open */
-// exitrouter = router_get_by_addr_port(circ->cpath->prev->addr,
-// circ->cpath->prev->port);
-// else /* not open */
/* for rend circs, circ->cpath->prev is not the last router in the
* circuit, it's the magical extra bob hop. so just check the nickname
* of the one we meant to finish at.
@@ -442,8 +439,7 @@ circuit_t *circuit_get_rendezvous(const char *cookie)
/* 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) {
- int now = time(NULL);
+void circuit_expire_building(time_t now) {
circuit_t *victim, *circ = global_circuitlist;
while(circ) {
@@ -480,14 +476,15 @@ void circuit_expire_building(void) {
}
/* count the number of circs starting at us that aren't open */
-int circuit_count_building(void) {
+int circuit_count_building(uint8_t purpose) {
circuit_t *circ;
int num=0;
for(circ=global_circuitlist;circ;circ = circ->next) {
- if(CIRCUIT_IS_ORIGIN(circ)
- && circ->state != CIRCUIT_STATE_OPEN
- && !circ->marked_for_close)
+ if(CIRCUIT_IS_ORIGIN(circ) &&
+ circ->state != CIRCUIT_STATE_OPEN &&
+ circ->purpose == purpose &&
+ !circ->marked_for_close)
num++;
}
return num;
@@ -518,41 +515,65 @@ int circuit_stream_is_being_handled(connection_t *conn) {
return 0;
}
-void circuit_build_needed_circs(time_t now) {
- static long time_to_new_circuit = 0;
+static circuit_t *
+circuit_get_youngest_clean_open(uint8_t purpose) {
circuit_t *circ;
+ circuit_t *youngest=NULL;
- if (options.SocksPort)
- /* launch a new circ for any pending streams that need one */
- connection_ap_attach_pending();
+ for(circ=global_circuitlist;circ;circ = circ->next) {
+ if(CIRCUIT_IS_ORIGIN(circ) && circ->state == CIRCUIT_STATE_OPEN &&
+ !circ->marked_for_close && circ->purpose == purpose &&
+ !circ->timestamp_dirty &&
+ (!youngest || youngest->timestamp_created < circ->timestamp_created))
+ youngest = circ;
+ }
+ return youngest;
+}
/* Build a new test circuit every 5 minutes */
#define TESTING_CIRCUIT_INTERVAL 300
- circ = circuit_get_best(NULL, 1, CIRCUIT_PURPOSE_C_GENERAL);
+/* this function is called once a second. its job is to make sure
+ * all services we offer have enough circuits available. Some
+ * services just want enough circuits for current tasks, whereas
+ * others want a minimum set of idle circuits hanging around.
+ */
+void circuit_build_needed_circs(time_t now) {
+ static long time_to_new_circuit = 0;
+ circuit_t *circ;
+
+ /* launch a new circ for any pending streams that need one */
+ connection_ap_attach_pending();
+
+ /* make sure any hidden services have enough intro points */
+ rend_services_init();
+
+ circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
+
if(time_to_new_circuit < now) {
- client_dns_clean();
- circuit_expire_unused_circuits();
circuit_reset_failure_count();
- if(circ && circ->timestamp_dirty) {
- log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement.");
- /* make a new circuit */
- circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
- } else if (options.RunTesting && circ &&
+ time_to_new_circuit = now + options.NewCircuitPeriod;
+ if(options.SocksPort)
+ client_dns_clean();
+ circuit_expire_old_circuits();
+
+ if(options.RunTesting && circ &&
circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
log_fn(LOG_INFO,"Creating a new testing circuit.");
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
}
- time_to_new_circuit = now + options.NewCircuitPeriod;
- time_to_new_circuit = now + options.NewCircuitPeriod;
}
-#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.
- */
+
+#define CIRCUIT_MIN_BUILDING_GENERAL 3
+ /* if there's no open circ, and less than 3 are on the way,
+ * go ahead and try another. */
+ if(!circ && circuit_count_building(CIRCUIT_PURPOSE_C_GENERAL)
+ < CIRCUIT_MIN_BUILDING_GENERAL) {
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
}
+
+ /* XXX count idle rendezvous circs and build more */
+
}
/* update digest from the payload of cell. assign integrity part to cell. */
@@ -1142,7 +1163,7 @@ void circuit_dump_by_conn(connection_t *conn, int severity) {
/* Don't keep more than 10 unused open circuits around. */
#define MAX_UNUSED_OPEN_CIRCUITS 10
-void circuit_expire_unused_circuits(void) {
+void circuit_expire_old_circuits(void) {
circuit_t *circ;
time_t now = time(NULL);
smartlist_t *unused_open_circs;