mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
r15653@tombo: nickm | 2007-12-23 14:15:12 -0500
Refactor circuit_launch* functions to take a bitfield of flags rather than 4 separate nonconsecutive flags arguments. Also, note a possible but in circuit_find_to_cannibalize, which seems to be ignoring its purpose argument. svn:r12948
This commit is contained in:
parent
473725e1a4
commit
da06bfb80f
2
doc/TODO
2
doc/TODO
@ -75,7 +75,7 @@ Things we'd like to do in 0.2.0.x:
|
||||
info and it's old enough, delete it. same with cached-routers*.
|
||||
- document the "3/4 and 7/8" business in the clients fetching consensus
|
||||
documents timeline. then document the bridge user download timeline.
|
||||
- refactor circuit_launch_by_foo so all those flags at the end are
|
||||
o refactor circuit_launch_by_foo so all those flags at the end are
|
||||
actually a flags argument.
|
||||
- config option __ControllerLimit that hangs up if there are a limit
|
||||
of controller connections already.
|
||||
|
@ -283,19 +283,23 @@ again:
|
||||
}
|
||||
|
||||
/** Create and return a new origin circuit. Initialize its purpose and
|
||||
* build-state based on our arguments. */
|
||||
* build-state based on our arguments. The <b>flags</b> argument is a
|
||||
* bitfield of CIRCLAUNCH_* flags. */
|
||||
origin_circuit_t *
|
||||
origin_circuit_init(uint8_t purpose, int onehop_tunnel,
|
||||
int need_uptime, int need_capacity, int internal)
|
||||
origin_circuit_init(uint8_t purpose, int flags)
|
||||
{
|
||||
/* sets circ->p_circ_id and circ->p_conn */
|
||||
origin_circuit_t *circ = origin_circuit_new();
|
||||
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OR_WAIT);
|
||||
circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
|
||||
circ->build_state->onehop_tunnel = onehop_tunnel;
|
||||
circ->build_state->need_uptime = need_uptime;
|
||||
circ->build_state->need_capacity = need_capacity;
|
||||
circ->build_state->is_internal = internal;
|
||||
circ->build_state->onehop_tunnel =
|
||||
((flags & CIRCLAUNCH_ONEHOP_TUNNEL) ? 1 : 0);
|
||||
circ->build_state->need_uptime =
|
||||
((flags & CIRCLAUNCH_NEED_UPTIME) ? 1 : 0);
|
||||
circ->build_state->need_capacity =
|
||||
((flags & CIRCLAUNCH_NEED_CAPACITY) ? 1 : 0);
|
||||
circ->build_state->is_internal =
|
||||
((flags & CIRCLAUNCH_IS_INTERNAL) ? 1 : 0);
|
||||
circ->_base.purpose = purpose;
|
||||
return circ;
|
||||
}
|
||||
@ -308,15 +312,12 @@ origin_circuit_init(uint8_t purpose, int onehop_tunnel,
|
||||
* it's not open already.
|
||||
*/
|
||||
origin_circuit_t *
|
||||
circuit_establish_circuit(uint8_t purpose, int onehop_tunnel,
|
||||
extend_info_t *exit,
|
||||
int need_uptime, int need_capacity, int internal)
|
||||
circuit_establish_circuit(uint8_t purpose, extend_info_t *exit, int flags)
|
||||
{
|
||||
origin_circuit_t *circ;
|
||||
int err_reason = 0;
|
||||
|
||||
circ = origin_circuit_init(purpose, onehop_tunnel,
|
||||
need_uptime, need_capacity, internal);
|
||||
circ = origin_circuit_init(purpose, flags);
|
||||
|
||||
if (onion_pick_cpath_exit(circ, exit) < 0 ||
|
||||
onion_populate_cpath(circ) < 0) {
|
||||
|
@ -791,19 +791,24 @@ circuit_get_intro_point(const char *digest)
|
||||
}
|
||||
|
||||
/** Return a circuit that is open, is CIRCUIT_PURPOSE_C_GENERAL,
|
||||
* has a timestamp_dirty value of 0, is uptime/capacity/internal
|
||||
* if required, and if info is defined, does not already use info
|
||||
* has a timestamp_dirty value of 0, has flags matching the CIRCLAUNCH_*
|
||||
* flags in <b>flags</b>, and if info is defined, does not already use info
|
||||
* as any of its hops; or NULL if no circuit fits this description.
|
||||
*
|
||||
* If ! need_uptime, prefer returning non-uptime circuits.
|
||||
* If !CIRCLAUNCH_NEED_UPTIME, prefer returning non-uptime circuits.
|
||||
*/
|
||||
origin_circuit_t *
|
||||
circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
|
||||
int need_uptime,
|
||||
int need_capacity, int internal)
|
||||
int flags)
|
||||
{
|
||||
/*XXXX020 arma: The purpose argument is ignored. Can that possibly be
|
||||
* right? */
|
||||
|
||||
circuit_t *_circ;
|
||||
origin_circuit_t *best=NULL;
|
||||
int need_uptime = flags & CIRCLAUNCH_NEED_UPTIME;
|
||||
int need_capacity = flags & CIRCLAUNCH_NEED_CAPACITY;
|
||||
int internal = flags & CIRCLAUNCH_IS_INTERNAL;
|
||||
|
||||
log_debug(LD_CIRC,
|
||||
"Hunting for a circ to cannibalize: purpose %d, uptime %d, "
|
||||
|
@ -371,6 +371,7 @@ circuit_predict_and_launch_new(void)
|
||||
int hidserv_needs_uptime=0, hidserv_needs_capacity=1;
|
||||
int port_needs_uptime=0, port_needs_capacity=1;
|
||||
time_t now = time(NULL);
|
||||
int flags = 0;
|
||||
|
||||
/* First, count how many of each type of circuit we have already. */
|
||||
for (circ=global_circuitlist;circ;circ = circ->next) {
|
||||
@ -402,22 +403,26 @@ circuit_predict_and_launch_new(void)
|
||||
* and no circuit is currently available that can handle it. */
|
||||
if (!circuit_all_predicted_ports_handled(now, &port_needs_uptime,
|
||||
&port_needs_capacity)) {
|
||||
if (port_needs_uptime)
|
||||
flags |= CIRCLAUNCH_NEED_UPTIME;
|
||||
if (port_needs_capacity)
|
||||
flags |= CIRCLAUNCH_NEED_CAPACITY;
|
||||
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, 0, NULL,
|
||||
port_needs_uptime, port_needs_capacity, 0);
|
||||
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Third, see if we need any more hidden service (server) circuits. */
|
||||
if (num_rend_services() && num_uptime_internal < 3) {
|
||||
flags = (CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_NEED_UPTIME |
|
||||
CIRCLAUNCH_IS_INTERNAL);
|
||||
log_info(LD_CIRC,
|
||||
"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, 0, NULL,
|
||||
1, 1, 1);
|
||||
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -426,12 +431,16 @@ circuit_predict_and_launch_new(void)
|
||||
&hidserv_needs_capacity) &&
|
||||
((num_uptime_internal<2 && hidserv_needs_uptime) ||
|
||||
num_internal<2)) {
|
||||
if (hidserv_needs_uptime)
|
||||
flags |= CIRCLAUNCH_NEED_UPTIME;
|
||||
if (hidserv_needs_capacity)
|
||||
flags |= CIRCLAUNCH_NEED_CAPACITY;
|
||||
flags |= CIRCLAUNCH_IS_INTERNAL;
|
||||
log_info(LD_CIRC,
|
||||
"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, 0, NULL,
|
||||
hidserv_needs_uptime, hidserv_needs_capacity, 1);
|
||||
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -469,7 +478,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, 0, NULL, 0, 0, 0);
|
||||
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -798,34 +807,33 @@ 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, int onehop_tunnel,
|
||||
routerinfo_t *exit, int need_uptime,
|
||||
int need_capacity, int internal)
|
||||
circuit_launch_by_router(uint8_t purpose,
|
||||
routerinfo_t *exit, int flags)
|
||||
{
|
||||
origin_circuit_t *circ;
|
||||
extend_info_t *info = NULL;
|
||||
if (exit)
|
||||
info = extend_info_from_router(exit);
|
||||
circ = circuit_launch_by_extend_info(
|
||||
purpose, onehop_tunnel, info, need_uptime, need_capacity, internal);
|
||||
circ = circuit_launch_by_extend_info(purpose, info, flags);
|
||||
if (info)
|
||||
extend_info_free(info);
|
||||
return circ;
|
||||
}
|
||||
|
||||
/** Launch a new circuit with purpose <b>purpose</b> and exit node
|
||||
* <b>extend_info</b> (or NULL to select a random exit node).
|
||||
* If <b>need_uptime</b> is true,
|
||||
* choose among routers with high uptime. If <b>need_capacity</b> is true,
|
||||
* choose among routers with high bandwidth. If <b>internal</b> is true, the
|
||||
* last hop need not be an exit node. Return the newly allocated circuit on
|
||||
* success, or NULL on failure. */
|
||||
* <b>extend_info</b> (or NULL to select a random exit node). If flags
|
||||
* contains CIRCLAUNCH_NEED_UPTIME, choose among routers with high uptime. If
|
||||
* CIRCLAUNCH_NEED_CAPACITY is set, choose among routers with high bandwidth.
|
||||
* If CIRCLAUNCH_IS_INTERNAL is true, the last hop need not be an exit node.
|
||||
* If CIRCLAUNCH_ONEHOP_TUNNEL is set, the circuit will have only one hop.
|
||||
* Return the newly allocated circuit on success, or NULL on failure. */
|
||||
origin_circuit_t *
|
||||
circuit_launch_by_extend_info(uint8_t purpose, int onehop_tunnel,
|
||||
extend_info_t *extend_info, int need_uptime,
|
||||
int need_capacity, int internal)
|
||||
circuit_launch_by_extend_info(uint8_t purpose,
|
||||
extend_info_t *extend_info,
|
||||
int flags)
|
||||
{
|
||||
origin_circuit_t *circ;
|
||||
int onehop_tunnel = flags & CIRCLAUNCH_ONEHOP_TUNNEL;
|
||||
|
||||
if (!onehop_tunnel && !router_have_minimum_dir_info()) {
|
||||
log_debug(LD_CIRC,"Haven't fetched enough directory info yet; canceling "
|
||||
@ -838,8 +846,7 @@ circuit_launch_by_extend_info(uint8_t purpose, int onehop_tunnel,
|
||||
/* see if there are appropriate circs available to cannibalize. */
|
||||
/* XXX020 if we're planning to add a hop, perhaps we want to look for
|
||||
* internal circs rather than exit circs? -RD */
|
||||
circ = circuit_find_to_cannibalize(purpose, extend_info,
|
||||
need_uptime, need_capacity, internal);
|
||||
circ = circuit_find_to_cannibalize(purpose, extend_info, flags);
|
||||
if (circ) {
|
||||
log_info(LD_CIRC,"Cannibalizing circ '%s' for purpose %d",
|
||||
build_state_get_exit_nickname(circ->build_state), purpose);
|
||||
@ -881,16 +888,14 @@ circuit_launch_by_extend_info(uint8_t purpose, int onehop_tunnel,
|
||||
|
||||
/* try a circ. if it fails, circuit_mark_for_close will increment
|
||||
* n_circuit_failures */
|
||||
return circuit_establish_circuit(purpose, onehop_tunnel, extend_info,
|
||||
need_uptime, need_capacity, internal);
|
||||
return circuit_establish_circuit(purpose, extend_info, flags);
|
||||
}
|
||||
|
||||
/** Launch a new circuit; see circuit_launch_by_extend_info() for
|
||||
* details on arguments. */
|
||||
origin_circuit_t *
|
||||
circuit_launch_by_nickname(uint8_t purpose, int onehop_tunnel,
|
||||
const char *exit_nickname,
|
||||
int need_uptime, int need_capacity, int internal)
|
||||
circuit_launch_by_nickname(uint8_t purpose,
|
||||
const char *exit_nickname, int flags)
|
||||
{
|
||||
routerinfo_t *router = NULL;
|
||||
|
||||
@ -902,8 +907,7 @@ circuit_launch_by_nickname(uint8_t purpose, int onehop_tunnel,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return circuit_launch_by_router(purpose, onehop_tunnel, router,
|
||||
need_uptime, need_capacity, internal);
|
||||
return circuit_launch_by_router(purpose, router, flags);
|
||||
}
|
||||
|
||||
/** Record another failure at opening a general circuit. When we have
|
||||
@ -1085,9 +1089,15 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
||||
else
|
||||
new_circ_purpose = desired_circuit_purpose;
|
||||
|
||||
circ = circuit_launch_by_extend_info(
|
||||
new_circ_purpose, want_onehop, extend_info,
|
||||
need_uptime, 1, need_internal);
|
||||
{
|
||||
int flags = CIRCLAUNCH_NEED_CAPACITY;
|
||||
if (want_onehop) flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
|
||||
if (need_uptime) flags |= CIRCLAUNCH_NEED_UPTIME;
|
||||
if (need_internal) flags |= CIRCLAUNCH_IS_INTERNAL;
|
||||
circ = circuit_launch_by_extend_info(new_circ_purpose, extend_info,
|
||||
flags);
|
||||
}
|
||||
|
||||
if (extend_info)
|
||||
extend_info_free(extend_info);
|
||||
|
||||
|
@ -2019,7 +2019,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
|
||||
|
||||
if (zero_circ) {
|
||||
/* start a new circuit */
|
||||
circ = origin_circuit_init(intended_purpose, 0, 0, 0, 0);
|
||||
circ = origin_circuit_init(intended_purpose, 0);
|
||||
}
|
||||
|
||||
/* now circ refers to something that is ready to be extended */
|
||||
|
40
src/or/or.h
40
src/or/or.h
@ -2473,13 +2473,10 @@ char *circuit_list_path_for_controller(origin_circuit_t *circ);
|
||||
void circuit_log_path(int severity, unsigned int domain,
|
||||
origin_circuit_t *circ);
|
||||
void circuit_rep_hist_note_result(origin_circuit_t *circ);
|
||||
origin_circuit_t *origin_circuit_init(uint8_t purpose, int onehop_tunnel,
|
||||
int need_uptime,
|
||||
int need_capacity, int internal);
|
||||
origin_circuit_t *origin_circuit_init(uint8_t purpose, int flags);
|
||||
origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
|
||||
int onehop_tunnel, extend_info_t *exit,
|
||||
int need_uptime, int need_capacity,
|
||||
int internal);
|
||||
extend_info_t *exit,
|
||||
int flags);
|
||||
int circuit_handle_first_hop(origin_circuit_t *circ);
|
||||
void circuit_n_conn_done(or_connection_t *or_conn, int status);
|
||||
int inform_testing_reachability(void);
|
||||
@ -2556,9 +2553,7 @@ origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
|
||||
or_circuit_t *circuit_get_rendezvous(const char *cookie);
|
||||
or_circuit_t *circuit_get_intro_point(const char *digest);
|
||||
origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose,
|
||||
extend_info_t *info,
|
||||
int need_uptime,
|
||||
int need_capacity, int internal);
|
||||
extend_info_t *info, int flags);
|
||||
void circuit_mark_all_unused_circs(void);
|
||||
void circuit_expire_all_dirty_circs(void);
|
||||
void _circuit_mark_for_close(circuit_t *circ, int reason,
|
||||
@ -2590,21 +2585,24 @@ int circuit_enough_testing_circs(void);
|
||||
|
||||
void circuit_has_opened(origin_circuit_t *circ);
|
||||
void circuit_build_failed(origin_circuit_t *circ);
|
||||
|
||||
/** Flag to set when a circuit should have only a single hop. */
|
||||
#define CIRCLAUNCH_ONEHOP_TUNNEL (1<<0)
|
||||
/** Flag to set when a circuit needs to be built of high-uptime nodes */
|
||||
#define CIRCLAUNCH_NEED_UPTIME (1<<1)
|
||||
/** Flag to set when a circuit needs to be build of high-capcity nodes */
|
||||
#define CIRCLAUNCH_NEED_CAPACITY (1<<2)
|
||||
/** Flag to set when the last hop of a circuit doesn't need to be an
|
||||
* exit node. */
|
||||
#define CIRCLAUNCH_IS_INTERNAL (1<<3)
|
||||
origin_circuit_t *circuit_launch_by_nickname(uint8_t purpose,
|
||||
int onehop_tunnel,
|
||||
const char *exit_nickname,
|
||||
int need_uptime, int need_capacity,
|
||||
int is_internal);
|
||||
const char *exit_nickname,
|
||||
int flags);
|
||||
origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
|
||||
int onehop_tunnel,
|
||||
extend_info_t *info,
|
||||
int need_uptime, int need_capacity,
|
||||
int is_internal);
|
||||
extend_info_t *info,
|
||||
int flags);
|
||||
origin_circuit_t *circuit_launch_by_router(uint8_t purpose,
|
||||
int onehop_tunnel,
|
||||
routerinfo_t *exit,
|
||||
int need_uptime, int need_capacity,
|
||||
int is_internal);
|
||||
routerinfo_t *exit, int flags);
|
||||
void circuit_reset_failure_count(int timeout);
|
||||
int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
|
||||
origin_circuit_t *circ,
|
||||
|
@ -647,9 +647,10 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
|
||||
/* Launch a circuit to alice's chosen rendezvous point.
|
||||
*/
|
||||
for (i=0;i<MAX_REND_FAILURES;i++) {
|
||||
int flags = CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_IS_INTERNAL;
|
||||
if (circ_needs_uptime) flags |= CIRCLAUNCH_NEED_UPTIME;
|
||||
launched = circuit_launch_by_extend_info(
|
||||
CIRCUIT_PURPOSE_S_CONNECT_REND, 0, extend_info,
|
||||
circ_needs_uptime, 1, 1);
|
||||
CIRCUIT_PURPOSE_S_CONNECT_REND, extend_info, flags);
|
||||
|
||||
if (launched)
|
||||
break;
|
||||
@ -728,8 +729,10 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
|
||||
log_info(LD_REND,"Reattempting rendezvous circuit to '%s'",
|
||||
oldstate->chosen_exit->nickname);
|
||||
|
||||
newcirc = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND, 0,
|
||||
oldstate->chosen_exit, 0, 1, 1);
|
||||
newcirc = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND,
|
||||
oldstate->chosen_exit,
|
||||
CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
|
||||
|
||||
if (!newcirc) {
|
||||
log_warn(LD_REND,"Couldn't relaunch rendezvous circuit to '%s'.",
|
||||
oldstate->chosen_exit->nickname);
|
||||
@ -769,7 +772,9 @@ rend_service_launch_establish_intro(rend_service_t *service,
|
||||
|
||||
++service->n_intro_circuits_launched;
|
||||
launched = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO,
|
||||
0, intro->extend_info, 1, 0, 1);
|
||||
intro->extend_info,
|
||||
CIRCLAUNCH_NEED_UPTIME|CIRCLAUNCH_IS_INTERNAL);
|
||||
|
||||
if (!launched) {
|
||||
log_info(LD_REND,
|
||||
"Can't launch circuit to establish introduction at %s.",
|
||||
|
@ -699,7 +699,8 @@ consider_testing_reachability(int test_or, int test_dir)
|
||||
log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
|
||||
!orport_reachable ? "reachability" : "bandwidth",
|
||||
me->address, me->or_port);
|
||||
circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, 0, me, 0, 1, 1);
|
||||
circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me,
|
||||
CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
|
||||
control_event_server_status(LOG_NOTICE,
|
||||
"CHECKING_REACHABILITY ORADDRESS=%s:%d",
|
||||
me->address, me->or_port);
|
||||
|
Loading…
Reference in New Issue
Block a user