aboutsummaryrefslogtreecommitdiff
path: root/src/or
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
parent6452aecedb2b0c498dcc7acddaca062c0b02bcc4 (diff)
downloadtor-fe221f3dff3fa1c79213f04261e4c7a70576b619.tar
tor-fe221f3dff3fa1c79213f04261e4c7a70576b619.tar.gz
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')
-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 ae7e4309c..ea620b102 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 780c8c0fd..782e1c7d7 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 b4dc8f6db..8ae3bab51 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 ae2d10fac..a8f300c79 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 50b080034..aa9d173df 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