|
@@ -86,6 +86,18 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
|
|
|
return 0; /* this circuit is screwed and doesn't know it yet,
|
|
|
* or is a rendezvous circuit. */
|
|
|
}
|
|
|
+ if (build_state->onehop_tunnel) {
|
|
|
+ if (conn->socks_request->command != SOCKS_COMMAND_CONNECT_DIR) {
|
|
|
+ log_debug(LD_CIRC,"Skipping one-hop circuit.");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (conn->socks_request->command == SOCKS_COMMAND_CONNECT_DIR) {
|
|
|
+ /* don't use three-hop circuits -- that could hurt our anonymity. */
|
|
|
+ log_debug(LD_CIRC,"Skipping multi-hop circuit for CONNECT_DIR.");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
if (!connection_ap_can_use_exit(conn, exitrouter)) {
|
|
|
/* can't exit from this router */
|
|
|
return 0;
|
|
@@ -313,7 +325,7 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
|
|
|
(!circ->timestamp_dirty ||
|
|
|
circ->timestamp_dirty + get_options()->MaxCircuitDirtiness > now)) {
|
|
|
cpath_build_state_t *build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
|
|
|
- if (build_state->is_internal)
|
|
|
+ if (build_state->is_internal || build_state->onehop_tunnel)
|
|
|
continue;
|
|
|
|
|
|
exitrouter = build_state_get_exit_router(build_state);
|
|
@@ -363,8 +375,10 @@ circuit_predict_and_launch_new(void)
|
|
|
continue; /* only count clean circs */
|
|
|
if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL)
|
|
|
continue; /* only pay attention to general-purpose circs */
|
|
|
- num++;
|
|
|
build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
|
|
|
+ if (build_state->onehop_tunnel)
|
|
|
+ continue;
|
|
|
+ num++;
|
|
|
if (build_state->is_internal)
|
|
|
num_internal++;
|
|
|
if (build_state->need_uptime && build_state->is_internal)
|
|
@@ -383,7 +397,7 @@ circuit_predict_and_launch_new(void)
|
|
|
log_info(LD_CIRC,
|
|
|
"Have %d clean circs (%d internal), need another exit circ.",
|
|
|
num, num_internal);
|
|
|
- circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL,
|
|
|
+ circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL,
|
|
|
port_needs_uptime, port_needs_capacity, 0);
|
|
|
return;
|
|
|
}
|
|
@@ -394,7 +408,7 @@ circuit_predict_and_launch_new(void)
|
|
|
"Have %d clean circs (%d internal), need another internal "
|
|
|
"circ for my hidden service.",
|
|
|
num, num_internal);
|
|
|
- circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL,
|
|
|
+ circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL,
|
|
|
1, 1, 1);
|
|
|
return;
|
|
|
}
|
|
@@ -408,7 +422,7 @@ circuit_predict_and_launch_new(void)
|
|
|
"Have %d clean circs (%d uptime-internal, %d internal), need"
|
|
|
" another hidserv circ.",
|
|
|
num, num_uptime_internal, num_internal);
|
|
|
- circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL,
|
|
|
+ circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL,
|
|
|
hidserv_needs_uptime, hidserv_needs_capacity, 1);
|
|
|
return;
|
|
|
}
|
|
@@ -447,7 +461,7 @@ circuit_build_needed_circs(time_t now)
|
|
|
circ &&
|
|
|
circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
|
|
|
log_fn(LOG_INFO,"Creating a new testing circuit.");
|
|
|
- circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, 0, 0, 0);
|
|
|
+ circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL, 0, 0, 0);
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
@@ -764,7 +778,7 @@ static int did_circs_fail_last_period = 0;
|
|
|
/** Launch a new circuit; see circuit_launch_by_extend_info() for
|
|
|
* details on arguments. */
|
|
|
origin_circuit_t *
|
|
|
-circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
|
|
|
+circuit_launch_by_router(uint8_t purpose, int onehop_tunnel, routerinfo_t *exit,
|
|
|
int need_uptime, int need_capacity, int internal)
|
|
|
{
|
|
|
origin_circuit_t *circ;
|
|
@@ -772,7 +786,7 @@ circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
|
|
|
if (exit)
|
|
|
info = extend_info_from_router(exit);
|
|
|
circ = circuit_launch_by_extend_info(
|
|
|
- purpose, info, need_uptime, need_capacity, internal);
|
|
|
+ purpose, onehop_tunnel, info, need_uptime, need_capacity, internal);
|
|
|
if (info)
|
|
|
extend_info_free(info);
|
|
|
return circ;
|
|
@@ -785,19 +799,20 @@ circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
|
|
|
* last hop need not be an exit node. Return the newly allocated circuit on
|
|
|
* success, or NULL on failure. */
|
|
|
origin_circuit_t *
|
|
|
-circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info,
|
|
|
- int need_uptime, int need_capacity, int internal)
|
|
|
+circuit_launch_by_extend_info(uint8_t purpose, int onehop_tunnel,
|
|
|
+ extend_info_t *extend_info, int need_uptime,
|
|
|
+ int need_capacity, int internal)
|
|
|
{
|
|
|
origin_circuit_t *circ;
|
|
|
|
|
|
- if (!router_have_minimum_dir_info()) {
|
|
|
+ if (!onehop_tunnel && !router_have_minimum_dir_info()) {
|
|
|
log_debug(LD_CIRC,"Haven't fetched enough directory info yet; canceling "
|
|
|
"circuit launch.");
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
if ((extend_info || purpose != CIRCUIT_PURPOSE_C_GENERAL) &&
|
|
|
- purpose != CIRCUIT_PURPOSE_TESTING) {
|
|
|
+ purpose != CIRCUIT_PURPOSE_TESTING && !onehop_tunnel) {
|
|
|
/* see if there are appropriate circs available to cannibalize. */
|
|
|
circ = circuit_find_to_cannibalize(CIRCUIT_PURPOSE_C_GENERAL, extend_info,
|
|
|
need_uptime, need_capacity, internal);
|
|
@@ -842,14 +857,15 @@ circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info,
|
|
|
|
|
|
/* try a circ. if it fails, circuit_mark_for_close will increment
|
|
|
* n_circuit_failures */
|
|
|
- return circuit_establish_circuit(purpose, extend_info,
|
|
|
+ return circuit_establish_circuit(purpose, onehop_tunnel, extend_info,
|
|
|
need_uptime, need_capacity, internal);
|
|
|
}
|
|
|
|
|
|
/** Launch a new circuit; see circuit_launch_by_extend_info() for
|
|
|
* details on arguments. */
|
|
|
origin_circuit_t *
|
|
|
-circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname,
|
|
|
+circuit_launch_by_nickname(uint8_t purpose, int onehop_tunnel,
|
|
|
+ const char *exit_nickname,
|
|
|
int need_uptime, int need_capacity, int internal)
|
|
|
{
|
|
|
routerinfo_t *router = NULL;
|
|
@@ -862,7 +878,7 @@ circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname,
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
- return circuit_launch_by_router(purpose, router,
|
|
|
+ return circuit_launch_by_router(purpose, onehop_tunnel, router,
|
|
|
need_uptime, need_capacity, internal);
|
|
|
}
|
|
|
|
|
@@ -904,6 +920,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
|
|
origin_circuit_t *circ;
|
|
|
int check_exit_policy;
|
|
|
int need_uptime, need_internal;
|
|
|
+ int want_onehop;
|
|
|
|
|
|
tor_assert(conn);
|
|
|
tor_assert(circp);
|
|
@@ -911,6 +928,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
|
|
check_exit_policy =
|
|
|
(conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
|
|
|
!connection_edge_is_rendezvous_stream(conn);
|
|
|
+ want_onehop = conn->socks_request->command == SOCKS_COMMAND_CONNECT_DIR;
|
|
|
|
|
|
need_uptime = (conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
|
|
|
smartlist_string_num_isin(get_options()->LongLivedPorts,
|
|
@@ -925,7 +943,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
|
|
return 1; /* we're happy */
|
|
|
}
|
|
|
|
|
|
- if (!router_have_minimum_dir_info()) {
|
|
|
+ if (!want_onehop && !router_have_minimum_dir_info()) {
|
|
|
if (!connection_get_by_type(CONN_TYPE_DIR)) {
|
|
|
log_notice(LD_APP|LD_DIR,
|
|
|
"Application request when we're believed to be "
|
|
@@ -1010,7 +1028,8 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
|
|
new_circ_purpose = desired_circuit_purpose;
|
|
|
|
|
|
circ = circuit_launch_by_extend_info(
|
|
|
- new_circ_purpose, extend_info, need_uptime, 1, need_internal);
|
|
|
+ new_circ_purpose, want_onehop, extend_info,
|
|
|
+ need_uptime, 1, need_internal);
|
|
|
if (extend_info)
|
|
|
extend_info_free(extend_info);
|
|
|
|