27 #define CIRCUITBUILD_PRIVATE
28 #define OCIRC_EVENT_PRIVATE
53 #include "core/or/trace_probes_circuit.h"
56 #include "feature/client/circpathbias.h"
81 #include "core/or/or_circuit_st.h"
129 #define MAX_CIRCID_ATTEMPTS 64
131 unsigned n_with_circ = 0, n_pending_destroy = 0, n_weird_pending_destroy = 0;
135 int64_t pending_destroy_time_total = 0;
136 int64_t pending_destroy_time_max = 0;
142 "Trying to pick a circuit ID for a connection from "
143 "a client with no identity.");
146 max_range = (chan->wide_circ_ids) ? (1u<<31) : (1u<<15);
147 mask = max_range - 1;
150 if (++attempts > MAX_CIRCID_ATTEMPTS) {
167 int64_t queued_destroys;
172 if (n_pending_destroy)
173 pending_destroy_time_total /= n_pending_destroy;
174 log_warn(
LD_CIRC,
"No unused circIDs found on channel %s wide "
175 "circID support, with %u inbound and %u outbound circuits. "
176 "Found %u circuit IDs in use by circuits, and %u with "
177 "pending destroy cells. (%u of those were marked bogusly.) "
178 "The ones with pending destroy cells "
179 "have been marked unusable for an average of %ld seconds "
180 "and a maximum of %ld seconds. This channel is %ld seconds "
181 "old. Failing a circuit.%s",
182 chan->wide_circ_ids ?
"with" :
"without",
184 n_with_circ, n_pending_destroy, n_weird_pending_destroy,
185 (
long)pending_destroy_time_total,
186 (
long)pending_destroy_time_max,
193 log_warn(
LD_BUG,
" This channel somehow has no cmux on it!");
201 queued_destroys = circuitmux_count_queued_destroy_cells(chan,
204 log_warn(
LD_CIRC,
" Circuitmux on this channel has %u circuits, "
205 "of which %u are active. It says it has %"PRId64
206 " destroy cells queued.",
216 circuitmux_assert_okay(chan->
cmux);
224 crypto_rand((
char*) &test_circ_id,
sizeof(test_circ_id));
225 test_circ_id &= mask;
226 }
while (test_circ_id == 0);
228 test_circ_id |= high_bit;
233 else if (in_use == 2) {
240 pending_destroy_time_total += waiting;
241 if (waiting > pending_destroy_time_max)
242 pending_destroy_time_max = waiting;
244 ++n_weird_pending_destroy;
262 const char *states[] = {
"closed",
"waiting for keys",
"open"};
275 (nickname?nickname:
"*unnamed*"));
285 if (!verbose && hop->
state != CPATH_STATE_OPEN)
318 }
while (hop != circ->
cpath);
322 smartlist_free(elements);
354 tor_log(severity,domain,
"%s",s);
364 cpath = head = circ->
cpath;
372 if (!extend_info_supports_ntor(cpath->
extend_info)) {
376 }
while (cpath != head);
395 log_info(
LD_CIRC,
"Generating cpath hop failed.");
409 if (circuit_can_use_tap(circ)) {
433 if (BUG(!path_supports_ntor)) {
481 int is_hs_v3_rp_circuit = 0;
484 is_hs_v3_rp_circuit = 1;
498 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
502 tor_trace(
TR_SUBSYS(circuit), TR_EV(establish), circ);
507 circuit_guard_state_t *
531 ocirc_chan_publish(msg);
544 const char *msg = NULL;
545 int should_launch = 0;
562 "Client asked me to connect directly to a private address");
563 return -END_CIRC_REASON_TORPROTOCOL;
574 orport4 ? &orport4->addr : NULL,
575 orport6 ? &orport6->addr : NULL,
582 log_info(
LD_CIRC,
"Next router is %s: %s",
590 log_info(
LD_CIRC,
"connect to firsthop failed. Closing.");
591 return -END_CIRC_REASON_CONNECTFAILED;
601 log_debug(
LD_CIRC,
"connecting in progress (or finished). Good.");
609 circ->base_.
n_chan = n_chan;
613 log_debug(
LD_CIRC,
"Conn open for %s. Delivering first onion skin.",
616 log_info(
LD_CIRC,
"circuit_send_next_onion_skin failed.");
617 circ->base_.
n_chan = NULL;
641 log_debug(
LD_CIRC,
"chan to %s, status=%d",
652 if (circ->marked_for_close || circ->n_chan || !circ->n_hop ||
656 const char *rsa_ident = NULL;
659 rsa_ident = circ->n_hop->identity_digest;
662 ed_ident = &circ->n_hop->ed_identity;
665 if (rsa_ident == NULL && ed_ident == NULL) {
682 log_info(
LD_CIRC,
"Channel failed; closing circ.");
683 circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
688 log_info(
LD_CIRC,
"Channel deprecated for origin circs; closing circ.");
689 circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
692 log_debug(
LD_CIRC,
"Found circ, sending create cell.");
697 extend_info_free(circ->n_hop);
704 "send_next_onion_skin failed; circuit marked for closing.");
705 circuit_mark_for_close(circ, -err_reason);
714 circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
721 SMARTLIST_FOREACH_END(circ);
723 smartlist_free(pending_circs);
746 create_cell->
cell_type == CELL_CREATE_FAST ||
751 static ratelim_t circid_warning_limit = RATELIM_INIT(9600);
753 "failed to get unique circID.");
759 memset(&cell, 0,
sizeof(
cell_t));
760 r = relayed ? create_cell_format_relayed(&cell, create_cell)
761 : create_cell_format(&cell, create_cell);
763 log_warn(
LD_CIRC,
"Couldn't format create cell");
766 log_debug(
LD_CIRC,
"Chosen circID %u.", (
unsigned)
id);
776 if (!CHANNEL_IS_OPEN(circ->
n_chan)) {
778 "Got first hop for a circuit without an opened channel. "
804 return ! circuit_has_usable_onion_key(circ);
837 uint16_t *handshake_type_out,
842 if (extend_info_supports_ntor(ei)) {
843 *cell_type_out = CELL_CREATE2;
844 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR;
847 *cell_type_out = CELL_CREATE;
848 *handshake_type_out = ONION_HANDSHAKE_TYPE_TAP;
863 uint8_t *create_cell_type_out,
864 uint16_t *handshake_type_out,
872 if (*handshake_type_out != ONION_HANDSHAKE_TYPE_TAP) {
873 *cell_type_out = RELAY_COMMAND_EXTEND2;
874 *create_cell_type_out = CELL_CREATE2;
877 *cell_type_out = RELAY_COMMAND_EXTEND;
878 *create_cell_type_out = CELL_CREATE;
929 if (circ->
cpath->
state == CPATH_STATE_CLOSED) {
965 memset(&cc, 0,
sizeof(cc));
967 log_debug(
LD_CIRC,
"First skin; sending create cell.");
1000 log_warn(
LD_CIRC,
"onion_skin_create (first hop) failed.");
1001 return - END_CIRC_REASON_INTERNAL;
1006 return - END_CIRC_REASON_RESOURCELIMIT;
1007 tor_trace(
TR_SUBSYS(circuit), TR_EV(first_onion_skin), circ, circ->
cpath);
1009 circ->
cpath->
state = CPATH_STATE_AWAITING_KEYS;
1011 log_info(
LD_CIRC,
"First hop: finished sending %s cell to '%s'",
1012 fast ?
"CREATE_FAST" :
"CREATE",
1031 log_warn(
LD_BUG,
"%d-hop circuit %p with purpose %d has no "
1035 r = GUARD_USABLE_NOW;
1039 const int is_usable_for_streams = (r == GUARD_USABLE_NOW);
1040 if (r == GUARD_USABLE_NOW) {
1042 }
else if (r == GUARD_MAYBE_USABLE_LATER) {
1047 tor_assert_nonfatal(r == GUARD_USABLE_NEVER);
1048 return - END_CIRC_REASON_INTERNAL;
1057 log_info(
LD_CIRC,
"circuit built!");
1065 if (is_usable_for_streams)
1073 "Tor has successfully opened a circuit. "
1074 "Looks like client functionality is working.");
1079 !router_all_orports_seem_reachable(options)) {
1086 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
1106 memset(&ec, 0,
sizeof(ec));
1110 log_debug(
LD_CIRC,
"starting to send subsequent skin.");
1121 int n_addrs_set = 0;
1127 if (orport6 && include_ipv6) {
1133 if (n_addrs_set == 0) {
1134 log_warn(
LD_BUG,
"No supported address family found in extend_info.");
1135 return - END_CIRC_REASON_INTERNAL;
1147 log_warn(
LD_CIRC,
"onion_skin_create failed.");
1148 return - END_CIRC_REASON_INTERNAL;
1152 log_info(
LD_CIRC,
"Sending extend relay cell.");
1155 uint16_t payload_len=0;
1158 log_warn(
LD_CIRC,
"Couldn't format extend cell");
1159 return -END_CIRC_REASON_INTERNAL;
1164 if (relay_send_command_from_edge(0,
TO_CIRCUIT(circ),
1166 (
char*)payload, payload_len,
1170 hop->
state = CPATH_STATE_AWAITING_KEYS;
1171 tor_trace(
TR_SUBSYS(circuit), TR_EV(intermediate_onion_skin), circ, hop);
1185 " seconds; assuming established circuits no longer work.",
1189 "Your system clock just jumped %"PRId64
" seconds %s; "
1190 "assuming established circuits no longer work.",
1192 seconds_elapsed >=0 ? seconds_elapsed : -seconds_elapsed),
1193 seconds_elapsed >=0 ?
"forward" :
"backward");
1197 (seconds_elapsed), was_idle?1:0);
1204 if (seconds_elapsed < 0) {
1223 char keys[CPATH_KEY_MATERIAL_LEN];
1228 log_warn(
LD_CIRC,
"pathbias_count_build_attempt failed: %d", rv);
1232 if (circ->
cpath->
state == CPATH_STATE_AWAITING_KEYS) {
1237 log_warn(
LD_PROTOCOL,
"got extended when circ already built? Closing.");
1238 return - END_CIRC_REASON_TORPROTOCOL;
1244 const char *msg = NULL;
1248 (uint8_t*)keys,
sizeof(keys),
1252 log_warn(
LD_CIRC,
"onion_skin_client_handshake failed: %s", msg);
1253 return -END_CIRC_REASON_TORPROTOCOL;
1260 return -END_CIRC_REASON_TORPROTOCOL;
1263 hop->
state = CPATH_STATE_OPEN;
1264 log_info(
LD_CIRC,
"Finished building circuit hop:");
1294 while (layer->next != circ->
cpath) {
1296 victim = layer->next;
1297 log_debug(
LD_CIRC,
"Killing a layer of the cpath.");
1300 if (stream->cpath_layer == victim) {
1301 log_info(
LD_APP,
"Marking stream %d for close because of truncate.",
1306 connection_mark_unattached_ap(stream, END_STREAM_REASON_DESTROY);
1310 layer->next = victim->next;
1314 log_info(
LD_CIRC,
"finished");
1360 int known_purpose = 0;
1433 if (BUG(exit_ei && !known_purpose)) {
1434 log_warn(
LD_BUG,
"Unhandled purpose %d with a chosen exit; "
1435 "assuming routelen %d.", purpose, routelen);
1459 log_debug(
LD_CIRC,
"Chosen route length %d (%d direct and %d indirect "
1460 "routers suitable).", routelen, num_acceptable_direct,
1461 num_acceptable_indirect);
1463 if (num_acceptable_direct < 1 || num_acceptable_indirect < routelen - 1) {
1465 "Not enough acceptable routers (%d/%d direct and %d/%d "
1466 "indirect routers suitable). Discarding this circuit.",
1467 num_acceptable_direct, routelen,
1468 num_acceptable_indirect, routelen);
1493 int *need_capacity))
1503 enough = (smartlist_len(sl) == 0);
1504 for (i = 0; i < smartlist_len(sl); ++i) {
1505 port = smartlist_get(sl, i);
1523 for (i = 0; i < smartlist_len(needed_ports); ++i) {
1527 port = *(uint16_t *)smartlist_get(needed_ports, i);
1573 int n_pending_connections = 0;
1575 int best_support = -1;
1576 int n_best_support=0;
1579 const node_t *selected_node=NULL;
1580 const int need_uptime = (flags & CRN_NEED_UPTIME) != 0;
1581 const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
1608 ++n_pending_connections;
1620 n_supported = tor_calloc(smartlist_len(the_nodes),
sizeof(
int));
1622 const int i = node_sl_idx;
1624 n_supported[i] = -1;
1631 if (!router_can_choose_node(node, flags)) {
1632 n_supported[i] = -1;
1635 if (node->is_bad_exit) {
1636 n_supported[i] = -1;
1640 n_supported[i] = -1;
1645 n_supported[i] = -1;
1649 n_supported[i] = -1;
1667 } SMARTLIST_FOREACH_END(conn);
1668 if (n_pending_connections > 0 && n_supported[i] == 0) {
1673 if (n_supported[i] > best_support) {
1676 best_support = n_supported[i]; n_best_support=1;
1679 }
else if (n_supported[i] == best_support) {
1684 } SMARTLIST_FOREACH_END(node);
1686 "Found %d servers that might support %d/%d pending connections.",
1687 n_best_support, best_support >= 0 ? best_support : 0,
1688 n_pending_connections);
1692 if (best_support > 0) {
1696 if (n_supported[node_sl_idx] == best_support)
1701 smartlist_free(supporting);
1710 if (best_support == -1) {
1711 if (need_uptime || need_capacity) {
1713 "We couldn't find any live%s%s routers; falling back "
1714 "to list of all routers.",
1715 need_capacity?
", fast":
"",
1716 need_uptime?
", stable":
"");
1718 flags &= ~(CRN_NEED_UPTIME|CRN_NEED_CAPACITY);
1721 log_notice(
LD_CIRC,
"All routers are down or won't exit%s -- "
1722 "choosing a doomed exit at random.",
1727 for (attempt = 0; attempt < 2; attempt++) {
1731 if (n_supported[node_sl_idx] != -1 &&
1737 } SMARTLIST_FOREACH_END(node);
1745 if (smartlist_len(needed_ports))
1749 smartlist_free(needed_ports);
1750 smartlist_free(supporting);
1754 if (selected_node) {
1756 return selected_node;
1760 "No exits in ExitNodes%s seem to be running: "
1761 "can't choose an exit.",
1763 ", except possibly those excluded by your configuration, " :
"");
1791 const routerset_t *pick_from,
1792 const routerset_t *exclude_set,
1796 const node_t *middle_node = NULL;
1812 } SMARTLIST_FOREACH_END(live_node);
1829 #define MAX_SANE_RESTRICTED_NODES 20
1836 if (smartlist_len(allowlisted_live_middles) <=
1837 MAX_SANE_RESTRICTED_NODES) {
1840 static ratelim_t pinned_notice_limit = RATELIM_INIT(24*3600);
1842 "Your _HSLayer%dNodes setting has resulted "
1843 "in %d total nodes. This is a lot of nodes. "
1844 "You may want to consider using a Tor controller "
1845 "to select and update a smaller set of nodes instead.",
1846 position_hint, smartlist_len(allowlisted_live_middles));
1856 smartlist_free(allowlisted_live_middles);
1857 smartlist_free(all_live_nodes);
1877 flags |= CRN_NEED_DESC;
1885 tor_assert_nonfatal(is_internal);
1895 const node_t *rendezvous_node = pick_rendezvous_node(flags);
1896 log_info(
LD_REND,
"Picked new RP: %s",
1898 return rendezvous_node;
1914 const char *description;
1915 uint8_t purpose = circ->base_.
purpose;
1927 log_warn(
LD_BUG,
"Called on non-origin circuit (purpose %d, %s)",
1936 description =
"requested exit node";
1951 description =
"chosen rendezvous point";
1955 description =
"controller-selected circuit target";
1962 log_warn(
LD_BUG,
"Using %s '%s' which is listed in ExcludeNodes%s, "
1963 "even though StrictNodes is set. Please report. "
1964 "(Circuit purpose: %s)",
1969 log_warn(
LD_CIRC,
"Using %s '%s' which is listed in "
1970 "ExcludeNodes%s, because no better options were available. To "
1971 "prevent this (and possibly break your Tor functionality), "
1972 "set the StrictNodes configuration option. "
1973 "(Circuit purpose: %s)",
1995 flags |= CRN_NEED_UPTIME;
1997 flags |= CRN_NEED_CAPACITY;
2015 if (state->is_ipv6_selftest && cur_len == state->desired_path_len - 2)
2016 return CRN_INITIATE_IPV6_EXTEND;
2031 int is_hs_v3_rp_circuit)
2036 log_debug(
LD_CIRC,
"Launching a one-hop circuit for dir tunnel%s.",
2037 (hs_service_allow_non_anonymous_connection(
get_options()) ?
2038 ", or intro or rendezvous connection" :
""));
2049 log_info(
LD_CIRC,
"Using requested exit node '%s'",
2054 flags |= cpath_build_state_to_crn_flags(state);
2058 flags |= CRN_DIRECT_CONN;
2059 if (is_hs_v3_rp_circuit)
2060 flags |= CRN_RENDEZVOUS_V3;
2064 log_warn(
LD_CIRC,
"Failed to choose an exit server");
2068 if (BUG(exit_ei == NULL))
2111 log_warn(
LD_CIRC,
"Couldn't extend circuit to new point %s.",
2113 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
2133 int flags = CRN_NEED_DESC;
2136 flags |= CRN_DIRECT_CONN;
2142 if (!router_can_choose_node(node, flags))
2145 } SMARTLIST_FOREACH_END(node);
2206 for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->
next) {
2245 for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->
next) {
2257 uint8_t purpose,
int cur_len)
2284 const routerset_t *vanguard_routerset = NULL;
2285 const node_t *node = NULL;
2290 }
else if (cur_len == 2) {
2303 static ratelim_t pinned_warning_limit = RATELIM_INIT(300);
2305 "Could not find a node that matches the configured "
2306 "_HSLayer%dNodes set", cur_len+1);
2328 tor_assert(CIRCUIT_PURPOSE_MIN_ <= purpose &&
2329 purpose <= CIRCUIT_PURPOSE_MAX_);
2331 log_debug(
LD_CIRC,
"Contemplating intermediate hop #%d: random choice.",
2336 flags |= cpath_build_state_to_crn_flags(state);
2337 flags |= cpath_build_state_to_crn_ipv6_extend_flag(state, cur_len);
2341 log_debug(
LD_GENERAL,
"Picking a sticky node (cur_len = %d)", cur_len);
2343 smartlist_free(excluded);
2365 smartlist_free(excluded);
2380 circuit_guard_state_t **guard_state_out)
2394 tor_assert_nonfatal(state);
2413 flags |= cpath_build_state_to_crn_flags(state);
2417 smartlist_free(excluded);
2430 uint8_t purpose = circ->base_.
purpose;
2436 log_debug(
LD_CIRC,
"Path is complete: %d steps long",
2441 log_debug(
LD_CIRC,
"Path is %d long; we want %d", cur_len,
2446 }
else if (cur_len == 0) {
2456 tor_assert_nonfatal(info || client);
2467 log_warn(
LD_CIRC,
"Failed to find node for hop #%d of our path. Discarding "
2468 "this circuit.", cur_len+1);
2472 log_debug(
LD_CIRC,
"Chose router %s for hop #%d (exit is %s)",
2477 extend_info_free(info);
2520 circuit_purpose_can_use_tap_impl(uint8_t purpose)
2535 return (circuit_purpose_can_use_tap_impl(circ->base_.
purpose) &&
2547 circuit_can_use_tap(circ));
2559 if (to_upgrade == NULL)
2562 log_info(
LD_GUARD,
"Upgrading %d circuits from 'waiting for better guard' "
2563 "to 'open'.", smartlist_len(to_upgrade));
2568 } SMARTLIST_FOREACH_END(circ);
2570 smartlist_free(to_upgrade);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
void tor_addr_make_unspec(tor_addr_t *a)
const char * hex_str(const char *from, size_t fromlen)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
int extend_info_is_a_configured_bridge(const extend_info_t *ei)
Header file for circuitbuild.c.
Fixed-size cell structure.
void channel_timestamp_client(channel_t *chan)
channel_t * channel_connect(const tor_addr_t *addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id)
int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info)
int channel_remote_identity_matches(const channel_t *chan, const char *rsa_id_digest, const ed25519_public_key_t *ed_id)
const char * channel_state_to_string(channel_state_t state)
const char * channel_describe_peer(channel_t *chan)
void channel_dump_statistics(channel_t *chan, int severity)
channel_t * channel_get_for_extend(const char *rsa_id_digest, const ed25519_public_key_t *ed_id, const tor_addr_t *target_ipv4_addr, const tor_addr_t *target_ipv6_addr, bool for_origin_circ, const char **msg_out, int *launch_out)
Header file for channel.c.
void channel_mark_as_used_for_origin_circuit(channel_t *chan)
int pathbias_count_build_attempt(origin_circuit_t *circ)
void pathbias_count_build_success(origin_circuit_t *circ)
static int circuit_send_first_onion_skin(origin_circuit_t *circ)
const char * build_state_get_exit_nickname(cpath_build_state_t *state)
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_build_no_more_hops(origin_circuit_t *circ)
int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
char * circuit_list_path(origin_circuit_t *circ, int verbose)
STATIC int count_acceptable_nodes(const smartlist_t *nodes, int direct)
STATIC int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei, int is_hs_v3_rp_circuit)
int circuit_handle_first_hop(origin_circuit_t *circ)
static smartlist_t * circuit_get_unhandled_ports(time_t now)
static int middle_node_must_be_vanguard(const or_options_t *options, uint8_t purpose, int cur_len)
origin_circuit_t * circuit_establish_circuit(uint8_t purpose, extend_info_t *exit_ei, int flags)
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
static const node_t * choose_good_exit_server(origin_circuit_t *circ, router_crn_flags_t flags, int is_internal)
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)
STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan)
int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei)
const uint8_t * build_state_get_exit_rsa_id(cpath_build_state_t *state)
STATIC int onion_extend_cpath(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)
char * circuit_list_path_for_controller(origin_circuit_t *circ)
const node_t * build_state_get_exit_node(cpath_build_state_t *state)
STATIC int new_route_len(uint8_t purpose, extend_info_t *exit_ei, const smartlist_t *nodes)
static int onion_populate_cpath(origin_circuit_t *circ)
int circuit_deliver_create_cell(circuit_t *circ, const struct create_cell_t *create_cell, int relayed)
static int circuit_may_omit_guard(const origin_circuit_t *circ)
const node_t * choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state, circuit_guard_state_t **guard_state_out)
static int ap_stream_wants_exit_attention(connection_t *conn)
void circuit_n_chan_done(channel_t *chan, int status, int close_origin_circuits)
static int circuit_cpath_supports_ntor(const origin_circuit_t *circ)
int circuit_timeout_want_to_count_circ(const origin_circuit_t *circ)
static void warn_if_last_router_excluded(origin_circuit_t *circ, const extend_info_t *exit_ei)
static char * circuit_list_path_impl(origin_circuit_t *circ, int verbose, int verbose_names)
static smartlist_t * build_vanguard_middle_exclude_list(uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
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)
origin_circuit_t * origin_circuit_init(uint8_t purpose, int flags)
int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, int *need_capacity)
void circuit_note_clock_jumped(int64_t seconds_elapsed, bool was_idle)
int circuit_send_next_onion_skin(origin_circuit_t *circ)
static smartlist_t * build_middle_exclude_list(uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
int circuit_finish_handshake(origin_circuit_t *circ, const created_cell_t *reply)
int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
int circuit_truncated(origin_circuit_t *circ, int reason)
circuit_guard_state_t * origin_circuit_get_guard_state(origin_circuit_t *circ)
static const node_t * choose_good_middle_server(uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
static void circuit_chan_publish(const origin_circuit_t *circ, const channel_t *chan)
static bool should_use_create_fast_for_circuit(origin_circuit_t *circ)
static int circuit_send_intermediate_onion_skin(origin_circuit_t *circ, crypt_path_t *hop)
static const node_t * choose_good_exit_server_general(router_crn_flags_t flags)
channel_t * channel_connect_for_circuit(const extend_info_t *ei)
static int node_handles_some_port(const node_t *node, smartlist_t *needed_ports)
void circuit_upgrade_circuits_from_guard_wait(void)
Header file for circuitbuild.c.
int circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan)
void circuit_set_n_circid_chan(circuit_t *circ, circid_t id, channel_t *chan)
void circuit_mark_all_dirty_circs_as_unusable(void)
origin_circuit_t * origin_circuit_new(void)
void circuit_set_state(circuit_t *circ, uint8_t state)
const char * circuit_purpose_to_string(uint8_t purpose)
int circuit_get_cpath_len(origin_circuit_t *circ)
smartlist_t * circuit_find_circuits_to_upgrade_from_guard_wait(void)
int circuit_get_cpath_opened_len(const origin_circuit_t *circ)
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
void circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
int circuit_event_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
time_t circuit_id_when_marked_unusable_on_channel(circid_t circ_id, channel_t *chan)
void circuit_mark_all_unused_circs(void)
Header file for circuitlist.c.
#define CIRCUIT_PURPOSE_S_CONNECT_REND
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
#define CIRCUIT_PURPOSE_REND_POINT_WAITING
#define CIRCUIT_STATE_OPEN
#define CIRCUIT_STATE_BUILDING
#define CIRCUIT_PURPOSE_C_REND_JOINED
#define CIRCUIT_PURPOSE_INTRO_POINT
#define CIRCUIT_PURPOSE_CONTROLLER
#define CIRCUIT_IS_ORIGIN(c)
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
#define CIRCUIT_STATE_GUARD_WAIT
#define CIRCUIT_PURPOSE_TESTING
#define CIRCUIT_PURPOSE_OR
#define CIRCUIT_STATE_CHAN_WAIT
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
#define CIRCUIT_PURPOSE_S_REND_JOINED
#define CIRCUIT_PURPOSE_C_REND_READY
#define CIRCUIT_PURPOSE_S_HSDIR_POST
#define CIRCUIT_PURPOSE_C_HSDIR_GET
#define CIRCUIT_PURPOSE_REND_ESTABLISHED
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED
#define CIRCUIT_PURPOSE_C_INTRODUCING
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND
#define CIRCUIT_PURPOSE_C_GENERAL
#define CIRCUIT_PURPOSE_HS_VANGUARDS
unsigned int circuitmux_num_active_circuits(circuitmux_t *cmux)
unsigned int circuitmux_num_circuits(circuitmux_t *cmux)
void circpad_machine_event_circ_added_hop(origin_circuit_t *on_circ)
void circpad_machine_event_circ_built(origin_circuit_t *circ)
Header file for circuitpadding.c.
void circuit_build_times_handle_completed_hop(origin_circuit_t *circ)
Header file for circuitstats.c.
int circuit_should_use_vanguards(uint8_t purpose)
void circuit_has_opened(origin_circuit_t *circ)
void circuit_reset_failure_count(int timeout)
int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port, int min)
void circuit_remove_handled_ports(smartlist_t *needed_ports)
int circuit_purpose_is_hidden_service(uint8_t purpose)
Header file for circuituse.c.
#define CIRCLAUNCH_NEED_CAPACITY
#define CIRCLAUNCH_IS_IPV6_SELFTEST
#define CIRCLAUNCH_ONEHOP_TUNNEL
#define CIRCLAUNCH_IS_V3_RP
#define CIRCLAUNCH_IS_INTERNAL
#define CIRCLAUNCH_NEED_UPTIME
void command_setup_channel(channel_t *chan)
Header file for command.c.
const or_options_t * get_options(void)
tor_cmdline_mode_t command
Header file for config.c.
Header file for connection.c.
int connection_ap_can_use_exit(const entry_connection_t *conn, const node_t *exit_node)
int connection_edge_is_rendezvous_stream(const edge_connection_t *conn)
edge_connection_t * TO_EDGE_CONN(connection_t *c)
entry_connection_t * TO_ENTRY_CONN(connection_t *c)
Header file for connection_edge.c.
#define AP_CONN_STATE_CIRCUIT_WAIT
void clear_broken_connection_map(int stop_recording)
Header file for connection_or.c.
void control_event_bootstrap(bootstrap_status_t status, int progress)
int control_event_general_status(int severity, const char *format,...)
int control_event_client_status(int severity, const char *format,...)
Header file for control_events.c.
Circuit-build-stse structure.
int cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
int cpath_init_circuit_crypto(crypt_path_t *cpath, const char *key_data, size_t key_data_len, int reverse, int is_hs_v3)
crypt_path_t * cpath_get_next_non_open_hop(crypt_path_t *cpath)
void cpath_free(crypt_path_t *victim)
Header file for crypt_path.c.
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
void crypto_rand(char *to, size_t n)
void * smartlist_choose(const smartlist_t *sl)
Common functions for using (pseudo-)random number generators.
const char * extend_info_describe(const extend_info_t *ei)
const char * node_describe(const node_t *node)
Header file for describe.c.
Header file for directory.c.
Entry connection structure.
guard_usable_t entry_guard_succeeded(circuit_guard_state_t **guard_state_p)
const node_t * guards_choose_guard(cpath_build_state_t *state, uint8_t purpose, circuit_guard_state_t **guard_state_out)
Header file for circuitbuild.c.
Header file for Tor tracing instrumentation definition.
const tor_addr_port_t * extend_info_get_orport(const extend_info_t *ei, int family)
extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect)
const tor_addr_port_t * extend_info_pick_orport(const extend_info_t *ei)
bool extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
extend_info_t * extend_info_dup(extend_info_t *info)
Header for core/or/extendinfo.c.
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
#define log_fn(severity, domain, args,...)
#define log_fn_ratelim(ratelim, severity, domain, args,...)
void note_that_we_maybe_cant_complete_circuits(void)
int have_completed_a_circuit(void)
void note_that_we_completed_a_circuit(void)
smartlist_t * get_connection_array(void)
void reset_all_main_loop_timers(void)
Header file for mainloop.c.
Header file for microdesc.c.
Header file for networkstatus.c.
int is_legal_nickname(const char *s)
Header file for nickname.c.
const node_t * router_choose_random_node(smartlist_t *excludedsmartlist, routerset_t *excludedset, router_crn_flags_t flags)
const node_t * node_sl_choose_by_bandwidth(const smartlist_t *sl, bandwidth_weight_rule_t rule)
Header file for node_select.c.
Node information structure.
void nodelist_add_node_and_family(smartlist_t *sl, const node_t *node)
const smartlist_t * nodelist_get_list(void)
int node_has_preferred_descriptor(const node_t *node, int for_direct_connect)
const node_t * node_get_by_id(const char *identity_digest)
void node_get_verbose_nickname(const node_t *node, char *verbose_name_out)
int node_exit_policy_rejects_all(const node_t *node)
Header file for nodelist.c.
Header file for ocirc_event.c.
int extend_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extend_cell_t *cell_in)
int onion_skin_client_handshake(int type, const onion_handshake_state_t *handshake_state, const uint8_t *reply, size_t reply_len, uint8_t *keys_out, size_t keys_out_len, uint8_t *rend_authenticator_out, const char **msg_out)
void onion_handshake_state_release(onion_handshake_state_t *state)
int onion_skin_create(int type, const extend_info_t *node, onion_handshake_state_t *state_out, uint8_t *onion_skin_out)
Header file for onion_crypto.c.
Header file for onion_fast.c.
Header file for onion_tap.c.
Master header file for Tor-specific functionality.
#define MIN_CIRCUITS_HANDLING_STREAM
#define DEFAULT_ROUTE_LEN
#define END_CIRC_REASON_NOPATH
#define MAX_VERBOSE_NICKNAME_LEN
#define RELAY_PAYLOAD_SIZE
#define END_CIRC_REASON_FLAG_REMOTE
Origin circuit structure.
addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr, uint16_t port, const node_t *node)
Header file for policies.c.
@ ADDR_POLICY_PROBABLY_REJECTED
void rep_hist_remove_predicted_ports(const smartlist_t *rmv_ports)
smartlist_t * rep_hist_get_predicted_ports(time_t now)
Header file for predict_ports.c.
char * rate_limit_log(ratelim_t *lim, time_t now)
void append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, cell_t *cell, cell_direction_t direction, streamid_t fromstream)
int router_digest_is_me(const char *digest)
Header file for router.c.
void router_add_running_nodes_to_smartlist(smartlist_t *sl, int flags)
Header file for routerlist.c.
int server_mode(const or_options_t *options)
Header file for routermode.c.
int routerset_contains_node(const routerset_t *set, const node_t *node)
void routerset_get_all_nodes(smartlist_t *out, const routerset_t *routerset, const routerset_t *excludeset, int running_only)
int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
void routerset_subtract_nodes(smartlist_t *lst, const routerset_t *routerset)
Header file for routerset.c.
void router_do_reachability_checks(void)
Header file for selftest.c.
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
int smartlist_contains_int_as_string(const smartlist_t *sl, int num)
void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_clear(smartlist_t *sl)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int(* is_canonical)(channel_t *)
unsigned int num_n_circuits
circ_id_type_bitfield_t circ_id_type
char identity_digest[DIGEST_LEN]
uint64_t global_identifier
channel_usage_info_t channel_usage
ratelim_t last_warned_circ_ids_exhausted
struct timeval timestamp_began
uint16_t marked_for_close
extend_info_t * chosen_exit
unsigned int is_ipv6_selftest
unsigned int onehop_tunnel
unsigned int need_capacity
uint8_t onionskin[CELL_PAYLOAD_SIZE - 4]
uint8_t reply[CELL_PAYLOAD_SIZE - 2]
struct crypt_path_t * prev
struct crypt_path_t * next
extend_info_t * extend_info
char rend_circ_nonce[DIGEST_LEN]
onion_handshake_state_t handshake_state
struct edge_connection_t * next_stream
unsigned int use_begindir
tor_addr_port_t orport_ipv4
create_cell_t create_cell
struct ed25519_public_key_t ed_pubkey
uint8_t node_id[DIGEST_LEN]
tor_addr_port_t orport_ipv6
ed25519_public_key_t ed_identity
char identity_digest[DIGEST_LEN]
char nickname[MAX_HEX_NICKNAME_LEN+1]
char identity[DIGEST_LEN]
struct routerset_t * ExcludeExitNodesUnion_
struct routerset_t * ExcludeNodes
struct routerset_t * ExitNodes
struct routerset_t * HSLayer2Nodes
struct smartlist_t * LongLivedPorts
int ExtendAllowPrivateAddresses
struct routerset_t * MiddleNodes
struct routerset_t * HSLayer3Nodes
uint32_t global_identifier
edge_connection_t * p_streams
cpath_build_state_t * build_state
struct circuit_guard_state_t * guard_state
unsigned first_hop_from_controller
#define MOCK_IMPL(rv, funcname, arglist)
void tor_gettimeofday(struct timeval *timeval)
Headers for transports.c.
#define tor_assert_nonfatal_unreached()
#define tor_fragile_assert()
#define IF_BUG_ONCE(cond)
int tor_digest_is_zero(const char *digest)