summaryrefslogtreecommitdiff
path: root/src/or/circuituse.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2005-11-25 08:08:56 +0000
committerRoger Dingledine <arma@torproject.org>2005-11-25 08:08:56 +0000
commitfe221f3dff3fa1c79213f04261e4c7a70576b619 (patch)
treea1dc14128e52ea005a5953489fbb651cba3b046f /src/or/circuituse.c
parent6452aecedb2b0c498dcc7acddaca062c0b02bcc4 (diff)
downloadtor-fe221f3dff3fa1c79213f04261e4c7a70576b619.tar.gz
tor-fe221f3dff3fa1c79213f04261e4c7a70576b619.zip
Start the process of treating internal circuits and exit circuits
separately. It's important to keep them separate because internal circuits have their last hops picked like middle hops, rather than like exit hops. So exiting on them will break the user's expectations. - Stop cannibalizing internal circuits for general exits, and stop cannibalizing exit circuits for rendezvous stuff. - Don't let new exit streams attach to internal circuits. - When deciding if we have enough circuits for internal and for exit, don't count the wrong ones. - Treat predicted resolves as predicted port 80 exits. svn:r5457
Diffstat (limited to 'src/or/circuituse.c')
-rw-r--r--src/or/circuituse.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 780c8c0fd3..782e1c7d73 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -29,10 +29,9 @@ static void circuit_increment_failure_count(void);
* Else return 0.
*/
static int
-circuit_is_acceptable(circuit_t *circ,
- connection_t *conn,
- int must_be_open,
- uint8_t purpose,
+circuit_is_acceptable(circuit_t *circ, connection_t *conn,
+ int must_be_open, uint8_t purpose,
+ int need_uptime, int need_internal,
time_t now)
{
routerinfo_t *exitrouter;
@@ -76,9 +75,9 @@ circuit_is_acceptable(circuit_t *circ,
*/
exitrouter = build_state_get_exit_router(circ->build_state);
- if (!circ->build_state->need_uptime &&
- smartlist_string_num_isin(get_options()->LongLivedPorts,
- conn->socks_request->port))
+ if (need_uptime && !circ->build_state->need_uptime)
+ return 0;
+ if (need_internal != circ->build_state->is_internal)
return 0;
if (purpose == CIRCUIT_PURPOSE_C_GENERAL) {
@@ -153,7 +152,8 @@ circuit_is_better(circuit_t *a, circuit_t *b, uint8_t purpose)
* closest introduce-purposed circuit that you can find.
*/
static circuit_t *
-circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose)
+circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose,
+ int need_uptime, int need_internal)
{
circuit_t *circ, *best=NULL;
time_t now = time(NULL);
@@ -165,7 +165,8 @@ circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose)
purpose == CIRCUIT_PURPOSE_C_REND_JOINED);
for (circ=global_circuitlist;circ;circ = circ->next) {
- if (!circuit_is_acceptable(circ,conn,must_be_open,purpose,now))
+ if (!circuit_is_acceptable(circ,conn,must_be_open,purpose,
+ need_uptime,need_internal,now))
continue;
/* now this is an acceptable circ to hand back. but that doesn't
@@ -278,8 +279,9 @@ circuit_remove_handled_ports(smartlist_t *needed_ports)
}
}
-/** 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".
+/** Return 1 if at least <b>min</b> general-purpose non-internal circuits
+ * will have an acceptable exit node for exit stream <b>conn</b> if it
+ * is defined, else for "*:port".
* Else return 0.
*/
int
@@ -296,6 +298,7 @@ circuit_stream_is_being_handled(connection_t *conn, uint16_t port, int min)
if (CIRCUIT_IS_ORIGIN(circ) &&
!circ->marked_for_close &&
circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
+ !circ->build_state->is_internal &&
(!circ->timestamp_dirty ||
circ->timestamp_dirty + get_options()->MaxCircuitDirtiness < now)) {
exitrouter = build_state_get_exit_router(circ->build_state);
@@ -320,7 +323,7 @@ circuit_stream_is_being_handled(connection_t *conn, uint16_t port, int min)
}
/** Don't keep more than 10 unused open circuits around. */
-#define MAX_UNUSED_OPEN_CIRCUITS 10
+#define MAX_UNUSED_OPEN_CIRCUITS 12
/** Figure out how many circuits we have open that are clean. Make
* sure it's enough for all the upcoming behaviors we predict we'll have.
@@ -378,8 +381,8 @@ circuit_predict_and_launch_new(void)
}
/* Fourth, see if we need any more hidden service (client) circuits. */
- if (rep_hist_get_predicted_hidserv(now, &hidserv_needs_uptime,
- &hidserv_needs_capacity) &&
+ if (rep_hist_get_predicted_internal(now, &hidserv_needs_uptime,
+ &hidserv_needs_capacity) &&
((num_uptime_internal<2 && hidserv_needs_uptime) ||
num_internal<2)) {
info(LD_CIRC,"Have %d clean circs (%d uptime-internal, %d internal),"
@@ -867,14 +870,19 @@ circuit_get_open_circ_or_launch(connection_t *conn,
{
circuit_t *circ;
int is_resolve;
- int need_uptime;
+ int need_uptime, need_internal;
tor_assert(conn);
tor_assert(circp);
tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
is_resolve = conn->socks_request->command == SOCKS_COMMAND_RESOLVE;
- circ = circuit_get_best(conn, 1, desired_circuit_purpose);
+ need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
+ conn->socks_request->port);
+ need_internal = desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL;
+
+ circ = circuit_get_best(conn, 1, desired_circuit_purpose,
+ need_uptime, need_internal);
if (circ) {
*circp = circ;
@@ -898,9 +906,6 @@ circuit_get_open_circ_or_launch(connection_t *conn,
return 0;
}
- need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
- conn->socks_request->port);
-
/* Do we need to check exit policy? */
if (!is_resolve && !connection_edge_is_rendezvous_stream(conn)) {
struct in_addr in;
@@ -909,19 +914,18 @@ circuit_get_open_circ_or_launch(connection_t *conn,
addr = ntohl(in.s_addr);
if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port,
need_uptime)) {
- /* LD_GENERAL? LD_APP? ???? NM */
- notice(LD_CIRC,"No Tor server exists that allows exit to %s:%d. Rejecting.",
+ notice(LD_APP,"No Tor server exists that allows exit to %s:%d. Rejecting.",
safe_str(conn->socks_request->address), conn->socks_request->port);
return -1;
}
}
/* is one already on the way? */
- circ = circuit_get_best(conn, 0, desired_circuit_purpose);
+ circ = circuit_get_best(conn, 0, desired_circuit_purpose,
+ need_uptime, need_internal);
if (!circ) {
extend_info_t *extend_info=NULL;
uint8_t new_circ_purpose;
- int is_internal;
if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
/* need to pick an intro point */
@@ -933,7 +937,7 @@ circuit_get_open_circ_or_launch(connection_t *conn,
conn->state = AP_CONN_STATE_RENDDESC_WAIT;
return 0;
}
- info(LD_REND,"Chose %s as intro point for %s.",
+ info(LD_REND,"Chose '%s' as intro point for '%s'.",
extend_info->nickname, safe_str(conn->rend_query));
}
@@ -960,15 +964,14 @@ circuit_get_open_circ_or_launch(connection_t *conn,
else
new_circ_purpose = desired_circuit_purpose;
- is_internal = (new_circ_purpose != CIRCUIT_PURPOSE_C_GENERAL || is_resolve);
circ = circuit_launch_by_extend_info(
- new_circ_purpose, extend_info, need_uptime, 1, is_internal);
+ new_circ_purpose, extend_info, need_uptime, 1, need_internal);
if (extend_info)
extend_info_free(extend_info);
if (desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL) {
/* help predict this next time */
- rep_hist_note_used_hidserv(time(NULL), need_uptime, 1);
+ rep_hist_note_used_internal(time(NULL), need_uptime, 1);
if (circ) {
/* write the service_id into circ */
strlcpy(circ->rend_query, conn->rend_query, sizeof(circ->rend_query));