43#include "core/or/trace_probes_circuit.h"
46#include "feature/client/circpathbias.h"
74#include "core/or/or_circuit_st.h"
91 if ((edge_conn->hs_ident && !origin_circ->
hs_ident) ||
92 (!edge_conn->hs_ident && origin_circ->
hs_ident) ||
93 (edge_conn->hs_ident && origin_circ->
hs_ident &&
109 int must_be_open, uint8_t purpose,
110 int need_uptime,
int need_internal,
147 purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED) {
153 if (origin_circ->unusable_for_new_conns)
172 purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
177 log_debug(
LD_CIRC,
"Not considering circuit with unknown router.");
183 log_debug(
LD_CIRC,
"Skipping one-hop circuit.");
304 }
else if (b_bits < 0) {
307 a_bits &= ~ oa->isolation_flags_mixed;
308 a_bits &= ~ ob->isolation_flags_mixed;
336 int must_be_open, uint8_t purpose,
337 int need_uptime,
int need_internal)
353 now_sec = now.tv_sec;
369 need_uptime,need_internal, now_sec))
378 SMARTLIST_FOREACH_END(circ);
390 if (circ->marked_for_close ||
398 SMARTLIST_FOREACH_END(circ);
416 for (cpath = circ->
cpath; cpath_next != circ->
cpath; cpath = cpath_next) {
417 cpath_next = cpath->
next;
450 struct timeval general_cutoff, begindir_cutoff, fourhop_cutoff,
451 close_cutoff, extremely_old_cutoff,
452 cannibalized_cutoff, c_intro_cutoff, s_intro_cutoff, stream_cutoff,
457 int any_opened_circs = 0;
467#define SET_CUTOFF(target, msec) do { \
468 long ms = tor_lround(msec); \
469 struct timeval diff; \
470 diff.tv_sec = ms / 1000; \
471 diff.tv_usec = (int)((ms % 1000) * 1000); \
472 timersub(&now, &diff, &target); \
519 SET_CUTOFF(stream_cutoff,
MAX(options->CircuitStreamTimeout,15)*1000 + 1000);
523 SET_CUTOFF(cannibalized_cutoff,
525 options->CircuitStreamTimeout * 1000) + 1000);
552 victim->marked_for_close)
568 if (build_state && build_state->onehop_tunnel)
569 cutoff = begindir_cutoff;
571 cutoff = close_cutoff;
573 cutoff = c_intro_cutoff;
575 cutoff = s_intro_cutoff;
579 cutoff = fourhop_cutoff;
581 cutoff = c_rend_ready_cutoff;
583 cutoff = close_cutoff;
586 cutoff = cannibalized_cutoff;
587 else if (build_state && build_state->desired_path_len >= 4)
588 cutoff = fourhop_cutoff;
590 cutoff = general_cutoff;
592 if (
timercmp(&victim->timestamp_began, &cutoff, OP_GT))
602 if (
timercmp(&victim->timestamp_began, &close_cutoff, OP_GT)) {
608 "No circuits are opened. Relaxing timeout for circuit %d "
609 "(a %s %d-hop circuit in state %s with channel state %s).",
625 first_hop_succeeded);
630 static ratelim_t relax_timeout_limit = RATELIM_INIT(3600);
634 "No circuits are opened. Relaxed timeout for circuit %d "
635 "(a %s %d-hop circuit in state %s with channel state %s) to "
636 "%ldms. However, it appears the circuit has timed out "
646 (
long)build_close_ms);
655 if (!victim->timestamp_dirty)
659 victim->purpose, victim->build_state->chosen_exit_name,
663 "%d secs since dirty.",
665 victim->purpose, victim->build_state->chosen_exit_name,
667 (
int)(now - victim->timestamp_dirty));
674 switch (victim->purpose) {
686 victim->timestamp_dirty > cutoff.tv_sec)
709 if (victim->timestamp_dirty > cutoff.tv_sec)
717 log_warn(
LD_BUG,
"Circuit %d (purpose %d, %s) has timed out, "
718 "yet has attached streams!",
730 "Deciding to count the timeout for circuit %"PRIu32,
746 if (
timercmp(&victim->timestamp_began, &extremely_old_cutoff, OP_LT)) {
748 "Extremely large value for circuit build timeout: %lds. "
749 "Assuming clock jump. Purpose %d (%s)",
750 (
long)(now.tv_sec - victim->timestamp_began.tv_sec),
756 (time_t)victim->timestamp_created.tv_sec)) {
763 switch (victim->purpose) {
774 log_info(
LD_CIRC,
"Rendezvous circ %u (state %d:%s, purpose %d) "
775 "as timed-out, closing it. Relaunching rendezvous attempt.",
776 (
unsigned)victim->n_circ_id,
789 "Abandoning circ %u %s:%u (state %d,%d:%s, purpose %d, "
792 (
unsigned)victim->n_circ_id,
801 "Abandoning circ %u %u (state %d,%d:%s, purpose %d, len %d)",
803 (
unsigned)victim->n_circ_id,
816 circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
819 } SMARTLIST_FOREACH_END(victim);
837 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_NONE);
838 } SMARTLIST_FOREACH_END(circ);
854#define MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG 10
855 time_t now = time(NULL);
856 time_t cutoff = now - age;
865 if (circ->timestamp_created.tv_sec >= cutoff)
869 if (hs_service_allow_non_anonymous_connection(options) &&
873 ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
878 if (smartlist_len(log_these) < MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG)
882 SMARTLIST_FOREACH_END(circ);
888 "Diagnostic for issue 8387: Found %d one-hop circuits more "
889 "than %d seconds old! Logging %d...",
890 n_found, age, smartlist_len(log_these));
893 char created[ISO_TIME_LEN+1];
903 char dirty_since[ISO_TIME_LEN+1];
906 tor_asprintf(&dirty,
"Dirty since %s (%ld seconds vs %ld-second cutoff)",
910 dirty = tor_strdup(
"Not marked dirty");
913 log_notice(
LD_HEARTBEAT,
" #%d created at %s. %s, %s. %s for close. "
914 "Package window: %d. "
915 "%s for new conns. %s.",
922 ocirc->unusable_for_new_conns ?
"Not usable" :
"usable",
927 for (conn = ocirc->p_streams; conn; conn = conn->
next_stream) {
929 char stream_created[ISO_TIME_LEN+1];
930 if (++stream_num >= 5)
936 "%s conn in state %s. "
937 "It is %slinked and %sreading from a linked connection %p. "
938 "Package window %d. "
939 "%s for close (%s:%d). Hold-open is %sset. "
940 "Has %ssent RELAY_END. %s on circuit.",
960 log_notice(
LD_HEARTBEAT,
" Linked to %s connection in state %s "
961 "(Purpose %d). %s for close (%s:%d). Hold-open is %sset. ",
970 } SMARTLIST_FOREACH_END(ocirc);
972 log_notice(
LD_HEARTBEAT,
"It has been %ld seconds since I last called "
973 "circuit_expire_old_circuits_clientside().",
977 smartlist_free(log_these);
989 for (i = 0; i < smartlist_len(needed_ports); ++i) {
990 port = smartlist_get(needed_ports, i);
994 log_debug(
LD_CIRC,
"Port %d is already being handled; removing.", *port);
998 log_debug(
LD_CIRC,
"Port %d is not handled.", *port);
1010 uint16_t port,
int min)
1014 time_t now = time(NULL);
1021 !circ->marked_for_close &&
1023 circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED) &&
1024 (!circ->timestamp_dirty ||
1025 circ->timestamp_dirty +
get_options()->MaxCircuitDirtiness > now)) {
1030 if (origin_circ->unusable_for_new_conns)
1038 if (exitnode && (!need_uptime || build_state->
need_uptime)) {
1054 SMARTLIST_FOREACH_END(circ);
1059#define MAX_UNUSED_OPEN_CIRCUITS 14
1067circuit_is_available_for_use(
const circuit_t *circ)
1084 origin_circ = CONST_TO_ORIGIN_CIRCUIT(circ);
1085 if (origin_circ->unusable_for_new_conns)
1100needs_exit_circuits(time_t now,
int *needs_uptime,
int *needs_capacity)
1108#define SUFFICIENT_UPTIME_INTERNAL_HS_SERVERS 3
1113needs_hs_server_circuits(time_t now,
int num_uptime_internal)
1120 if (num_uptime_internal >= SUFFICIENT_UPTIME_INTERNAL_HS_SERVERS) {
1142#define SUFFICIENT_INTERNAL_HS_CLIENTS 3
1146#define SUFFICIENT_UPTIME_INTERNAL_HS_CLIENTS 2
1151needs_hs_client_circuits(time_t now,
int *needs_uptime,
int *needs_capacity,
1152 int num_internal,
int num_uptime_internal)
1157 int requires_uptime = num_uptime_internal <
1158 SUFFICIENT_UPTIME_INTERNAL_HS_CLIENTS &&
1161 return (used_internal_recently &&
1162 (requires_uptime || num_internal < SUFFICIENT_INTERNAL_HS_CLIENTS) &&
1168#define DFLT_CBT_UNUSED_OPEN_CIRCS (10)
1169#define MIN_CBT_UNUSED_OPEN_CIRCS 0
1170#define MAX_CBT_UNUSED_OPEN_CIRCS MAX_UNUSED_OPEN_CIRCUITS
1176needs_circuits_for_build(
int num)
1180 DFLT_CBT_UNUSED_OPEN_CIRCS,
1181 MIN_CBT_UNUSED_OPEN_CIRCS,
1182 MAX_CBT_UNUSED_OPEN_CIRCS) &&
1198 int num=0, num_internal=0, num_uptime_internal=0;
1199 int hidserv_needs_uptime=0, hidserv_needs_capacity=1;
1200 int port_needs_uptime=0, port_needs_capacity=1;
1201 time_t now = time(NULL);
1215 if (!circuit_is_available_for_use(circ))
1224 num_uptime_internal++;
1226 SMARTLIST_FOREACH_END(circ);
1232 if (needs_exit_circuits(now, &port_needs_uptime, &port_needs_capacity)) {
1233 if (port_needs_uptime)
1235 if (port_needs_capacity)
1239 "Have %d clean circs (%d internal), need another exit circ.",
1246 if (needs_hs_server_circuits(now, num_uptime_internal)) {
1251 "Have %d clean circs (%d internal), need another internal "
1252 "circ for my hidden service.",
1258 if (needs_hs_client_circuits(now, &hidserv_needs_uptime,
1259 &hidserv_needs_capacity,
1260 num_internal, num_uptime_internal))
1262 if (hidserv_needs_uptime)
1264 if (hidserv_needs_capacity)
1269 "Have %d clean circs (%d uptime-internal, %d internal), need"
1270 " another hidden service circ.",
1271 num, num_uptime_internal, num_internal);
1280 if (needs_circuits_for_build(num)) {
1288 "Have %d clean circs need another buildtime test circ.", num);
1295#define TESTING_CIRCUIT_INTERVAL 300
1328 static time_t time_to_expire_and_reset = 0;
1330 if (time_to_expire_and_reset < now) {
1389 log_debug(
LD_APP,
"Removing stream %d from circ %u",
1437 log_warn(
LD_BUG,
"Edge connection not in circuit's list.");
1463 if (circ->timestamp_dirty &&
1464 circ->timestamp_dirty +
get_options()->MaxCircuitDirtiness <
1468 log_debug(
LD_CIRC,
"Closing n_circ_id %u (dirty %ld sec ago, "
1470 (
unsigned)circ->n_circ_id,
1471 (
long)(now.tv_sec - circ->timestamp_dirty),
1476 tor_trace(
TR_SUBSYS(circuit), TR_EV(idle_timeout),
1478 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
1481 if (
timercmp(&circ->timestamp_began, &cutoff, OP_LT)) {
1485 circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
1496 "Closing circuit %"PRIu32
1497 " that has been unused for %ld msec.",
1499 tv_mdiff(&circ->timestamp_began, &now));
1500 tor_trace(
TR_SUBSYS(circuit), TR_EV(idle_timeout),
1502 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
1512 "Ancient non-dirty circuit %d is still around after "
1513 "%ld milliseconds. Purpose: %d (%s)",
1515 tv_mdiff(&circ->timestamp_began, &now),
1523 } SMARTLIST_FOREACH_END(circ);
1541#define IDLE_ONE_HOP_CIRC_TIMEOUT 60
1568 log_info(
LD_CIRC,
"Closing circ_id %u (empty %d secs ago)",
1571 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
1574 SMARTLIST_FOREACH_END(circ);
1578#define NUM_PARALLEL_TESTING_CIRCS 4
1610 SMARTLIST_FOREACH_END(circ);
1645 router_all_orports_seem_reachable(options))
1649 "Our testing circuit (to see if your ORPort is reachable) "
1650 "has failed. I'll try again later.");
1666 tor_trace(
TR_SUBSYS(circuit), TR_EV(opened), circ);
1767 int failed_at_last_hop = 0;
1784 static ratelim_t pathfail_limit = RATELIM_INIT(3600);
1786 "Our circuit %u (id: %" PRIu32
") died due to an invalid "
1787 "selected path, purpose %s. This may be a torrc "
1788 "configuration issue, or a bug.",
1795 HS_METRICS_ERR_RDV_PATH);
1809 failed_at_last_hop = 1;
1821 int already_marked = 0;
1822 if (circ->base_.
n_chan) {
1823 n_chan = circ->base_.
n_chan;
1836 "Our circuit %u (id: %" PRIu32
") failed to get a response "
1837 "from the first hop (%s). I'm going to try to rotate to a "
1838 "better connection.",
1844 "Our circuit %u (id: %" PRIu32
") died before the first hop "
1845 "with no connection",
1848 if (!already_marked) {
1862 switch (circ->base_.
purpose) {
1868 if (failed_at_last_hop) {
1903 "Couldn't connect to the client's chosen rend point %s "
1906 failed_at_last_hop?
"last":
"non-last");
1909 HS_METRICS_ERR_RDV_RP_CONN_FAILURE);
1928#define MAX_CIRCUIT_FAILURES 5
1944have_enough_path_info(
int need_exit)
1980 return (purpose >= CIRCUIT_PURPOSE_C_HS_MIN_ &&
1981 purpose <= CIRCUIT_PURPOSE_C_HS_MAX_);
1988 return (purpose >= CIRCUIT_PURPOSE_S_HS_MIN_ &&
1989 purpose <= CIRCUIT_PURPOSE_S_HS_MAX_);
2004 (CONST_TO_ORIGIN_CIRCUIT(circ)->hs_ident != NULL));
2037 int has_extend_info,
2042 if (onehop_tunnel) {
2108 log_debug(
LD_CIRC,
"Haven't %s yet; canceling "
2111 "fetched enough directory info" :
2112 "received a consensus with exits");
2119 extend_info != NULL,
2126 uint8_t old_purpose = circ->base_.
purpose;
2129 log_info(
LD_CIRC,
"Cannibalizing circ %u (id: %" PRIu32
") for "
2166 &old_timestamp_began);
2185 "unexpected purpose %d when cannibalizing a circ.",
2191 tor_trace(
TR_SUBSYS(circuit), TR_EV(cannibalized), circ);
2240 uint8_t desired_circuit_purpose,
2244 int check_exit_policy;
2245 int need_uptime, need_internal;
2253 log_err(
LD_BUG,
"Connection state mismatch: wanted "
2254 "AP_CONN_STATE_CIRCUIT_WAIT, but got %d (%s)",
2284 desired_circuit_purpose,
2285 need_uptime, need_internal);
2297 int have_path = have_enough_path_info(!need_internal);
2311 tor_assert_nonfatal_once(rv);
2313 "Application request when we haven't %s. "
2314 "Optimistically trying known %s again.",
2316 "used client functionality lately" :
2317 "received a consensus with exits",
2318 options->
UseBridges ?
"bridges" :
"entrynodes");
2326 "Application request when we haven't %s. "
2327 "Optimistically trying directory fetches again.",
2329 "used client functionality lately" :
2330 "received a consensus with exits");
2344 if (check_exit_policy) {
2356 "No Tor server allows exit to %s:%d. Rejecting.",
2368 "Requested exit point '%s' is excluded or "
2369 "would refuse request. %s.",
2376 desired_circuit_purpose,
2388 desired_circuit_purpose,
2389 need_uptime, need_internal);
2391 log_debug(
LD_CIRC,
"one on the way!");
2404 static ratelim_t delay_limit = RATELIM_INIT(10*60);
2407 log_notice(
LD_APP,
"We'd like to launch a circuit to handle a "
2408 "connection, but we already have %d general-purpose client "
2409 "circuits pending. Waiting until some finish.%s",
2423 log_info(
LD_REND,
"No intro points: re-fetching service descriptor.");
2428 log_info(
LD_REND,
"Chose %s as intro point for service",
2449 log_warn(
LD_CIRC,
"Could not make a one-hop connection to %s. "
2454 log_debug(
LD_DIR,
"considering %d, %s",
2469 log_info(
LD_DIR,
"Broken exit digest on tunnel conn. Closing.");
2473 log_info(
LD_DIR,
"Broken address %s on tunnel conn. Closing.",
2489 "Requested exit point '%s' is not known. %s.",
2496 desired_circuit_purpose,
2506 uint8_t new_circ_purpose;
2512 new_circ_purpose = desired_circuit_purpose;
2527 log_info(
LD_GENERAL,
"Getting rendezvous circuit to v3 service!");
2534 extend_info_free(extend_info);
2546 log_info(
LD_CIRC,
"The application request to %s:%d has launched "
2547 "%d circuits without finding one it likes.",
2556 if (edge_conn->hs_ident) {
2584 "No safe circuit (purpose %d) ready for edge "
2585 "connection; delaying.",
2586 desired_circuit_purpose);
2604 for (cpath = circ->
cpath; cpath_next != circ->
cpath; cpath = cpath_next) {
2605 cpath_next = cpath->
next;
2606 if (crypt_path == cpath)
2620 const node_t *exitnode = NULL;
2623 log_debug(
LD_APP|
LD_CIRC,
"attaching new conn to circ. n_circ_id %u.",
2632 ENTRY_TO_CONN(apconn)->timestamp_last_read_allowed = time(NULL);
2674 log_info(
LD_APP,
"Looks like completed circuit to %s %s allow "
2675 "optimistic data for connection to %s",
2694 if (cp[1] ==
'\0' ||
2696 !strcasecmp(address, &cp[1]))
2698 }
else if (strcasecmp(cp, address) == 0) {
2701 } SMARTLIST_FOREACH_END(cp);
2714 char *new_address = NULL;
2716 uint64_t stream_id = 0;
2861 "Tried for %d seconds to get a connection to %s:%d. Giving up.",
2880 if (networkstatus_consensus_is_already_downloading(
2886 log_info(
LD_DIR,
"Closing extra consensus fetch (to %s) since one "
2898 if (!node && !want_onehop) {
2905 "Requested exit point '%s' is not known. %s.",
2917 "Requested exit point '%s' is excluded or "
2918 "would refuse request. %s.",
2944 "Attaching apconn to circ %u (stream %d sec old).",
2945 (
unsigned)circ->base_.
n_circ_id, conn_age);
2963 if (retval < 0)
return -1;
2969 "rend joined circ %u (id: %" PRIu32
") already here. "
2970 "Attaching. (stream %d sec old)",
2996 log_info(
LD_REND,
"This connection is no longer ready to attach; its "
2998 "(We probably have to re-fetch its descriptor.)");
3002 if (rendcirc && (rendcirc->base_.
purpose ==
3005 "pending-join circ %u (id: %" PRIu32
") already here, with "
3006 "intro ack. Stalling. (stream %d sec old)",
3015 if (retval < 0)
return -1;
3017 if (rendcirc && introcirc) {
3022 &introcirc->hs_ident->intro_auth_pk));
3024 &introcirc->hs_ident->intro_auth_pk);
3030 log_info(
LD_REND,
"Intro circ %u (id: %" PRIu32
") present and "
3031 "awaiting ACK. Rend circuit %u (id: %" PRIu32
"). "
3032 "Stalling. (stream %d sec old)",
3034 introcirc->global_identifier,
3035 rendcirc ? (
unsigned)
TO_CIRCUIT(rendcirc)->n_circ_id : 0,
3043 if (rendcirc && introcirc &&
3046 "ready rend circ %u (id: %" PRIu32
") already here. No"
3047 "intro-ack yet on intro %u (id: %" PRIu32
"). "
3048 "(stream %d sec old)",
3052 introcirc->global_identifier, conn_age);
3057 log_info(
LD_REND,
"Found open intro circ %u (id: %" PRIu32
"). "
3058 "Rend circuit %u (id: %" PRIu32
"); Considering "
3059 "sending introduction. (stream %d sec old)",
3061 introcirc->global_identifier,
3068 introcirc->base_.timestamp_dirty = time(NULL);
3087 log_info(
LD_REND,
"Intro %u (id: %" PRIu32
") and rend circuit %u "
3088 "(id: %" PRIu32
") circuits are not both ready. "
3089 "Stalling conn. (%d sec old)",
3090 introcirc ? (
unsigned)
TO_CIRCUIT(introcirc)->n_circ_id : 0,
3091 introcirc ? introcirc->global_identifier : 0,
3092 rendcirc ? (
unsigned)
TO_CIRCUIT(rendcirc)->n_circ_id : 0,
3102 uint8_t old_purpose;
3107 if (circ->
purpose == new_purpose)
return;
3110 if (CIRCUIT_IS_CONFLUX(circ)) {
3112 if (new_purpose != CIRCUIT_PURPOSE_CONFLUX_LINKED)
3117 char old_purpose_desc[80] =
"";
3120 old_purpose_desc[80-1] =
'\0';
3123 "changing purpose of origin circ %d "
3124 "from \"%s\" (%d) to \"%s\" (%d)",
3140 tor_trace(
TR_SUBSYS(circuit), TR_EV(change_purpose), circ, old_purpose,
3168 circ->unusable_for_new_conns = 1;
3186 "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 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_V3_RP
#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 RELAY_PAYLOAD_SIZE
#define END_CIRC_REASON_MEASUREMENT_EXPIRED
#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.
int server_mode(const or_options_t *options)
Header file for routermode.c.
int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
int router_orport_seems_reachable(const or_options_t *options, int family)
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)