#ifndef TOR_ENTRYNODES_H
#define TOR_ENTRYNODES_H
#include "lib/container/handles.h"
typedef struct guard_selection_t guard_selection_t;
typedef struct entry_guard_t entry_guard_t;
typedef struct circuit_guard_state_t circuit_guard_state_t;
typedef struct entry_guard_restriction_t entry_guard_restriction_t;
typedef struct guard_pathbias_t {
unsigned int path_bias_noticed : 1;
unsigned int path_bias_warned : 1;
unsigned int path_bias_extreme : 1;
unsigned int path_bias_disabled : 1;
unsigned int path_bias_use_noticed : 1;
unsigned int path_bias_use_extreme : 1;
double circ_attempts;
double circ_successes;
double successful_circuits_closed;
double collapsed_circuits;
double unusable_circuits;
double timeouts;
double use_attempts;
double use_successes;
} guard_pathbias_t;
#if defined(ENTRYNODES_PRIVATE)
#include "lib/crypt_ops/crypto_ed25519.h"
#define GUARD_REACHABLE_NO 0
#define GUARD_REACHABLE_YES 1
#define GUARD_REACHABLE_MAYBE 2
struct entry_guard_t {
HANDLE_ENTRY(entry_guard, entry_guard_t);
char nickname[MAX_HEX_NICKNAME_LEN+1];
char identity[DIGEST_LEN];
ed25519_public_key_t ed_id;
time_t sampled_on_date;
time_t unlisted_since_date;
char *sampled_by_version;
unsigned currently_listed : 1;
time_t confirmed_on_date;
int sampled_idx;
int confirmed_idx;
char *selection_name;
tor_addr_port_t *bridge_addr;
time_t last_tried_to_connect;
unsigned is_reachable : 2;
unsigned is_pending : 1;
unsigned is_persistent : 1;
time_t failing_since;
unsigned is_filtered_guard : 1;
unsigned is_usable_filtered_guard : 1;
unsigned is_primary:1;
char *extra_state_fields;
guard_selection_t *in_selection;
guard_pathbias_t pb;
};
typedef enum guard_selection_type_t {
GS_TYPE_INFER=0,
GS_TYPE_NORMAL=1,
GS_TYPE_BRIDGE,
GS_TYPE_RESTRICTED,
} guard_selection_type_t;
struct guard_selection_t {
char *name;
guard_selection_type_t type;
int primary_guards_up_to_date;
smartlist_t *sampled_entry_guards;
smartlist_t *confirmed_entry_guards;
smartlist_t *primary_entry_guards;
time_t last_time_on_internet;
int next_confirmed_idx;
int next_sampled_idx;
};
struct entry_guard_handle_t;
typedef enum guard_restriction_type_t {
RST_EXIT_NODE = 0,
RST_OUTDATED_MD_DIRSERVER = 1
} guard_restriction_type_t;
struct entry_guard_restriction_t {
guard_restriction_type_t type;
uint8_t exclude_id[DIGEST_LEN];
};
struct circuit_guard_state_t {
struct entry_guard_handle_t *guard;
time_t state_set_at;
uint8_t state;
entry_guard_restriction_t *restrictions;
};
#endif
int guards_update_all(void);
const node_t *guards_choose_guard(cpath_build_state_t *state,
uint8_t purpose,
circuit_guard_state_t **guard_state_out);
const node_t *guards_choose_dirguard(uint8_t dir_purpose,
circuit_guard_state_t **guard_state_out);
#if 1
entry_guard_t *entry_guard_get_by_id_digest_for_guard_selection(
guard_selection_t *gs, const char *digest);
entry_guard_t *entry_guard_get_by_id_digest(const char *digest);
circuit_guard_state_t *
get_guard_state_for_bridge_desc_fetch(const char *digest);
void entry_guards_changed_for_guard_selection(guard_selection_t *gs);
void entry_guards_changed(void);
guard_selection_t * get_guard_selection_info(void);
int num_live_entry_guards_for_guard_selection(
guard_selection_t *gs,
int for_directory);
int num_live_entry_guards(int for_directory);
#endif
const node_t *entry_guard_find_node(const entry_guard_t *guard);
const char *entry_guard_get_rsa_id_digest(const entry_guard_t *guard);
const char *entry_guard_describe(const entry_guard_t *guard);
guard_pathbias_t *entry_guard_get_pathbias_state(entry_guard_t *guard);
typedef enum {
GUARD_USAGE_TRAFFIC = 0,
GUARD_USAGE_DIRGUARD = 1
} guard_usage_t;
#define circuit_guard_state_free(val) \
FREE_AND_NULL(circuit_guard_state_t, circuit_guard_state_free_, (val))
void circuit_guard_state_free_(circuit_guard_state_t *state);
int entry_guard_pick_for_circuit(guard_selection_t *gs,
guard_usage_t usage,
entry_guard_restriction_t *rst,
const node_t **chosen_node_out,
circuit_guard_state_t **guard_state_out);
typedef enum {
GUARD_USABLE_NEVER = -1,
GUARD_MAYBE_USABLE_LATER = 0,
GUARD_USABLE_NOW = 1,
} guard_usable_t;
guard_usable_t entry_guard_succeeded(circuit_guard_state_t **guard_state_p);
void entry_guard_failed(circuit_guard_state_t **guard_state_p);
void entry_guard_cancel(circuit_guard_state_t **guard_state_p);
void entry_guard_chan_failed(channel_t *chan);
int entry_guards_update_all(guard_selection_t *gs);
int entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
const smartlist_t *all_circuits,
smartlist_t *newly_complete_out);
int entry_guard_state_should_expire(circuit_guard_state_t *guard_state);
void entry_guards_note_internet_connectivity(guard_selection_t *gs);
int update_guard_selection_choice(const or_options_t *options);
int entry_guard_could_succeed(const circuit_guard_state_t *guard_state);
MOCK_DECL(int,num_bridges_usable,(int use_maybe_reachable));
#ifdef ENTRYNODES_PRIVATE
#define DFLT_MAX_SAMPLE_THRESHOLD_PERCENT 20
#define DFLT_MAX_SAMPLE_SIZE 60
#define DFLT_MIN_FILTERED_SAMPLE_SIZE 20
#define DFLT_REMOVE_UNLISTED_GUARDS_AFTER_DAYS 20
#define DFLT_GUARD_LIFETIME_DAYS 120
#define DFLT_GUARD_CONFIRMED_MIN_LIFETIME_DAYS 60
#define DFLT_N_PRIMARY_GUARDS 3
#define DFLT_N_PRIMARY_GUARDS_TO_USE 1
#define DFLT_N_PRIMARY_DIR_GUARDS_TO_USE 3
#define DFLT_INTERNET_LIKELY_DOWN_INTERVAL (10*60)
#define DFLT_NONPRIMARY_GUARD_CONNECT_TIMEOUT 15
#define DFLT_NONPRIMARY_GUARD_IDLE_TIMEOUT (10*60)
#define DFLT_MEANINGFUL_RESTRICTION_PERCENT 20
#define DFLT_EXTREME_RESTRICTION_PERCENT 1
STATIC double get_max_sample_threshold(void);
STATIC int get_max_sample_size_absolute(void);
STATIC int get_min_filtered_sample_size(void);
STATIC int get_remove_unlisted_guards_after_days(void);
STATIC int get_guard_lifetime(void);
STATIC int get_guard_confirmed_min_lifetime(void);
STATIC int get_n_primary_guards(void);
STATIC int get_n_primary_guards_to_use(guard_usage_t usage);
STATIC int get_internet_likely_down_interval(void);
STATIC int get_nonprimary_guard_connect_timeout(void);
STATIC int get_nonprimary_guard_idle_timeout(void);
STATIC double get_meaningful_restriction_threshold(void);
STATIC double get_extreme_restriction_threshold(void);
HANDLE_DECL(entry_guard, entry_guard_t, STATIC)
#define entry_guard_handle_free(h) \
FREE_AND_NULL(entry_guard_handle_t, entry_guard_handle_free_, (h))
STATIC guard_selection_type_t guard_selection_infer_type(
guard_selection_type_t type_in,
const char *name);
STATIC guard_selection_t *guard_selection_new(const char *name,
guard_selection_type_t type);
STATIC guard_selection_t *get_guard_selection_by_name(
const char *name, guard_selection_type_t type, int create_if_absent);
STATIC void guard_selection_free_(guard_selection_t *gs);
#define guard_selection_free(gs) \
FREE_AND_NULL(guard_selection_t, guard_selection_free_, (gs))
MOCK_DECL(STATIC int, entry_guard_is_listed,
(guard_selection_t *gs, const entry_guard_t *guard));
STATIC const char *choose_guard_selection(const or_options_t *options,
const networkstatus_t *ns,
const guard_selection_t *old_selection,
guard_selection_type_t *type_out);
STATIC entry_guard_t *get_sampled_guard_with_id(guard_selection_t *gs,
const uint8_t *rsa_id);
MOCK_DECL(STATIC time_t, randomize_time, (time_t now, time_t max_backdate));
MOCK_DECL(STATIC circuit_guard_state_t *,
circuit_guard_state_new,(entry_guard_t *guard, unsigned state,
entry_guard_restriction_t *rst));
STATIC entry_guard_t *entry_guard_add_to_sample(guard_selection_t *gs,
const node_t *node);
STATIC entry_guard_t *entry_guards_expand_sample(guard_selection_t *gs);
STATIC char *entry_guard_encode_for_state(entry_guard_t *guard, int
dense_sampled_index);
STATIC entry_guard_t *entry_guard_parse_from_state(const char *s);
#define entry_guard_free(e) \
FREE_AND_NULL(entry_guard_t, entry_guard_free_, (e))
STATIC void entry_guard_free_(entry_guard_t *e);
STATIC void entry_guards_update_filtered_sets(guard_selection_t *gs);
STATIC int entry_guards_all_primary_guards_are_down(guard_selection_t *gs);
#define SAMPLE_EXCLUDE_CONFIRMED (1u<<0)
#define SAMPLE_EXCLUDE_PRIMARY (1u<<1)
#define SAMPLE_EXCLUDE_PENDING (1u<<2)
#define SAMPLE_NO_UPDATE_PRIMARY (1u<<3)
#define SAMPLE_EXCLUDE_NO_DESCRIPTOR (1u<<4)
STATIC entry_guard_t *first_reachable_filtered_entry_guard(
guard_selection_t *gs,
const entry_guard_restriction_t *rst,
unsigned flags);
STATIC void entry_guard_consider_retry(entry_guard_t *guard);
STATIC void make_guard_confirmed(guard_selection_t *gs, entry_guard_t *guard);
STATIC void entry_guards_update_confirmed(guard_selection_t *gs);
STATIC void entry_guards_update_primary(guard_selection_t *gs);
STATIC int num_reachable_filtered_guards(const guard_selection_t *gs,
const entry_guard_restriction_t *rst);
STATIC void sampled_guards_update_from_consensus(guard_selection_t *gs);
#define GUARD_CIRC_STATE_USABLE_ON_COMPLETION 1
#define GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD 2
#define GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD 3
#define GUARD_CIRC_STATE_COMPLETE 4
#define GUARD_CIRC_STATE_DEAD 5
STATIC void entry_guards_note_guard_failure(guard_selection_t *gs,
entry_guard_t *guard);
STATIC entry_guard_t *select_entry_guard_for_circuit(guard_selection_t *gs,
guard_usage_t usage,
const entry_guard_restriction_t *rst,
unsigned *state_out);
STATIC void mark_primary_guards_maybe_reachable(guard_selection_t *gs);
STATIC unsigned entry_guards_note_guard_success(guard_selection_t *gs,
entry_guard_t *guard,
unsigned old_state);
STATIC int entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b);
STATIC char *getinfo_helper_format_single_entry_guard(const entry_guard_t *e);
STATIC entry_guard_restriction_t *guard_create_exit_restriction(
const uint8_t *exit_id);
STATIC entry_guard_restriction_t *guard_create_dirserver_md_restriction(void);
STATIC void entry_guard_restriction_free_(entry_guard_restriction_t *rst);
#define entry_guard_restriction_free(rst) \
FREE_AND_NULL(entry_guard_restriction_t, \
entry_guard_restriction_free_, (rst))
#endif
void remove_all_entry_guards_for_guard_selection(guard_selection_t *gs);
void remove_all_entry_guards(void);
struct bridge_info_t;
void entry_guard_learned_bridge_identity(const tor_addr_port_t *addrport,
const uint8_t *rsa_id_digest);
int entry_list_is_constrained(const or_options_t *options);
int guards_retry_optimistic(const or_options_t *options);
int entry_guards_parse_state_for_guard_selection(
guard_selection_t *gs, or_state_t *state, int set, char **msg);
int entry_guards_parse_state(or_state_t *state, int set, char **msg);
void entry_guards_update_state(or_state_t *state);
int getinfo_helper_entry_guards(control_connection_t *conn,
const char *question, char **answer,
const char **errmsg);
int entries_known_but_down(const or_options_t *options);
void entries_retry_all(const or_options_t *options);
char *entry_guards_get_err_str_if_dir_info_missing(int using_mds,
int num_present, int num_usable);
char *guard_selection_get_err_str_if_dir_info_missing(guard_selection_t *gs,
int using_mds,
int num_present, int num_usable);
void entry_guards_free_all(void);
double pathbias_get_close_success_count(entry_guard_t *guard);
double pathbias_get_use_success_count(entry_guard_t *guard);
typedef struct guardfraction_bandwidth_t {
int guard_bw;
int non_guard_bw;
} guardfraction_bandwidth_t;
int should_apply_guardfraction(const networkstatus_t *ns);
void
guard_get_guardfraction_bandwidth(guardfraction_bandwidth_t *guardfraction_bw,
int orig_bandwidth,
uint32_t guardfraction_percentage);
#endif