diff options
author | Roger Dingledine <arma@torproject.org> | 2003-11-16 21:49:52 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2003-11-16 21:49:52 +0000 |
commit | 6d0e611fde9d8610a0e3837da17545f8f42e1adc (patch) | |
tree | 18fd02ae1cea86594471ff9dd9e89c10a41df07e /src/or/circuit.c | |
parent | f5089681f795b435ec8a7454e2b91d8b3596a01b (diff) | |
download | tor-6d0e611fde9d8610a0e3837da17545f8f42e1adc.tar tor-6d0e611fde9d8610a0e3837da17545f8f42e1adc.tar.gz |
change when circuits are built and expired
not quite happy with it yet
svn:r817
Diffstat (limited to 'src/or/circuit.c')
-rw-r--r-- | src/or/circuit.c | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index 7208489fa..f591c11a8 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -205,18 +205,45 @@ circuit_t *circuit_get_by_conn(connection_t *conn) { return NULL; } -circuit_t *circuit_get_newest_open(void) { - circuit_t *circ, *bestcirc=NULL; +/* Find the newest circ that conn can use, preferably one which is + * dirty and not too old. + * If !conn, return newest open. + */ +circuit_t *circuit_get_newest_open(connection_t *conn) { + circuit_t *circ, *newest=NULL, *leastdirty=NULL; for(circ=global_circuitlist;circ;circ = circ->next) { - if(circ->cpath && circ->state == CIRCUIT_STATE_OPEN && circ->n_conn && (!bestcirc || - bestcirc->timestamp_created < circ->timestamp_created)) { - log_fn(LOG_DEBUG,"Choosing circuit %s:%d:%d.", circ->n_conn->address, circ->n_port, circ->n_circ_id); - assert(circ->n_circ_id); - bestcirc = circ; + if(conn && connection_ap_can_use_exit(conn, + router_get_by_addr_port(circ->cpath->prev->addr, circ->cpath->prev->port)) < 0) { + log_fn(LOG_DEBUG,"Skipping %s:%d:%d because we couldn't exit there.", + circ->n_conn->address, circ->n_port, circ->n_circ_id); + continue; } + if(circ->cpath && circ->state == CIRCUIT_STATE_OPEN && circ->n_conn) { + if(!newest || newest->timestamp_created < circ->timestamp_created) { + assert(circ->n_circ_id); + newest = circ; + } + if(conn && circ->timestamp_dirty && + (!leastdirty || leastdirty->timestamp_dirty < circ->timestamp_dirty)) { + assert(circ->n_circ_id); + leastdirty = circ; + } + } + } + + if(leastdirty && + leastdirty->timestamp_dirty+options.NewCircuitPeriod > time(NULL)) { + log_fn(LOG_DEBUG,"Choosing in-use circuit %s:%d:%d.", + leastdirty->n_conn->address, leastdirty->n_port, leastdirty->n_circ_id); + return leastdirty; + } + if(newest) { + log_fn(LOG_DEBUG,"Choosing circuit %s:%d:%d.", + newest->n_conn->address, newest->n_port, newest->n_circ_id); + return newest; } - return bestcirc; + return NULL; } int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, @@ -491,13 +518,8 @@ int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t void circuit_close(circuit_t *circ) { connection_t *conn; - circuit_t *youngest=NULL; assert(circ); - if(options.SocksPort) { - youngest = circuit_get_newest_open(); - log_fn(LOG_DEBUG,"youngest %d, circ %d.",(int)youngest, (int)circ); - } circuit_remove(circ); if(circ->n_conn) connection_send_destroy(circ->n_circ_id, circ->n_conn); @@ -509,11 +531,6 @@ void circuit_close(circuit_t *circ) { for(conn=circ->p_streams; conn; conn=conn->next_stream) { connection_send_destroy(circ->p_circ_id, conn); } - if(options.SocksPort && youngest == circ) { /* check this after we've sent the destroys, to reduce races */ - /* our current circuit just died. Launch another one pronto. */ - log_fn(LOG_INFO,"Youngest circuit dying. Launching a replacement."); - circuit_launch_new(1); - } circuit_free(circ); } @@ -606,15 +623,15 @@ void circuit_dump_by_conn(connection_t *conn, int severity) { void circuit_expire_unused_circuits(void) { circuit_t *circ, *tmpcirc; - circuit_t *youngest; - - youngest = circuit_get_newest_open(); + time_t now = time(NULL); circ = global_circuitlist; while(circ) { tmpcirc = circ; circ = circ->next; - if(tmpcirc != youngest && !tmpcirc->p_conn && !tmpcirc->p_streams) { + if(tmpcirc->timestamp_dirty && + tmpcirc->timestamp_dirty + options.NewCircuitPeriod < now && + !tmpcirc->p_conn && !tmpcirc->p_streams) { log_fn(LOG_DEBUG,"Closing n_circ_id %d",tmpcirc->n_circ_id); circuit_close(tmpcirc); } @@ -624,34 +641,33 @@ void circuit_expire_unused_circuits(void) { /* failure_status code: negative means reset failures to 0. Other values mean * add that value to the current number of failures, then if we don't have too * many failures on record, try to make a new circuit. + * + * Return -1 if you aren't going to try to make a circuit, 0 if you did try. */ -void circuit_launch_new(int failure_status) { +int circuit_launch_new(int failure_status) { static int failures=0; if(!options.SocksPort) /* we're not an application proxy. no need for circuits. */ - return; + return -1; if(failure_status == -1) { /* I was called because a circuit succeeded */ failures = 0; - return; + return -1; } failures += failure_status; -retry_circuit: - if(failures > 5) { - log_fn(LOG_INFO,"Giving up for now, %d failures.", failures); - return; + return -1; } if(circuit_establish_circuit() < 0) { failures++; - goto retry_circuit; + return 0; } failures = 0; - return; + return 0; } int circuit_establish_circuit(void) { |