tor
master
|
Code to manage our fixed first nodes for various functions. More...
#include "or.h"
#include "channel.h"
#include "bridges.h"
#include "circpathbias.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "circuitstats.h"
#include "config.h"
#include "confparse.h"
#include "connection.h"
#include "control.h"
#include "crypto_rand.h"
#include "directory.h"
#include "entrynodes.h"
#include "main.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "router.h"
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
#include "transports.h"
#include "statefile.h"
Macros | |
#define | ENTRYNODES_PRIVATE |
#define | MIN_GUARDS_FOR_MD_RESTRICTION 10 |
#define | PB_FIELD(field) |
#define | FIELD(f) strmap_set(vals, #f, &f); |
#define | HANDLE_TIME(field) |
#define | PB_FIELD(field) |
#define | SLOW_GUARD_STATE_FLUSH_TIME 600 |
#define | FAST_GUARD_STATE_FLUSH_TIME 30 |
Functions | |
int | should_apply_guardfraction (const networkstatus_t *ns) |
STATIC guard_selection_type_t | guard_selection_infer_type (guard_selection_type_t type, 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) |
guard_selection_t * | get_guard_selection_info (void) |
const char * | entry_guard_describe (const entry_guard_t *guard) |
const char * | entry_guard_get_rsa_id_digest (const entry_guard_t *guard) |
guard_pathbias_t * | entry_guard_get_pathbias_state (entry_guard_t *guard) |
MOCK_IMPL (STATIC time_t, randomize_time,(time_t now, time_t max_backdate)) | |
STATIC const char * | choose_guard_selection (const or_options_t *options, const networkstatus_t *live_ns, const guard_selection_t *old_selection, guard_selection_type_t *type_out) |
int | update_guard_selection_choice (const or_options_t *options) |
STATIC entry_guard_t * | get_sampled_guard_with_id (guard_selection_t *gs, const uint8_t *rsa_id) |
STATIC entry_guard_t * | entry_guard_add_to_sample (guard_selection_t *gs, const node_t *node) |
void | entry_guard_learned_bridge_identity (const tor_addr_port_t *addrport, const uint8_t *rsa_id_digest) |
STATIC int | num_reachable_filtered_guards (const guard_selection_t *gs, const entry_guard_restriction_t *rst) |
STATIC entry_guard_t * | entry_guards_expand_sample (guard_selection_t *gs) |
MOCK_IMPL (STATIC int, entry_guard_is_listed,(guard_selection_t *gs, const entry_guard_t *guard)) | |
STATIC void | sampled_guards_update_from_consensus (guard_selection_t *gs) |
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_guards_update_filtered_sets (guard_selection_t *gs) |
STATIC entry_guard_t * | sample_reachable_filtered_entry_guards (guard_selection_t *gs, const entry_guard_restriction_t *rst, unsigned flags) |
STATIC void | entry_guards_update_confirmed (guard_selection_t *gs) |
STATIC void | make_guard_confirmed (guard_selection_t *gs, entry_guard_t *guard) |
STATIC void | entry_guards_update_primary (guard_selection_t *gs) |
STATIC void | entry_guard_consider_retry (entry_guard_t *guard) |
void | entry_guards_note_internet_connectivity (guard_selection_t *gs) |
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 | entry_guards_note_guard_failure (guard_selection_t *gs, entry_guard_t *guard) |
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 void | entry_guard_restriction_free_ (entry_guard_restriction_t *rst) |
void | circuit_guard_state_free_ (circuit_guard_state_t *state) |
MOCK_IMPL (STATIC circuit_guard_state_t *, circuit_guard_state_new,(entry_guard_t *guard, unsigned state, entry_guard_restriction_t *rst)) | |
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) |
guard_usable_t | entry_guard_succeeded (circuit_guard_state_t **guard_state_p) |
void | entry_guard_cancel (circuit_guard_state_t **guard_state_p) |
void | entry_guard_failed (circuit_guard_state_t **guard_state_p) |
void | entry_guard_chan_failed (channel_t *chan) |
STATIC int | entry_guards_all_primary_guards_are_down (guard_selection_t *gs) |
int | entry_guards_upgrade_waiting_circuits (guard_selection_t *gs, const smartlist_t *all_circuits_in, smartlist_t *newly_complete_out) |
int | entry_guard_state_should_expire (circuit_guard_state_t *guard_state) |
int | entry_guards_update_all (guard_selection_t *gs) |
STATIC char * | entry_guard_encode_for_state (entry_guard_t *guard) |
STATIC entry_guard_t * | entry_guard_parse_from_state (const char *s) |
entry_guard_t * | entry_guard_get_by_id_digest_for_guard_selection (guard_selection_t *gs, const char *digest) |
const node_t * | entry_guard_find_node (const entry_guard_t *guard) |
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) |
STATIC void | entry_guard_free_ (entry_guard_t *e) |
int | entry_list_is_constrained (const or_options_t *options) |
MOCK_IMPL (int, num_bridges_usable,(int use_maybe_reachable)) | |
int | entry_guards_parse_state (or_state_t *state, int set, char **msg) |
void | entry_guards_changed_for_guard_selection (guard_selection_t *gs) |
void | entry_guards_changed (void) |
void | entry_guards_update_state (or_state_t *state) |
int | entry_guard_could_succeed (const circuit_guard_state_t *guard_state) |
STATIC char * | getinfo_helper_format_single_entry_guard (const entry_guard_t *e) |
int | getinfo_helper_entry_guards (control_connection_t *conn, const char *question, char **answer, const char **errmsg) |
void | guard_get_guardfraction_bandwidth (guardfraction_bandwidth_t *guardfraction_bw, int orig_bandwidth, uint32_t guardfraction_percentage) |
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) |
void | remove_all_entry_guards_for_guard_selection (guard_selection_t *gs) |
void | remove_all_entry_guards (void) |
const node_t * | guards_choose_dirguard (uint8_t dir_purpose, circuit_guard_state_t **guard_state_out) |
int | guards_retry_optimistic (const or_options_t *options) |
char * | guard_selection_get_err_str_if_dir_info_missing (guard_selection_t *gs, int using_mds, int num_present, int num_usable) |
char * | entry_guards_get_err_str_if_dir_info_missing (int using_mds, int num_present, int num_usable) |
STATIC void | guard_selection_free_ (guard_selection_t *gs) |
void | entry_guards_free_all (void) |
parameters for networkstatus algorithm | |
These parameters are taken from the consensus; some are overrideable in the torrc. | |
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) |
STATIC void | mark_primary_guards_maybe_reachable (guard_selection_t *gs) |
Code to manage our fixed first nodes for various functions.
Entry nodes can be guards (for general use) or bridges (for censorship circumvention).
In general, we use entry guards to prevent traffic-sampling attacks: if we chose every circuit independently, an adversary controlling some fraction of paths on the network would observe a sample of every user's traffic. Using guards gives users a chance of not being profiled.
The current entry guard selection code is designed to try to avoid ever trying every guard on the network, to try to stick to guards that we've used before, to handle hostile/broken networks, and to behave sanely when the network goes up and down.
Our algorithm works as follows: First, we maintain a SAMPLE of guards we've seen in the networkstatus consensus. We maintain this sample over time, and store it persistently; it is chosen without reference to our configuration or firewall rules. Guards remain in the sample as they enter and leave the consensus. We expand this sample as needed, up to a maximum size.
As a subset of the sample, we maintain a FILTERED SET of the guards that we would be willing to use if we could connect to them. The filter removes all the guards that we're excluding because they're bridges (or not bridges), because we have restrictive firewall rules, because of ExcludeNodes, because we of path bias restrictions, because they're absent from the network at present, and so on.
As a subset of the filtered set, we keep a REACHABLE FILTERED SET (also called a "usable filtered set") of those guards that we call "reachable" or "maybe reachable". A guard is reachable if we've connected to it more recently than we've failed. A guard is "maybe reachable" if we have never tried to connect to it, or if we failed to connect to it so long ago that we no longer think our failure means it's down.
As a persistent ordered list whose elements are taken from the sampled set, we track a CONFIRMED GUARDS LIST. A guard becomes confirmed when we successfully build a circuit through it, and decide to use that circuit. We order the guards on this list by the order in which they became confirmed.
And as a final group, we have an ordered list of PRIMARY GUARDS, whose elements are taken from the filtered set. We prefer confirmed guards to non-confirmed guards for this list, and place other restrictions on it. The primary guards are the ones that we connect to "when nothing is wrong" – circuits through them can be used immediately.
To build circuits, we take a primary guard if possible – or a reachable filtered confirmed guard if no primary guard is possible – or a random reachable filtered guard otherwise. If the guard is primary, we can use the circuit immediately on success. Otherwise, the guard is now "pending" – we won't use its circuit unless all of the circuits we're trying to build through better guards have definitely failed.
While we're building circuits, we track a little "guard state" for each circuit. We use this to keep track of whether the circuit is one that we can use as soon as it's done, or whether it's one that we should keep around to see if we can do better. In the latter case, a periodic call to entry_guards_upgrade_waiting_circuits() will eventually upgrade it.
#define FAST_GUARD_STATE_FLUSH_TIME 30 |
How long will we let a change in our guard nodes stay un-saved when we are not trying to avoid disk writes?
#define HANDLE_TIME | ( | field | ) |
#define MIN_GUARDS_FOR_MD_RESTRICTION 10 |
If we have fewer than this many possible usable guards, don't set MD-availability-based restrictions: we might blacklist all of them.
#define PB_FIELD | ( | field | ) |
#define PB_FIELD | ( | field | ) |
#define SLOW_GUARD_STATE_FLUSH_TIME 600 |
How long will we let a change in our guard nodes stay un-saved when we are trying to avoid disk writes?
STATIC const char* choose_guard_selection | ( | const or_options_t * | options, |
const networkstatus_t * | live_ns, | ||
const guard_selection_t * | old_selection, | ||
guard_selection_type_t * | type_out | ||
) |
Given our options and our list of nodes, return the name of the guard selection that we should use. Return NULL for "use the same selection you were using before.
void circuit_guard_state_free_ | ( | circuit_guard_state_t * | state | ) |
Release all storage held in state.
STATIC entry_guard_t* entry_guard_add_to_sample | ( | guard_selection_t * | gs, |
const node_t * | node | ||
) |
Allocate a new entry_guard_t object for node, add it to the sampled entry guards in gs, and return it. node must not currently be a sampled guard in gs.
void entry_guard_cancel | ( | circuit_guard_state_t ** | guard_state_p | ) |
Cancel the selection of *guard_state_p without declaring success or failure. It is safe to call this function if success or failure has already been declared.
void entry_guard_chan_failed | ( | channel_t * | chan | ) |
Run the entry_guard_failed() function on every circuit that is pending on chan.
STATIC void entry_guard_consider_retry | ( | entry_guard_t * | guard | ) |
If guard is unreachable, consider whether enough time has passed to consider it maybe-reachable again.
int entry_guard_could_succeed | ( | const circuit_guard_state_t * | guard_state | ) |
Return true iff the circuit's guard can succeed that is can be used.
const char* entry_guard_describe | ( | const entry_guard_t * | guard | ) |
Return a statically allocated human-readable description of guard
STATIC char* entry_guard_encode_for_state | ( | entry_guard_t * | guard | ) |
Return a newly allocated string for encoding the persistent parts of guard to the state file.
void entry_guard_failed | ( | circuit_guard_state_t ** | guard_state_p | ) |
Called by the circuit building module when a circuit has failed: informs the guards code that the guard in *guard_state_p is not working, and advances the state of the guard module.
const node_t* entry_guard_find_node | ( | const entry_guard_t * | guard | ) |
Return the node_t associated with a single entry_guard_t. May return NULL if the guard is not currently in the consensus.
STATIC void entry_guard_free_ | ( | entry_guard_t * | e | ) |
Release all storage held by e.
entry_guard_t* entry_guard_get_by_id_digest | ( | const char * | digest | ) |
If digest matches the identity of any node in the entry_guards list for the default guard selection state, return that node. Else return NULL.
entry_guard_t* entry_guard_get_by_id_digest_for_guard_selection | ( | guard_selection_t * | gs, |
const char * | digest | ||
) |
If digest matches the identity of any node in the entry_guards list for the provided guard selection state, return that node. Else return NULL.
guard_pathbias_t* entry_guard_get_pathbias_state | ( | entry_guard_t * | guard | ) |
Return the pathbias state associated with guard.
const char* entry_guard_get_rsa_id_digest | ( | const entry_guard_t * | guard | ) |
Return guard's 20-byte RSA identity digest
STATIC int entry_guard_has_higher_priority | ( | entry_guard_t * | a, |
entry_guard_t * | b | ||
) |
Helper: Return true iff a has higher priority than b.
void entry_guard_learned_bridge_identity | ( | const tor_addr_port_t * | addrport, |
const uint8_t * | rsa_id_digest | ||
) |
Update the guard subsystem's knowledge of the identity of the bridge at addrport. Idempotent.
STATIC entry_guard_t* entry_guard_parse_from_state | ( | const char * | s | ) |
Given a string generated by entry_guard_encode_for_state(), parse it (if possible) and return an entry_guard_t object for it. Return NULL on complete failure.
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 | ||
) |
Pick a suitable entry guard for a circuit in, and place that guard in *chosen_node_out. Set *guard_state_out to an opaque state object that will record whether the circuit is ready to be used or not. Return 0 on success; on failure, return -1.
If a restriction is provided in rst, do not return any guards that violate it, and remember that restriction in guard_state_out for later use. (Takes ownership of the rst object.)
STATIC void entry_guard_restriction_free_ | ( | entry_guard_restriction_t * | rst | ) |
Release all storage held in restriction
int entry_guard_state_should_expire | ( | circuit_guard_state_t * | guard_state | ) |
Return true iff the circuit whose state is guard_state should expire.
guard_usable_t entry_guard_succeeded | ( | circuit_guard_state_t ** | guard_state_p | ) |
Called by the circuit building module when a circuit has succeeded: informs the guards code that the guard in *guard_state_p is working, and advances the state of the guard module. On a GUARD_USABLE_NEVER return value, the circuit is broken and should not be used. On a GUARD_USABLE_NOW return value, the circuit is ready to use. On a GUARD_MAYBE_USABLE_LATER return value, the circuit should not be used until we find out whether preferred guards will work for us.
STATIC int entry_guards_all_primary_guards_are_down | ( | guard_selection_t * | gs | ) |
Return true iff every primary guard in gs is believed to be unreachable.
void entry_guards_changed | ( | void | ) |
Our list of entry guards has changed for the default guard selection context, or some element of one of our entry guards has changed. Write the changes to disk within the next few minutes.
void entry_guards_changed_for_guard_selection | ( | guard_selection_t * | gs | ) |
Our list of entry guards has changed for a particular guard selection context, or some element of one of our entry guards has changed for one. Write the changes to disk within the next few minutes.
STATIC entry_guard_t* entry_guards_expand_sample | ( | guard_selection_t * | gs | ) |
Add new guards to the sampled guards in gs until there are enough usable filtered guards, but never grow the sample beyond its maximum size. Return the last guard added, or NULL if none were added.
void entry_guards_free_all | ( | void | ) |
Release all storage held by the list of entry guards and related memory structs.
char* entry_guards_get_err_str_if_dir_info_missing | ( | int | using_mds, |
int | num_present, | ||
int | num_usable | ||
) |
As guard_selection_have_enough_dir_info_to_build_circuits, but uses the default guard selection.
STATIC void entry_guards_note_guard_failure | ( | guard_selection_t * | gs, |
entry_guard_t * | guard | ||
) |
Note that we failed to connect to or build circuits through guard. Use with a guard returned by select_entry_guard_for_circuit().
STATIC unsigned entry_guards_note_guard_success | ( | guard_selection_t * | gs, |
entry_guard_t * | guard, | ||
unsigned | old_state | ||
) |
Note that we successfully connected to, and built a circuit through guard. Given the old guard-state of the circuit in old_state, return the new guard-state of the circuit.
Be aware: the circuit is only usable when its guard-state becomes GUARD_CIRC_STATE_COMPLETE.
void entry_guards_note_internet_connectivity | ( | guard_selection_t * | gs | ) |
Tell the entry guards subsystem that we have confirmed that as of just now, we're on the internet.
int entry_guards_parse_state | ( | or_state_t * | state, |
int | set, | ||
char ** | msg | ||
) |
Parse state and learn about the entry guards it describes. If set is true, and there are no errors, replace the guard list in the default guard selection context with what we find. On success, return 0. On failure, alloc into *msg a string describing the error, and return -1.
int entry_guards_update_all | ( | guard_selection_t * | gs | ) |
Update all derived pieces of the guard selection state in gs. Return true iff we should stop using all previously generated circuits.
STATIC void entry_guards_update_confirmed | ( | guard_selection_t * | gs | ) |
Find the confirmed guards from among the sampled guards in gs, and put them in confirmed_entry_guards in the correct order. Recalculate their indices.
STATIC void entry_guards_update_filtered_sets | ( | guard_selection_t * | gs | ) |
Update the is_filtered_guard and is_usable_filtered_guard flag on every guard in gs.
STATIC void entry_guards_update_primary | ( | guard_selection_t * | gs | ) |
Recalculate the list of primary guards (the ones we'd prefer to use) from the filtered sample and the confirmed list.
void entry_guards_update_state | ( | or_state_t * | state | ) |
If the entry guard info has not changed, do nothing and return. Otherwise, free the EntryGuards piece of state and create a new one out of the global entry_guards list, and then mark state dirty so it will get saved to disk.
int entry_guards_upgrade_waiting_circuits | ( | guard_selection_t * | gs, |
const smartlist_t * | all_circuits_in, | ||
smartlist_t * | newly_complete_out | ||
) |
Look at all of the origin_circuit_t * objects in all_circuits_in, and see if any of them that were previously not ready to use for guard-related reasons are now ready to use. Place those circuits in newly_complete_out, and mark them COMPLETE.
Return 1 if we upgraded any circuits, and 0 otherwise.
int entry_list_is_constrained | ( | const or_options_t * | options | ) |
Return 0 if we're fine adding arbitrary routers out of the directory to our entry guard list, or return 1 if we have a list already and we must stick to it.
STATIC double get_extreme_restriction_threshold | ( | void | ) |
If our configuration retains fewer than this fraction of guards from the torrc, we are in an extremely restricted setting, and should warn.
STATIC int get_guard_confirmed_min_lifetime | ( | void | ) |
We remove confirmed guards from the sample if they were sampled GUARD_LIFETIME_DAYS ago and confirmed this many days ago.
STATIC int get_guard_lifetime | ( | void | ) |
We remove unconfirmed guards from the sample after this many days, regardless of whether they are listed or unlisted.
STATIC guard_selection_t* get_guard_selection_by_name | ( | const char * | name, |
guard_selection_type_t | type, | ||
int | create_if_absent | ||
) |
Return the guard selection called name. If there is none, and create_if_absent is true, then create and return it. If there is none, and create_if_absent is false, then return NULL.
guard_selection_t* get_guard_selection_info | ( | void | ) |
Get current default guard_selection_t, creating it if necessary
circuit_guard_state_t* get_guard_state_for_bridge_desc_fetch | ( | const char * | digest | ) |
We are about to connect to bridge with identity digest to fetch its descriptor. Create a new guard state for this connection and return it.
STATIC int get_internet_likely_down_interval | ( | void | ) |
If we haven't successfully built or used a circuit in this long, then consider that the internet is probably down.
STATIC int get_max_sample_size_absolute | ( | void | ) |
We never let our sampled guard set grow larger than this number.
STATIC double get_max_sample_threshold | ( | void | ) |
We never let our sampled guard set grow larger than this fraction of the guards on the network.
STATIC double get_meaningful_restriction_threshold | ( | void | ) |
If our configuration retains fewer than this fraction of guards from the torrc, we are in a restricted setting.
STATIC int get_min_filtered_sample_size | ( | void | ) |
We always try to make our sample contain at least this many guards.
STATIC int get_n_primary_guards | ( | void | ) |
How many guards do we try to keep on our primary guard list?
STATIC int get_n_primary_guards_to_use | ( | guard_usage_t | usage | ) |
Return the number of the live primary guards we should look at when making a circuit.
STATIC int get_nonprimary_guard_connect_timeout | ( | void | ) |
If we're trying to connect to a nonprimary guard for at least this many seconds, and we haven't gotten the connection to work, we will treat lower-priority guards as usable.
STATIC int get_nonprimary_guard_idle_timeout | ( | void | ) |
If a circuit has been sitting around in 'waiting for better guard' state for at least this long, we'll expire it.
STATIC int get_remove_unlisted_guards_after_days | ( | void | ) |
If a guard is unlisted for this many days in a row, we remove it.
STATIC entry_guard_t* get_sampled_guard_with_id | ( | guard_selection_t * | gs, |
const uint8_t * | rsa_id | ||
) |
Return the sampled guard with the RSA identity digest rsa_id, or NULL if we don't have one.
int getinfo_helper_entry_guards | ( | control_connection_t * | conn, |
const char * | question, | ||
char ** | answer, | ||
const char ** | errmsg | ||
) |
If question is the string "entry-guards", then dump to *answer a newly allocated string describing all of the nodes in the global entry_guards list. See control-spec.txt for details. For backward compatibility, we also handle the string "helper-nodes".
XXX this should be totally redesigned after prop 271 too, and that's going to take some control spec work.
STATIC char* getinfo_helper_format_single_entry_guard | ( | const entry_guard_t * | e | ) |
Format a single entry guard in the format expected by the controller. Return a newly allocated string.
STATIC entry_guard_restriction_t* guard_create_dirserver_md_restriction | ( | void | ) |
Allocate and return an outdated md guard restriction. Return NULL if no such restriction is needed.
STATIC void guard_selection_free_ | ( | guard_selection_t * | gs | ) |
Free one guard selection context
char* guard_selection_get_err_str_if_dir_info_missing | ( | guard_selection_t * | gs, |
int | using_mds, | ||
int | num_present, | ||
int | num_usable | ||
) |
Check if we are missing any crucial dirinfo for the guard subsystem to work. Return NULL if everything went well, otherwise return a newly allocated string with an informative error message. In the latter case, use the genreal descriptor information using_mds, num_present and num_usable to improve the error message.
STATIC guard_selection_type_t guard_selection_infer_type | ( | guard_selection_type_t | type, |
const char * | name | ||
) |
Try to determine the correct type for a selection named "name", if type is GS_TYPE_INFER.
STATIC guard_selection_t* guard_selection_new | ( | const char * | name, |
guard_selection_type_t | type | ||
) |
Allocate and return a new guard_selection_t, with the name name.
const node_t* guards_choose_dirguard | ( | uint8_t | dir_purpose, |
circuit_guard_state_t ** | guard_state_out | ||
) |
Helper: pick a directory guard, with whatever algorithm is used.
const node_t* guards_choose_guard | ( | cpath_build_state_t * | state, |
uint8_t | purpose, | ||
circuit_guard_state_t ** | guard_state_out | ||
) |
Helper: pick a guard for a circuit, with whatever algorithm is used.
int guards_retry_optimistic | ( | const or_options_t * | options | ) |
If we're running with a constrained guard set, then maybe mark our guards usable. Return 1 if we do; 0 if we don't.
int guards_update_all | ( | void | ) |
Helper: Update the status of all entry guards, in whatever algorithm is used. Return true if we should stop using all previously generated circuits, by calling circuit_mark_all_unused_circs() and circuit_mark_all_dirty_circs_as_unusable().
STATIC void make_guard_confirmed | ( | guard_selection_t * | gs, |
entry_guard_t * | guard | ||
) |
Mark guard as a confirmed guard – that is, one that we have connected to, and intend to use again.
STATIC void mark_primary_guards_maybe_reachable | ( | guard_selection_t * | gs | ) |
Called when the network comes up after having seemed to be down for a while: Mark the primary guards as maybe-reachable so that we'll try them again.
MOCK_IMPL | ( | STATIC | time_t, |
randomize_time | , | ||
(time_t now, time_t max_backdate) | |||
) |
Return an interval betweeen 'now' and 'max_backdate' seconds in the past, chosen uniformly at random. We use this before recording persistent dates, so that we aren't leaking exactly when we recorded it.
MOCK_IMPL | ( | STATIC | int, |
entry_guard_is_listed | , | ||
(guard_selection_t *gs, const entry_guard_t *guard) | |||
) |
Return true iff guard is currently "listed" – that is, it appears in the consensus, or as a configured bridge (as appropriate)
MOCK_IMPL | ( | STATIC circuit_guard_state_t * | , |
circuit_guard_state_new | , | ||
(entry_guard_t *guard, unsigned state, entry_guard_restriction_t *rst) | |||
) |
Allocate and return a new circuit_guard_state_t to track the result of using guard for a given operation.
MOCK_IMPL | ( | int | , |
num_bridges_usable | , | ||
(int use_maybe_reachable) | |||
) |
Return the number of bridges that have descriptors that are marked with purpose 'bridge' and are running. If use_maybe_reachable is true, include bridges that might be reachable in the count. Otherwise, if it is false, only include bridges that have recently been found running in the count.
We use this function to decide if we're ready to start building circuits through our bridges, or if we need to wait until the directory "server/authority" requests finish.
STATIC int num_reachable_filtered_guards | ( | const guard_selection_t * | gs, |
const entry_guard_restriction_t * | rst | ||
) |
Return the number of sampled guards in gs that are "filtered" (that is, we're willing to connect to them) and that are "usable" (that is, either "reachable" or "maybe reachable").
If a restriction is provided in rst, do not count any guards that violate it.
void remove_all_entry_guards | ( | void | ) |
Remove all currently listed entry guards, so new ones will be chosen.
XXXX This function shouldn't exist – it's meant to support the DROPGUARDS command, which is deprecated.
void remove_all_entry_guards_for_guard_selection | ( | guard_selection_t * | gs | ) |
Remove all currently listed entry guards for a given guard selection context. This frees and replaces gs, so don't use gs after calling this function.
STATIC entry_guard_t* sample_reachable_filtered_entry_guards | ( | guard_selection_t * | gs, |
const entry_guard_restriction_t * | rst, | ||
unsigned | flags | ||
) |
Return a random guard from the reachable filtered sample guards in gs, subject to the exclusion rules listed in flags. Return NULL if no such guard can be found.
Make sure that the sample is big enough, and that all the filter flags are set correctly, before calling this function.
If a restriction is provided in rst, do not return any guards that violate it.
STATIC void sampled_guards_update_from_consensus | ( | guard_selection_t * | gs | ) |
Update the status of all sampled guards based on the arrival of a new consensus networkstatus document. This will include marking some guards as listed or unlisted, and removing expired guards.
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 | ||
) |
Get a guard for use with a circuit. Prefer to pick a running primary guard; then a non-pending running filtered confirmed guard; then a non-pending runnable filtered guard. Update the last_tried_to_connect time and the is_pending fields of the guard as appropriate. Set state_out to the new guard-state of the circuit.
int should_apply_guardfraction | ( | const networkstatus_t * | ns | ) |
Return 0 if we should apply guardfraction information found in the consensus. A specific consensus can be specified with the ns argument, if NULL the most recent one will be picked.
int update_guard_selection_choice | ( | const or_options_t * | options | ) |
Check whether we should switch from our current guard selection to a different one. If so, switch and return 1. Return 0 otherwise.
On a 1 return, the caller should mark all currently live circuits unusable for new streams, by calling circuit_mark_all_unused_circs() and circuit_mark_all_dirty_circs_as_unusable().