circuitlist.c File Reference

Manage the global circuit list. More...

#include "or.h"
#include "ht.h"

Data Structures

struct  orconn_circid_circuit_map_t

Functions

static void circuit_free (circuit_t *circ)
static void circuit_free_cpath (crypt_path_t *cpath)
static void circuit_free_cpath_node (crypt_path_t *victim)
static INLINE int _orconn_circid_entries_eq (orconn_circid_circuit_map_t *a, orconn_circid_circuit_map_t *b)
static INLINE unsigned int _orconn_circid_entry_hash (orconn_circid_circuit_map_t *a)
static HT_HEAD (HT_PROTOTYPE(orconn_circid_map, HT_PROTOTYPE(orconn_circid_circuit_map_t)
void circuit_set_p_circid_orconn (or_circuit_t *circ, circid_t id, or_connection_t *conn)
void circuit_set_n_circid_orconn (circuit_t *circ, circid_t id, or_connection_t *conn)
void circuit_set_state (circuit_t *circ, uint8_t state)
static void circuit_add (circuit_t *circ)
void circuit_get_all_pending_on_or_conn (smartlist_t *out, or_connection_t *or_conn)
int circuit_count_pending_on_or_conn (or_connection_t *or_conn)
void circuit_close_all_marked (void)
circuit_t_circuit_get_global_list (void)
const char * circuit_state_to_string (int state)
const char * circuit_purpose_to_controller_string (uint8_t purpose)
int32_t circuit_initial_package_window (void)
static void init_circuit_base (circuit_t *circ)
origin_circuit_torigin_circuit_new (void)
or_circuit_tor_circuit_new (circid_t p_circ_id, or_connection_t *p_conn)
void circuit_free_all (void)
static void circuit_dump_details (int severity, circuit_t *circ, int conn_array_index, const char *type, int this_circid, int other_circid)
void circuit_dump_by_conn (connection_t *conn, int severity)
origin_circuit_tcircuit_get_by_global_id (uint32_t id)
static INLINE circuit_tcircuit_get_by_circid_orconn_impl (circid_t circ_id, or_connection_t *conn)
circuit_tcircuit_get_by_circid_orconn (circid_t circ_id, or_connection_t *conn)
int circuit_id_in_use_on_orconn (circid_t circ_id, or_connection_t *conn)
circuit_tcircuit_get_by_edge_conn (edge_connection_t *conn)
void circuit_unlink_all_from_or_conn (or_connection_t *conn, int reason)
origin_circuit_tcircuit_get_by_rend_query_and_purpose (const char *rend_query, uint8_t purpose)
origin_circuit_tcircuit_get_next_by_pk_and_purpose (origin_circuit_t *start, const char *digest, uint8_t purpose)
static or_circuit_tcircuit_get_by_rend_token_and_purpose (uint8_t purpose, const char *token, size_t len)
or_circuit_tcircuit_get_rendezvous (const char *cookie)
or_circuit_tcircuit_get_intro_point (const char *digest)
origin_circuit_tcircuit_find_to_cannibalize (uint8_t purpose, extend_info_t *info, int flags)
int circuit_get_cpath_len (origin_circuit_t *circ)
crypt_path_tcircuit_get_cpath_hop (origin_circuit_t *circ, int hopnum)
void circuit_mark_all_unused_circs (void)
void circuit_expire_all_dirty_circs (void)
void _circuit_mark_for_close (circuit_t *circ, int reason, int line, const char *file)
void assert_cpath_layer_ok (const crypt_path_t *cp)
static void assert_cpath_ok (const crypt_path_t *cp)
void assert_circuit_ok (const circuit_t *c)

Variables

circuit_tglobal_circuitlist = NULL
static smartlist_tcircuits_pending_or_conns = NULL


Detailed Description

Manage the global circuit list.


Function Documentation

circuit_t* _circuit_get_global_list ( void   ) 

void _circuit_mark_for_close ( circuit_t circ,
int  reason,
int  line,
const char *  file 
)

Mark circ to be closed next time we call circuit_close_all_marked(). Do any cleanup needed:

  • If state is onionskin_pending, remove circ from the onion_pending list.
  • If circ isn't open yet: call circuit_build_failed() if we're the origin, and in either case call circuit_rep_hist_note_result() to note stats.
  • If purpose is C_INTRODUCE_ACK_WAIT, remove the intro point we just tried from our list of intro points for that service descriptor.
  • Send appropriate destroys and edge_destroys for conns and streams attached to circ.
  • If circ->rend_splice is set (we are the midpoint of a joined rendezvous stream), then mark the other circuit to close as well.

References or_circuit_t::_base, edge_connection_t::_base, assert_circuit_ok(), origin_circuit_t::build_state, build_state_get_exit_nickname(), cpath_build_state_t::chosen_exit, circuit_build_failed(), CIRCUIT_IS_ORIGIN, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, circuit_rep_hist_note_result(), CIRCUIT_STATE_ONIONSKIN_PENDING, CIRCUIT_STATE_OPEN, CIRCUIT_STATE_OR_WAIT, connection_edge_destroy(), connection_or_send_destroy(), control_event_circuit_status(), edge_connection_t::edge_has_sent_end, END_CIRC_AT_ORIGIN, END_CIRC_REASON_FLAG_REMOTE, edge_connection_t::end_reason, END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED, LD_BUG, LD_REND, connection_t::marked_for_close, circuit_t::marked_for_close, circuit_t::marked_for_close_file, circuit_t::n_circ_id, circuit_t::n_conn, or_circuit_t::n_streams, edge_connection_t::next_stream, edge_connection_t::on_circuit, rend_data_t::onion_address, onion_pending_remove(), or_circuit_t::p_circ_id, or_circuit_t::p_conn, origin_circuit_t::p_streams, circuit_t::purpose, rend_client_remove_intro_point(), origin_circuit_t::rend_data, or_circuit_t::rend_splice, or_circuit_t::resolving_streams, safe_str_client(), smartlist_remove(), circuit_t::state, TO_CIRCUIT, TO_CONN, TO_OR_CIRCUIT(), TO_ORIGIN_CIRCUIT(), and tor_assert.

static INLINE int _orconn_circid_entries_eq ( orconn_circid_circuit_map_t a,
orconn_circid_circuit_map_t b 
) [static]

Helper for hash tables: compare the OR connection and circuit ID for a and b, and return less than, equal to, or greater than zero appropriately.

static INLINE unsigned int _orconn_circid_entry_hash ( orconn_circid_circuit_map_t a  )  [static]

Helper: return a hash based on circuit ID and the pointer value of or_conn in a.

void assert_circuit_ok ( const circuit_t c  ) 

void assert_cpath_layer_ok ( const crypt_path_t cp  ) 

Verify that cpath layer cp has all of its invariants correct. Trigger an assert if anything is invalid.

References crypt_path_t::b_crypto, crypt_path_t::deliver_window, crypt_path_t::dh_handshake_state, crypt_path_t::f_crypto, LD_BUG, crypt_path_t::magic, crypt_path_t::package_window, crypt_path_t::state, and tor_assert.

Referenced by assert_connection_ok(), and assert_cpath_ok().

static void assert_cpath_ok ( const crypt_path_t cp  )  [static]

Verify that cpath cp has all of its invariants correct. Trigger an assert if anything is invalid.

References assert_cpath_layer_ok(), crypt_path_t::next, crypt_path_t::prev, crypt_path_t::state, and tor_assert.

Referenced by assert_circuit_ok().

static void circuit_add ( circuit_t circ  )  [static]

Add circ to the global list of circuits. This is called only from within circuit_new.

References circuit_t::next.

Referenced by init_circuit_base().

void circuit_close_all_marked ( void   ) 

Detach from the global circuit list, and deallocate, all circuits that have been marked for close.

References circuit_free(), circuit_t::marked_for_close, and circuit_t::next.

Referenced by run_scheduled_events().

int circuit_count_pending_on_or_conn ( or_connection_t or_conn  ) 

Return the number of circuits in state OR_WAIT, waiting for the given connection.

References circuit_get_all_pending_on_or_conn(), LD_CIRC, or_connection_t::nickname, smartlist_create(), and smartlist_free().

Referenced by control_event_or_conn_status().

void circuit_dump_by_conn ( connection_t conn,
int  severity 
)

static void circuit_dump_details ( int  severity,
circuit_t circ,
int  conn_array_index,
const char *  type,
int  this_circid,
int  other_circid 
) [static]

A helper function for circuit_dump_by_conn() below. Log a bunch of information about circuit circ.

References CIRCUIT_IS_ORIGIN, circuit_log_path(), circuit_state_to_string(), LD_CIRC, circuit_t::state, circuit_t::timestamp_created, and TO_ORIGIN_CIRCUIT().

Referenced by circuit_dump_by_conn().

void circuit_expire_all_dirty_circs ( void   ) 

Go through the circuitlist; for each circuit that starts at us and is dirty, frob its timestamp_dirty so we won't use it for any new streams.

This is useful for letting the user change pseudonyms, so new streams will not be linkable to old streams.

References CIRCUIT_IS_ORIGIN, get_options(), circuit_t::marked_for_close, or_options_t::MaxCircuitDirtiness, circuit_t::next, and circuit_t::timestamp_dirty.

Referenced by circuit_note_clock_jumped(), do_hup(), options_act(), and signewnym_impl().

origin_circuit_t* circuit_find_to_cannibalize ( uint8_t  purpose,
extend_info_t info,
int  flags 
)

Return a circuit that is open, is CIRCUIT_PURPOSE_C_GENERAL, has a timestamp_dirty value of 0, has flags matching the CIRCLAUNCH_* flags in flags, and if info is defined, does not already use info as any of its hops; or NULL if no circuit fits this description.

The purpose argument (currently ignored) refers to the purpose of the circuit we want to create, not the purpose of the circuit we want to cannibalize.

If !CIRCLAUNCH_NEED_UPTIME, prefer returning non-uptime circuits.

References origin_circuit_t::build_state, CIRCLAUNCH_IS_INTERNAL, CIRCLAUNCH_NEED_CAPACITY, CIRCLAUNCH_NEED_UPTIME, CIRCUIT_IS_ORIGIN, CIRCUIT_PURPOSE_C_GENERAL, CIRCUIT_STATE_OPEN, origin_circuit_t::cpath, DIGEST_LEN, crypt_path_t::extend_info, extend_info_t::identity_digest, cpath_build_state_t::is_internal, LD_CIRC, circuit_t::marked_for_close, cpath_build_state_t::need_capacity, cpath_build_state_t::need_uptime, crypt_path_t::next, circuit_t::next, circuit_t::purpose, origin_circuit_t::remaining_relay_early_cells, router_get_by_digest(), routers_in_same_family(), circuit_t::state, circuit_t::timestamp_dirty, and TO_ORIGIN_CIRCUIT().

Referenced by circuit_launch_by_extend_info().

static void circuit_free ( circuit_t circ  )  [static]

void circuit_free_all ( void   ) 

static void circuit_free_cpath ( crypt_path_t cpath  )  [static]

Deallocate space associated with the linked list cpath.

References circuit_free_cpath_node(), and crypt_path_t::next.

Referenced by circuit_free().

static void circuit_free_cpath_node ( crypt_path_t victim  )  [static]

void circuit_get_all_pending_on_or_conn ( smartlist_t out,
or_connection_t or_conn 
)

circuit_t* circuit_get_by_circid_orconn ( circid_t  circ_id,
or_connection_t conn 
)

Return a circ such that:

  • circ->n_circ_id or circ->p_circ_id is equal to circ_id, and
  • circ is attached to conn, either as p_conn or n_conn.
  • circ is not marked for close. Return NULL if no such circuit exists.

References circuit_get_by_circid_orconn_impl(), and circuit_t::marked_for_close.

Referenced by command_process_created_cell(), command_process_destroy_cell(), command_process_relay_cell(), and connection_cpu_process_inbuf().

static INLINE circuit_t* circuit_get_by_circid_orconn_impl ( circid_t  circ_id,
or_connection_t conn 
) [static]

Return a circ such that:

  • circ->n_circ_id or circ->p_circ_id is equal to circ_id, and
  • circ is attached to conn, either as p_conn or n_conn. Return NULL if no such circuit exists.

References CIRCUIT_IS_ORIGIN, LD_BUG, circuit_t::n_circ_id, circuit_t::n_conn, circuit_t::next, or_circuit_t::p_circ_id, or_circuit_t::p_conn, and TO_OR_CIRCUIT().

Referenced by assert_circuit_ok(), circuit_get_by_circid_orconn(), and circuit_id_in_use_on_orconn().

circuit_t* circuit_get_by_edge_conn ( edge_connection_t conn  ) 

origin_circuit_t* circuit_get_by_global_id ( uint32_t  id  ) 

Return the circuit whose global ID is id, or NULL if no such circuit exists.

References CIRCUIT_IS_ORIGIN, circuit_t::marked_for_close, circuit_t::next, and TO_ORIGIN_CIRCUIT().

Referenced by get_circ().

origin_circuit_t* circuit_get_by_rend_query_and_purpose ( const char *  rend_query,
uint8_t  purpose 
)

Return a circ such that:

  • circ->rend_data->query is equal to rend_query, and
  • circ->purpose is equal to purpose.

Return NULL if no such circuit exists.

References CIRCUIT_PURPOSE_IS_ORIGIN, circuit_t::marked_for_close, circuit_t::next, rend_data_t::onion_address, circuit_t::purpose, rend_cmp_service_ids(), origin_circuit_t::rend_data, TO_ORIGIN_CIRCUIT(), and tor_assert.

Referenced by rend_client_introduction_acked().

static or_circuit_t* circuit_get_by_rend_token_and_purpose ( uint8_t  purpose,
const char *  token,
size_t  len 
) [static]

Return the first OR circuit in the global list whose purpose is purpose, and whose rend_token is the len-byte token.

References circuit_t::marked_for_close, circuit_t::next, circuit_t::purpose, and TO_OR_CIRCUIT().

Referenced by circuit_get_intro_point(), and circuit_get_rendezvous().

crypt_path_t* circuit_get_cpath_hop ( origin_circuit_t circ,
int  hopnum 
)

Return the hopnumth hop in circ->cpath, or NULL if there aren't that many hops in the list.

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

Referenced by handle_control_attachstream().

int circuit_get_cpath_len ( origin_circuit_t circ  ) 

Return the number of hops in circuit's path.

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

Referenced by handle_control_attachstream(), and onion_extend_cpath().

or_circuit_t* circuit_get_intro_point ( const char *  digest  ) 

Return the circuit waiting for intro cells of the given digest. Return NULL if no such circuit is found.

References circuit_get_by_rend_token_and_purpose(), CIRCUIT_PURPOSE_INTRO_POINT, and DIGEST_LEN.

Referenced by rend_mid_establish_intro(), and rend_mid_introduce().

origin_circuit_t* circuit_get_next_by_pk_and_purpose ( origin_circuit_t start,
const char *  digest,
uint8_t  purpose 
)

Return the first circuit originating here in global_circuitlist after start whose purpose is purpose, and where digest (if set) matches the rend_pk_digest field. Return NULL if no circuit is found. If start is NULL, begin at the start of the list.

References CIRCUIT_PURPOSE_IS_ORIGIN, DIGEST_LEN, circuit_t::marked_for_close, circuit_t::next, circuit_t::purpose, TO_CIRCUIT, TO_ORIGIN_CIRCUIT(), and tor_assert.

Referenced by find_intro_circuit(), and router_perform_bandwidth_test().

or_circuit_t* circuit_get_rendezvous ( const char *  cookie  ) 

Return the circuit waiting for a rendezvous with the provided cookie. Return NULL if no such circuit is found.

References circuit_get_by_rend_token_and_purpose(), CIRCUIT_PURPOSE_REND_POINT_WAITING, and REND_COOKIE_LEN.

Referenced by rend_mid_establish_rendezvous(), and rend_mid_rendezvous().

int circuit_id_in_use_on_orconn ( circid_t  circ_id,
or_connection_t conn 
)

Return true iff the circuit ID circ_id is currently used by a circuit, marked or not, on conn.

References circuit_get_by_circid_orconn_impl().

Referenced by command_process_create_cell(), and get_unique_circ_id_by_conn().

int32_t circuit_initial_package_window ( void   ) 

Pick a reasonable package_window to start out for our circuits. Originally this was hard-coded at 1000, but now the consensus votes on the answer. See proposal 168.

References CIRCWINDOW_START, and networkstatus_get_param().

Referenced by init_circuit_base(), onion_append_hop(), rend_client_receive_rendezvous(), and rend_service_rendezvous_has_opened().

void circuit_mark_all_unused_circs ( void   ) 

Go through the circuitlist; mark-for-close each circuit that starts at us but has not yet been used.

References CIRCUIT_IS_ORIGIN, circuit_t::marked_for_close, circuit_t::next, and circuit_t::timestamp_dirty.

Referenced by circuit_note_clock_jumped(), and options_act().

const char* circuit_purpose_to_controller_string ( uint8_t  purpose  ) 

void circuit_set_n_circid_orconn ( circuit_t circ,
circid_t  id,
or_connection_t conn 
)

Set the n_conn field of a circuit circ, along with the corresponding circuit ID, and add the circuit as appropriate to the (orconn,id)->circuit map.

References bool_eq, CELL_DIRECTION_OUT, cell_queue_t::n, circuit_t::n_conn_cells, circuit_t::next_active_on_n_conn, and tor_assert.

Referenced by circuit_deliver_create_cell(), circuit_free(), circuit_unlink_all_from_or_conn(), command_process_destroy_cell(), and connection_edge_process_relay_cell().

void circuit_set_p_circid_orconn ( or_circuit_t circ,
circid_t  id,
or_connection_t conn 
)

Set the p_conn field of a circuit circ, along with the corresponding circuit ID, and add the circuit as appropriate to the (orconn,id)->circuit map.

References bool_eq, CELL_DIRECTION_IN, cell_queue_t::n, or_circuit_t::next_active_on_p_conn, or_circuit_t::p_conn_cells, TO_CIRCUIT, and tor_assert.

Referenced by circuit_free(), circuit_unlink_all_from_or_conn(), command_process_destroy_cell(), and or_circuit_new().

void circuit_set_state ( circuit_t circ,
uint8_t  state 
)

const char* circuit_state_to_string ( int  state  ) 

void circuit_unlink_all_from_or_conn ( or_connection_t conn,
int  reason 
)

For each circuit that has conn as n_conn or p_conn, unlink the circuit from the orconn,circid map, and mark it for close if it hasn't been marked already.

References CIRCUIT_IS_ORIGIN, circuit_set_n_circid_orconn(), circuit_set_p_circid_orconn(), connection_or_unlink_all_active_circs(), circuit_t::marked_for_close, circuit_t::n_conn, circuit_t::next, or_circuit_t::p_conn, and TO_OR_CIRCUIT().

Referenced by connection_about_to_close_connection().

static HT_HEAD ( HT_PROTOTYPE(  orconn_circid_map,
HT_PROTOTYPE(  orconn_circid_circuit_map_t 
) [static]

static void init_circuit_base ( circuit_t circ  )  [static]

or_circuit_t* or_circuit_new ( circid_t  p_circ_id,
or_connection_t p_conn 
)

origin_circuit_t* origin_circuit_new ( void   ) 


Variable Documentation

A list of all the circuits in CIRCUIT_STATE_OR_WAIT.

A global list of all circuits at this hop.


Generated on Tue May 25 00:30:40 2010 for tor by  doxygen 1.5.6