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"
136#define MAX_CIRCID_ATTEMPTS 64
138 unsigned n_with_circ = 0, n_pending_destroy = 0, n_weird_pending_destroy = 0;
142 int64_t pending_destroy_time_total = 0;
143 int64_t pending_destroy_time_max = 0;
149 "Trying to pick a circuit ID for a connection from "
150 "a client with no identity.");
153 max_range = (chan->wide_circ_ids) ? (1u<<31) : (1u<<15);
154 mask = max_range - 1;
157 if (++attempts > MAX_CIRCID_ATTEMPTS) {
174 int64_t queued_destroys;
179 if (n_pending_destroy)
180 pending_destroy_time_total /= n_pending_destroy;
181 log_warn(
LD_CIRC,
"No unused circIDs found on channel %s wide "
182 "circID support, with %u inbound and %u outbound circuits. "
183 "Found %u circuit IDs in use by circuits, and %u with "
184 "pending destroy cells. (%u of those were marked bogusly.) "
185 "The ones with pending destroy cells "
186 "have been marked unusable for an average of %ld seconds "
187 "and a maximum of %ld seconds. This channel is %ld seconds "
188 "old. Failing a circuit.%s",
189 chan->wide_circ_ids ?
"with" :
"without",
191 n_with_circ, n_pending_destroy, n_weird_pending_destroy,
192 (
long)pending_destroy_time_total,
193 (
long)pending_destroy_time_max,
200 log_warn(
LD_BUG,
" This channel somehow has no cmux on it!");
208 queued_destroys = circuitmux_count_queued_destroy_cells(chan,
211 log_warn(
LD_CIRC,
" Circuitmux on this channel has %u circuits, "
212 "of which %u are active. It says it has %"PRId64
213 " destroy cells queued.",
223 circuitmux_assert_okay(chan->
cmux);
231 crypto_rand((
char*) &test_circ_id,
sizeof(test_circ_id));
232 test_circ_id &= mask;
233 }
while (test_circ_id == 0);
235 test_circ_id |= high_bit;
240 else if (in_use == 2) {
247 pending_destroy_time_total += waiting;
248 if (waiting > pending_destroy_time_max)
249 pending_destroy_time_max = waiting;
251 ++n_weird_pending_destroy;
269 const char *states[] = {
"closed",
"waiting for keys",
"open"};
282 (nickname?nickname:
"*unnamed*"));
292 if (!verbose && hop->
state != CPATH_STATE_OPEN)
325 }
while (hop != circ->
cpath);
329 smartlist_free(elements);
361 tor_log(severity,domain,
"%s",s);
371 cpath = head = circ->
cpath;
379 if (!extend_info_supports_ntor(cpath->
extend_info)) {
383 }
while (cpath != head);
402 log_info(
LD_CIRC,
"Generating cpath hop failed.");
433 if (BUG(!path_supports_ntor)) {
495 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
499 tor_trace(
TR_SUBSYS(circuit), TR_EV(establish), circ);
536 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
540 tor_trace(
TR_SUBSYS(circuit), TR_EV(establish), circ);
545circuit_guard_state_t *
569 ocirc_chan_publish(msg);
582 const char *msg = NULL;
583 int should_launch = 0;
600 "Client asked me to connect directly to a private address");
601 return -END_CIRC_REASON_TORPROTOCOL;
612 orport4 ? &orport4->addr : NULL,
613 orport6 ? &orport6->addr : NULL,
620 log_info(
LD_CIRC,
"Next router is %s: %s",
628 log_info(
LD_CIRC,
"connect to firsthop failed. Closing.");
629 return -END_CIRC_REASON_CONNECTFAILED;
639 log_debug(
LD_CIRC,
"connecting in progress (or finished). Good.");
647 circ->base_.
n_chan = n_chan;
651 log_debug(
LD_CIRC,
"Conn open for %s. Delivering first onion skin.",
654 log_info(
LD_CIRC,
"circuit_send_next_onion_skin failed.");
655 circ->base_.
n_chan = NULL;
679 log_debug(
LD_CIRC,
"chan to %s, status=%d",
690 if (circ->marked_for_close || circ->n_chan || !circ->n_hop ||
694 const char *rsa_ident = NULL;
697 rsa_ident = circ->n_hop->identity_digest;
700 ed_ident = &circ->n_hop->ed_identity;
703 if (rsa_ident == NULL && ed_ident == NULL) {
720 log_info(
LD_CIRC,
"Channel failed; closing circ.");
721 circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
726 log_info(
LD_CIRC,
"Channel deprecated for origin circs; closing circ.");
727 circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
730 log_debug(
LD_CIRC,
"Found circ, sending create cell.");
735 extend_info_free(circ->n_hop);
742 "send_next_onion_skin failed; circuit marked for closing.");
743 circuit_mark_for_close(circ, -err_reason);
752 circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
759 SMARTLIST_FOREACH_END(circ);
761 smartlist_free(pending_circs);
784 create_cell->
cell_type == CELL_CREATE_FAST ||
789 static ratelim_t circid_warning_limit = RATELIM_INIT(9600);
791 "failed to get unique circID.");
797 memset(&cell, 0,
sizeof(
cell_t));
798 r = relayed ? create_cell_format_relayed(&cell, create_cell)
799 : create_cell_format(&cell, create_cell);
801 log_warn(
LD_CIRC,
"Couldn't format create cell");
804 log_debug(
LD_CIRC,
"Chosen circID %u.", (
unsigned)
id);
816 if (!CHANNEL_IS_OPEN(circ->
n_chan)) {
818 "Got first hop for a circuit without an opened channel. "
844 return ! circuit_has_usable_onion_key(circ);
877 uint16_t *handshake_type_out,
882 *cell_type_out = CELL_CREATE2;
887 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR_V3;
889 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR_V3;
891 *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR;
905 uint8_t *create_cell_type_out,
906 uint16_t *handshake_type_out,
912 *cell_type_out = RELAY_COMMAND_EXTEND2;
913 *create_cell_type_out = CELL_CREATE2;
963 if (circ->
cpath->
state == CPATH_STATE_CLOSED) {
999 memset(&cc, 0,
sizeof(cc));
1001 log_debug(
LD_CIRC,
"First skin; sending create cell.");
1035 log_warn(
LD_CIRC,
"onion_skin_create (first hop) failed.");
1036 return - END_CIRC_REASON_INTERNAL;
1041 return - END_CIRC_REASON_RESOURCELIMIT;
1042 tor_trace(
TR_SUBSYS(circuit), TR_EV(first_onion_skin), circ, circ->
cpath);
1044 circ->
cpath->
state = CPATH_STATE_AWAITING_KEYS;
1046 log_info(
LD_CIRC,
"First hop: finished sending %s cell to '%s'",
1047 fast ?
"CREATE_FAST" :
"CREATE",
1066 log_warn(
LD_BUG,
"%d-hop circuit %p with purpose %d has no "
1070 r = GUARD_USABLE_NOW;
1074 const int is_usable_for_streams = (r == GUARD_USABLE_NOW);
1075 if (r == GUARD_USABLE_NOW) {
1077 }
else if (r == GUARD_MAYBE_USABLE_LATER) {
1082 tor_assert_nonfatal(r == GUARD_USABLE_NEVER);
1083 return - END_CIRC_REASON_INTERNAL;
1092 log_info(
LD_CIRC,
"circuit built!");
1100 if (is_usable_for_streams)
1108 "Tor has successfully opened a circuit. "
1109 "Looks like client functionality is working.");
1114 !router_all_orports_seem_reachable(options)) {
1121 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
1141 memset(&ec, 0,
sizeof(ec));
1145 log_debug(
LD_CIRC,
"starting to send subsequent skin.");
1156 int n_addrs_set = 0;
1162 if (orport6 && include_ipv6) {
1168 if (n_addrs_set == 0) {
1169 log_warn(
LD_BUG,
"No supported address family found in extend_info.");
1170 return - END_CIRC_REASON_INTERNAL;
1183 log_warn(
LD_CIRC,
"onion_skin_create failed.");
1184 return - END_CIRC_REASON_INTERNAL;
1188 log_info(
LD_CIRC,
"Sending extend relay cell.");
1191 uint16_t payload_len=0;
1194 log_warn(
LD_CIRC,
"Couldn't format extend cell");
1195 return -END_CIRC_REASON_INTERNAL;
1200 log_warn(
LD_BUG,
"Generated a too-long extend cell");
1201 return -END_CIRC_REASON_INTERNAL;
1206 if (relay_send_command_from_edge(0,
TO_CIRCUIT(circ),
1208 (
char*)payload, payload_len,
1212 hop->
state = CPATH_STATE_AWAITING_KEYS;
1213 tor_trace(
TR_SUBSYS(circuit), TR_EV(intermediate_onion_skin), circ, hop);
1227 " seconds; assuming established circuits no longer work.",
1231 "Your system clock just jumped %"PRId64
" seconds %s; "
1232 "assuming established circuits no longer work.",
1234 seconds_elapsed >=0 ? seconds_elapsed : -seconds_elapsed),
1235 seconds_elapsed >=0 ?
"forward" :
"backward");
1239 (seconds_elapsed), was_idle?1:0);
1246 if (seconds_elapsed < 0) {
1270 log_warn(
LD_CIRC,
"pathbias_count_build_attempt failed: %d", rv);
1274 if (circ->
cpath->
state == CPATH_STATE_AWAITING_KEYS) {
1279 log_warn(
LD_PROTOCOL,
"got extended when circ already built? Closing.");
1280 return - END_CIRC_REASON_TORPROTOCOL;
1286 size_t keylen =
sizeof(keys);
1288 const char *msg = NULL;
1293 (uint8_t*)keys, &keylen,
1298 log_warn(
LD_CIRC,
"onion_skin_client_handshake failed: %s", msg);
1299 return -END_CIRC_REASON_TORPROTOCOL;
1305 hop, keys, keylen)<0) {
1306 return -END_CIRC_REASON_TORPROTOCOL;
1326 "Unexpected path length %d for exit circuit %d, purpose %d",
1335 "Unexpected path length %d for exit circuit %d, purpose %d",
1344 hop->
state = CPATH_STATE_OPEN;
1345 log_info(
LD_CIRC,
"Finished building circuit hop:");
1375 while (layer->next != circ->
cpath) {
1377 victim = layer->next;
1378 log_debug(
LD_CIRC,
"Killing a layer of the cpath.");
1381 if (stream->cpath_layer == victim) {
1382 log_info(
LD_APP,
"Marking stream %d for close because of truncate.",
1387 connection_mark_unattached_ap(stream, END_STREAM_REASON_DESTROY);
1391 layer->next = victim->next;
1395 log_info(
LD_CIRC,
"finished");
1441 int known_purpose = 0;
1510 if (BUG(exit_ei && !known_purpose)) {
1511 log_warn(
LD_BUG,
"Unhandled purpose %d with a chosen exit; "
1512 "assuming routelen %d.", purpose, routelen);
1536 log_debug(
LD_CIRC,
"Chosen route length %d (%d direct and %d indirect "
1537 "routers suitable).", routelen, num_acceptable_direct,
1538 num_acceptable_indirect);
1540 if (num_acceptable_direct < 1 || num_acceptable_indirect < routelen - 1) {
1542 "Not enough acceptable routers (%d/%d direct and %d/%d "
1543 "indirect routers suitable). Discarding this circuit.",
1544 num_acceptable_direct, routelen,
1545 num_acceptable_indirect, routelen);
1570 int *need_capacity))
1580 enough = (smartlist_len(sl) == 0);
1581 for (i = 0; i < smartlist_len(sl); ++i) {
1582 port = smartlist_get(sl, i);
1600 for (i = 0; i < smartlist_len(needed_ports); ++i) {
1604 port = *(uint16_t *)smartlist_get(needed_ports, i);
1650 int n_pending_connections = 0;
1652 int best_support = -1;
1653 int n_best_support=0;
1656 const node_t *selected_node=NULL;
1657 const int need_uptime = (flags & CRN_NEED_UPTIME) != 0;
1658 const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
1681 ++n_pending_connections;
1693 n_supported = tor_calloc(smartlist_len(the_nodes),
sizeof(
int));
1695 const int i = node_sl_idx;
1697 n_supported[i] = -1;
1704 if (!router_can_choose_node(node, flags)) {
1705 n_supported[i] = -1;
1708 if (node->is_bad_exit) {
1709 n_supported[i] = -1;
1713 n_supported[i] = -1;
1718 n_supported[i] = -1;
1722 n_supported[i] = -1;
1740 } SMARTLIST_FOREACH_END(conn);
1741 if (n_pending_connections > 0 && n_supported[i] == 0) {
1746 if (n_supported[i] > best_support) {
1749 best_support = n_supported[i]; n_best_support=1;
1752 }
else if (n_supported[i] == best_support) {
1757 } SMARTLIST_FOREACH_END(node);
1759 "Found %d servers that might support %d/%d pending connections.",
1760 n_best_support, best_support >= 0 ? best_support : 0,
1761 n_pending_connections);
1765 if (best_support > 0) {
1769 if (n_supported[node_sl_idx] == best_support)
1774 smartlist_free(supporting);
1783 if (best_support == -1) {
1784 if (need_uptime || need_capacity) {
1786 "We couldn't find any live%s%s routers; falling back "
1787 "to list of all routers.",
1788 need_capacity?
", fast":
"",
1789 need_uptime?
", stable":
"");
1791 flags &= ~(CRN_NEED_UPTIME|CRN_NEED_CAPACITY);
1794 log_notice(
LD_CIRC,
"All routers are down or won't exit%s -- "
1795 "choosing a doomed exit at random.",
1800 for (attempt = 0; attempt < 2; attempt++) {
1804 if (n_supported[node_sl_idx] != -1 &&
1810 } SMARTLIST_FOREACH_END(node);
1818 if (smartlist_len(needed_ports))
1822 smartlist_free(needed_ports);
1823 smartlist_free(supporting);
1827 if (selected_node) {
1829 return selected_node;
1833 "No exits in ExitNodes%s seem to be running: "
1834 "can't choose an exit.",
1836 ", except possibly those excluded by your configuration, " :
"");
1856 const routerset_t *pick_from,
1857 const routerset_t *exclude_set,
1861 const node_t *middle_node = NULL;
1877 } SMARTLIST_FOREACH_END(live_node);
1894#define MAX_SANE_RESTRICTED_NODES 20
1901 if (smartlist_len(allowlisted_live_middles) <=
1902 MAX_SANE_RESTRICTED_NODES) {
1905 static ratelim_t pinned_notice_limit = RATELIM_INIT(24*3600);
1907 "Your _HSLayer%dNodes setting has resulted "
1908 "in %d total nodes. This is a lot of nodes. "
1909 "You may want to consider using a Tor controller "
1910 "to select and update a smaller set of nodes instead.",
1911 position_hint, smartlist_len(allowlisted_live_middles));
1921 smartlist_free(allowlisted_live_middles);
1922 smartlist_free(all_live_nodes);
1942 flags |= CRN_NEED_DESC;
1951 tor_assert_nonfatal(is_internal);
1953 flags |= CRN_FOR_HS;
1975 const char *description;
1976 uint8_t purpose = circ->base_.
purpose;
1988 log_warn(
LD_BUG,
"Called on non-origin circuit (purpose %d, %s)",
1996 case CIRCUIT_PURPOSE_CONFLUX_LINKED:
1999 description =
"requested exit node";
2014 description =
"chosen rendezvous point";
2018 description =
"controller-selected circuit target";
2025 log_warn(
LD_BUG,
"Using %s '%s' which is listed in ExcludeNodes%s, "
2026 "even though StrictNodes is set. Please report. "
2027 "(Circuit purpose: %s)",
2032 log_warn(
LD_CIRC,
"Using %s '%s' which is listed in "
2033 "ExcludeNodes%s, because no better options were available. To "
2034 "prevent this (and possibly break your Tor functionality), "
2035 "set the StrictNodes configuration option. "
2036 "(Circuit purpose: %s)",
2058 flags |= CRN_NEED_UPTIME;
2060 flags |= CRN_NEED_CAPACITY;
2078 if (state->is_ipv6_selftest && cur_len == state->desired_path_len - 2)
2079 return CRN_INITIATE_IPV6_EXTEND;
2098 log_debug(
LD_CIRC,
"Launching a one-hop circuit for dir tunnel%s.",
2099 (hs_service_allow_non_anonymous_connection(
get_options()) ?
2100 ", or intro or rendezvous connection" :
""));
2111 log_info(
LD_CIRC,
"Using requested exit node '%s'",
2116 flags |= cpath_build_state_to_crn_flags(state);
2120 flags |= CRN_DIRECT_CONN;
2122 flags |= CRN_CONFLUX;
2126 log_warn(
LD_CIRC,
"Failed to choose an exit server");
2136 if (BUG(exit_ei == NULL))
2179 log_warn(
LD_CIRC,
"Couldn't extend circuit to new point %s.",
2181 circuit_mark_for_close(
TO_CIRCUIT(circ), -err_reason);
2199 int flags = CRN_NEED_DESC;
2202 flags |= CRN_DIRECT_CONN;
2208 if (!router_can_choose_node(node, flags))
2211 } SMARTLIST_FOREACH_END(node);
2272 for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->
next) {
2315 for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->
next) {
2327 uint8_t purpose,
int cur_len)
2360 const routerset_t *vanguard_routerset = NULL;
2361 const node_t *node = NULL;
2367 }
else if (cur_len == 2) {
2375 if (BUG(!vanguard_routerset)) {
2384 static ratelim_t pinned_warning_limit = RATELIM_INIT(300);
2386 "Could not find a node that matches the configured "
2387 "_HSLayer%dNodes set", cur_len+1);
2410 tor_assert(CIRCUIT_PURPOSE_MIN_ <= purpose &&
2411 purpose <= CIRCUIT_PURPOSE_MAX_);
2413 log_debug(
LD_CIRC,
"Contemplating intermediate hop #%d: random choice.",
2418 flags |= cpath_build_state_to_crn_flags(state);
2419 flags |= cpath_build_state_to_crn_ipv6_extend_flag(state, cur_len);
2423 log_debug(
LD_GENERAL,
"Picking a sticky node (cur_len = %d)", cur_len);
2425 smartlist_free(excluded);
2447 smartlist_free(excluded);
2463 circuit_guard_state_t **guard_state_out)
2477 tor_assert_nonfatal(state);
2496 flags |= cpath_build_state_to_crn_flags(state);
2500 smartlist_free(excluded);
2513 uint8_t purpose = circ->base_.
purpose;
2519 log_debug(
LD_CIRC,
"Path is complete: %d steps long",
2524 log_debug(
LD_CIRC,
"Path is %d long; we want %d", cur_len,
2529 }
else if (cur_len == 0) {
2539 tor_assert_nonfatal(info || client);
2556 "Failed to find node for hop #%d of our path. Discarding "
2557 "this circuit.", cur_len+1);
2560 "Failed to find node for hop #%d of our path. Discarding "
2561 "this circuit.", cur_len+1);
2566 log_debug(
LD_CIRC,
"Chose router %s for hop #%d (exit is %s)",
2571 extend_info_free(info);
2629 if (to_upgrade == NULL)
2632 log_info(
LD_GUARD,
"Upgrading %d circuits from 'waiting for better guard' "
2633 "to 'open'.", smartlist_len(to_upgrade));
2638 } SMARTLIST_FOREACH_END(circ);
2640 smartlist_free(to_upgrade);
2645#define EXT_TYPE_SUBPROTO 3
2656 trn_extension_field_t *fld = NULL;
2657 trn_subproto_request_t *req = NULL;
2658 trn_subproto_request_ext_t *req_ext = NULL;
2661 fld = trn_extension_field_new();
2662 req_ext = trn_subproto_request_ext_new();
2664 req = trn_subproto_request_new();
2665 req->protocol_id = PRT_RELAY;
2667 trn_subproto_request_ext_add_reqs(req_ext, req);
2673 ssize_t len = trn_subproto_request_ext_encoded_len(req_ext);
2676 if (BUG(len > UINT8_MAX))
2679 trn_extension_field_setlen_field(fld, len);
2680 trn_extension_field_set_field_type(fld, EXT_TYPE_SUBPROTO);
2681 trn_extension_field_set_field_len(fld, len);
2682 uint8_t *out = trn_extension_field_getarray_field(fld);
2683 ssize_t len2 = trn_subproto_request_ext_encode(out, len, req_ext);
2684 if (BUG(len != len2))
2687 trn_extension_add_fields(ext, fld);
2694 trn_subproto_request_ext_free(req_ext);
2695 trn_subproto_request_free(req);
2696 trn_extension_field_free(fld);
2705 const trn_extension_field_t *fa = *(trn_extension_field_t **)a;
2706 const trn_extension_field_t *fb = *(trn_extension_field_t **)b;
2707 uint8_t ta = trn_extension_field_get_field_type(fa);
2708 uint8_t tb = trn_extension_field_get_field_type(fb);
2728 size_t *msg_len_out,
2731 tor_assert(ei && msg_out && msg_len_out && params_out);
2732 bool cc_enabled =
false;
2736 trn_extension_t *ext = trn_extension_new();
2754 size_t n_fields = trn_extension_getlen_fields(ext);
2755 qsort(trn_extension_getarray_fields(ext),
2756 n_fields,
sizeof(trn_extension_field_t *),
2759 trn_extension_set_num(ext, n_fields);
2761 ssize_t total_len = trn_extension_encoded_len(ext);
2762 if (BUG(total_len < 0))
2765 *msg_out = tor_malloc_zero(total_len);
2766 *msg_len_out = total_len;
2767 if (BUG(trn_extension_encode(*msg_out, total_len, ext) < 0)) {
2770 trn_extension_free(ext);
2774 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)
channel_t * channel_connect(const tor_addr_t *addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id)
const char * channel_describe_peer(channel_t *chan)
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)
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)
void circuit_n_chan_done(channel_t *chan, int status, int close_origin_circuits)
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)
channel_t * channel_connect_for_circuit(const extend_info_t *ei)
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)
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)
bool congestion_control_enabled(void)
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.
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
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]
char nickname[MAX_HEX_NICKNAME_LEN+1]
bool exit_supports_congestion_control
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)