Macros | Functions
circuitbuild.c File Reference
#include "core/or/or.h"
#include "app/config/config.h"
#include "lib/confmgt/confparse.h"
#include "core/crypto/hs_ntor.h"
#include "core/crypto/onion_crypto.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_tap.h"
#include "core/crypto/relay_crypto.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/mainloop.h"
#include "core/or/channel.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuitstats.h"
#include "core/or/circuituse.h"
#include "core/or/circuitpadding.h"
#include "core/or/command.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
#include "core/or/onion.h"
#include "core/or/ocirc_event.h"
#include "core/or/policies.h"
#include "core/or/relay.h"
#include "core/or/crypt_path.h"
#include "feature/client/bridges.h"
#include "feature/client/circpathbias.h"
#include "feature/client/entrynodes.h"
#include "feature/client/transports.h"
#include "feature/control/control_events.h"
#include "feature/dircommon/directory.h"
#include "feature/nodelist/describe.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nickname.h"
#include "feature/nodelist/node_select.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
#include "feature/relay/router.h"
#include "feature/relay/routermode.h"
#include "feature/relay/selftest.h"
#include "feature/rend/rendcommon.h"
#include "feature/stats/predict_ports.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "core/or/cell_st.h"
#include "core/or/cpath_build_state_st.h"
#include "core/or/entry_connection_st.h"
#include "core/or/extend_info_st.h"
#include "feature/nodelist/node_st.h"
#include "core/or/or_circuit_st.h"
#include "core/or/origin_circuit_st.h"
#include "feature/nodelist/microdesc_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerstatus_st.h"

Go to the source code of this file.




static channel_tchannel_connect_for_circuit (const tor_addr_t *addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id)
static int circuit_deliver_create_cell (circuit_t *circ, const create_cell_t *create_cell, int relayed)
static int circuit_send_first_onion_skin (origin_circuit_t *circ)
static int circuit_build_no_more_hops (origin_circuit_t *circ)
static int circuit_send_intermediate_onion_skin (origin_circuit_t *circ, crypt_path_t *hop)
static const node_tchoose_good_middle_server (uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
STATIC circid_t get_unique_circ_id_by_chan (channel_t *chan)
static char * circuit_list_path_impl (origin_circuit_t *circ, int verbose, int verbose_names)
char * circuit_list_path (origin_circuit_t *circ, int verbose)
char * circuit_list_path_for_controller (origin_circuit_t *circ)
void circuit_log_path (int severity, unsigned int domain, origin_circuit_t *circ)
static int circuit_cpath_supports_ntor (const origin_circuit_t *circ)
static int onion_populate_cpath (origin_circuit_t *circ)
origin_circuit_torigin_circuit_init (uint8_t purpose, int flags)
origin_circuit_tcircuit_establish_circuit (uint8_t purpose, extend_info_t *exit_ei, int flags)
circuit_guard_state_t * origin_circuit_get_guard_state (origin_circuit_t *circ)
static void circuit_chan_publish (const origin_circuit_t *circ, const channel_t *chan)
int circuit_handle_first_hop (origin_circuit_t *circ)
void circuit_n_chan_done (channel_t *chan, int status, int close_origin_circuits)
int inform_testing_reachability (void)
static int should_use_create_fast_for_circuit (origin_circuit_t *circ)
int circuit_timeout_want_to_count_circ (const origin_circuit_t *circ)
static void circuit_pick_create_handshake (uint8_t *cell_type_out, uint16_t *handshake_type_out, const extend_info_t *ei)
static void circuit_pick_extend_handshake (uint8_t *cell_type_out, uint8_t *create_cell_type_out, uint16_t *handshake_type_out, const extend_info_t *ei)
static int circuit_purpose_may_omit_guard (int purpose)
int circuit_send_next_onion_skin (origin_circuit_t *circ)
void circuit_note_clock_jumped (int64_t seconds_elapsed, bool was_idle)
int circuit_extend (cell_t *cell, circuit_t *circ)
int circuit_finish_handshake (origin_circuit_t *circ, const created_cell_t *reply)
int circuit_truncated (origin_circuit_t *circ, int reason)
int onionskin_answer (or_circuit_t *circ, const created_cell_t *created_cell, const char *keys, size_t keys_len, const uint8_t *rend_circ_nonce)
int route_len_for_purpose (uint8_t purpose, extend_info_t *exit_ei)
STATIC int new_route_len (uint8_t purpose, extend_info_t *exit_ei, const smartlist_t *nodes)
static smartlist_tcircuit_get_unhandled_ports (time_t now)
 MOCK_IMPL (int, circuit_all_predicted_ports_handled,(time_t now, int *need_uptime, int *need_capacity))
static int node_handles_some_port (const node_t *node, smartlist_t *needed_ports)
static int ap_stream_wants_exit_attention (connection_t *conn)
static const node_tchoose_good_exit_server_general (router_crn_flags_t flags)
static const node_tpick_rendezvous_node (router_crn_flags_t flags)
static const node_tpick_restricted_middle_node (router_crn_flags_t flags, const routerset_t *pick_from, const routerset_t *exclude_set, const smartlist_t *exclude_list, int position_hint)
static const node_tchoose_good_exit_server (origin_circuit_t *circ, router_crn_flags_t flags, int is_internal)
static void warn_if_last_router_excluded (origin_circuit_t *circ, const extend_info_t *exit_ei)
STATIC int onion_pick_cpath_exit (origin_circuit_t *circ, extend_info_t *exit_ei, int is_hs_v3_rp_circuit)
int circuit_append_new_exit (origin_circuit_t *circ, extend_info_t *exit_ei)
int circuit_extend_to_new_exit (origin_circuit_t *circ, extend_info_t *exit_ei)
 MOCK_IMPL (STATIC int, count_acceptable_nodes,(const smartlist_t *nodes, int direct))
static smartlist_tbuild_vanguard_middle_exclude_list (uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
static smartlist_tbuild_middle_exclude_list (uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
static int middle_node_must_be_vanguard (const or_options_t *options, uint8_t purpose, int cur_len)
static const node_tpick_vanguard_middle_node (const or_options_t *options, router_crn_flags_t flags, int cur_len, const smartlist_t *excluded)
const node_tchoose_good_entry_server (uint8_t purpose, cpath_build_state_t *state, circuit_guard_state_t **guard_state_out)
STATIC int onion_extend_cpath (origin_circuit_t *circ)
extend_info_textend_info_new (const char *nickname, const char *rsa_id_digest, const ed25519_public_key_t *ed_id, crypto_pk_t *onion_key, const curve25519_public_key_t *ntor_key, const tor_addr_t *addr, uint16_t port)
extend_info_textend_info_from_node (const node_t *node, int for_direct_connect)
void extend_info_free_ (extend_info_t *info)
extend_info_textend_info_dup (extend_info_t *info)
const node_tbuild_state_get_exit_node (cpath_build_state_t *state)
const uint8_t * build_state_get_exit_rsa_id (cpath_build_state_t *state)
const char * build_state_get_exit_nickname (cpath_build_state_t *state)
int extend_info_addr_is_allowed (const tor_addr_t *addr)
int extend_info_supports_tap (const extend_info_t *ei)
int extend_info_supports_ntor (const extend_info_t *ei)
static int circuit_purpose_can_use_tap_impl (uint8_t purpose)
int circuit_can_use_tap (const origin_circuit_t *circ)
int circuit_has_usable_onion_key (const origin_circuit_t *circ)
int extend_info_has_preferred_onion_key (const extend_info_t *ei)
void circuit_upgrade_circuits_from_guard_wait (void)

Detailed Description

Implements the details of building circuits (by chosing paths, constructing/sending create/extend cells, and so on).

On the client side, this module handles launching circuits. Circuit launches are srtarted from circuit_establish_circuit(), called from circuit_launch_by_extend_info()). To choose the path the circuit will take, onion_extend_cpath() calls into a maze of node selection functions.

Once the circuit is ready to be launched, the first hop is treated as a special case with circuit_handle_first_hop(), since it might need to open a channel. As the channel opens, and later as CREATED and RELAY_EXTENDED cells arrive, the client will invoke circuit_send_next_onion_skin() to send CREATE or RELAY_EXTEND cells.

On the server side, this module also handles the logic of responding to RELAY_EXTEND requests, using circuit_extend().

Definition in file circuitbuild.c.

Function Documentation

◆ ap_stream_wants_exit_attention()

static int ap_stream_wants_exit_attention ( connection_t conn)

Return true iff conn needs another general circuit to be built.

Definition at line 1751 of file circuitbuild.c.

References CONN_TYPE_AP, and connection_t::type.

◆ build_middle_exclude_list()

static smartlist_t* build_middle_exclude_list ( uint8_t  purpose,
cpath_build_state_t state,
crypt_path_t head,
int  cur_len 

Build a list of nodes to exclude from the choice of this middle hop, based on already chosen nodes.

Vanguard circuits have their own path selection rules

Definition at line 2414 of file circuitbuild.c.

References build_state_get_exit_node(), build_vanguard_middle_exclude_list(), circuit_should_use_vanguards(), crypt_path_t::next, and nodelist_add_node_and_family().

◆ build_state_get_exit_nickname()

const char* build_state_get_exit_nickname ( cpath_build_state_t state)

Return the nickname for the chosen exit router in state. If there is no chosen exit, or if we don't know the routerinfo_t for the chosen exit, return NULL.

Definition at line 2846 of file circuitbuild.c.

References cpath_build_state_t::chosen_exit, and extend_info_t::nickname.

Referenced by circuit_list_path_impl().

◆ build_state_get_exit_node()

const node_t* build_state_get_exit_node ( cpath_build_state_t state)

Return the node_t for the chosen exit router in state. If there is no chosen exit, or if we don't know the node_t for the chosen exit, return NULL.

Definition at line 2823 of file circuitbuild.c.

References cpath_build_state_t::chosen_exit, and extend_info_t::identity_digest.

Referenced by build_middle_exclude_list(), build_vanguard_middle_exclude_list(), circuit_is_acceptable(), and circuit_stream_is_being_handled().

◆ build_state_get_exit_rsa_id()

const uint8_t* build_state_get_exit_rsa_id ( cpath_build_state_t state)

Return the RSA ID digest for the chosen exit router in state. If there is no chosen exit, return NULL.

Definition at line 2834 of file circuitbuild.c.

References cpath_build_state_t::chosen_exit, and extend_info_t::identity_digest.

Referenced by guards_choose_guard().

◆ build_vanguard_middle_exclude_list()

static smartlist_t* build_vanguard_middle_exclude_list ( uint8_t  purpose,
cpath_build_state_t state,
crypt_path_t head,
int  cur_len 

Build the exclude list for vanguard circuits.

For vanguard circuits we exclude all the already chosen nodes (including the exit) from being middle hops to prevent the creation of A - B - A subpaths. We also allow the 4th hop to be the same as the guard node so as to not leak guard information to RP/IP/HSDirs.

For vanguard circuits, we don't apply any subnet or family restrictions. This is to avoid impossible-to-build circuit paths, or just situations where our earlier guards prevent us from using most of our later ones.

The alternative is building the circuit in reverse. Reverse calls to onion_extend_cpath() (ie: select outer hops first) would then have the property that you don't gain information about inner hops by observing outer ones. See for this.

(Note further that we still exclude the exit to prevent A - B - A at the end of the path.

Definition at line 2367 of file circuitbuild.c.

References build_state_get_exit_node(), DEFAULT_ROUTE_LEN, crypt_path_t::next, and smartlist_add().

Referenced by build_middle_exclude_list().

◆ channel_connect_for_circuit()

static channel_t * channel_connect_for_circuit ( const tor_addr_t addr,
uint16_t  port,
const char *  id_digest,
const ed25519_public_key_t ed_id 

This function tries to get a channel to the specified endpoint, and then calls command_setup_channel() to give it the right callbacks.

Definition at line 108 of file circuitbuild.c.

References channel_connect(), and command_setup_channel().

◆ choose_good_entry_server()

const node_t* choose_good_entry_server ( uint8_t  purpose,
cpath_build_state_t state,
circuit_guard_state_t **  guard_state_out 

Pick a good entry server for the circuit to be built according to state. Don't reuse a chosen exit (if any), don't use this router (if we're an OR), and respect firewall settings; if we're configured to use entry guards, return one.

Set *guard_state_out to information about the guard that we're selecting, which we'll use later to remember whether the guard worked or not.

Definition at line 2575 of file circuitbuild.c.

◆ choose_good_exit_server()

static const node_t* choose_good_exit_server ( origin_circuit_t circ,
router_crn_flags_t  flags,
int  is_internal 

Return a pointer to a suitable router to be the exit node for the circuit of purpose purpose that we're about to build (or NULL if no router is suitable).

For general-purpose circuits, pass it off to choose_good_exit_server_general()

For client-side rendezvous circuits, choose a random node, weighted toward the preferences in 'options'.

Definition at line 2098 of file circuitbuild.c.

◆ choose_good_exit_server_general()

static const node_t* choose_good_exit_server_general ( router_crn_flags_t  flags)

Return a pointer to a suitable router to be the exit node for the general-purpose circuit we're about to build.

Look through the connection array, and choose a router that maximizes the number of pending streams that can exit from this router.

Return NULL if we can't find any suitable routers.

Definition at line 1779 of file circuitbuild.c.

◆ choose_good_middle_server()

static const node_t * choose_good_middle_server ( uint8_t  purpose,
cpath_build_state_t state,
crypt_path_t head,
int  cur_len 

A helper function used by onion_extend_cpath(). Use purpose and state and the cpath head (currently populated only to length cur_len to decide a suitable middle hop for a circuit. In particular, make sure we don't pick the exit node or its family, and make sure we don't duplicate any previous nodes or their families.

If a hidden service circuit wants a specific middle node, pin it.

Definition at line 2513 of file circuitbuild.c.

◆ circuit_append_new_exit()

int circuit_append_new_exit ( origin_circuit_t circ,
extend_info_t exit_ei 

Give circ a new exit destination to exit, and add a hop to the cpath reflecting this. Don't send the next extend cell – the caller will do this if it wants to.

Definition at line 2269 of file circuitbuild.c.

References origin_circuit_t::build_state, and tor_assert().

Referenced by circuit_extend_to_new_exit().

◆ circuit_build_no_more_hops()

static int circuit_build_no_more_hops ( origin_circuit_t circ)

Called from circuit_send_next_onion_skin() when we find that we have no more hops: mark the circuit as finished, and perform the necessary bookkeeping. Return 0 on success; -reason on failure (if the circuit should be torn down).

Definition at line 1035 of file circuitbuild.c.

References circuit_get_cpath_len(), circuit_purpose_may_omit_guard(), origin_circuit_t::guard_state, and circuit_t::purpose.

Referenced by circuit_send_next_onion_skin().

◆ circuit_chan_publish()

static void circuit_chan_publish ( const origin_circuit_t circ,
const channel_t chan 

Helper function to publish a channel association message

circuit_handle_first_hop() calls this to notify subscribers about a channel launch event, which associates a circuit with a channel. This doesn't always correspond to an assignment of the circuit's n_chan field, because that seems to be only for fully-open channels.

Definition at line 523 of file circuitbuild.c.

◆ circuit_cpath_supports_ntor()

static int circuit_cpath_supports_ntor ( const origin_circuit_t circ)

Return 1 iff every node in circ's cpath definitely supports ntor.

Definition at line 366 of file circuitbuild.c.

References origin_circuit_t::cpath, and crypt_path_t::extend_info.

◆ circuit_deliver_create_cell()

static int circuit_deliver_create_cell ( circuit_t circ,
const create_cell_t create_cell,
int  relayed 

Find a new circid that isn't currently in use on the circ->n_chan for the outgoing circuit circ, and deliver the cell create_cell to this circuit. If relayed is true, this is a create cell somebody gave us via an EXTEND cell, so we shouldn't worry if we don't understand it. Return -1 if we failed to find a suitable circid, else return 0.

Definition at line 711 of file circuitbuild.c.

References create_cell_t::cell_type, circuit_t::n_chan, and tor_assert().

◆ circuit_establish_circuit()

origin_circuit_t* circuit_establish_circuit ( uint8_t  purpose,
extend_info_t exit_ei,
int  flags 

Build a new circuit for purpose. If exit is defined, then use that as your exit router, else choose a suitable exit node.

Also launch a connection to the first OR in the chosen path, if it's not open already.

Definition at line 479 of file circuitbuild.c.

References CIRCLAUNCH_IS_V3_RP, onion_pick_cpath_exit(), onion_populate_cpath(), and origin_circuit_init().

◆ circuit_extend()

int circuit_extend ( cell_t cell,
circuit_t circ 

Take the 'extend' cell, pull out addr/port plus the onion skin and identity digest for the next hop. If we're already connected, pass the onion skin to the next hop using a create cell; otherwise launch a new OR connection, and circ will notice when the connection succeeds or fails.

Return -1 if we want to warn and tear down the circuit, else return 0.

Definition at line 1212 of file circuitbuild.c.

References log_fn, and circuit_t::n_chan.

◆ circuit_extend_to_new_exit()

int circuit_extend_to_new_exit ( origin_circuit_t circ,
extend_info_t exit_ei 

Take an open circ, and add a new hop at the end, based on info. Set its state back to CIRCUIT_STATE_BUILDING, and then send the next extend cell to begin connecting to that hop.

Definition at line 2290 of file circuitbuild.c.

References circuit_append_new_exit(), circuit_send_next_onion_skin(), circuit_set_state(), CIRCUIT_STATE_BUILDING, circuit_t::timestamp_began, TO_CIRCUIT, and warn_if_last_router_excluded().

◆ circuit_finish_handshake()

int circuit_finish_handshake ( origin_circuit_t circ,
const created_cell_t reply 

A "created" cell reply came back to us on circuit circ. (The body of reply varies depending on what sort of handshake this is.)

Calculate the appropriate keys and digests, make sure KH is correct, and initialize this hop of the cpath.

Return - reason if we want to mark circ for close, else return 0.

Definition at line 1371 of file circuitbuild.c.

◆ circuit_get_unhandled_ports()

static smartlist_t* circuit_get_unhandled_ports ( time_t  now)

Return a newly allocated list of uint16_t * for each predicted port not handled by a current circuit.

Definition at line 1687 of file circuitbuild.c.

References circuit_remove_handled_ports(), and rep_hist_get_predicted_ports().

Referenced by MOCK_IMPL().

◆ circuit_handle_first_hop()

int circuit_handle_first_hop ( origin_circuit_t circ)

Start establishing the first hop of our circuit. Figure out what OR we should connect to, and if necessary start the connection to it. If we're already connected, then send the 'create' cell. Return 0 for ok, -reason if circ should be marked-for-close.

Definition at line 539 of file circuitbuild.c.

References origin_circuit_t::cpath, cpath_get_next_non_open_hop(), crypt_path_t::extend_info, and tor_assert().

◆ circuit_list_path()

char* circuit_list_path ( origin_circuit_t circ,
int  verbose 

If verbose is false, allocate and return a comma-separated list of the currently built elements of circ. If verbose is true, also list information about link status in a more verbose format using spaces.

Definition at line 338 of file circuitbuild.c.

References circuit_list_path_impl().

Referenced by circuit_log_path().

◆ circuit_list_path_for_controller()

char* circuit_list_path_for_controller ( origin_circuit_t circ)

Allocate and return a comma-separated list of the currently built elements of circ, giving each as a verbose nickname.

Definition at line 347 of file circuitbuild.c.

References circuit_list_path_impl().

Referenced by circuit_describe_status_for_controller().

◆ circuit_list_path_impl()

static char* circuit_list_path_impl ( origin_circuit_t circ,
int  verbose,
int  verbose_names 

If verbose is false, allocate and return a comma-separated list of the currently built elements of circ. If verbose is true, also list information about link status in a more verbose format using spaces. If verbose_names is false, give hex digests; if verbose_names is true, use $DIGEST=Name style names.

Definition at line 264 of file circuitbuild.c.

References origin_circuit_t::build_state, build_state_get_exit_nickname(), CIRCUIT_STATE_OPEN, origin_circuit_t::cpath, cpath_build_state_t::desired_path_len, crypt_path_t::extend_info, extend_info_t::identity_digest, cpath_build_state_t::is_internal, cpath_build_state_t::need_uptime, smartlist_add_asprintf(), crypt_path_t::state, and circuit_t::state.

Referenced by circuit_list_path(), and circuit_list_path_for_controller().

◆ circuit_log_path()

void circuit_log_path ( int  severity,
unsigned int  domain,
origin_circuit_t circ 

Log, at severity severity, the nicknames of each router in circ's cpath. Also log the length of the cpath, and the intended exit point.

Definition at line 357 of file circuitbuild.c.

References circuit_list_path(), tor_free, and tor_log().

◆ circuit_n_chan_done()

void circuit_n_chan_done ( channel_t chan,
int  status,
int  close_origin_circuits 

Find any circuits that are waiting on or_conn to become open and get them to send their create cells forward.

Status is 1 if connect succeeded, or 0 if connect failed.

Close_origin_circuits is 1 if we should close all the origin circuits through this channel, or 0 otherwise. (This happens when we want to retry an older guard.)

Definition at line 627 of file circuitbuild.c.

◆ circuit_note_clock_jumped()

void circuit_note_clock_jumped ( int64_t  seconds_elapsed,
bool  was_idle 

Our clock just jumped by seconds_elapsed. If was_idle is true, then the monotonic time matches; otherwise it doesn't. Assume something has also gone wrong with our network: notify the user, and abandon all not-yet-used circuits.

Definition at line 1173 of file circuitbuild.c.

References circuit_mark_all_dirty_circs_as_unusable(), circuit_mark_all_unused_circs(), control_event_client_status(), control_event_general_status(), LD_GENERAL, LOG_NOTICE, LOG_WARN, note_that_we_maybe_cant_complete_circuits(), reset_all_main_loop_timers(), and tor_log().

◆ circuit_pick_create_handshake()

static void circuit_pick_create_handshake ( uint8_t *  cell_type_out,
uint16_t *  handshake_type_out,
const extend_info_t ei 

Decide whether to use a TAP or ntor handshake for connecting to ei directly, and set *cell_type_out and *handshake_type_out accordingly. Note that TAP handshakes in CREATE cells are only used for direct connections:

  • from Single Onions to rend points not in the service's consensus. This is checked in onion_populate_cpath.

Definition at line 856 of file circuitbuild.c.

Referenced by circuit_pick_extend_handshake().

◆ circuit_pick_extend_handshake()

static void circuit_pick_extend_handshake ( uint8_t *  cell_type_out,
uint8_t *  create_cell_type_out,
uint16_t *  handshake_type_out,
const extend_info_t ei 

Decide whether to use a TAP or ntor handshake for extending to ei and set *handshake_type_out accordingly. Decide whether we should use an EXTEND2 or an EXTEND cell to do so, and set *cell_type_out and *create_cell_type_out accordingly. Note that TAP handshakes in EXTEND cells are only used:

  • from clients to intro points, and
  • from hidden services to rend points. This is checked in onion_populate_cpath.

Definition at line 882 of file circuitbuild.c.

References circuit_pick_create_handshake().

◆ circuit_purpose_may_omit_guard()

static int circuit_purpose_may_omit_guard ( int  purpose)

Return true iff purpose is a purpose for a circuit which is allowed to have no guard configured, even if the circuit is multihop and guards are enabled.

Definition at line 908 of file circuitbuild.c.


Referenced by circuit_build_no_more_hops().

◆ circuit_send_first_onion_skin()

static int circuit_send_first_onion_skin ( origin_circuit_t circ)

Called from circuit_send_next_onion_skin() when we find ourselves connected to the first hop in circ: Send a CREATE or CREATE2 or CREATE_FAST cell to that hop. Return 0 on success; -reason on failure (if the circuit should be torn down).

Definition at line 971 of file circuitbuild.c.

Referenced by circuit_send_next_onion_skin().

◆ circuit_send_intermediate_onion_skin()

static int circuit_send_intermediate_onion_skin ( origin_circuit_t circ,
crypt_path_t hop 

Called from circuit_send_next_onion_skin() when we find that we have a hop other than the first that we need to extend to: use hop's information to extend the circuit another step. Return 0 on success; -reason on failure (if the circuit should be torn down).

Definition at line 1109 of file circuitbuild.c.

Referenced by circuit_send_next_onion_skin().

◆ circuit_send_next_onion_skin()

int circuit_send_next_onion_skin ( origin_circuit_t circ)

This is the backbone function for building circuits.

If circ's first hop is closed, then we need to build a create cell and send it forward.

Otherwise, if circ's cpath still has any non-open hops, we need to build a relay extend cell and send it forward to the next non-open hop.

If all hops on the cpath are open, we're done building the circuit and we should do housekeeping for the newly opened circuit.

Return -reason if we want to tear down circ, else return 0.

Definition at line 937 of file circuitbuild.c.

References circpad_machine_event_circ_added_hop(), circpad_machine_event_circ_built(), circuit_build_no_more_hops(), circuit_build_times_handle_completed_hop(), circuit_send_first_onion_skin(), circuit_send_intermediate_onion_skin(), CIRCUIT_STATE_BUILDING, origin_circuit_t::cpath, cpath_get_next_non_open_hop(), crypt_path_t::state, circuit_t::state, and tor_assert().

Referenced by circuit_extend_to_new_exit().

◆ circuit_timeout_want_to_count_circ()

int circuit_timeout_want_to_count_circ ( const origin_circuit_t circ)

Return true if circ is the type of circuit we want to count timeouts from.

In particular, we want to consider any circuit that plans to build at least 3 hops (but maybe more), but has 3 or fewer hops built so far.

We still want to consider circuits before 3 hops, because we need to decide if we should convert them to a measurement circuit in circuit_build_times_handle_completed_hop(), rather than letting slow circuits get killed right away.

Definition at line 841 of file circuitbuild.c.

References origin_circuit_t::build_state, circuit_get_cpath_opened_len(), DEFAULT_ROUTE_LEN, cpath_build_state_t::desired_path_len, and origin_circuit_t::has_opened.

Referenced by circuit_build_times_handle_completed_hop().

◆ circuit_truncated()

int circuit_truncated ( origin_circuit_t circ,
int  reason 

We received a relay truncated cell on circ.

Since we don't send truncates currently, getting a truncated means that a connection broke or an extend failed. For now, just give up: force circ to close, and return 0.

Definition at line 1429 of file circuitbuild.c.

References tor_assert().

◆ circuit_upgrade_circuits_from_guard_wait()

void circuit_upgrade_circuits_from_guard_wait ( void  )

Find the circuits that are waiting to find out whether their guards are usable, and if any are ready to become usable, mark them open and try attaching streams as appropriate.

Definition at line 2937 of file circuitbuild.c.

References circuit_find_circuits_to_upgrade_from_guard_wait().

Referenced by second_elapsed_callback().

◆ extend_info_addr_is_allowed()

int extend_info_addr_is_allowed ( const tor_addr_t addr)

Return true iff the given address can be used to extend to.

Definition at line 2855 of file circuitbuild.c.

References tor_assert().

◆ extend_info_dup()

extend_info_t* extend_info_dup ( extend_info_t info)

Allocate and return a new extend_info_t with the same contents as info.

Definition at line 2805 of file circuitbuild.c.

References tor_assert().

◆ extend_info_free_()

void extend_info_free_ ( extend_info_t info)

Release storage held by an extend_info_t struct.

Definition at line 2794 of file circuitbuild.c.

◆ extend_info_from_node()

extend_info_t* extend_info_from_node ( const node_t node,
int  for_direct_connect 

Allocate and return a new extend_info that can be used to build a circuit to or through the node node. Use the primary address of the node (i.e. its IPv4 address) unless for_direct_connect is true, in which case the preferred address is used instead. May return NULL if there is not enough info about node to extend to it–for example, if the preferred routerinfo_t or microdesc_t is missing, or if for_direct_connect is true and none of the node's addresses is allowed by tor's firewall and IP version config.

Definition at line 2717 of file circuitbuild.c.

References fascist_firewall_choose_address_node(), and node_has_preferred_descriptor().

◆ extend_info_new()

extend_info_t* extend_info_new ( const char *  nickname,
const char *  rsa_id_digest,
const ed25519_public_key_t ed_id,
crypto_pk_t onion_key,
const curve25519_public_key_t ntor_key,
const tor_addr_t addr,
uint16_t  port 

Allocate a new extend_info object based on the various arguments.

Definition at line 2683 of file circuitbuild.c.

◆ get_unique_circ_id_by_chan()

STATIC circid_t get_unique_circ_id_by_chan ( channel_t chan)

Search for a value for circ_id that we can use on chan for an outbound circuit, until we get a circ_id that is not in use by any other circuit on that conn.

Return it, or 0 if can't get a unique circ_id.

Definition at line 127 of file circuitbuild.c.

References channel_s::circ_id_type, CIRC_ID_TYPE_NEITHER, and tor_assert().

◆ inform_testing_reachability()

int inform_testing_reachability ( void  )

We've decided to start our reachability testing. If all is set, log this to the user. Return 1 if we did, or 0 if we chose not to log anything.

Definition at line 774 of file circuitbuild.c.

References routerinfo_t::addr, control_event_server_status(), routerinfo_t::dir_port, LOG_NOTICE, routerinfo_t::or_port, tor_dup_ip(), and tor_snprintf().

◆ middle_node_must_be_vanguard()

static int middle_node_must_be_vanguard ( const or_options_t options,
uint8_t  purpose,
int  cur_len 

Return true if we MUST use vanguards for picking this middle node.

Definition at line 2450 of file circuitbuild.c.

References circuit_purpose_is_hidden_service(), or_options_t::HSLayer2Nodes, and or_options_t::HSLayer3Nodes.

◆ MOCK_IMPL() [1/2]

MOCK_IMPL ( int  ,
circuit_all_predicted_ports_handled  ,
(time_t now, int *need_uptime, int *need_capacity)   

Return 1 if we already have circuits present or on the way for all anticipated ports. Return 0 if we should make more.

If we're returning 0, set need_uptime and need_capacity to indicate any requirements that the unhandled ports have.

Definition at line 1700 of file circuitbuild.c.

References circuit_get_unhandled_ports(), and tor_assert().

◆ MOCK_IMPL() [2/2]

count_acceptable_nodes  ,
(const smartlist_t *nodes, int direct)   

Return the number of routers in routers that are currently up and available for building circuits through.

(Note that this function may overcount or undercount, if we have descriptors that are not the type we would prefer to use for some particular router. See bug #25885.)

Definition at line 2318 of file circuitbuild.c.

◆ new_route_len()

STATIC int new_route_len ( uint8_t  purpose,
extend_info_t exit_ei,
const smartlist_t nodes 

Choose a length for a circuit of purpose purpose and check if enough routers are available.

If the routerlist nodes doesn't have enough routers to handle the desired path length, return -1.

Definition at line 1656 of file circuitbuild.c.

References route_len_for_purpose(), and tor_assert().

◆ node_handles_some_port()

static int node_handles_some_port ( const node_t node,
smartlist_t needed_ports 

Return 1 if node can handle one or more of the ports in needed_ports, else return 0.

Definition at line 1727 of file circuitbuild.c.

◆ onion_extend_cpath()

STATIC int onion_extend_cpath ( origin_circuit_t circ)

Choose a suitable next hop for the circuit circ. Append the hop info to circ->cpath.

Return 1 if the path is complete, 0 if we successfully added a hop, and -1 on error.

Definition at line 2627 of file circuitbuild.c.

References origin_circuit_t::build_state, circuit_get_cpath_len(), cpath_build_state_t::desired_path_len, and circuit_t::purpose.

Referenced by onion_populate_cpath().

◆ onion_pick_cpath_exit()

STATIC int onion_pick_cpath_exit ( origin_circuit_t circ,
extend_info_t exit_ei,
int  is_hs_v3_rp_circuit 

Decide a suitable length for circ's cpath, and pick an exit router (or use exit if provided). Store these in the cpath.

If is_hs_v3_rp_circuit is set, then this exit should be suitable to be used as an HS v3 rendezvous point.

Return 0 if ok, -1 if circuit should be closed.

Definition at line 2218 of file circuitbuild.c.

References origin_circuit_t::build_state, and cpath_build_state_t::onehop_tunnel.

Referenced by circuit_establish_circuit().

◆ onion_populate_cpath()

static int onion_populate_cpath ( origin_circuit_t circ)

Pick all the entries in our cpath. Stop and return 0 when we're happy, or return -1 if an error occurs.

Definition at line 390 of file circuitbuild.c.

References origin_circuit_t::build_state, onion_extend_cpath(), and tor_assert().

Referenced by circuit_establish_circuit().

◆ onionskin_answer()

int onionskin_answer ( or_circuit_t circ,
const created_cell_t created_cell,
const char *  keys,
size_t  keys_len,
const uint8_t *  rend_circ_nonce 

Given a response payload and keys, initialize, then send a created cell back.

Definition at line 1474 of file circuitbuild.c.

References tor_assert().

◆ origin_circuit_get_guard_state()

circuit_guard_state_t* origin_circuit_get_guard_state ( origin_circuit_t circ)

Return the guard state associated with circ, which may be NULL.

Definition at line 508 of file circuitbuild.c.

References origin_circuit_t::guard_state.

Referenced by circ_state_has_higher_priority().

◆ origin_circuit_init()

origin_circuit_t* origin_circuit_init ( uint8_t  purpose,
int  flags 

Create and return a new origin circuit. Initialize its purpose and build-state based on our arguments. The flags argument is a bitfield of CIRCLAUNCH_* flags.

Definition at line 453 of file circuitbuild.c.

References origin_circuit_t::build_state, circuit_set_state(), CIRCUIT_STATE_CHAN_WAIT, origin_circuit_new(), and TO_CIRCUIT.

Referenced by circuit_establish_circuit().

◆ pick_restricted_middle_node()

static const node_t* pick_restricted_middle_node ( router_crn_flags_t  flags,
const routerset_t *  pick_from,
const routerset_t *  exclude_set,
const smartlist_t exclude_list,
int  position_hint 

Max number of restricted nodes before we alert the user and try to load balance for them.

The most aggressive vanguard design had 16 nodes at layer3. Let's give a small ceiling above that.

Definition at line 2009 of file circuitbuild.c.

References router_add_running_nodes_to_smartlist(), and tor_assert().

◆ pick_vanguard_middle_node()

static const node_t* pick_vanguard_middle_node ( const or_options_t options,
router_crn_flags_t  flags,
int  cur_len,
const smartlist_t excluded 

Pick a sticky vanguard middle node or return NULL if not found. See doc of pick_restricted_middle_node() for argument details.

Definition at line 2474 of file circuitbuild.c.

References or_options_t::HSLayer2Nodes, and or_options_t::HSLayer3Nodes.

◆ route_len_for_purpose()

int route_len_for_purpose ( uint8_t  purpose,
extend_info_t exit_ei 

Helper for new_route_len(). Choose a circuit length for purpose purpose: DEFAULT_ROUTE_LEN (+ 1 if someone else chose the exit). If someone else chose the exit, they could be colluding with the exit, so add a randomly selected node to preserve anonymity.

Here, "exit node" sometimes means an OR acting as an internal endpoint, rather than as a relay to an external endpoint. This means there need to be at least DEFAULT_ROUTE_LEN routers between us and the internal endpoint to preserve the same anonymity properties that we would get when connecting to an external endpoint. These internal endpoints can include:

  • Connections to a directory of hidden services (CIRCUIT_PURPOSE_C_GENERAL)
  • A client connecting to an introduction point, which the hidden service picked (CIRCUIT_PURPOSE_C_INTRODUCING, via circuit_get_open_circ_or_launch() which rewrites it from CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT)
  • A hidden service connecting to a rendezvous point, which the client picked (CIRCUIT_PURPOSE_S_CONNECT_REND, via rend_service_receive_introduction() and rend_service_relaunch_rendezvous)

There are currently two situations where we picked the exit node ourselves, making DEFAULT_ROUTE_LEN a safe circuit length:

onion_pick_cpath_exit() bypasses us (by not calling new_route_len()) in the one-hop tunnel case, so we don't need to handle that.

Definition at line 1566 of file circuitbuild.c.


Referenced by new_route_len().

◆ should_use_create_fast_for_circuit()

static int should_use_create_fast_for_circuit ( origin_circuit_t circ)

Return true iff we should send a create_fast cell to start building a given circuit

Definition at line 807 of file circuitbuild.c.

References origin_circuit_t::cpath, crypt_path_t::extend_info, and tor_assert().

◆ warn_if_last_router_excluded()

static void warn_if_last_router_excluded ( origin_circuit_t circ,
const extend_info_t exit_ei 

Log a warning if the user specified an exit for the circuit that has been excluded from use by ExcludeNodes or ExcludeExitNodes.

Definition at line 2134 of file circuitbuild.c.

References origin_circuit_t::build_state, CIRCUIT_PURPOSE_INTRO_POINT, CIRCUIT_PURPOSE_OR, CIRCUIT_PURPOSE_REND_ESTABLISHED, CIRCUIT_PURPOSE_REND_POINT_WAITING, or_options_t::ExcludeNodes, cpath_build_state_t::onehop_tunnel, and circuit_t::purpose.

Referenced by circuit_extend_to_new_exit().