aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/circuitlist.c8
-rw-r--r--src/or/circuituse.c57
-rw-r--r--src/or/or.h5
-rw-r--r--src/or/rendservice.c4
-rw-r--r--src/or/rephist.c62
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