aboutsummaryrefslogtreecommitdiff
path: root/src/or/circuituse.c
diff options
context:
space:
mode:
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));