tor  master
Data Structures | Macros | Typedefs | Functions
routerlist.c File Reference

Code to maintain and access the global list of routerinfos for known servers. More...

#include "or.h"
#include "backtrace.h"
#include "bridges.h"
#include "crypto_ed25519.h"
#include "circuitstats.h"
#include "config.h"
#include "connection.h"
#include "control.h"
#include "crypto_rand.h"
#include "directory.h"
#include "dirserv.h"
#include "entrynodes.h"
#include "fp_pair.h"
#include "geoip.h"
#include "hibernate.h"
#include "main.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
#include "rendcommon.h"
#include "rendservice.h"
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
#include "sandbox.h"
#include "torcert.h"
#include "dirauth/dirvote.h"
#include "dirauth/mode.h"
Include dependency graph for routerlist.c:

Data Structures

struct  cert_list_t
 
struct  duration_idx_t
 

Macros

#define ROUTERLIST_PRIVATE
 
#define SDMAP_FOREACH(map, keyvar, valvar)
 
#define RIMAP_FOREACH(map, keyvar, valvar)   DIGESTMAP_FOREACH(rimap_to_digestmap(map), keyvar, routerinfo_t *, valvar)
 
#define EIMAP_FOREACH(map, keyvar, valvar)   DIGESTMAP_FOREACH(eimap_to_digestmap(map), keyvar, extrainfo_t *, valvar)
 
#define DSMAP_FOREACH(map, keyvar, valvar)
 
#define eimap_free(map, fn)   MAP_FREE_AND_NULL(eimap, (map), (fn))
 
#define rimap_free(map, fn)   MAP_FREE_AND_NULL(rimap, (map), (fn))
 
#define dsmap_free(map, fn)   MAP_FREE_AND_NULL(dsmap, (map), (fn))
 
#define sdmap_free(map, fn)   MAP_FREE_AND_NULL(sdmap, (map), (fn))
 
#define cert_list_free(val)   FREE_AND_NULL(cert_list_t, cert_list_free_, (val))
 
#define DEAD_CERT_LIFETIME   (2*24*60*60)
 
#define SUPERSEDED_CERT_LIFETIME   (2*24*60*60)
 
#define N_AUTH_CERT_DL_FAILURES_TO_BUG_USER   2
 
#define RRS_FORCE   1
 
#define RRS_DONT_REMOVE_OLD   2
 
#define LOG_FALSE_POSITIVES_DURING_BOOTSTRAP   0
 
#define DIR_503_TIMEOUT   (60*60)
 
#define RETRY_ALTERNATE_IP_VERSION(retry_label)
 
#define RETRY_WITHOUT_EXCLUDE(retry_label)
 
#define SKIP_MISSING_TRUSTED_EXTRAINFO(type, identity)
 
#define DEFAULT_MAX_BELIEVABLE_BANDWIDTH   10000000 /* 10 MB/sec */
 
#define BRIDGE_MIN_BELIEVABLE_BANDWIDTH   20000 /* 20 kB/sec */
 
#define BRIDGE_MAX_BELIEVABLE_BANDWIDTH   100000 /* 100 kB/sec */
 
#define signed_descriptor_free(val)   FREE_AND_NULL(signed_descriptor_t, signed_descriptor_free_, (val))
 
#define should_cache_old_descriptors()   directory_caches_dir_info(get_options())
 
#define dir_server_free(val)   FREE_AND_NULL(dir_server_t, dir_server_free_, (val))
 
#define MIN_DL_PER_REQUEST   32
 
#define MIN_REQUESTS   3
 
#define MAX_DL_TO_DELAY   16
 
#define DUMMY_DOWNLOAD_INTERVAL   (20*60)
 
#define ROUTER_MAX_COSMETIC_TIME_DIFFERENCE   (2*60*60)
 
#define ROUTER_ALLOW_UPTIME_DRIFT   (6*60*60)
 

Typedefs

typedef struct cert_list_t cert_list_t
 

Functions

int get_n_authorities (dirinfo_type_t type)
 
 MOCK_IMPL (smartlist_t *, list_authority_ids_with_downloads,(void))
 
 MOCK_IMPL (download_status_t *, id_only_download_status_for_authority_id,(const char *digest))
 
 MOCK_IMPL (smartlist_t *, list_sk_digests_for_authority_id,(const char *digest))
 
 MOCK_IMPL (download_status_t *, download_status_for_authority_id_and_sk,(const char *id_digest, const char *sk_digest))
 
int trusted_dirs_reload_certs (void)
 
int trusted_dirs_load_certs_from_string (const char *contents, int source, int flush, const char *source_dir)
 
void trusted_dirs_flush_certs_to_disk (void)
 
authority_cert_tauthority_cert_get_newest_by_id (const char *id_digest)
 
authority_cert_tauthority_cert_get_by_sk_digest (const char *sk_digest)
 
authority_cert_tauthority_cert_get_by_digests (const char *id_digest, const char *sk_digest)
 
void authority_cert_get_all (smartlist_t *certs_out)
 
void authority_cert_dl_failed (const char *id_digest, const char *signing_key_digest, int status)
 
int authority_cert_is_blacklisted (const authority_cert_t *cert)
 
int authority_cert_dl_looks_uncertain (const char *id_digest)
 
void authority_certs_fetch_missing (networkstatus_t *status, time_t now, const char *dir_hint)
 
int router_reload_router_list (void)
 
const smartlist_trouter_get_trusted_dir_servers (void)
 
const smartlist_trouter_get_fallback_dir_servers (void)
 
const routerstatus_trouter_pick_directory_server (dirinfo_type_t type, int flags)
 
dir_server_trouter_get_trusteddirserver_by_digest (const char *digest)
 
dir_server_trouter_get_fallback_dirserver_by_digest (const char *digest)
 
int router_digest_is_fallback_dir (const char *digest)
 
 MOCK_IMPL (dir_server_t *, trusteddirserver_get_by_v3_auth_digest,(const char *digest))
 
const routerstatus_trouter_pick_trusteddirserver (dirinfo_type_t type, int flags)
 
const routerstatus_trouter_pick_fallback_dirserver (dirinfo_type_t type, int flags)
 
STATIC int router_is_already_dir_fetching (const tor_addr_port_t *ap, int serverdesc, int microdesc)
 
int router_skip_or_reachability (const or_options_t *options, int try_ip_pref)
 
STATIC const routerstatus_trouter_pick_directory_server_impl (dirinfo_type_t type, int flags, int *n_busy_out)
 
int routers_have_same_or_addrs (const routerinfo_t *r1, const routerinfo_t *r2)
 
void router_reset_status_download_failures (void)
 
void router_add_running_nodes_to_smartlist (smartlist_t *sl, int need_uptime, int need_capacity, int need_guard, int need_desc, int pref_addr, int direct_conn)
 
const routerinfo_trouterlist_find_my_routerinfo (void)
 
uint32_t router_get_advertised_bandwidth (const routerinfo_t *router)
 
uint32_t router_get_advertised_bandwidth_capped (const routerinfo_t *router)
 
STATIC void scale_array_elements_to_u64 (uint64_t *entries_out, const double *entries_in, int n_entries, uint64_t *total_out)
 
STATIC int choose_array_element_by_weight (const uint64_t *entries, int n_entries)
 
double frac_nodes_with_descriptors (const smartlist_t *sl, bandwidth_weight_rule_t rule)
 
const node_tnode_sl_choose_by_bandwidth (const smartlist_t *sl, bandwidth_weight_rule_t rule)
 
const node_trouter_choose_random_node (smartlist_t *excludedsmartlist, routerset_t *excludedset, router_crn_flags_t flags)
 
int hex_digest_nickname_decode (const char *hexdigest, char *digest_out, char *nickname_qualifier_char_out, char *nickname_out)
 
int hex_digest_nickname_matches (const char *hexdigest, const char *identity_digest, const char *nickname)
 
int router_digest_is_trusted_dir_type (const char *digest, dirinfo_type_t type)
 
int hexdigest_to_digest (const char *hexdigest, char *digest)
 
routerinfo_trouter_get_mutable_by_digest (const char *digest)
 
const routerinfo_trouter_get_by_id_digest (const char *digest)
 
signed_descriptor_trouter_get_by_descriptor_digest (const char *digest)
 
 MOCK_IMPL (signed_descriptor_t *, router_get_by_extrainfo_digest,(const char *digest))
 
 MOCK_IMPL (signed_descriptor_t *, extrainfo_get_by_descriptor_digest,(const char *digest))
 
const char * signed_descriptor_get_body (const signed_descriptor_t *desc)
 
const char * signed_descriptor_get_annotations (const signed_descriptor_t *desc)
 
routerlist_trouter_get_routerlist (void)
 
void routerinfo_free_ (routerinfo_t *router)
 
void extrainfo_free_ (extrainfo_t *extrainfo)
 
void routerlist_free_ (routerlist_t *rl)
 
void dump_routerlist_mem_usage (int severity)
 
 MOCK_IMPL (STATIC was_router_added_t, extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible))
 
void routerlist_remove (routerlist_t *rl, routerinfo_t *ri, int make_old, time_t now)
 
void routerlist_free_all (void)
 
void routerlist_reset_warnings (void)
 
 MOCK_IMPL (int, router_descriptor_is_older_than,(const routerinfo_t *router, int seconds))
 
was_router_added_t router_add_to_routerlist (routerinfo_t *router, const char **msg, int from_cache, int from_fetch)
 
was_router_added_t router_add_extrainfo_to_routerlist (extrainfo_t *ei, const char **msg, int from_cache, int from_fetch)
 
void routerlist_remove_old_routers (void)
 
void routerlist_descriptors_added (smartlist_t *sl, int from_cache)
 
int router_load_single_router (const char *s, uint8_t purpose, int cache, const char **msg)
 
int router_load_routers_from_string (const char *s, const char *eos, saved_location_t saved_location, smartlist_t *requested_fingerprints, int descriptor_digests, const char *prepend_annotations)
 
void router_load_extrainfo_from_string (const char *s, const char *eos, saved_location_t saved_location, smartlist_t *requested_fingerprints, int descriptor_digests)
 
void update_all_descriptor_downloads (time_t now)
 
void routerlist_retry_directory_downloads (time_t now)
 
int router_exit_policy_rejects_all (const routerinfo_t *router)
 
dir_server_ttrusted_dir_server_new (const char *nickname, const char *address, uint16_t dir_port, uint16_t or_port, const tor_addr_port_t *ipv6_addrport, const char *digest, const char *v3_auth_digest, dirinfo_type_t type, double weight)
 
dir_server_tfallback_dir_server_new (const tor_addr_t *addr, uint16_t dir_port, uint16_t or_port, const tor_addr_port_t *addrport_ipv6, const char *id_digest, double weight)
 
void dir_server_add (dir_server_t *ent)
 
void authority_cert_free_ (authority_cert_t *cert)
 
void clear_dir_servers (void)
 
void list_pending_microdesc_downloads (digest256map_t *result)
 
 MOCK_IMPL (STATIC void, initiate_descriptor_downloads,(const routerstatus_t *source, int purpose, smartlist_t *digests, int lo, int hi, int pds_flags))
 
void launch_descriptor_downloads (int purpose, smartlist_t *downloadable, const routerstatus_t *source, time_t now)
 
void update_consensus_router_descriptor_downloads (time_t now, int is_vote, networkstatus_t *consensus)
 
void update_router_descriptor_downloads (time_t now)
 
void update_extrainfo_downloads (time_t now)
 
void router_reset_descriptor_download_failures (void)
 
int router_differences_are_cosmetic (const routerinfo_t *r1, const routerinfo_t *r2)
 
int routerinfo_incompatible_with_extrainfo (const crypto_pk_t *identity_pkey, extrainfo_t *ei, signed_descriptor_t *sd, const char **msg)
 
int routerinfo_has_curve25519_onion_key (const routerinfo_t *ri)
 
int routerstatus_version_supports_extend2_cells (const routerstatus_t *rs, int allow_unknown_versions)
 
void routerlist_assert_ok (const routerlist_t *rl)
 
const char * esc_router_info (const routerinfo_t *router)
 
void routers_sort_by_identity (smartlist_t *routers)
 
void refresh_all_country_info (void)
 

Detailed Description

Code to maintain and access the global list of routerinfos for known servers.

A "routerinfo_t" object represents a single self-signed router descriptor, as generated by a Tor relay in order to tell the rest of the world about its keys, address, and capabilities. An "extrainfo_t" object represents an adjunct "extra-info" object, certified by a corresponding router descriptor, reporting more information about the relay that nearly all users will not need.

Most users will not use router descriptors for most relays. Instead, they use the information in microdescriptors and in the consensus networkstatus.

Right now, routerinfo_t objects are used in these ways:

Routerinfos are mostly created by parsing them from a string, in routerparse.c. We store them to disk on receiving them, and periodically discard the ones we don't need. On restarting, we re-read them from disk. (This also applies to extrainfo documents, if we are configured to fetch them.)

In order to keep our list of routerinfos up-to-date, we periodically check whether there are any listed in the latest consensus (or in the votes from other authorities, if we are an authority) that we don't have. (This also applies to extrainfo documents, if we are configured to fetch them.)

Almost nothing in Tor should use a routerinfo_t to refer directly to a relay; instead, almost everything should use node_t (implemented in nodelist.c), which provides a common interface to routerinfo_t, routerstatus_t, and microdescriptor_t.


This module also has some of the functions used for choosing random nodes according to different rules and weights. Historically, they were all in this module. Now, they are spread across this module, nodelist.c, and networkstatus.c. (TODO: Fix that.)


(For historical reasons) this module also contains code for handling the list of fallback directories, the list of directory authorities, and the list of authority certificates.

For the directory authorities, we have a list containing the public identity key, and contact points, for each authority. The authorities receive descriptors from relays, and publish consensuses, descriptors, and microdescriptors. This list is pre-configured.

Fallback directories are well-known, stable, but untrusted directory caches that clients which have not yet bootstrapped can use to get their first networkstatus consensus, in order to find out where the Tor network really is. This list is pre-configured in fallback_dirs.inc. Every authority also serves as a fallback.

Both fallback directories and directory authorities are are represented by a dir_server_t.

Authority certificates are signed with authority identity keys; they are used to authenticate shorter-term authority signing keys. We fetch them when we find a consensus or a vote that has been signed with a signing key we don't recognize. We cache them on disk and load them on startup. Authority operators generate them with the "tor-gencert" utility.

TODO: Authority certificates should be a separate module.

TODO: dir_server_t stuff should be in a separate module.

Macro Definition Documentation

◆ BRIDGE_MIN_BELIEVABLE_BANDWIDTH

#define BRIDGE_MIN_BELIEVABLE_BANDWIDTH   20000 /* 20 kB/sec */

When weighting bridges, enforce these values as lower and upper bound for believable bandwidth, because there is no way for us to verify a bridge's bandwidth currently.

◆ DEFAULT_MAX_BELIEVABLE_BANDWIDTH

#define DEFAULT_MAX_BELIEVABLE_BANDWIDTH   10000000 /* 10 MB/sec */

Do not weight any declared bandwidth more than this much when picking routers by bandwidth.

◆ DIR_503_TIMEOUT

#define DIR_503_TIMEOUT   (60*60)

How long do we avoid using a directory server after it's given us a 503?

◆ DSMAP_FOREACH

#define DSMAP_FOREACH (   map,
  keyvar,
  valvar 
)
Value:
DIGESTMAP_FOREACH(dsmap_to_digestmap(map), keyvar, download_status_t *, \
valvar)
Definition: or.h:2107

◆ DUMMY_DOWNLOAD_INTERVAL

#define DUMMY_DOWNLOAD_INTERVAL   (20*60)

How often should we launch a server/authority request to be sure of getting a guess for our IP?

◆ MAX_DL_TO_DELAY

#define MAX_DL_TO_DELAY   16

If we want fewer than this many descriptors, wait until we want more, or until TestingClientMaxIntervalWithoutRequest has passed.

◆ MIN_DL_PER_REQUEST

#define MIN_DL_PER_REQUEST   32

Don't split our requests so finely that we are requesting fewer than this number per server. (Grouping more than this at once leads to diminishing returns.)

◆ MIN_REQUESTS

#define MIN_REQUESTS   3

To prevent a single screwy cache from confusing us by selective reply, try to split our requests into at least this many requests.

◆ RETRY_ALTERNATE_IP_VERSION

#define RETRY_ALTERNATE_IP_VERSION (   retry_label)
Value:
STMT_BEGIN \
if (result == NULL && try_ip_pref && options->ClientUseIPv4 \
&& fascist_firewall_use_ipv6(options) && !server_mode(options) \
&& !n_busy) { \
n_excluded = 0; \
n_busy = 0; \
try_ip_pref = 0; \
goto retry_label; \
} \
STMT_END \
int fascist_firewall_use_ipv6(const or_options_t *options)
Definition: policies.c:437

◆ RETRY_WITHOUT_EXCLUDE

#define RETRY_WITHOUT_EXCLUDE (   retry_label)
Value:
STMT_BEGIN \
if (result == NULL && try_excluding && !options->StrictNodes \
&& n_excluded && !n_busy) { \
try_excluding = 0; \
n_excluded = 0; \
n_busy = 0; \
try_ip_pref = 1; \
goto retry_label; \
} \
STMT_END

◆ ROUTER_ALLOW_UPTIME_DRIFT

#define ROUTER_ALLOW_UPTIME_DRIFT   (6*60*60)

We allow uptime to vary from how much it ought to be by this much.

◆ ROUTER_MAX_COSMETIC_TIME_DIFFERENCE

#define ROUTER_MAX_COSMETIC_TIME_DIFFERENCE   (2*60*60)

Any changes in a router descriptor's publication time larger than this are automatically non-cosmetic.

◆ SDMAP_FOREACH

#define SDMAP_FOREACH (   map,
  keyvar,
  valvar 
)
Value:
DIGESTMAP_FOREACH(sdmap_to_digestmap(map), keyvar, signed_descriptor_t *, \
valvar)
Definition: or.h:2144

◆ SKIP_MISSING_TRUSTED_EXTRAINFO

#define SKIP_MISSING_TRUSTED_EXTRAINFO (   type,
  identity 
)
Value:
STMT_BEGIN \
int is_trusted_extrainfo = router_digest_is_trusted_dir_type( \
(identity), EXTRAINFO_DIRINFO); \
if (((type) & EXTRAINFO_DIRINFO) && \
!router_supports_extrainfo((identity), is_trusted_extrainfo)) \
continue; \
STMT_END
int router_digest_is_trusted_dir_type(const char *digest, dirinfo_type_t type)
Definition: routerlist.c:2987
int router_supports_extrainfo(const char *identity_digest, int is_authority)
Definition: directory.c:312
Definition: or.h:2886

Function Documentation

◆ authority_cert_dl_failed()

void authority_cert_dl_failed ( const char *  id_digest,
const char *  signing_key_digest,
int  status 
)

Called when an attempt to download a certificate with the authority with ID id_digest and, if not NULL, signed with key signing_key_digest fails with HTTP response code status: remember the failure, so we don't try again immediately.

Here is the call graph for this function:

◆ authority_cert_dl_looks_uncertain()

int authority_cert_dl_looks_uncertain ( const char *  id_digest)

Return true iff when we've been getting enough failures when trying to download the certificate with ID digest id_digest that we're willing to start bugging the user about it.

Here is the call graph for this function:

◆ authority_cert_free_()

void authority_cert_free_ ( authority_cert_t cert)

Free storage held in cert.

◆ authority_cert_get_all()

void authority_cert_get_all ( smartlist_t certs_out)

Add every known authority_cert_t to certs_out.

Here is the call graph for this function:

◆ authority_cert_get_by_digests()

authority_cert_t* authority_cert_get_by_digests ( const char *  id_digest,
const char *  sk_digest 
)

Return the v3 authority certificate with signing key matching sk_digest, for the authority with identity digest id_digest. Return NULL if no such authority is known.

Here is the call graph for this function:

◆ authority_cert_get_by_sk_digest()

authority_cert_t* authority_cert_get_by_sk_digest ( const char *  sk_digest)

Return the newest v3 authority certificate whose directory signing key has digest sk_digest. Return NULL if no such certificate is known.

Here is the call graph for this function:

◆ authority_cert_get_newest_by_id()

authority_cert_t* authority_cert_get_newest_by_id ( const char *  id_digest)

Return the newest v3 authority certificate whose v3 authority identity key has digest id_digest. Return NULL if no such authority is known, or it has no certificate.

◆ authority_cert_is_blacklisted()

int authority_cert_is_blacklisted ( const authority_cert_t cert)

Return true iff cert authenticates some atuhority signing key which, because of the old openssl heartbleed vulnerability, should never be trusted.

Here is the call graph for this function:

◆ authority_certs_fetch_missing()

void authority_certs_fetch_missing ( networkstatus_t status,
time_t  now,
const char *  dir_hint 
)

Try to download any v3 authority certificates that we may be missing. If status is provided, try to get all the ones that were used to sign status. Additionally, try to have a non-expired certificate for every V3 authority in trusted_dir_servers. Don't fetch certificates we already have.

If dir_hint is non-NULL, it's the identity digest for a directory that we've just successfully retrieved a consensus or certificates from, so try it first to fetch any missing certificates.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ choose_array_element_by_weight()

STATIC int choose_array_element_by_weight ( const uint64_t *  entries,
int  n_entries 
)

Pick a random element of n_entries-element array entries, choosing each element with a probability proportional to its (uint64_t) value, and return the index of that element. If all elements are 0, choose an index at random. Return -1 on error.

Here is the call graph for this function:

◆ clear_dir_servers()

void clear_dir_servers ( void  )

Remove all members from the list of dir servers.

◆ dir_server_add()

void dir_server_add ( dir_server_t ent)

Add a directory server to the global list(s).

Here is the call graph for this function:

◆ dump_routerlist_mem_usage()

void dump_routerlist_mem_usage ( int  severity)

Log information about how much memory is being used for routerlist, at log level severity.

Here is the call graph for this function:

◆ esc_router_info()

const char* esc_router_info ( const routerinfo_t router)

Allocate and return a new string representing the contact info and platform string for router, surrounded by quotes and using standard C escapes.

THIS FUNCTION IS NOT REENTRANT. Don't call it from outside the main thread. Also, each call invalidates the last-returned value, so don't try log_warn(LD_GENERAL, "%s %s", esc_router_info(a), esc_router_info(b));

If router is NULL, it just frees its internal memory and returns.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extrainfo_free_()

void extrainfo_free_ ( extrainfo_t extrainfo)

Release all storage held by extrainfo

◆ fallback_dir_server_new()

dir_server_t* fallback_dir_server_new ( const tor_addr_t addr,
uint16_t  dir_port,
uint16_t  or_port,
const tor_addr_port_t addrport_ipv6,
const char *  id_digest,
double  weight 
)

Return a new dir_server_t for a fallback directory server at addr:or_port/dir_port, with identity key digest id_digest

◆ frac_nodes_with_descriptors()

double frac_nodes_with_descriptors ( const smartlist_t sl,
bandwidth_weight_rule_t  rule 
)

For all nodes in sl, return the fraction of those nodes, weighted by their weighted bandwidths with rule rule, for which we have descriptors.

◆ get_n_authorities()

int get_n_authorities ( dirinfo_type_t  type)

Return the number of directory authorities whose type matches some bit set in type

Here is the caller graph for this function:

◆ hex_digest_nickname_decode()

int hex_digest_nickname_decode ( const char *  hexdigest,
char *  digest_out,
char *  nickname_qualifier_char_out,
char *  nickname_out 
)

Helper: given an extended nickname in hexdigest try to decode it. Return 0 on success, -1 on failure. Store the result into the DIGEST_LEN-byte buffer at digest_out, the single character at nickname_qualifier_char_out, and the MAXNICKNAME_LEN+1-byte buffer at nickname_out.

The recognized format is: HexName = Dollar? HexDigest NamePart? Dollar = '?' HexDigest = HexChar*20 HexChar = 'a'..'f' | 'A'..'F' | '0'..'9' NamePart = QualChar Name QualChar = '=' | '~' Name = NameChar*(1..MAX_NICKNAME_LEN) NameChar = Any ASCII alphanumeric character

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hex_digest_nickname_matches()

int hex_digest_nickname_matches ( const char *  hexdigest,
const char *  identity_digest,
const char *  nickname 
)

Helper: Return true iff the identity_digest and nickname combination of a router, encoded in hexadecimal, matches hexdigest (which is optionally prefixed with a single dollar sign). Return false if hexdigest is malformed, or it doesn't match.

Here is the call graph for this function:

◆ hexdigest_to_digest()

int hexdigest_to_digest ( const char *  hexdigest,
char *  digest 
)

If hexdigest is correctly formed, base16_decode it into digest, which must have DIGEST_LEN space in it. Return 0 on success, -1 on failure.

Here is the call graph for this function:

◆ launch_descriptor_downloads()

void launch_descriptor_downloads ( int  purpose,
smartlist_t downloadable,
const routerstatus_t source,
time_t  now 
)

Given a purpose (FETCH_MICRODESC or FETCH_SERVERDESC) and a list of router descriptor digests or microdescriptor digest256s in downloadable, decide whether to delay fetching until we have more. If we don't want to delay, launch one or more requests to the appropriate directory authorities.

Here is the call graph for this function:

◆ list_pending_microdesc_downloads()

void list_pending_microdesc_downloads ( digest256map_t *  result)

For every microdescriptor we are currently downloading by descriptor digest, set result[d] to (void*)1.

◆ MOCK_IMPL() [1/10]

MOCK_IMPL ( smartlist_t ,
list_authority_ids_with_downloads  ,
(void)   
)

Return a list of authority ID digests with potentially enumerable lists of download_status_t objects; used by controller GETINFO queries.

◆ MOCK_IMPL() [2/10]

MOCK_IMPL ( download_status_t ,
id_only_download_status_for_authority_id  ,
(const char *digest)   
)

Given an authority ID digest, return a pointer to the default download status, or NULL if there is no such entry in trusted_dir_certs

◆ MOCK_IMPL() [3/10]

MOCK_IMPL ( smartlist_t ,
list_sk_digests_for_authority_id  ,
(const char *digest)   
)

Given an authority ID digest, return a smartlist of signing key digests for which download_status_t is potentially queryable, or NULL if no such authority ID digest is known.

◆ MOCK_IMPL() [4/10]

MOCK_IMPL ( download_status_t ,
download_status_for_authority_id_and_sk  ,
(const char *id_digest, const char *sk_digest)   
)

Given an authority ID digest and a signing key digest, return the download_status_t or NULL if none exists.

◆ MOCK_IMPL() [5/10]

MOCK_IMPL ( dir_server_t ,
trusteddirserver_get_by_v3_auth_digest  ,
(const char *digest)   
)

Return the dir_server_t for the directory authority whose v3 identity key hashes to digest, or NULL if no such authority is known.

Here is the call graph for this function:

◆ MOCK_IMPL() [6/10]

MOCK_IMPL ( signed_descriptor_t ,
router_get_by_extrainfo_digest  ,
(const char *digest)   
)

Return the signed descriptor for the router in our routerlist whose 20-byte extra-info digest is digest. Return NULL if no such router is known.

◆ MOCK_IMPL() [7/10]

MOCK_IMPL ( signed_descriptor_t ,
extrainfo_get_by_descriptor_digest  ,
(const char *digest)   
)

Return the signed descriptor for the extrainfo_t in our routerlist whose extra-info-digest is digest. Return NULL if no such extra-info document is known.

◆ MOCK_IMPL() [8/10]

MOCK_IMPL ( STATIC  was_router_added_t,
extrainfo_insert  ,
(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)   
)

Adds the extrainfo_t ei to the routerlist rl, if there is a corresponding router in rl->routers or rl->old_routers. Return the status of inserting ei. Free ei if it isn't inserted.

Here is the call graph for this function:

◆ MOCK_IMPL() [9/10]

MOCK_IMPL ( int  ,
router_descriptor_is_older_than  ,
(const routerinfo_t *router, int seconds)   
)

Return 1 if the signed descriptor of this router is older than seconds seconds. Otherwise return 0.

Here is the call graph for this function:

◆ MOCK_IMPL() [10/10]

MOCK_IMPL ( STATIC  void,
initiate_descriptor_downloads  ,
(const routerstatus_t *source, int purpose, smartlist_t *digests, int lo, int hi, int pds_flags)   
)

Launch downloads for all the descriptors whose digests or digests256 are listed as digests[i] for lo <= i < hi. (Lo and hi may be out of range.) If source is given, download from source; otherwise, download from an appropriate random directory server.

◆ node_sl_choose_by_bandwidth()

const node_t* node_sl_choose_by_bandwidth ( const smartlist_t sl,
bandwidth_weight_rule_t  rule 
)

Choose a random element of status list sl, weighted by the advertised bandwidth of each node

◆ refresh_all_country_info()

void refresh_all_country_info ( void  )

Called when we change a node set, or when we reload the geoip IPv4 list: recompute all country info in all configuration node sets and in the routerlist.

Here is the call graph for this function:

◆ router_add_extrainfo_to_routerlist()

was_router_added_t router_add_extrainfo_to_routerlist ( extrainfo_t ei,
const char **  msg,
int  from_cache,
int  from_fetch 
)

Insert ei into the routerlist, or free it. Other arguments are as for router_add_to_routerlist(). Return ROUTER_ADDED_SUCCESSFULLY iff we actually inserted it, ROUTER_BAD_EI otherwise.

Here is the call graph for this function:

◆ router_add_running_nodes_to_smartlist()

void router_add_running_nodes_to_smartlist ( smartlist_t sl,
int  need_uptime,
int  need_capacity,
int  need_guard,
int  need_desc,
int  pref_addr,
int  direct_conn 
)

Add every suitable node from our nodelist to sl, so that we can pick a node for a circuit.

◆ router_add_to_routerlist()

was_router_added_t router_add_to_routerlist ( routerinfo_t router,
const char **  msg,
int  from_cache,
int  from_fetch 
)

Add router to the routerlist, if we don't already have it. Replace older entries (if any) with the same key. Note: Callers should not hold their pointers to router if this function fails; router will either be inserted into the routerlist or freed. Similarly, even if this call succeeds, they should not hold their pointers to router after subsequent calls with other routerinfo's – they might cause the original routerinfo to get freed.

Returns the status for the operation. Might set *msg if it wants the poster of the router to know something.

If from_cache, this descriptor came from our disk cache. If from_fetch, we received it in response to a request we made. (If both are false, that means it was uploaded to us as an auth dir server or via the controller.)

This function should be called after routers_update_status_from_consensus_networkstatus; subsequently, you should call router_rebuild_store and routerlist_descriptors_added.

Here is the call graph for this function:

◆ router_choose_random_node()

const node_t* router_choose_random_node ( smartlist_t excludedsmartlist,
routerset_t *  excludedset,
router_crn_flags_t  flags 
)

Return a random running node from the nodelist. Never pick a node that is in excludedsmartlist, or which matches excludedset, even if they are the only nodes available. If CRN_NEED_UPTIME is set in flags and any router has more than a minimum uptime, return one of those. If CRN_NEED_CAPACITY is set in flags, weight your choice by the advertised capacity of each router. If CRN_NEED_GUARD is set in flags, consider only Guard routers. If CRN_WEIGHT_AS_EXIT is set in flags, we weight bandwidths as if picking an exit node, otherwise we weight bandwidths for picking a relay node (that is, possibly discounting exit nodes). If CRN_NEED_DESC is set in flags, we only consider nodes that have a routerinfo or microdescriptor – that is, enough info to be used to build a circuit. If CRN_PREF_ADDR is set in flags, we only consider nodes that have an address that is preferred by the ClientPreferIPv6ORPort setting (regardless of this flag, we exclude nodes that aren't allowed by the firewall, including ClientUseIPv4 0 and fascist_firewall_use_ipv6() == 0).

◆ router_differences_are_cosmetic()

int router_differences_are_cosmetic ( const routerinfo_t r1,
const routerinfo_t r2 
)

Return true iff the only differences between r1 and r2 are such that would not cause a recent (post 0.1.1.6) dirserver to republish.

Here is the call graph for this function:

◆ router_digest_is_fallback_dir()

int router_digest_is_fallback_dir ( const char *  digest)

Return 1 if any fallback dirserver's identity key hashes to digest, or 0 if no such fallback is in the list of fallback_dir_servers. (fallback_dir_servers is affected by the FallbackDir and UseDefaultFallbackDirs torrc options.) The list of fallback directories includes the list of authorities.

Here is the call graph for this function:

◆ router_digest_is_trusted_dir_type()

int router_digest_is_trusted_dir_type ( const char *  digest,
dirinfo_type_t  type 
)

Return true iff digest is the digest of the identity key of a trusted directory matching at least one bit of type. If type is zero (NO_DIRINFO), or ALL_DIRINFO, any authority is okay.

Here is the call graph for this function:

◆ router_exit_policy_rejects_all()

int router_exit_policy_rejects_all ( const routerinfo_t router)

Return true iff router does not permit exit streams.

◆ router_get_advertised_bandwidth()

uint32_t router_get_advertised_bandwidth ( const routerinfo_t router)

Return the smaller of the router's configured BandwidthRate and its advertised capacity.

◆ router_get_advertised_bandwidth_capped()

uint32_t router_get_advertised_bandwidth_capped ( const routerinfo_t router)

Return the smaller of the router's configured BandwidthRate and its advertised capacity, capped by max-believe-bw.

◆ router_get_by_descriptor_digest()

signed_descriptor_t* router_get_by_descriptor_digest ( const char *  digest)

Return the router in our routerlist whose 20-byte descriptor is digest. Return NULL if no such router is known.

◆ router_get_by_id_digest()

const routerinfo_t* router_get_by_id_digest ( const char *  digest)

Return the router in our routerlist whose 20-byte key digest is digest. Return NULL if no such router is known.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ router_get_fallback_dirserver_by_digest()

dir_server_t* router_get_fallback_dirserver_by_digest ( const char *  digest)

Return the dir_server_t for the fallback dirserver whose identity key hashes to digest, or NULL if no such fallback is in the list of fallback_dir_servers. (fallback_dir_servers is affected by the FallbackDir and UseDefaultFallbackDirs torrc options.) The list of fallback directories includes the list of authorities.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ router_get_mutable_by_digest()

routerinfo_t* router_get_mutable_by_digest ( const char *  digest)

As router_get_by_id_digest,but return a pointer that you're allowed to modify

Here is the caller graph for this function:

◆ router_get_routerlist()

routerlist_t* router_get_routerlist ( void  )

Return the current list of all known routers.

Here is the caller graph for this function:

◆ router_get_trusted_dir_servers()

const smartlist_t* router_get_trusted_dir_servers ( void  )

Return a smartlist containing a list of dir_server_t * for all known trusted dirservers. Callers must not modify the list or its contents.

Here is the caller graph for this function:

◆ router_get_trusteddirserver_by_digest()

dir_server_t* router_get_trusteddirserver_by_digest ( const char *  digest)

Return the dir_server_t for the directory authority whose identity key hashes to digest, or NULL if no such authority is known.

Here is the call graph for this function:

◆ router_load_extrainfo_from_string()

void router_load_extrainfo_from_string ( const char *  s,
const char *  eos,
saved_location_t  saved_location,
smartlist_t requested_fingerprints,
int  descriptor_digests 
)

Parse one or more extrainfos from s (ending immediately before eos if eos is present). Other arguments are as for router_load_routers_from_string().

Here is the call graph for this function:

◆ router_load_routers_from_string()

int router_load_routers_from_string ( const char *  s,
const char *  eos,
saved_location_t  saved_location,
smartlist_t requested_fingerprints,
int  descriptor_digests,
const char *  prepend_annotations 
)

Given a string s containing some routerdescs, parse it and put the routers into our directory. If saved_location is SAVED_NOWHERE, the routers are in response to a query to the network: cache them by adding them to the journal.

Return the number of routers actually added.

If requested_fingerprints is provided, it must contain a list of uppercased fingerprints. Do not update any router whose fingerprint is not on the list; after updating a router, remove its fingerprint from the list.

If descriptor_digests is non-zero, then the requested_fingerprints are descriptor digests. Otherwise they are identity digests.

Here is the call graph for this function:

◆ router_load_single_router()

int router_load_single_router ( const char *  s,
uint8_t  purpose,
int  cache,
const char **  msg 
)

Code to parse a single router descriptor and insert it into the routerlist. Return -1 if the descriptor was ill-formed; 0 if the descriptor was well-formed but could not be added; and 1 if the descriptor was added.

If we don't add it and msg is not NULL, then assign to *msg a static string describing the reason for refusing the descriptor.

This is used only by the controller.

Here is the call graph for this function:

◆ router_pick_directory_server()

const routerstatus_t* router_pick_directory_server ( dirinfo_type_t  type,
int  flags 
)

Try to find a running dirserver that supports operations of type.

If there are no running dirservers in our routerlist and the PDS_RETRY_IF_NO_SERVERS flag is set, set all the fallback ones (including authorities) as running again, and pick one.

If the PDS_IGNORE_FASCISTFIREWALL flag is set, then include dirservers that we can't reach.

If the PDS_ALLOW_SELF flag is not set, then don't include ourself (if we're a dirserver).

Don't pick a fallback directory mirror if any non-fallback is viable; (the fallback directory mirrors include the authorities) try to avoid using servers that have returned 503 recently.

◆ router_pick_directory_server_impl()

STATIC const routerstatus_t* router_pick_directory_server_impl ( dirinfo_type_t  type,
int  flags,
int *  n_busy_out 
)

Pick a random running valid directory server/mirror from our routerlist. Arguments are as for router_pick_directory_server(), except:

If n_busy_out is provided, set *n_busy_out to the number of directories that we excluded for no other reason than PDS_NO_EXISTING_SERVERDESC_FETCH or PDS_NO_EXISTING_MICRODESC_FETCH.

◆ router_pick_fallback_dirserver()

const routerstatus_t* router_pick_fallback_dirserver ( dirinfo_type_t  type,
int  flags 
)

Try to find a running fallback directory. Flags are as for router_pick_directory_server.

◆ router_pick_trusteddirserver()

const routerstatus_t* router_pick_trusteddirserver ( dirinfo_type_t  type,
int  flags 
)

Try to find a running directory authority. Flags are as for router_pick_directory_server.

◆ router_reload_router_list()

int router_reload_router_list ( void  )

Load all cached router descriptors and extra-info documents from the store. Return 0 on success and -1 on failure.

Here is the call graph for this function:

◆ router_reset_descriptor_download_failures()

void router_reset_descriptor_download_failures ( void  )

Reset the consensus and extra-info download failure count on all routers. When we get a new consensus, routers_update_status_from_consensus_networkstatus() will reset the download statuses on the descriptors in that consensus.

◆ router_reset_status_download_failures()

void router_reset_status_download_failures ( void  )

Reset all internal variables used to count failed downloads of network status objects.

◆ routerinfo_free_()

void routerinfo_free_ ( routerinfo_t router)

Free all storage held by router.

◆ routerinfo_incompatible_with_extrainfo()

int routerinfo_incompatible_with_extrainfo ( const crypto_pk_t identity_pkey,
extrainfo_t ei,
signed_descriptor_t sd,
const char **  msg 
)

Check whether sd describes a router descriptor compatible with the extrainfo document ei.

identity_pkey (which must also be provided) is RSA1024 identity key for the router. We use it to check the signature of the extrainfo document, if it has not already been checked.

If no router is compatible with ei, ei should be dropped. Return 0 for "compatible", return 1 for "reject, and inform whoever uploaded <b>ei</b>, and return -1 for "reject silently.". If msg is present, set *msg to a description of the incompatibility (if any).

Set the extrainfo_is_bogus field in sd if the digests matched but the extrainfo was nonetheless incompatible.

Here is the call graph for this function:

◆ routerlist_assert_ok()

void routerlist_assert_ok ( const routerlist_t rl)

Assert that the internal representation of rl is self-consistent.

◆ routerlist_descriptors_added()

void routerlist_descriptors_added ( smartlist_t sl,
int  from_cache 
)

We just added a new set of descriptors. Take whatever extra steps we need.

Here is the call graph for this function:

◆ routerlist_find_my_routerinfo()

const routerinfo_t* routerlist_find_my_routerinfo ( void  )

Look through the routerlist until we find a router that has my key. Return it.

◆ routerlist_free_()

void routerlist_free_ ( routerlist_t rl)

Free all storage held by a routerlist rl.

◆ routerlist_free_all()

void routerlist_free_all ( void  )

Free all memory held by the routerlist module. Note: Calling routerlist_free_all() should always be paired with a call to nodelist_free_all(). These should only be called during cleanup.

◆ routerlist_remove()

void routerlist_remove ( routerlist_t rl,
routerinfo_t ri,
int  make_old,
time_t  now 
)

Remove an item ri from the routerlist rl, updating indices as needed. If idx is nonnegative and smartlist_get(rl->routers, idx) == ri, we don't need to do a linear search over the list to decide which to remove. We fill the gap in rl->routers with a later element in the list, if any exists. ri is freed.

If make_old is true, instead of deleting the router, we try adding it to rl->old_routers.

Here is the call graph for this function:

◆ routerlist_remove_old_routers()

void routerlist_remove_old_routers ( void  )

Deactivate any routers from the routerlist that are more than ROUTER_MAX_AGE seconds old and not recommended by any networkstatuses; remove old routers from the list of cached routers if we have too many.

◆ routerlist_reset_warnings()

void routerlist_reset_warnings ( void  )

Forget that we have issued any router-related warnings, so that we'll warn again if we see the same errors.

Here is the call graph for this function:

◆ routerlist_retry_directory_downloads()

void routerlist_retry_directory_downloads ( time_t  now)

Clear all our timeouts for fetching v3 directory stuff, and then give it all a try again.

◆ routers_have_same_or_addrs()

int routers_have_same_or_addrs ( const routerinfo_t r1,
const routerinfo_t r2 
)

Return true iff r1 and r2 have the same address and OR port.

Here is the caller graph for this function:

◆ routers_sort_by_identity()

void routers_sort_by_identity ( smartlist_t routers)

Sort a list of routerinfo_t in ascending order of identity digest.

Here is the call graph for this function:

◆ scale_array_elements_to_u64()

STATIC void scale_array_elements_to_u64 ( uint64_t *  entries_out,
const double *  entries_in,
int  n_entries,
uint64_t *  total_out 
)

Given an array of double/uint64_t unions that are currently being used as doubles, convert them to uint64_t, and try to scale them linearly so as to much of the range of uint64_t. If total_out is provided, set it to the sum of all elements in the array before scaling.

Here is the call graph for this function:

◆ signed_descriptor_get_annotations()

const char* signed_descriptor_get_annotations ( const signed_descriptor_t desc)

As signed_descriptor_get_body(), but points to the beginning of the annotations section rather than the beginning of the descriptor.

◆ signed_descriptor_get_body()

const char* signed_descriptor_get_body ( const signed_descriptor_t desc)

Return a pointer to the signed textual representation of a descriptor. The returned string is not guaranteed to be NUL-terminated: the string's length will be in desc->signed_descriptor_len.

The caller must not free the string returned.

Here is the caller graph for this function:

◆ trusted_dir_server_new()

dir_server_t* trusted_dir_server_new ( const char *  nickname,
const char *  address,
uint16_t  dir_port,
uint16_t  or_port,
const tor_addr_port_t ipv6_addrport,
const char *  digest,
const char *  v3_auth_digest,
dirinfo_type_t  type,
double  weight 
)

Create an authoritative directory server at address:port, with identity key digest. If address is NULL, add ourself. Return the new trusted directory server entry on success or NULL if we couldn't add it.

Here is the call graph for this function:

◆ trusted_dirs_flush_certs_to_disk()

void trusted_dirs_flush_certs_to_disk ( void  )

Save all v3 key certificates to the cached-certs file.

◆ trusted_dirs_load_certs_from_string()

int trusted_dirs_load_certs_from_string ( const char *  contents,
int  source,
int  flush,
const char *  source_dir 
)

Load a bunch of new key certificates from the string contents. If source is TRUSTED_DIRS_CERTS_SRC_FROM_STORE, the certificates are from the cache, and we don't need to flush them to disk. If we are a dirauth loading our own cert, source is TRUSTED_DIRS_CERTS_SRC_SELF. Otherwise, source is download type: TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST or TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST. If flush is true, we need to flush any changed certificates to disk now. Return 0 on success, -1 if any certs fail to parse.

If source_dir is non-NULL, it's the identity digest for a directory that we've just successfully retrieved certificates from, so try it first to fetch any missing certificates.

◆ trusted_dirs_reload_certs()

int trusted_dirs_reload_certs ( void  )

Reload the cached v3 key certificates from the cached-certs file in the data directory. Return 0 on success, -1 on failure.

◆ update_all_descriptor_downloads()

void update_all_descriptor_downloads ( time_t  now)

Update downloads for router descriptors and/or microdescriptors as appropriate.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_consensus_router_descriptor_downloads()

void update_consensus_router_descriptor_downloads ( time_t  now,
int  is_vote,
networkstatus_t consensus 
)

For any descriptor that we want that's currently listed in consensus, download it as appropriate.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_extrainfo_downloads()

void update_extrainfo_downloads ( time_t  now)

Launch extrainfo downloads as needed.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_router_descriptor_downloads()

void update_router_descriptor_downloads ( time_t  now)

Launch downloads for router status as needed.

Here is the call graph for this function:
Here is the caller graph for this function: