43#include "core/or/trace_probes_circuit.h"
46#include "feature/client/circpathbias.h"
74#include "core/or/or_circuit_st.h"
93 if ((edge_conn->hs_ident && !origin_circ->
hs_ident) ||
94 (!edge_conn->hs_ident && origin_circ->
hs_ident) ||
95 (edge_conn->hs_ident && origin_circ->
hs_ident &&
111 int must_be_open, uint8_t purpose,
112 int need_uptime,
int need_internal,
149 purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED) {
155 if (origin_circ->unusable_for_new_conns)
174 purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
179 log_debug(
LD_CIRC,
"Not considering circuit with unknown router.");
185 log_debug(
LD_CIRC,
"Skipping one-hop circuit.");
306 }
else if (b_bits < 0) {
309 a_bits &= ~ oa->isolation_flags_mixed;
310 a_bits &= ~ ob->isolation_flags_mixed;
338 int must_be_open, uint8_t purpose,
339 int need_uptime,
int need_internal)
355 now_sec = now.tv_sec;
371 need_uptime,need_internal, now_sec))
380 SMARTLIST_FOREACH_END(circ);
392 if (circ->marked_for_close ||
400 SMARTLIST_FOREACH_END(circ);
418 for (cpath = circ->
cpath; cpath_next != circ->
cpath; cpath = cpath_next) {
419 cpath_next = cpath->
next;
452 struct timeval general_cutoff, begindir_cutoff, fourhop_cutoff,
453 close_cutoff, extremely_old_cutoff,
454 cannibalized_cutoff, c_intro_cutoff, s_intro_cutoff, stream_cutoff,
459 int any_opened_circs = 0;
469#define SET_CUTOFF(target, msec) do { \
470 long ms = tor_lround(msec); \
471 struct timeval diff; \
472 diff.tv_sec = ms / 1000; \
473 diff.tv_usec = (int)((ms % 1000) * 1000); \
474 timersub(&now, &diff, &target); \
521 SET_CUTOFF(stream_cutoff, MAX(options->CircuitStreamTimeout,15)*1000 + 1000);
525 SET_CUTOFF(cannibalized_cutoff,
527 options->CircuitStreamTimeout * 1000) + 1000);
554 victim->marked_for_close)
570 if (build_state && build_state->onehop_tunnel)
571 cutoff = begindir_cutoff;
573 cutoff = close_cutoff;
575 cutoff = c_intro_cutoff;
577 cutoff = s_intro_cutoff;
581 cutoff = fourhop_cutoff;
583 cutoff = c_rend_ready_cutoff;
585 cutoff = close_cutoff;
588 cutoff = cannibalized_cutoff;
589 else if (build_state && build_state->desired_path_len >= 4)
590 cutoff = fourhop_cutoff;
592 cutoff = general_cutoff;
594 if (
timercmp(&victim->timestamp_began, &cutoff, OP_GT))
604 if (
timercmp(&victim->timestamp_began, &close_cutoff, OP_GT)) {
610 "No circuits are opened. Relaxing timeout for circuit %d "
611 "(a %s %d-hop circuit in state %s with channel state %s).",
627 first_hop_succeeded);
632 static ratelim_t relax_timeout_limit = RATELIM_INIT(3600);
636 "No circuits are opened. Relaxed timeout for circuit %d "
637 "(a %s %d-hop circuit in state %s with channel state %s) to "
638 "%ldms. However, it appears the circuit has timed out "
648 (long)build_close_ms);
657 if (!victim->timestamp_dirty)
661 victim->purpose, victim->build_state->chosen_exit_name,
665 "%d secs since dirty.",
667 victim->purpose, victim->build_state->chosen_exit_name,
669 (int)(now - victim->timestamp_dirty));
676 switch (victim->purpose) {
688 victim->timestamp_dirty > cutoff.tv_sec)
711 if (victim->timestamp_dirty > cutoff.tv_sec)
719 log_warn(
LD_BUG,
"Circuit %d (purpose %d, %s) has timed out, "
720 "yet has attached streams!",
732 "Deciding to count the timeout for circuit %"PRIu32,
748 if (
timercmp(&victim->timestamp_began, &extremely_old_cutoff, OP_LT)) {
750 "Extremely large value for circuit build timeout: %lds. "
751 "Assuming clock jump. Purpose %d (%s)",
752 (
long)(now.tv_sec - victim->timestamp_began.tv_sec),
758 (time_t)victim->timestamp_created.tv_sec)) {
765 switch (victim->purpose) {
776 log_info(
LD_CIRC,
"Rendezvous circ %u (state %d:%s, purpose %d) "
777 "as timed-out, closing it. Relaunching rendezvous attempt.",
778 (
unsigned)victim->n_circ_id,
791 "Abandoning circ %u %s:%u (state %d,%d:%s, purpose %d, "
794 (
unsigned)victim->n_circ_id,
803 "Abandoning circ %u %u (state %d,%d:%s, purpose %d, len %d)",
805 (
unsigned)victim->n_circ_id,
818 circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
821 } SMARTLIST_FOREACH_END(victim);
839 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_NONE);
840 } SMARTLIST_FOREACH_END(circ);
856#define MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG 10
857 time_t now = time(NULL);
858 time_t cutoff = now - age;
867 if (circ->timestamp_created.tv_sec >= cutoff)
871 if (hs_service_allow_non_anonymous_connection(options) &&
875 ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
880 if (smartlist_len(log_these) < MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG)
884 SMARTLIST_FOREACH_END(circ);
890 "Diagnostic for issue 8387: Found %d one-hop circuits more "
891 "than %d seconds old! Logging %d...",
892 n_found, age, smartlist_len(log_these));
895 char created[ISO_TIME_LEN+1];
905 char dirty_since[ISO_TIME_LEN+1];
908 tor_asprintf(&dirty,
"Dirty since %s (%ld seconds vs %ld-second cutoff)",
912 dirty = tor_strdup(
"Not marked dirty");
915 log_notice(
LD_HEARTBEAT,
" #%d created at %s. %s, %s. %s for close. "
916 "Package window: %d. "
917 "%s for new conns. %s.",
924 ocirc->unusable_for_new_conns ?
"Not usable" :
"usable",
929 for (conn = ocirc->p_streams; conn; conn = conn->
next_stream) {
931 char stream_created[ISO_TIME_LEN+1];
932 if (++stream_num >= 5)
938 "%s conn in state %s. "
939 "It is %slinked and %sreading from a linked connection %p. "
940 "Package window %d. "
941 "%s for close (%s:%d). Hold-open is %sset. "
942 "Has %ssent RELAY_END. %s on circuit.",
962 log_notice(
LD_HEARTBEAT,
" Linked to %s connection in state %s "
963 "(Purpose %d). %s for close (%s:%d). Hold-open is %sset. ",
972 } SMARTLIST_FOREACH_END(ocirc);
974 log_notice(
LD_HEARTBEAT,
"It has been %ld seconds since I last called "
975 "circuit_expire_old_circuits_clientside().",
979 smartlist_free(log_these);
991 for (i = 0; i < smartlist_len(needed_ports); ++i) {
992 port = smartlist_get(needed_ports, i);
996 log_debug(
LD_CIRC,
"Port %d is already being handled; removing.", *port);
1000 log_debug(
LD_CIRC,
"Port %d is not handled.", *port);
1012 uint16_t port,
int min)
1016 time_t now = time(NULL);
1023 !circ->marked_for_close &&
1025 circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED) &&
1026 (!circ->timestamp_dirty ||
1027 circ->timestamp_dirty +
get_options()->MaxCircuitDirtiness > now)) {
1032 if (origin_circ->unusable_for_new_conns)
1040 if (exitnode && (!need_uptime || build_state->
need_uptime)) {
1056 SMARTLIST_FOREACH_END(circ);
1061#define MAX_UNUSED_OPEN_CIRCUITS 14
1069circuit_is_available_for_use(
const circuit_t *circ)
1086 origin_circ = CONST_TO_ORIGIN_CIRCUIT(circ);
1087 if (origin_circ->unusable_for_new_conns)
1102needs_exit_circuits(time_t now,
int *needs_uptime,
int *needs_capacity)
1110#define SUFFICIENT_UPTIME_INTERNAL_HS_SERVERS 3
1115needs_hs_server_circuits(time_t now,
int num_uptime_internal)
1122 if (num_uptime_internal >= SUFFICIENT_UPTIME_INTERNAL_HS_SERVERS) {
1144#define SUFFICIENT_INTERNAL_HS_CLIENTS 3
1148#define SUFFICIENT_UPTIME_INTERNAL_HS_CLIENTS 2
1153needs_hs_client_circuits(time_t now,
int *needs_uptime,
int *needs_capacity,
1154 int num_internal,
int num_uptime_internal)
1159 int requires_uptime = num_uptime_internal <
1160 SUFFICIENT_UPTIME_INTERNAL_HS_CLIENTS &&
1163 return (used_internal_recently &&
1164 (requires_uptime || num_internal < SUFFICIENT_INTERNAL_HS_CLIENTS) &&
1170#define DFLT_CBT_UNUSED_OPEN_CIRCS (10)
1171#define MIN_CBT_UNUSED_OPEN_CIRCS 0
1172#define MAX_CBT_UNUSED_OPEN_CIRCS MAX_UNUSED_OPEN_CIRCUITS
1178needs_circuits_for_build(
int num)
1182 DFLT_CBT_UNUSED_OPEN_CIRCS,
1183 MIN_CBT_UNUSED_OPEN_CIRCS,
1184 MAX_CBT_UNUSED_OPEN_CIRCS) &&
1200 int num=0, num_internal=0, num_uptime_internal=0;
1201 int hidserv_needs_uptime=0, hidserv_needs_capacity=1;
1202 int port_needs_uptime=0, port_needs_capacity=1;
1203 time_t now = time(NULL);
1217 if (!circuit_is_available_for_use(circ))
1226 num_uptime_internal++;
1228 SMARTLIST_FOREACH_END(circ);
1234 if (needs_exit_circuits(now, &port_needs_uptime, &port_needs_capacity)) {
1235 if (port_needs_uptime)
1237 if (port_needs_capacity)
1241 "Have %d clean circs (%d internal), need another exit circ.",
1248 if (needs_hs_server_circuits(now, num_uptime_internal)) {
1253 "Have %d clean circs (%d internal), need another internal "
1254 "circ for my hidden service.",
1260 if (needs_hs_client_circuits(now, &hidserv_needs_uptime,
1261 &hidserv_needs_capacity,
1262 num_internal, num_uptime_internal))
1264 if (hidserv_needs_uptime)
1266 if (hidserv_needs_capacity)
1271 "Have %d clean circs (%d uptime-internal, %d internal), need"
1272 " another hidden service circ.",
1273 num, num_uptime_internal, num_internal);
1282 if (needs_circuits_for_build(num)) {
1290 "Have %d clean circs need another buildtime test circ.", num);
1297#define TESTING_CIRCUIT_INTERVAL 300
1330 static time_t time_to_expire_and_reset = 0;
1332 if (time_to_expire_and_reset < now) {
1362 bool update_dirty =
false;
1395 log_debug(
LD_APP,
"Removing stream %d from circ %u",
1447 log_warn(
LD_BUG,
"Edge connection not in circuit's list.");
1473 if (circ->timestamp_dirty &&
1474 circ->timestamp_dirty +
get_options()->MaxCircuitDirtiness <
1478 log_debug(
LD_CIRC,
"Closing n_circ_id %u (dirty %ld sec ago, "
1480 (
unsigned)circ->n_circ_id,
1481 (
long)(now.tv_sec - circ->timestamp_dirty),
1486 tor_trace(
TR_SUBSYS(circuit), TR_EV(idle_timeout),
1488 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
1491 if (
timercmp(&circ->timestamp_began, &cutoff, OP_LT)) {
1495 circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
1506 "Closing circuit %"PRIu32
1507 " that has been unused for %ld msec.",
1509 tv_mdiff(&circ->timestamp_began, &now));
1510 tor_trace(
TR_SUBSYS(circuit), TR_EV(idle_timeout),
1512 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
1522 "Ancient non-dirty circuit %d is still around after "
1523 "%ld milliseconds. Purpose: %d (%s)",
1525 tv_mdiff(&circ->timestamp_began, &now),
1533 } SMARTLIST_FOREACH_END(circ);
1551#define IDLE_ONE_HOP_CIRC_TIMEOUT 60
1578 log_info(
LD_CIRC,
"Closing circ_id %u (empty %d secs ago)",
1581 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
1584 SMARTLIST_FOREACH_END(circ);
1588#define NUM_PARALLEL_TESTING_CIRCS 4
1620 SMARTLIST_FOREACH_END(circ);
1634 !router_orport_seems_reachable(
get_options(), AF_INET)) {
1654 if (server_mode(options) &&
1655 router_all_orports_seem_reachable(options))
1659 "Our testing circuit (to see if your ORPort is reachable) "
1660 "has failed. I'll try again later.");
1676 tor_trace(
TR_SUBSYS(circuit), TR_EV(opened), circ);
1777 int failed_at_last_hop = 0;
1794 static ratelim_t pathfail_limit = RATELIM_INIT(3600);
1796 "Our circuit %u (id: %" PRIu32
") died due to an invalid "
1797 "selected path, purpose %s. This may be a torrc "
1798 "configuration issue, or a bug.",
1805 HS_METRICS_ERR_RDV_PATH);
1819 failed_at_last_hop = 1;
1831 int already_marked = 0;
1832 if (circ->base_.
n_chan) {
1833 n_chan = circ->base_.
n_chan;
1846 "Our circuit %u (id: %" PRIu32
") failed to get a response "
1847 "from the first hop (%s). I'm going to try to rotate to a "
1848 "better connection.",
1854 "Our circuit %u (id: %" PRIu32
") died before the first hop "
1855 "with no connection",
1858 if (!already_marked) {
1872 switch (circ->base_.
purpose) {
1878 if (failed_at_last_hop) {
1913 "Couldn't connect to the client's chosen rend point %s "
1916 failed_at_last_hop?
"last":
"non-last");
1919 HS_METRICS_ERR_RDV_RP_CONN_FAILURE);
1938#define MAX_CIRCUIT_FAILURES 5
1954have_enough_path_info(
int need_exit)
1990 return (purpose >= CIRCUIT_PURPOSE_C_HS_MIN_ &&
1991 purpose <= CIRCUIT_PURPOSE_C_HS_MAX_);
1998 return (purpose >= CIRCUIT_PURPOSE_S_HS_MIN_ &&
1999 purpose <= CIRCUIT_PURPOSE_S_HS_MAX_);
2014 (CONST_TO_ORIGIN_CIRCUIT(circ)->hs_ident != NULL));
2047 int has_extend_info,
2052 if (onehop_tunnel) {
2118 log_debug(
LD_CIRC,
"Haven't %s yet; canceling "
2121 "fetched enough directory info" :
2122 "received a consensus with exits");
2129 extend_info != NULL,
2136 uint8_t old_purpose = circ->base_.
purpose;
2139 log_info(
LD_CIRC,
"Cannibalizing circ %u (id: %" PRIu32
") for "
2176 &old_timestamp_began);
2195 "unexpected purpose %d when cannibalizing a circ.",
2201 tor_trace(
TR_SUBSYS(circuit), TR_EV(cannibalized), circ);
2250 uint8_t desired_circuit_purpose,
2254 int check_exit_policy;
2255 int need_uptime, need_internal;
2263 log_err(
LD_BUG,
"Connection state mismatch: wanted "
2264 "AP_CONN_STATE_CIRCUIT_WAIT, but got %d (%s)",
2294 desired_circuit_purpose,
2295 need_uptime, need_internal);
2307 int have_path = have_enough_path_info(!need_internal);
2321 tor_assert_nonfatal_once(rv);
2323 "Application request when we haven't %s. "
2324 "Optimistically trying known %s again.",
2326 "used client functionality lately" :
2327 "received a consensus with exits",
2328 options->
UseBridges ?
"bridges" :
"entrynodes");
2336 "Application request when we haven't %s. "
2337 "Optimistically trying directory fetches again.",
2339 "used client functionality lately" :
2340 "received a consensus with exits");
2354 if (check_exit_policy) {
2366 "No Tor server allows exit to %s:%d. Rejecting.",
2378 "Requested exit point '%s' is excluded or "
2379 "would refuse request. %s.",
2386 desired_circuit_purpose,
2398 desired_circuit_purpose,
2399 need_uptime, need_internal);
2401 log_debug(
LD_CIRC,
"one on the way!");
2414 static ratelim_t delay_limit = RATELIM_INIT(10*60);
2417 log_notice(
LD_APP,
"We'd like to launch a circuit to handle a "
2418 "connection, but we already have %d general-purpose client "
2419 "circuits pending. Waiting until some finish.%s",
2433 log_info(
LD_REND,
"No intro points: re-fetching service descriptor.");
2438 log_info(
LD_REND,
"Chose %s as intro point for service",
2459 log_warn(
LD_CIRC,
"Could not make a one-hop connection to %s. "
2464 log_debug(
LD_DIR,
"considering %d, %s",
2479 log_info(
LD_DIR,
"Broken exit digest on tunnel conn. Closing.");
2483 log_info(
LD_DIR,
"Broken address %s on tunnel conn. Closing.",
2499 "Requested exit point '%s' is not known. %s.",
2506 desired_circuit_purpose,
2516 uint8_t new_circ_purpose;
2522 new_circ_purpose = desired_circuit_purpose;
2536 log_info(
LD_GENERAL,
"Getting rendezvous circuit to v3 service!");
2543 extend_info_free(extend_info);
2555 log_info(
LD_CIRC,
"The application request to %s:%d has launched "
2556 "%d circuits without finding one it likes.",
2565 if (edge_conn->hs_ident) {
2593 "No safe circuit (purpose %d) ready for edge "
2594 "connection; delaying.",
2595 desired_circuit_purpose);
2613 for (cpath = circ->
cpath; cpath_next != circ->
cpath; cpath = cpath_next) {
2614 cpath_next = cpath->
next;
2615 if (crypt_path == cpath)
2629 const node_t *exitnode = NULL;
2632 log_debug(
LD_APP|
LD_CIRC,
"attaching new conn to circ. n_circ_id %u.",
2641 ENTRY_TO_CONN(apconn)->timestamp_last_read_allowed = time(NULL);
2683 log_info(
LD_APP,
"Looks like completed circuit to %s %s allow "
2684 "optimistic data for connection to %s",
2703 if (cp[1] ==
'\0' ||
2705 !strcasecmp(address, &cp[1]))
2707 }
else if (strcasecmp(cp, address) == 0) {
2710 } SMARTLIST_FOREACH_END(cp);
2723 char *new_address = NULL;
2725 uint64_t stream_id = 0;
2881 "Tried for %d seconds to get a connection to %s:%d. Giving up.",
2900 if (networkstatus_consensus_is_already_downloading(
2906 log_info(
LD_DIR,
"Closing extra consensus fetch (to %s) since one "
2918 if (!node && !want_onehop) {
2925 "Requested exit point '%s' is not known. %s.",
2937 "Requested exit point '%s' is excluded or "
2938 "would refuse request. %s.",
2964 "Attaching apconn to circ %u (stream %d sec old).",
2965 (
unsigned)circ->base_.
n_circ_id, conn_age);
2983 if (retval < 0)
return -1;
2989 "rend joined circ %u (id: %" PRIu32
") already here. "
2990 "Attaching. (stream %d sec old)",
3016 log_info(
LD_REND,
"This connection is no longer ready to attach; its "
3018 "(We probably have to re-fetch its descriptor.)");
3022 if (rendcirc && (rendcirc->base_.
purpose ==
3025 "pending-join circ %u (id: %" PRIu32
") already here, with "
3026 "intro ack. Stalling. (stream %d sec old)",
3035 if (retval < 0)
return -1;
3037 if (rendcirc && introcirc) {
3042 &introcirc->hs_ident->intro_auth_pk));
3044 &introcirc->hs_ident->intro_auth_pk);
3050 log_info(
LD_REND,
"Intro circ %u (id: %" PRIu32
") present and "
3051 "awaiting ACK. Rend circuit %u (id: %" PRIu32
"). "
3052 "Stalling. (stream %d sec old)",
3054 introcirc->global_identifier,
3055 rendcirc ? (
unsigned)
TO_CIRCUIT(rendcirc)->n_circ_id : 0,
3063 if (rendcirc && introcirc &&
3066 "ready rend circ %u (id: %" PRIu32
") already here. No"
3067 "intro-ack yet on intro %u (id: %" PRIu32
"). "
3068 "(stream %d sec old)",
3072 introcirc->global_identifier, conn_age);
3077 log_info(
LD_REND,
"Found open intro circ %u (id: %" PRIu32
"). "
3078 "Rend circuit %u (id: %" PRIu32
"); Considering "
3079 "sending introduction. (stream %d sec old)",
3081 introcirc->global_identifier,
3088 introcirc->base_.timestamp_dirty = time(NULL);
3107 log_info(
LD_REND,
"Intro %u (id: %" PRIu32
") and rend circuit %u "
3108 "(id: %" PRIu32
") circuits are not both ready. "
3109 "Stalling conn. (%d sec old)",
3110 introcirc ? (
unsigned)
TO_CIRCUIT(introcirc)->n_circ_id : 0,
3111 introcirc ? introcirc->global_identifier : 0,
3112 rendcirc ? (unsigned)
TO_CIRCUIT(rendcirc)->n_circ_id : 0,
3122 uint8_t old_purpose;
3127 if (circ->
purpose == new_purpose)
return;
3130 if (CIRCUIT_IS_CONFLUX(circ)) {
3132 if (new_purpose != CIRCUIT_PURPOSE_CONFLUX_LINKED)
3137 char old_purpose_desc[80] =
"";
3140 old_purpose_desc[80-1] =
'\0';
3143 "changing purpose of origin circ %d "
3144 "from \"%s\" (%d) to \"%s\" (%d)",
3160 tor_trace(
TR_SUBSYS(circuit), TR_EV(change_purpose), circ, old_purpose,
3188 circ->unusable_for_new_conns = 1;
3206 "Wrong relay_body_len: %d (should be at most %d)",
int tor_addr_parse(tor_addr_t *addr, const char *src)
int tor_addr_is_null(const tor_addr_t *addr)
#define tor_addr_from_in(dest, in)
int addressmap_have_mapping(const char *address, int update_expiry)
void addressmap_clean(time_t now)
void addressmap_register(const char *address, char *new_address, time_t expires, addressmap_entry_source_t source, const int wildcard_addr, const int wildcard_new_addr, uint64_t stream_id)
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
int n_bits_set_u8(uint8_t v)
Header file for circuitbuild.c.
time_t channel_when_last_xmit(channel_t *chan)
const char * channel_state_to_string(channel_state_t state)
int channel_is_client(const channel_t *chan)
const char * channel_describe_peer(channel_t *chan)
Header file for channel.c.
void pathbias_count_use_attempt(origin_circuit_t *circ)
int pathbias_check_close(origin_circuit_t *ocirc, int reason)
void pathbias_count_timeout(origin_circuit_t *circ)
int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
const char * build_state_get_exit_nickname(cpath_build_state_t *state)
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
int circuit_timeout_want_to_count_circ(const origin_circuit_t *circ)
int circuit_all_predicted_ports_handled(time_t now, int *need_uptime, int *need_capacity)
origin_circuit_t * circuit_establish_circuit(uint8_t purpose, extend_info_t *exit_ei, int flags)
const node_t * build_state_get_exit_node(cpath_build_state_t *state)
Header file for circuitbuild.c.
int circuit_any_opened_circuits(void)
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
int circuit_get_cpath_len(origin_circuit_t *circ)
void assert_circuit_ok(const circuit_t *c)
const char * circuit_state_to_string(int state)
int circuit_event_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
origin_circuit_t * circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info, int flags)
const char * circuit_purpose_to_string(uint8_t purpose)
smartlist_t * circuit_get_global_origin_circuit_list(void)
smartlist_t * circuit_get_global_list(void)
Header file for circuitlist.c.
#define CIRCUIT_PURPOSE_S_CONNECT_REND
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING
#define CIRCUIT_STATE_OPEN
#define CIRCUIT_PURPOSE_IS_ORIGIN(p)
#define CIRCUIT_PURPOSE_C_REND_JOINED
#define CIRCUIT_PURPOSE_S_INTRO
#define CIRCUIT_PURPOSE_CONTROLLER
#define CIRCUIT_IS_ORIGIN(c)
#define CIRCUIT_PURPOSE_C_CIRCUIT_PADDING
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
#define CIRCUIT_PURPOSE_TESTING
#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_C_INTRODUCING
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND
#define CIRCUIT_PURPOSE_C_GENERAL
#define CIRCUIT_PURPOSE_COUNTS_TOWARDS_MAXPENDING(p)
#define CIRCUIT_PURPOSE_CONFLUX_UNLINKED
#define CIRCUIT_PURPOSE_HS_VANGUARDS
void circpad_machine_event_circ_purpose_changed(origin_circuit_t *circ)
void circpad_machine_event_circ_has_no_streams(origin_circuit_t *circ)
void circpad_machine_event_circ_has_streams(origin_circuit_t *circ)
Header file for circuitpadding.c.
int circuit_build_times_needs_circuits_now(const circuit_build_times_t *cbt)
circuit_build_times_t * get_circuit_build_times_mutable(void)
void circuit_build_times_set_timeout(circuit_build_times_t *cbt)
double get_circuit_build_timeout_ms(void)
void circuit_build_times_count_timeout(circuit_build_times_t *cbt, int did_onehop)
const circuit_build_times_t * get_circuit_build_times(void)
double get_circuit_build_close_time_ms(void)
void circuit_build_times_mark_circ_as_measurement_only(origin_circuit_t *circ)
int circuit_build_times_enough_to_compute(const circuit_build_times_t *cbt)
int circuit_build_times_count_close(circuit_build_times_t *cbt, int did_onehop, time_t start_time)
int circuit_build_times_disabled(const or_options_t *options)
Header file for circuitstats.c.
void circuit_build_failed(origin_circuit_t *circ)
void circuit_sent_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
void circuit_expire_old_circuits_serverside(time_t now)
bool circuit_is_hs_v3(const circuit_t *circ)
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
static int count_pending_general_client_circuits(void)
static void circuit_testing_failed(origin_circuit_t *circ, int at_last_hop)
static void circuit_testing_opened(origin_circuit_t *circ)
static int circuit_matches_with_rend_stream(const edge_connection_t *edge_conn, const origin_circuit_t *origin_circ)
static int circuit_try_clearing_isolation_state(origin_circuit_t *circ)
bool circuit_purpose_is_hs_service(const uint8_t purpose)
origin_circuit_t * circuit_launch(uint8_t purpose, int flags)
void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
void circuit_log_ancient_one_hop_circuits(int age)
void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
static int have_performed_bandwidth_test
void circuit_expire_waiting_for_better_guard(void)
void circuit_expire_old_circs_as_needed(time_t now)
static void circuit_predict_and_launch_new(void)
int circuit_should_use_vanguards(uint8_t purpose)
void reset_bandwidth_test(void)
int hostname_in_track_host_exits(const or_options_t *options, const char *address)
int circuit_is_acceptable(const origin_circuit_t *origin_circ, const entry_connection_t *conn, int must_be_open, uint8_t purpose, int need_uptime, int need_internal, time_t now)
static void consider_recording_trackhost(const entry_connection_t *conn, const origin_circuit_t *circ)
static int n_circuit_failures
#define MAX_CIRCUIT_FAILURES
void circuit_has_opened(origin_circuit_t *circ)
void circuit_expire_building(void)
static int circuit_should_cannibalize_to_build(uint8_t purpose_to_build, int has_extend_info, int onehop_tunnel)
void circuit_build_needed_circs(time_t now)
static int did_circs_fail_last_period
bool circuit_purpose_is_hs_vanguards(const uint8_t purpose)
int connection_ap_handshake_attach_circuit(entry_connection_t *conn)
void circuit_reset_failure_count(int timeout)
#define IDLE_ONE_HOP_CIRC_TIMEOUT
STATIC void circuit_expire_old_circuits_clientside(void)
static int circuit_is_better(const origin_circuit_t *oa, const origin_circuit_t *ob, const entry_connection_t *conn)
bool circuit_purpose_is_hs_client(const uint8_t purpose)
int connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn, origin_circuit_t *circ, crypt_path_t *cpath)
int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port, int min)
static void circuit_increment_failure_count(void)
static int circuit_get_open_circ_or_launch(entry_connection_t *conn, uint8_t desired_circuit_purpose, origin_circuit_t **circp)
#define MAX_UNUSED_OPEN_CIRCUITS
void circuit_remove_handled_ports(smartlist_t *needed_ports)
int circuit_enough_testing_circs(void)
static bool connection_ap_socks_iso_keepalive_enabled(const entry_connection_t *)
static int connection_ap_get_nonrend_circ_purpose(const entry_connection_t *conn)
void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
#define NUM_PARALLEL_TESTING_CIRCS
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
#define TESTING_CIRCUIT_INTERVAL
static origin_circuit_t * circuit_get_best(const entry_connection_t *conn, int must_be_open, uint8_t purpose, int need_uptime, int need_internal)
static time_t last_expired_clientside_circuits
void circuit_try_attaching_streams(origin_circuit_t *circ)
static void link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ, crypt_path_t *cpath)
static int cpath_is_on_circuit(origin_circuit_t *circ, crypt_path_t *crypt_path)
int circuit_purpose_is_hidden_service(uint8_t purpose)
Header file for circuituse.c.
#define CIRCLAUNCH_NEED_CAPACITY
#define CIRCLAUNCH_ONEHOP_TUNNEL
#define CIRCLAUNCH_IS_INTERNAL
#define CIRCLAUNCH_NEED_UPTIME
const char * escaped_safe_str_client(const char *address)
const or_options_t * get_options(void)
Header file for config.c.
Public APIs for conflux multipath support.
void conflux_circuit_has_opened(origin_circuit_t *orig_circ)
void conflux_circuit_has_closed(circuit_t *circ)
void conflux_predict_new(time_t now)
origin_circuit_t * conflux_get_circ_for_conn(const entry_connection_t *conn, time_t now)
Header file for conflux_pool.c.
void conflux_sync_circ_fields(conflux_t *cfx, origin_circuit_t *ref_circ)
void conflux_update_resolving_streams(or_circuit_t *circ, edge_connection_t *stream)
void conflux_update_p_streams(origin_circuit_t *circ, edge_connection_t *stream)
void conflux_update_n_streams(or_circuit_t *circ, edge_connection_t *stream)
Header file for conflux_util.c.
const char * conn_type_to_string(int type)
connection_t * connection_get_by_type(int type)
const char * conn_state_to_string(int type, int state)
Header file for connection.c.
int connection_edge_compatible_with_circuit(const entry_connection_t *conn, const origin_circuit_t *circ)
void connection_ap_mark_as_waiting_for_renddesc(entry_connection_t *entry_conn)
void connection_ap_fail_onehop(const char *failed_digest, cpath_build_state_t *build_state)
void connection_ap_rescan_and_attach_pending(void)
int connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
bool connection_half_edges_waiting(const origin_circuit_t *circ)
void circuit_clear_isolation(origin_circuit_t *circ)
entry_connection_t * EDGE_TO_ENTRY_CONN(edge_connection_t *c)
int connection_ap_handshake_send_resolve(entry_connection_t *ap_conn)
int connection_edge_update_circuit_isolation(const entry_connection_t *conn, origin_circuit_t *circ, int dry_run)
int connection_ap_can_use_exit(const entry_connection_t *conn, const node_t *exit_node)
void connection_ap_attach_pending(int retry)
int connection_edge_is_rendezvous_stream(const edge_connection_t *conn)
void circuit_discard_optional_exit_enclaves(extend_info_t *info)
Header file for connection_edge.c.
#define AP_CONN_STATE_CONTROLLER_WAIT
#define AP_CONN_STATE_CIRCUIT_WAIT
int control_event_circuit_purpose_changed(origin_circuit_t *circ, int old_purpose)
int control_event_circuit_cannibalized(origin_circuit_t *circ, int old_purpose, const struct timeval *old_tv_created)
Header file for control_events.c.
Circuit-build-stse structure.
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)
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
const char * extend_info_describe(const extend_info_t *ei)
const char * node_describe(const node_t *node)
Header file for describe.c.
#define tor_memneq(a, b, sz)
Client/server directory connection structure.
dir_connection_t * TO_DIR_CONN(connection_t *c)
Header file for directory.c.
#define DIR_PURPOSE_UPLOAD_HSDESC
#define DIR_PURPOSE_FETCH_CONSENSUS
#define DIR_PURPOSE_FETCH_HSDESC
Entry connection structure.
#define ENTRY_TO_EDGE_CONN(c)
void entry_guard_failed(circuit_guard_state_t **guard_state_p)
int entry_list_is_constrained(const or_options_t *options)
int entry_guard_state_should_expire(circuit_guard_state_t *guard_state)
int guards_retry_optimistic(const or_options_t *options)
Header file for circuitbuild.c.
const char * escaped(const char *s)
Header file for Tor tracing instrumentation definition.
extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect, bool for_exit)
extend_info_t * extend_info_new(const char *nickname, const char *rsa_id_digest, const ed25519_public_key_t *ed_id, const curve25519_public_key_t *ntor_key, const tor_addr_t *addr, uint16_t port, const protover_summary_flags_t *pv, bool for_exit_use)
bool extend_info_has_orport(const extend_info_t *ei, const tor_addr_t *addr, uint16_t port)
Header for core/or/extendinfo.c.
void hs_circ_cleanup_on_repurpose(circuit_t *circ)
bool hs_circ_is_rend_sent_in_intro1(const origin_circuit_t *circ)
void hs_circ_retry_service_rendezvous_point(const origin_circuit_t *circ)
Header file containing circuit data for the whole HS subsystem.
void hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn)
int hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
int hs_client_send_introduce1(origin_circuit_t *intro_circ, origin_circuit_t *rend_circ)
void hs_client_circuit_has_opened(origin_circuit_t *circ)
extend_info_t * hs_client_get_random_intro_from_edge(const edge_connection_t *edge_conn)
int hs_client_setup_intro_circ_auth_key(origin_circuit_t *circ)
Header file containing client data for the HS subsystem.
void hs_dec_rdv_stream_counter(origin_circuit_t *circ)
Header file containing common data for the whole HS subsystem.
hs_ident_circuit_t * hs_ident_circuit_new(const ed25519_public_key_t *identity_pk)
Header file containing circuit and connection identifier data for the whole HS subsystem.
Header for feature/hs/hs_metrics.c.
#define hs_metrics_failed_rdv(i, reason)
void hs_service_circuit_has_opened(origin_circuit_t *circ)
unsigned int hs_service_get_num_services(void)
void hs_stats_note_service_rendezvous_launch(void)
Header file for hs_stats.c.
int tor_inet_aton(const char *str, struct in_addr *addr)
#define log_fn(severity, domain, args,...)
#define log_fn_ratelim(ratelim, severity, domain, args,...)
int connection_is_reading(const connection_t *conn)
Header file for mainloop.c.
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
const node_t * node_get_by_id(const char *identity_digest)
const node_t * node_get_by_nickname(const char *nickname, unsigned flags)
int node_has_preferred_descriptor(const node_t *node, int for_direct_connect)
int router_exit_policy_all_nodes_reject(const tor_addr_t *addr, uint16_t port, int need_uptime)
consensus_path_type_t router_have_consensus_path(void)
int router_have_minimum_dir_info(void)
Header file for nodelist.c.
Master header file for Tor-specific functionality.
#define MIN_CIRCUITS_HANDLING_STREAM
#define END_CIRC_REASON_MEASUREMENT_EXPIRED
#define RELAY_PAYLOAD_SIZE_MAX
#define END_CIRC_AT_ORIGIN
Origin circuit structure.
@ PATH_STATE_BUILD_SUCCEEDED
addr_policy_result_t compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, const smartlist_t *policy)
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_note_used_internal(time_t now, int need_uptime, int need_capacity)
int predicted_ports_prediction_time_remaining(time_t now)
int rep_hist_get_predicted_internal(time_t now, int *need_uptime, int *need_capacity)
Header file for predict_ports.c.
int tor_asprintf(char **strp, const char *fmt,...)
int proxy_mode(const or_options_t *options)
Header file for proxymode.c.
char * rate_limit_log(ratelim_t *lim, time_t now)
void routerlist_retry_directory_downloads(time_t now)
int hexdigest_to_digest(const char *hexdigest, char *digest)
Header file for routerlist.c.
Header file for routermode.c.
int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
void router_do_reachability_checks(void)
void router_perform_bandwidth_test(int num_circs, time_t now)
Header file for selftest.c.
int smartlist_contains_int_as_string(const smartlist_t *sl, int num)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_del(smartlist_t *sl, int idx)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
Client request structure.
#define SOCKS_COMMAND_CONNECT
unsigned int is_bad_for_new_circs
unsigned int received_destroy
uint16_t marked_for_close
struct timeval timestamp_began
struct timeval timestamp_created
struct connection_t * linked_conn
unsigned int hold_open_until_flushed
unsigned int reading_from_linked_conn
uint16_t marked_for_close
const char * marked_for_close_file
extend_info_t * chosen_exit
unsigned int onehop_tunnel
struct crypt_path_t * prev
struct crypt_path_t * next
extend_info_t * extend_info
char * requested_resource
struct crypt_path_t * cpath_layer
struct edge_connection_t * next_stream
unsigned int edge_has_sent_end
struct circuit_t * on_circuit
socks_request_t * socks_request
unsigned int num_circuits_launched
unsigned int chosen_exit_optional
unsigned int may_use_optimistic_data
unsigned int hs_with_pow_conn
unsigned int use_begindir
unsigned int socks_iso_keep_alive
char identity_digest[DIGEST_LEN]
ed25519_public_key_t intro_auth_pk
ed25519_public_key_t identity_pk
ed25519_public_key_t identity_pk
edge_connection_t * resolving_streams
struct or_circuit_t * rend_splice
edge_connection_t * n_streams
struct routerset_t * ExcludeExitNodes
struct smartlist_t * TrackHostExits
struct routerset_t * EntryNodes
struct routerset_t * ExcludeNodes
int MaxClientCircuitsPending
int DisablePredictedCircuits
struct smartlist_t * LongLivedPorts
uint32_t global_identifier
unsigned int relaxed_timeout
struct hs_ident_circuit_t * hs_ident
edge_connection_t * p_streams
unsigned int isolation_values_set
uint32_t n_overhead_written_circ_bw
path_state_bitfield_t path_state
uint32_t n_delivered_read_circ_bw
uint32_t n_delivered_written_circ_bw
uint32_t n_overhead_read_circ_bw
smartlist_t * prepend_policy
cpath_build_state_t * build_state
unsigned int isolation_any_streams_attached
struct circuit_guard_state_t * guard_state
char address[MAX_SOCKS_ADDR_LEN]
void format_local_iso_time(char *buf, time_t t)
#define timercmp(tv1, tv2, op)
void tor_gettimeofday(struct timeval *timeval)
long tv_mdiff(const struct timeval *start, const struct timeval *end)
#define tor_fragile_assert()
int strcasecmpend(const char *s1, const char *s2)
int tor_digest_is_zero(const char *digest)