diff options
author | Roger Dingledine <arma@torproject.org> | 2004-12-05 07:10:08 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-12-05 07:10:08 +0000 |
commit | ef6c9d18e799e5b02505ba73bbf36bfe92ce5a8b (patch) | |
tree | 24e864902bc7196fb3e2ca1a39fc7463c2582d1c /src/or/circuituse.c | |
parent | 32e74d352500dc228a1de5d5bc97e219897ef09b (diff) | |
download | tor-ef6c9d18e799e5b02505ba73bbf36bfe92ce5a8b.tar.gz tor-ef6c9d18e799e5b02505ba73bbf36bfe92ce5a8b.zip |
New circuit building strategy: keep a list of ports that we've used in the past 6 hours, and always try to have 2 circuits open or on the way
that will handle each such port. (We can extend this to include addresses
if exit policies shift to require that.) Seed us with port 80 so web
browsers won't complain that Tor is "slow to start up".
This was necessary because our old circuit building strategy just involved
counting circuits, and as time went by we would build up a big pile of
circuits that had peculiar exit policies (e.g. only exit to 9001-9100)
which would take up space in the circuit pile but never get used.
Fix router_compare_addr_to_addr_policy: it was not treating a port of *
as always matching, so we were picking reject *:* nodes as exit nodes too.
If you haven't used a clean circuit in an hour, throw it away, just to
be on the safe side.
This means after 6 hours a totally unused Tor client will have no
circuits open.
svn:r3078
Diffstat (limited to 'src/or/circuituse.c')
-rw-r--r-- | src/or/circuituse.c | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 64604679da..e316522d0f 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -249,16 +249,34 @@ void circuit_expire_building(time_t now) { } } -/** How many circuits do we want simultaneously in-progress to handle - * a given stream? +/** Remove any elements in <b>needed_ports</b> that are handled by an + * open or in-progress circuit. */ -#define MIN_CIRCUITS_HANDLING_STREAM 2 +void +circuit_remove_handled_ports(smartlist_t *needed_ports) { + int i; + uint16_t port; + char *portstring; + + for (i = 0; i < smartlist_len(needed_ports); ++i) { + portstring = smartlist_get(needed_ports, i); + port = *(uint16_t*)(portstring); + tor_assert(port); + if (circuit_stream_is_being_handled(NULL, port, 2)) { +// log_fn(LOG_DEBUG,"Port %d is already being handled; removing.", port); + smartlist_del(needed_ports, i--); + tor_free(portstring); + } else { + log_fn(LOG_DEBUG,"Port %d is not handled.", port); + } + } +} -/** Return 1 if at least MIN_CIRCUITS_HANDLING_STREAM non-open - * general-purpose circuits will have an acceptable exit node for - * conn. Else return 0. +/** Return 1 if at least <b>min</b> general-purpose circuits will have + * an acceptable exit node for conn if conn is defined, else for "*:port". + * Else return 0. */ -int circuit_stream_is_being_handled(connection_t *conn) { +int circuit_stream_is_being_handled(connection_t *conn, uint16_t port, int min) { circuit_t *circ; routerinfo_t *exitrouter; int num=0; @@ -266,15 +284,19 @@ int circuit_stream_is_being_handled(connection_t *conn) { for (circ=global_circuitlist;circ;circ = circ->next) { if (CIRCUIT_IS_ORIGIN(circ) && - circ->state != CIRCUIT_STATE_OPEN && !circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_C_GENERAL && (!circ->timestamp_dirty || circ->timestamp_dirty + get_options()->NewCircuitPeriod < now)) { exitrouter = router_get_by_digest(circ->build_state->chosen_exit_digest); - if (exitrouter && connection_ap_can_use_exit(conn, exitrouter)) - if (++num >= MIN_CIRCUITS_HANDLING_STREAM) + if (exitrouter && + ((conn && connection_ap_can_use_exit(conn, exitrouter)) || + (!conn && + router_compare_addr_to_addr_policy(0, port, exitrouter->exit_policy) != + ADDR_POLICY_REJECTED))) { + if (++num >= min) return 1; + } } } return 0; @@ -316,6 +338,7 @@ void circuit_build_needed_circs(time_t now) { } } +#if 0 /** How many simultaneous in-progress general-purpose circuits do we * want to be building at once, if there are no open general-purpose * circuits? @@ -327,6 +350,14 @@ void circuit_build_needed_circs(time_t now) { < CIRCUIT_MIN_BUILDING_GENERAL) { circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL); } +#endif + + /* if we know of a port that's been requested recently and no + * circuit is currently available that can handle it, start one + * for that too. */ + if (!circuit_all_predicted_ports_handled(now)) { + circuit_launch_by_identity(CIRCUIT_PURPOSE_C_GENERAL, NULL); + } /* XXX count idle rendezvous circs and build more */ } @@ -471,12 +502,19 @@ circuit_expire_old_circuits(void) } else if (!circ->timestamp_dirty && CIRCUIT_IS_ORIGIN(circ) && circ->state == CIRCUIT_STATE_OPEN && circ->purpose == CIRCUIT_PURPOSE_C_GENERAL) { - /* Also, gather a list of open unused general 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); +#define CIRCUIT_UNUSED_CIRC_TIMEOUT 3600 /* an hour */ + if (circ->timestamp_created + CIRCUIT_UNUSED_CIRC_TIMEOUT < now) { + log_fn(LOG_DEBUG,"Closing circuit that has been unused for %d seconds.", + (int)(now - circ->timestamp_created)); + circuit_mark_for_close(circ); + } else { + /* Also, gather a list of open unused general 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 < smartlist_len(unused_open_circs); ++i) { |