27#define CIRCUITBUILD_PRIVATE
28#define OCIRC_EVENT_PRIVATE
53#include "core/or/trace_probes_circuit.h"
57#include "feature/client/circpathbias.h"
83#include "core/or/or_circuit_st.h"
86#include "trunnel/extension.h"
87#include "trunnel/congestion_control.h"
88#include "trunnel/subproto_request.h"
91 const circuit_guard_state_t *guard_state);
108 const struct circuit_guard_state_t *guard_state,
109 bool for_origin_circ))
120 guard_state, for_origin_circ);
141#define MAX_CIRCID_ATTEMPTS 64
143 unsigned n_with_circ = 0, n_pending_destroy = 0, n_weird_pending_destroy = 0;
147 int64_t pending_destroy_time_total = 0;
148 int64_t pending_destroy_time_max = 0;
154 "Trying to pick a circuit ID for a connection from "
155 "a client with no identity.");
158 max_range = (chan->wide_circ_ids) ? (1u<<31) : (1u<<15);
159 mask = max_range - 1;
162 if (++attempts > MAX_CIRCID_ATTEMPTS) {
179 int64_t queued_destroys;
184 if (n_pending_destroy)
185 pending_destroy_time_total /= n_pending_destroy;
186 log_warn(
LD_CIRC,
"No unused circIDs found on channel %s wide "
187 "circID support, with %u inbound and %u outbound circuits. "
188 "Found %u circuit IDs in use by circuits, and %u with "
189 "pending destroy cells. (%u of those were marked bogusly.) "
190 "The ones with pending destroy cells "
191 "have been marked unusable for an average of %ld seconds "
192 "and a maximum of %ld seconds. This channel is %ld seconds "
193 "old. Failing a circuit.%s",
194 chan->wide_circ_ids ?
"with" :
"without",
196 n_with_circ, n_pending_destroy, n_weird_pending_destroy,
197 (
long)pending_destroy_time_total,
198 (
long)pending_destroy_time_max,
205 log_warn(
LD_BUG,
" This channel somehow has no cmux on it!");
213 queued_destroys = circuitmux_count_queued_destroy_cells(chan,
216 log_warn(
LD_CIRC,
" Circuitmux on this channel has %u circuits, "
217 "of which %u are active. It says it has %"PRId64
218 " destroy cells queued.",
228 circuitmux_assert_okay(chan->
cmux);
236 crypto_rand((
char*) &test_circ_id,
sizeof(test_circ_id));
237 test_circ_id &= mask;
238 }
while (test_circ_id == 0);
240 test_circ_id |= high_bit;
245 else if (in_use == 2) {
252 pending_destroy_time_total += waiting;
253 if (waiting > pending_destroy_time_max)
254 pending_destroy_time_max = waiting;
256 ++n_weird_pending_destroy;
274 const char *states[] = {
"closed",
"waiting for keys",
"open"};
287 (nickname?nickname:
"*unnamed*"));
297 if (!verbose && hop->
state != CPATH_STATE_OPEN)
330 }
while (hop != circ->
cpath);
334 smartlist_free(elements);
366 tor_log(severity,domain,
"%s",s);
376 cpath = head = circ->
cpath;
384 if (!extend_info_supports_ntor(cpath->
extend_info)) {
388 }
while (cpath != head);
407 log_info(
LD_CIRC,
"Generating cpath hop failed.");
438 if (BUG(!path_supports_ntor)) {
486 return circuit_establish_circuit_with_guard(purpose, exit_ei, flags, NULL);
490circuit_establish_circuit_with_guard(uint8_t purpose,
extend_info_t *exit_ei,
492 const circuit_guard_state_t *guard_state)
507 err_reason = circuit_handle_first_hop_with_guard(circ, guard_state);
508 if (err_reason < 0) {
509 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
513 tor_trace(
TR_SUBSYS(circuit), TR_EV(establish), circ);
550 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
560 tor_trace(
TR_SUBSYS(circuit), TR_EV(establish), circ);
565circuit_guard_state_t *
589 ocirc_chan_publish(msg);
599 return circuit_handle_first_hop_with_guard(circ, NULL);
604 const circuit_guard_state_t *guard_state)
609 const char *msg = NULL;
610 int should_launch = 0;
627 "Client asked me to connect directly to a private address");
628 return -END_CIRC_REASON_TORPROTOCOL;
639 orport4 ? &orport4->addr : NULL,
640 orport6 ? &orport6->addr : NULL,
647 log_info(
LD_CIRC,
"Next router is %s: %s",
657 log_info(
LD_CIRC,
"connect to firsthop failed. Closing.");
658 return -END_CIRC_REASON_CONNECTFAILED;
668 log_debug(
LD_CIRC,
"connecting in progress (or finished). Good.");
676 circ->base_.
n_chan = n_chan;
680 log_debug(
LD_CIRC,
"Conn open for %s. Delivering first onion skin.",
683 log_info(
LD_CIRC,
"circuit_send_next_onion_skin failed.");
684 circ->base_.
n_chan = NULL;
704 log_debug(
LD_CIRC,
"chan to %s, status=%d",
715 if (circ->marked_for_close || circ->n_chan || !circ->n_hop ||
719 const char *rsa_ident = NULL;
722 rsa_ident = circ->n_hop->identity_digest;
725 ed_ident = &circ->n_hop->ed_identity;
728 if (rsa_ident == NULL && ed_ident == NULL) {
745 log_info(
LD_CIRC,
"Channel failed; closing circ.");
746 circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
750 log_debug(
LD_CIRC,
"Found circ, sending create cell.");
755 extend_info_free(circ->n_hop);
762 "send_next_onion_skin failed; circuit marked for closing.");
763 circuit_mark_for_close(circ, -err_reason);
772 circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
779 SMARTLIST_FOREACH_END(circ);
781 smartlist_free(pending_circs);
804 create_cell->
cell_type == CELL_CREATE_FAST ||
809 static ratelim_t circid_warning_limit = RATELIM_INIT(9600);
811 "failed to get unique circID.");
817 memset(&cell, 0,
sizeof(
cell_t));
818 r = relayed ? create_cell_format_relayed(&cell, create_cell)
819 : create_cell_format(&cell, create_cell);
821 log_warn(
LD_CIRC,
"Couldn't format create cell");
824 log_debug(
LD_CIRC,
"Chosen circID %u.", (
unsigned)
id);
836 if (!CHANNEL_IS_OPEN(circ->
n_chan)) {
838 "Got first hop for a circuit without an opened channel. "
864 return ! circuit_has_usable_onion_key(circ);
897 uint16_t *handshake_type_out,
902 *cell_type_out = CELL_CREATE2;
906 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR_V3;
908 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR_V3;
910 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR;
924 uint8_t *create_cell_type_out,
925 uint16_t *handshake_type_out,
931 *cell_type_out = RELAY_COMMAND_EXTEND2;
932 *create_cell_type_out = CELL_CREATE2;
982 if (circ->
cpath->
state == CPATH_STATE_CLOSED) {
1018 memset(&cc, 0,
sizeof(cc));
1020 log_debug(
LD_CIRC,
"First skin; sending create cell.");
1054 log_warn(
LD_CIRC,
"onion_skin_create (first hop) failed.");
1055 return - END_CIRC_REASON_INTERNAL;
1060 return - END_CIRC_REASON_RESOURCELIMIT;
1061 tor_trace(
TR_SUBSYS(circuit), TR_EV(first_onion_skin), circ, circ->
cpath);
1063 circ->
cpath->
state = CPATH_STATE_AWAITING_KEYS;
1065 log_info(
LD_CIRC,
"First hop: finished sending %s cell to '%s'",
1066 fast ?
"CREATE_FAST" :
"CREATE",
1085 log_warn(
LD_BUG,
"%d-hop circuit %p with purpose %d has no "
1089 r = GUARD_USABLE_NOW;
1093 const int is_usable_for_streams = (r == GUARD_USABLE_NOW);
1094 if (r == GUARD_USABLE_NOW) {
1096 }
else if (r == GUARD_MAYBE_USABLE_LATER) {
1101 tor_assert_nonfatal(r == GUARD_USABLE_NEVER);
1102 return - END_CIRC_REASON_INTERNAL;
1111 log_info(
LD_CIRC,
"circuit built!");
1119 if (is_usable_for_streams)
1127 "Tor has successfully opened a circuit. "
1128 "Looks like client functionality is working.");
1132 if (server_mode(options) &&
1133 !router_all_orports_seem_reachable(options)) {
1140 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
1159 const bool include_ipv6 = server_mode(
get_options());
1160 memset(&ec, 0,
sizeof(ec));
1164 log_debug(
LD_CIRC,
"starting to send subsequent skin.");
1175 int n_addrs_set = 0;
1181 if (orport6 && include_ipv6) {
1187 if (n_addrs_set == 0) {
1188 log_warn(
LD_BUG,
"No supported address family found in extend_info.");
1189 return - END_CIRC_REASON_INTERNAL;
1202 log_warn(
LD_CIRC,
"onion_skin_create failed.");
1203 return - END_CIRC_REASON_INTERNAL;
1207 log_info(
LD_CIRC,
"Sending extend relay cell.");
1210 uint16_t payload_len=0;
1213 log_warn(
LD_CIRC,
"Couldn't format extend cell");
1214 return -END_CIRC_REASON_INTERNAL;
1219 log_warn(
LD_BUG,
"Generated a too-long extend cell");
1220 return -END_CIRC_REASON_INTERNAL;
1225 if (relay_send_command_from_edge(0,
TO_CIRCUIT(circ),
1227 (
char*)payload, payload_len,
1231 hop->
state = CPATH_STATE_AWAITING_KEYS;
1232 tor_trace(
TR_SUBSYS(circuit), TR_EV(intermediate_onion_skin), circ, hop);
1246 " seconds; assuming established circuits no longer work.",
1250 "Your system clock just jumped %"PRId64
" seconds %s; "
1251 "assuming established circuits no longer work.",
1253 seconds_elapsed >=0 ? seconds_elapsed : -seconds_elapsed),
1254 seconds_elapsed >=0 ?
"forward" :
"backward");
1258 (seconds_elapsed), was_idle?1:0);
1265 if (seconds_elapsed < 0) {
1289 log_warn(
LD_CIRC,
"pathbias_count_build_attempt failed: %d", rv);
1293 if (circ->
cpath->
state == CPATH_STATE_AWAITING_KEYS) {
1298 log_warn(
LD_PROTOCOL,
"got extended when circ already built? Closing.");
1299 return - END_CIRC_REASON_TORPROTOCOL;
1305 size_t keylen =
sizeof(keys);
1307 const char *msg = NULL;
1312 (uint8_t*)keys, &keylen,
1317 log_warn(
LD_CIRC,
"onion_skin_client_handshake failed: %s", msg);
1318 return -END_CIRC_REASON_TORPROTOCOL;
1324 hop, keys, keylen)<0) {
1325 return -END_CIRC_REASON_TORPROTOCOL;
1345 "Unexpected path length %d for exit circuit %d, purpose %d",
1354 "Unexpected path length %d for exit circuit %d, purpose %d",
1363 hop->
state = CPATH_STATE_OPEN;
1364 log_info(
LD_CIRC,
"Finished building circuit hop:");
1394 while (layer->next != circ->
cpath) {
1396 victim = layer->next;
1397 log_debug(
LD_CIRC,
"Killing a layer of the cpath.");
1400 if (stream->cpath_layer == victim) {
1401 log_info(
LD_APP,
"Marking stream %d for close because of truncate.",
1406 connection_mark_unattached_ap(stream, END_STREAM_REASON_DESTROY);
1410 layer->next = victim->next;
1418 log_info(
LD_CIRC,
"finished");
1464 int known_purpose = 0;
1533 if (BUG(exit_ei && !known_purpose)) {
1534 log_warn(
LD_BUG,
"Unhandled purpose %d with a chosen exit; "
1535 "assuming routelen %d.", purpose, routelen);
1559 log_debug(
LD_CIRC,
"Chosen route length %d (%d direct and %d indirect "
1560 "routers suitable).", routelen, num_acceptable_direct,
1561 num_acceptable_indirect);
1563 if (num_acceptable_direct < 1 || num_acceptable_indirect < routelen - 1) {
1565 "Not enough acceptable routers (%d/%d direct and %d/%d "
1566 "indirect routers suitable). Discarding this circuit.",
1567 num_acceptable_direct, routelen,
1568 num_acceptable_indirect, routelen);
1593 int *need_capacity))
1603 enough = (smartlist_len(sl) == 0);
1604 for (i = 0; i < smartlist_len(sl); ++i) {
1605 port = smartlist_get(sl, i);
1623 for (i = 0; i < smartlist_len(needed_ports); ++i) {
1627 port = *(uint16_t *)smartlist_get(needed_ports, i);
1673 int n_pending_connections = 0;
1675 int best_support = -1;
1676 int n_best_support=0;
1679 const node_t *selected_node=NULL;
1680 const int need_uptime = (flags & CRN_NEED_UPTIME) != 0;
1681 const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
1704 ++n_pending_connections;
1716 n_supported = tor_calloc(smartlist_len(the_nodes),
sizeof(
int));
1718 const int i = node_sl_idx;
1720 n_supported[i] = -1;
1727 if (!router_can_choose_node(node, flags)) {
1728 n_supported[i] = -1;
1731 if (node->is_bad_exit) {
1732 n_supported[i] = -1;
1736 n_supported[i] = -1;
1741 n_supported[i] = -1;
1745 n_supported[i] = -1;
1763 } SMARTLIST_FOREACH_END(conn);
1764 if (n_pending_connections > 0 && n_supported[i] == 0) {
1769 if (n_supported[i] > best_support) {
1772 best_support = n_supported[i]; n_best_support=1;
1775 }
else if (n_supported[i] == best_support) {
1780 } SMARTLIST_FOREACH_END(node);
1782 "Found %d servers that might support %d/%d pending connections.",
1783 n_best_support, best_support >= 0 ? best_support : 0,
1784 n_pending_connections);
1788 if (best_support > 0) {
1792 if (n_supported[node_sl_idx] == best_support)
1797 smartlist_free(supporting);
1806 if (best_support == -1) {
1807 if (need_uptime || need_capacity) {
1809 "We couldn't find any live%s%s routers; falling back "
1810 "to list of all routers.",
1811 need_capacity?
", fast":
"",
1812 need_uptime?
", stable":
"");
1814 flags &= ~(CRN_NEED_UPTIME|CRN_NEED_CAPACITY);
1817 log_notice(
LD_CIRC,
"All routers are down or won't exit%s -- "
1818 "choosing a doomed exit at random.",
1823 for (attempt = 0; attempt < 2; attempt++) {
1827 if (n_supported[node_sl_idx] != -1 &&
1833 } SMARTLIST_FOREACH_END(node);
1841 if (smartlist_len(needed_ports))
1845 smartlist_free(needed_ports);
1846 smartlist_free(supporting);
1850 if (selected_node) {
1852 return selected_node;
1856 "No exits in ExitNodes%s seem to be running: "
1857 "can't choose an exit.",
1859 ", except possibly those excluded by your configuration, " :
"");
1879 const routerset_t *pick_from,
1880 const routerset_t *exclude_set,
1884 const node_t *middle_node = NULL;
1900 } SMARTLIST_FOREACH_END(live_node);
1917#define MAX_SANE_RESTRICTED_NODES 20
1924 if (smartlist_len(allowlisted_live_middles) <=
1925 MAX_SANE_RESTRICTED_NODES) {
1928 static ratelim_t pinned_notice_limit = RATELIM_INIT(24*3600);
1930 "Your _HSLayer%dNodes setting has resulted "
1931 "in %d total nodes. This is a lot of nodes. "
1932 "You may want to consider using a Tor controller "
1933 "to select and update a smaller set of nodes instead.",
1934 position_hint, smartlist_len(allowlisted_live_middles));
1944 smartlist_free(allowlisted_live_middles);
1945 smartlist_free(all_live_nodes);
1965 flags |= CRN_NEED_DESC;
1974 tor_assert_nonfatal(is_internal);
1976 flags |= CRN_FOR_HS;
1998 const char *description;
1999 uint8_t purpose = circ->base_.
purpose;
2011 log_warn(
LD_BUG,
"Called on non-origin circuit (purpose %d, %s)",
2019 case CIRCUIT_PURPOSE_CONFLUX_LINKED:
2022 description =
"requested exit node";
2037 description =
"chosen rendezvous point";
2041 description =
"controller-selected circuit target";
2048 log_warn(
LD_BUG,
"Using %s '%s' which is listed in ExcludeNodes%s, "
2049 "even though StrictNodes is set. Please report. "
2050 "(Circuit purpose: %s)",
2055 log_warn(
LD_CIRC,
"Using %s '%s' which is listed in "
2056 "ExcludeNodes%s, because no better options were available. To "
2057 "prevent this (and possibly break your Tor functionality), "
2058 "set the StrictNodes configuration option. "
2059 "(Circuit purpose: %s)",
2081 flags |= CRN_NEED_UPTIME;
2083 flags |= CRN_NEED_CAPACITY;
2101 if (state->is_ipv6_selftest && cur_len == state->desired_path_len - 2)
2102 return CRN_INITIATE_IPV6_EXTEND;
2121 log_debug(LD_CIRC,
"Launching a one-hop circuit for dir tunnel%s.",
2122 (hs_service_allow_non_anonymous_connection(get_options()) ?
2123 ", or intro or rendezvous connection" :
""));
2124 state->desired_path_len = 1;
2126 int r = new_route_len(circ->base_.purpose, exit_ei, nodelist_get_list());
2129 state->desired_path_len = r;
2134 log_info(
LD_CIRC,
"Using requested exit node '%s'",
2139 flags |= cpath_build_state_to_crn_flags(state);
2143 flags |= CRN_DIRECT_CONN;
2145 flags |= CRN_CONFLUX;
2149 log_warn(
LD_CIRC,
"Failed to choose an exit server");
2159 if (BUG(exit_ei == NULL))
2202 log_warn(
LD_CIRC,
"Couldn't extend circuit to new point %s.",
2204 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
2222 int flags = CRN_NEED_DESC;
2225 flags |= CRN_DIRECT_CONN;
2231 if (!router_can_choose_node(node, flags))
2234 } SMARTLIST_FOREACH_END(node);
2295 for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->
next) {
2338 for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->
next) {
2350 uint8_t purpose,
int cur_len)
2383 const routerset_t *vanguard_routerset = NULL;
2384 const node_t *node = NULL;
2390 }
else if (cur_len == 2) {
2398 if (BUG(!vanguard_routerset)) {
2407 static ratelim_t pinned_warning_limit = RATELIM_INIT(300);
2409 "Could not find a node that matches the configured "
2410 "_HSLayer%dNodes set", cur_len+1);
2433 tor_assert(CIRCUIT_PURPOSE_MIN_ <= purpose &&
2434 purpose <= CIRCUIT_PURPOSE_MAX_);
2436 log_debug(
LD_CIRC,
"Contemplating intermediate hop #%d: random choice.",
2441 flags |= cpath_build_state_to_crn_flags(state);
2442 flags |= cpath_build_state_to_crn_ipv6_extend_flag(state, cur_len);
2446 log_debug(
LD_GENERAL,
"Picking a sticky node (cur_len = %d)", cur_len);
2448 smartlist_free(excluded);
2470 smartlist_free(excluded);
2486 circuit_guard_state_t **guard_state_out)
2500 tor_assert_nonfatal(state);
2519 flags |= cpath_build_state_to_crn_flags(state);
2523 smartlist_free(excluded);
2536 uint8_t purpose = circ->base_.
purpose;
2542 log_debug(
LD_CIRC,
"Path is complete: %d steps long",
2547 log_debug(
LD_CIRC,
"Path is %d long; we want %d", cur_len,
2552 }
else if (cur_len == 0) {
2562 tor_assert_nonfatal(info || client);
2579 "Failed to find node for hop #%d of our path. Discarding "
2580 "this circuit.", cur_len+1);
2583 "Failed to find node for hop #%d of our path. Discarding "
2584 "this circuit.", cur_len+1);
2589 log_debug(
LD_CIRC,
"Chose router %s for hop #%d (exit is %s)",
2594 extend_info_free(info);
2652 if (to_upgrade == NULL)
2655 log_info(
LD_GUARD,
"Upgrading %d circuits from 'waiting for better guard' "
2656 "to 'open'.", smartlist_len(to_upgrade));
2661 } SMARTLIST_FOREACH_END(circ);
2663 smartlist_free(to_upgrade);
2668#define EXT_TYPE_SUBPROTO 3
2679 trn_extension_field_t *fld = NULL;
2680 trn_subproto_request_t *req = NULL;
2681 trn_subproto_request_ext_t *req_ext = NULL;
2684 fld = trn_extension_field_new();
2685 req_ext = trn_subproto_request_ext_new();
2687 req = trn_subproto_request_new();
2688 req->protocol_id = PRT_RELAY;
2690 trn_subproto_request_ext_add_reqs(req_ext, req);
2696 ssize_t len = trn_subproto_request_ext_encoded_len(req_ext);
2699 if (BUG(len > UINT8_MAX))
2702 trn_extension_field_setlen_field(fld, len);
2703 trn_extension_field_set_field_type(fld, EXT_TYPE_SUBPROTO);
2704 trn_extension_field_set_field_len(fld, len);
2705 uint8_t *out = trn_extension_field_getarray_field(fld);
2706 ssize_t len2 = trn_subproto_request_ext_encode(out, len, req_ext);
2707 if (BUG(len != len2))
2710 trn_extension_add_fields(ext, fld);
2717 trn_subproto_request_ext_free(req_ext);
2718 trn_subproto_request_free(req);
2719 trn_extension_field_free(fld);
2728 const trn_extension_field_t *fa = *(trn_extension_field_t **)a;
2729 const trn_extension_field_t *fb = *(trn_extension_field_t **)b;
2730 uint8_t ta = trn_extension_field_get_field_type(fa);
2731 uint8_t tb = trn_extension_field_get_field_type(fb);
2751 size_t *msg_len_out,
2754 tor_assert(ei && msg_out && msg_len_out && params_out);
2755 bool cc_enabled =
false;
2759 trn_extension_t *ext = trn_extension_new();
2777 size_t n_fields = trn_extension_getlen_fields(ext);
2778 qsort(trn_extension_getarray_fields(ext),
2779 n_fields,
sizeof(trn_extension_field_t *),
2782 trn_extension_set_num(ext, n_fields);
2784 ssize_t total_len = trn_extension_encoded_len(ext);
2785 if (BUG(total_len < 0))
2788 *msg_out = tor_malloc_zero(total_len);
2789 *msg_len_out = total_len;
2790 if (BUG(trn_extension_encode(*msg_out, total_len, ext) < 0)) {
2793 trn_extension_free(ext);
2797 trn_extension_free(ext);
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_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)
const char * channel_state_to_string(channel_state_t state)
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_describe_peer(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, const struct circuit_guard_state_t *guard_state, bool for_origin_circ)
void channel_dump_statistics(channel_t *chan, int severity)
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)
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 client_circ_negotiation_message(const extend_info_t *ei, uint8_t **msg_out, size_t *msg_len_out, circuit_params_t *params_out)
int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
STATIC int count_acceptable_nodes(const smartlist_t *nodes, int direct)
const char * build_state_get_exit_nickname(cpath_build_state_t *state)
static int build_cgo_subproto_request(trn_extension_t *ext)
int circuit_handle_first_hop(origin_circuit_t *circ)
static int middle_node_must_be_vanguard(const or_options_t *options, uint8_t purpose, int cur_len)
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
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)
STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan)
static smartlist_t * build_middle_exclude_list(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei)
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)
void circuit_n_chan_done(channel_t *chan, int status)
STATIC int new_route_len(uint8_t purpose, extend_info_t *exit_ei, const smartlist_t *nodes)
static const node_t * choose_good_middle_server(const origin_circuit_t *, uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
circuit_guard_state_t * origin_circuit_get_guard_state(origin_circuit_t *circ)
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)
static int ap_stream_wants_exit_attention(connection_t *conn)
STATIC int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
const uint8_t * build_state_get_exit_rsa_id(cpath_build_state_t *state)
static smartlist_t * build_vanguard_middle_exclude_list(uint8_t purpose, cpath_build_state_t *state, crypt_path_t *head, int cur_len)
static int circuit_cpath_supports_ntor(const origin_circuit_t *circ)
int circuit_timeout_want_to_count_circ(const origin_circuit_t *circ)
static smartlist_t * circuit_get_unhandled_ports(time_t now)
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 const node_t * choose_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)
origin_circuit_t * circuit_establish_circuit_conflux(const uint8_t *conflux_nonce, uint8_t purpose, extend_info_t *exit_ei, int flags)
char * circuit_list_path(origin_circuit_t *circ, int verbose)
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 int ext_cmp(const void *a, const void *b)
int circuit_finish_handshake(origin_circuit_t *circ, const created_cell_t *reply)
static const node_t * choose_good_exit_server_general(router_crn_flags_t flags)
int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
origin_circuit_t * circuit_establish_circuit(uint8_t purpose, extend_info_t *exit_ei, int flags)
int circuit_truncated(origin_circuit_t *circ, int reason)
const node_t * choose_good_entry_server(const origin_circuit_t *circ, uint8_t purpose, cpath_build_state_t *state, circuit_guard_state_t **guard_state_out)
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)
const node_t * build_state_get_exit_node(cpath_build_state_t *state)
channel_t * channel_connect_for_circuit(const extend_info_t *ei, const struct circuit_guard_state_t *guard_state, bool for_origin_circ)
static int node_handles_some_port(const node_t *node, smartlist_t *needed_ports)
static char * circuit_list_path_impl(origin_circuit_t *circ, int verbose, int verbose_names)
void circuit_upgrade_circuits_from_guard_wait(void)
origin_circuit_t * origin_circuit_init(uint8_t purpose, int flags)
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)
void circuit_set_state(circuit_t *circ, uint8_t state)
smartlist_t * circuit_find_circuits_to_upgrade_from_guard_wait(void)
origin_circuit_t * origin_circuit_new(void)
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
int circuit_get_cpath_len(origin_circuit_t *circ)
int circuit_get_cpath_opened_len(const origin_circuit_t *circ)
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)
crypt_path_t * circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
const char * circuit_purpose_to_string(uint8_t purpose)
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_CONFLUX_UNLINKED
#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_INTERNAL
#define CIRCLAUNCH_NEED_UPTIME
#define CIRCLAUNCH_NEED_CONFLUX
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.
void conflux_add_middles_to_exclude_list(const origin_circuit_t *orig_circ, smartlist_t *excluded)
Header file for conflux_pool.c.
congestion_control_t * congestion_control_new(const circuit_params_t *params, cc_path_t path)
int congestion_control_build_ext_request(trn_extension_t *ext)
Public APIs for congestion control.
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)
entry_connection_t * TO_ENTRY_CONN(connection_t *c)
edge_connection_t * TO_EDGE_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.
crypt_path_t * cpath_get_next_non_open_hop(crypt_path_t *cpath)
int cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
int cpath_init_circuit_crypto(relay_crypto_alg_t alg, crypt_path_t *cpath, const char *key_data, size_t key_data_len)
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 * smartlist_choose(const smartlist_t *sl)
void crypto_rand(char *to, size_t n)
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.
const routerset_t * get_layer2_guards(void)
guard_usable_t entry_guard_succeeded(circuit_guard_state_t **guard_state_p)
bool vanguards_lite_is_enabled(void)
const node_t * guards_choose_guard(const origin_circuit_t *circ, 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.
extend_info_t * extend_info_dup(extend_info_t *info)
extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect, bool for_exit)
const tor_addr_port_t * extend_info_pick_orport(const extend_info_t *ei)
const tor_addr_port_t * extend_info_get_orport(const extend_info_t *ei, int family)
bool extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
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.
const node_t * node_get_by_id(const char *identity_digest)
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)
void node_get_verbose_nickname(const node_t *node, char *verbose_name_out)
int router_have_minimum_dir_info(void)
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_create(int type, const extend_info_t *node, onion_handshake_state_t *state_out, uint8_t *onion_skin_out, size_t onion_skin_out_maxlen)
void onion_handshake_state_release(onion_handshake_state_t *state)
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_len_out, uint8_t *rend_authenticator_out, circuit_params_t *params_out, const char **msg_out)
Header file for onion_crypto.c.
Header file for onion_fast.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 END_CIRC_REASON_FLAG_REMOTE
#define RELAY_PAYLOAD_SIZE_MAX
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.
Headers and type declarations for protover.c.
#define PROTOVER_RELAY_CRYPT_CGO
char * rate_limit_log(ratelim_t *lim, time_t now)
int append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, cell_t *cell, cell_direction_t direction, streamid_t fromstream)
size_t circuit_max_relay_payload(const circuit_t *circ, const crypt_path_t *cpath, uint8_t relay_command)
#define MAX_RELAY_KEY_MATERIAL_LEN
@ RELAY_CRYPTO_ALG_CGO_CLIENT
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.
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
relay_cell_fmt_t cell_fmt
relay_crypto_alg_t crypto_alg
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
unsigned int need_conflux
uint8_t onionskin[MAX_CREATE_LEN]
uint8_t reply[MAX_CREATED_LEN]
struct crypt_path_t * prev
struct crypt_path_t * next
relay_cell_fmt_t relay_cell_format
extend_info_t * extend_info
char rend_circ_nonce[DIGEST_LEN]
onion_handshake_state_t handshake_state
struct congestion_control_t * ccontrol
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]
bool use_congestion_control
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)