diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitlist.c | 8 | ||||
-rw-r--r-- | src/or/circuituse.c | 57 | ||||
-rw-r--r-- | src/or/or.h | 5 | ||||
-rw-r--r-- | src/or/rendservice.c | 4 | ||||
-rw-r--r-- | src/or/rephist.c | 62 |
5 files changed, 73 insertions, 63 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index ae7e4309c7..ea620b102e 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -552,10 +552,10 @@ circuit_get_rendezvous(const char *cookie) * if required, and if info is defined, does not already use info * as any of its hops; or NULL if no circuit fits this description. * - * Avoid returning need_uptime circuits if not necessary. + * Return need_uptime circuits if that is requested; and if it's not + * requested, return non-uptime circuits if possible, else either. * - * FFFF As a more important goal, not yet implemented, avoid returning - * internal circuits if not necessary. + * Only return internal circuits if that is requested. */ circuit_t * circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, @@ -575,7 +575,7 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, !circ->timestamp_dirty && (!need_uptime || circ->build_state->need_uptime) && (!need_capacity || circ->build_state->need_capacity) && - (!internal || circ->build_state->is_internal)) { + (internal == circ->build_state->is_internal)) { if (info) { /* need to make sure we don't duplicate hops */ crypt_path_t *hop = circ->cpath; 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)); diff --git a/src/or/or.h b/src/or/or.h index b4dc8f6db2..8ae3bab511 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1947,10 +1947,9 @@ void rep_history_clean(time_t before); void rep_hist_note_used_port(uint16_t port, time_t now); smartlist_t *rep_hist_get_predicted_ports(time_t now); -void rep_hist_note_used_hidserv(time_t now, int need_uptime, int need_capacity); -int rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capacity); void rep_hist_note_used_resolve(time_t now); -int rep_hist_get_predicted_resolve(time_t now); +void rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity); +int rep_hist_get_predicted_internal(time_t now, int *need_uptime, int *need_capacity); void rep_hist_free_all(void); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index ae2d10facc..a8f300c798 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -545,7 +545,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, size_t request_l circ_needs_uptime = rend_service_requires_uptime(service); /* help predict this next time */ - rep_hist_note_used_hidserv(time(NULL), circ_needs_uptime, 1); + rep_hist_note_used_internal(time(NULL), circ_needs_uptime, 1); /* Launch a circuit to alice's chosen rendezvous point. */ @@ -652,7 +652,7 @@ rend_service_launch_establish_intro(rend_service_t *service, const char *nicknam info(LD_REND, "Launching circuit to introduction point %s for service %s", nickname, service->service_id); - rep_hist_note_used_hidserv(time(NULL), 1, 0); + rep_hist_note_used_internal(time(NULL), 1, 0); ++service->n_intro_circuits_launched; launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname, 1, 0, 1); diff --git a/src/or/rephist.c b/src/or/rephist.c index 50b0800345..aa9d173df0 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -666,7 +666,7 @@ predicted_ports_free(void) /** Remember that <b>port</b> has been asked for as of time <b>now</b>. * This is used for predicting what sorts of streams we'll make in the - * future and making circuits to anticipate that. + * future and making exit circuits to anticipate that. */ void rep_hist_note_used_port(uint16_t port, time_t now) @@ -727,53 +727,61 @@ rep_hist_get_predicted_ports(time_t now) return predicted_ports_list; } +/** The user asked us to do a resolve. Rather than keeping track of + * timings and such of resolves, we fake it for now by making treating + * it the same way as a connection to port 80. This way we will continue + * to have circuits lying around if the user only uses Tor for resolves. + */ +void +rep_hist_note_used_resolve(time_t now) +{ + rep_hist_note_used_port(80, now); +} + +#if 0 +int +rep_hist_get_predicted_resolve(time_t now) +{ + return 0; +} +#endif + /** The last time at which we needed an internal circ. */ -static time_t predicted_hidserv_time = 0; +static time_t predicted_internal_time = 0; /** The last time we needed an internal circ with good uptime. */ -static time_t predicted_hidserv_uptime_time = 0; +static time_t predicted_internal_uptime_time = 0; /** The last time we needed an internal circ with good capacity. */ -static time_t predicted_hidserv_capacity_time = 0; +static time_t predicted_internal_capacity_time = 0; /** Remember that we used an internal circ at time <b>now</b>. */ void -rep_hist_note_used_hidserv(time_t now, int need_uptime, int need_capacity) +rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity) { - predicted_hidserv_time = now; + predicted_internal_time = now; if (need_uptime) - predicted_hidserv_uptime_time = now; + predicted_internal_uptime_time = now; if (need_capacity) - predicted_hidserv_capacity_time = now; + predicted_internal_capacity_time = now; } /** Return 1 if we've used an internal circ recently; else return 0. */ int -rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capacity) +rep_hist_get_predicted_internal(time_t now, int *need_uptime, int *need_capacity) { - if (!predicted_hidserv_time) { /* initialize it */ - predicted_hidserv_time = now; - predicted_hidserv_uptime_time = now; - predicted_hidserv_capacity_time = now; + if (!predicted_internal_time) { /* initialize it */ + predicted_internal_time = now; + predicted_internal_uptime_time = now; + predicted_internal_capacity_time = now; } - if (predicted_hidserv_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) + if (predicted_internal_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) return 0; /* too long ago */ - if (predicted_hidserv_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) + if (predicted_internal_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) *need_uptime = 1; - if (predicted_hidserv_capacity_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) + if (predicted_internal_capacity_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) *need_capacity = 1; return 1; } -/* not used yet */ -void -rep_hist_note_used_resolve(time_t now) -{ -} -int -rep_hist_get_predicted_resolve(time_t now) -{ - return 0; -} - /** Free all storage held by the OR/link history caches, by the * bandwidth history arrays, or by the port history. */ void |