Tor
0.4.7.0-alpha-dev
|
Functions to compute directory consensus, and schedule voting. More...
#include "core/or/or.h"
#include "app/config/config.h"
#include "app/config/resolve_addr.h"
#include "core/or/policies.h"
#include "core/or/protover.h"
#include "core/or/tor_version_st.h"
#include "core/or/versions.h"
#include "feature/dirauth/bwauth.h"
#include "feature/dirauth/dircollate.h"
#include "feature/dirauth/dsigs_parse.h"
#include "feature/dirauth/guardfraction.h"
#include "feature/dirauth/recommend_pkg.h"
#include "feature/dirauth/voteflags.h"
#include "feature/dircache/dirserv.h"
#include "feature/dirclient/dirclient.h"
#include "feature/dircommon/directory.h"
#include "feature/dirparse/microdesc_parse.h"
#include "feature/dirparse/ns_parse.h"
#include "feature/dirparse/parsecommon.h"
#include "feature/dirparse/signing.h"
#include "feature/nodelist/authcert.h"
#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/fmt_routerstatus.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodefamily.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
#include "feature/stats/rephist.h"
#include "feature/client/entrynodes.h"
#include "feature/nodelist/torcert.h"
#include "feature/dirauth/voting_schedule.h"
#include "feature/dirauth/dirvote.h"
#include "feature/dirauth/authmode.h"
#include "feature/dirauth/shared_random_state.h"
#include "feature/dirauth/dirauth_sys.h"
#include "feature/nodelist/authority_cert_st.h"
#include "feature/dircache/cached_dir_st.h"
#include "feature/dirclient/dir_server_st.h"
#include "feature/dirauth/dirauth_options_st.h"
#include "feature/nodelist/document_signature_st.h"
#include "feature/nodelist/microdesc_st.h"
#include "feature/nodelist/networkstatus_st.h"
#include "feature/nodelist/networkstatus_voter_info_st.h"
#include "feature/nodelist/node_st.h"
#include "feature/dirauth/ns_detached_signatures_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist_st.h"
#include "feature/dirauth/vote_microdesc_hash_st.h"
#include "feature/nodelist/vote_routerstatus_st.h"
#include "feature/dircommon/vote_timing_st.h"
#include "lib/container/order.h"
#include "lib/encoding/confline.h"
#include "lib/crypt_ops/crypto_format.h"
Go to the source code of this file.
Data Structures | |
struct | pending_consensus_t |
struct | dir_src_ent_t |
struct | pending_vote_t |
struct | consensus_method_range_t |
struct | microdesc_vote_line_t |
Macros | |
#define | DIRVOTE_PRIVATE |
#define | DIGEST_ALG_BW_FILE DIGEST_SHA256 |
#define | get_most_frequent_member(lst) smartlist_get_most_frequent_string(lst) |
#define | CMP_FIELD(utype, itype, field) |
#define | MIN_VOTES_FOR_PARAM 3 |
#define | RANGE_CHECK(a, b, c, d, e, f, g, mx) |
#define | CHECK_EQ(a, b, margin) ((a)-(b) >= 0 ? (a)-(b) <= (margin) : (b)-(a) <= (margin)) |
#define | IF_TIME_FOR_NEXT_ACTION(when_field, done_field) |
#define | ENDIF |
Functions | |
static int | dirvote_add_signatures_to_all_pending_consensuses (const char *detached_signatures_body, const char *source, const char **msg_out) |
static int | dirvote_add_signatures_to_pending_consensus (pending_consensus_t *pc, ns_detached_signatures_t *sigs, const char *source, int severity, const char **msg_out) |
static char * | list_v3_auth_ids (void) |
static void | dirvote_fetch_missing_votes (void) |
static void | dirvote_fetch_missing_signatures (void) |
static int | dirvote_perform_vote (void) |
static void | dirvote_clear_votes (int all_votes) |
static int | dirvote_compute_consensuses (void) |
static int | dirvote_publish_consensus (void) |
STATIC authority_cert_t * | authority_cert_dup (authority_cert_t *cert) |
static char * | format_line_if_present (const char *keyword, const char *opt_value) |
static char * | format_protocols_lines_for_vote (const networkstatus_t *v3_ns) |
STATIC char * | format_networkstatus_vote (crypto_pk_t *private_signing_key, networkstatus_t *v3_ns) |
static void | dirvote_get_preferred_voting_intervals (vote_timing_t *timing_out) |
static int | vote_routerstatus_find_microdesc_hash (char *digest256_out, const vote_routerstatus_t *vrs, int method, digest_algorithm_t alg) |
static networkstatus_voter_info_t * | get_voter (const networkstatus_t *vote) |
static int | compare_votes_by_authority_id_ (const void **_a, const void **_b) |
static int | compare_dir_src_ents_by_authority_id_ (const void **_a, const void **_b) |
static void | get_frequent_members (smartlist_t *out, smartlist_t *in, int min) |
static int | compare_vote_rs (const vote_routerstatus_t *a, const vote_routerstatus_t *b) |
static int | compare_vote_rs_ (const void **_a, const void **_b) |
static int | compare_orports_ (const void **_a, const void **_b) |
static vote_routerstatus_t * | compute_routerstatus_consensus (smartlist_t *votes, int consensus_method, char *microdesc_digest256_out, tor_addr_port_t *best_alt_orport_out) |
static int | cmp_int_strings_ (const void **_a, const void **_b) |
static int | compute_consensus_method (smartlist_t *votes) |
static int | consensus_method_is_supported (int method) |
STATIC char * | make_consensus_method_list (int low, int high, const char *separator) |
static char * | compute_consensus_versions_list (smartlist_t *lst, int n_versioning) |
STATIC int32_t | dirvote_get_intermediate_param_value (const smartlist_t *param_list, const char *keyword, int32_t default_val) |
STATIC smartlist_t * | dirvote_compute_params (smartlist_t *votes, int method, int total_authorities) |
static bw_weights_error_t | networkstatus_check_weights (int64_t Wgg, int64_t Wgd, int64_t Wmg, int64_t Wme, int64_t Wmd, int64_t Wee, int64_t Wed, int64_t scale, int64_t G, int64_t M, int64_t E, int64_t D, int64_t T, int64_t margin, int do_balance) |
int | networkstatus_compute_bw_weights_v10 (smartlist_t *chunks, int64_t G, int64_t M, int64_t E, int64_t D, int64_t T, int64_t weight_scale) |
static void | update_total_bandwidth_weights (const routerstatus_t *rs, int is_exit, int is_guard, int64_t *G, int64_t *M, int64_t *E, int64_t *D, int64_t *T) |
static const char * | get_nth_protocol_set_vote (int n, const networkstatus_t *vote) |
static char * | compute_nth_protocol_set (int n, int n_voters, const smartlist_t *votes) |
STATIC char * | networkstatus_compute_consensus (smartlist_t *votes, int total_authorities, crypto_pk_t *identity_key, crypto_pk_t *signing_key, const char *legacy_id_key_digest, crypto_pk_t *legacy_signing_key, consensus_flavor_t flavor) |
STATIC int64_t | extract_param_buggy (const char *params, const char *param_name, int64_t default_value) |
STATIC char * | compute_consensus_package_lines (smartlist_t *votes) |
STATIC int | networkstatus_add_detached_signatures (networkstatus_t *target, ns_detached_signatures_t *sigs, const char *source, int severity, const char **msg_out) |
static char * | networkstatus_format_signatures (networkstatus_t *consensus, int for_detached_signatures) |
STATIC char * | networkstatus_get_detached_signatures (smartlist_t *consensuses) |
static char * | get_detached_signatures_from_pending_consensuses (pending_consensus_t *pending, int n_flavors) |
time_t | dirvote_act (const or_options_t *options, time_t now) |
static void | dirvote_clear_pending_consensuses (void) |
static void | assert_any_sig_good (const networkstatus_voter_info_t *vi) |
static void | add_new_cert_if_needed (const struct authority_cert_t *cert) |
pending_vote_t * | dirvote_add_vote (const char *vote_body, time_t time_posted, const char *where_from, const char **msg_out, int *status_out) |
static void | write_v3_votes_to_disk (const smartlist_t *pending_votes) |
int | dirvote_add_signatures (const char *detached_signatures_body, const char *source, const char **msg) |
void | dirvote_free_all (void) |
const char * | dirvote_get_pending_consensus (consensus_flavor_t flav) |
const char * | dirvote_get_pending_detached_signatures (void) |
const cached_dir_t * | dirvote_get_vote (const char *fp, int flags) |
STATIC microdesc_t * | dirvote_create_microdescriptor (const routerinfo_t *ri, int consensus_method) |
static ssize_t | dirvote_format_microdesc_vote_line (char *out_buf, size_t out_buf_len, const microdesc_t *md, int consensus_method_low, int consensus_method_high) |
vote_microdesc_hash_t * | dirvote_format_all_microdesc_vote_lines (const routerinfo_t *ri, time_t now, smartlist_t *microdescriptors_out) |
static void | extract_shared_random_commits (networkstatus_t *ns, const smartlist_t *tokens) |
void | dirvote_parse_sr_commits (networkstatus_t *ns, const smartlist_t *tokens) |
void | dirvote_clear_commits (networkstatus_t *ns) |
void | dirvote_dirreq_get_status_vote (const char *url, smartlist_t *items, smartlist_t *dir_items) |
uint32_t | dirserv_get_bandwidth_for_router_kb (const routerinfo_t *ri) |
static int | compare_routerinfo_addrs_by_family (const routerinfo_t *a, const routerinfo_t *b, int family) |
STATIC int | compare_routerinfo_by_ipv4 (const void **a, const void **b) |
STATIC int | compare_routerinfo_by_ipv6 (const void **a, const void **b) |
STATIC int | compare_routerinfo_usefulness (const routerinfo_t *first, const routerinfo_t *second) |
STATIC digestmap_t * | get_sybil_list_by_ip_version (const smartlist_t *routers, sa_family_t family) |
STATIC digestmap_t * | get_all_possible_sybil (const smartlist_t *routers) |
static char * | version_from_platform (const char *platform) |
char * | format_recommended_version_list (const config_line_t *ln, int warn) |
static void | routers_make_ed_keys_unique (smartlist_t *routers) |
static void | clear_status_flags_on_sybil (routerstatus_t *rs) |
networkstatus_t * | dirserv_generate_networkstatus_vote_obj (crypto_pk_t *private_key, authority_cert_t *cert) |
Variables | |
static smartlist_t * | pending_vote_list = NULL |
static smartlist_t * | previous_vote_list = NULL |
static pending_consensus_t | pending_consensuses [N_CONSENSUS_FLAVORS] |
static char * | pending_consensus_signatures = NULL |
static smartlist_t * | pending_consensus_signature_list = NULL |
static const struct consensus_method_range_t | microdesc_consensus_methods [] |
const char | DIRVOTE_UNIVERSAL_FLAGS [] |
const char | DIRVOTE_OPTIONAL_FLAGS [] |
Functions to compute directory consensus, and schedule voting.
This module is the center of the consensus-voting based directory authority system. With this system, a set of authorities first publish vote based on their opinions of the network, and then compute a consensus from those votes. Each authority signs the consensus, and clients trust the consensus if enough known authorities have signed it.
The code in this module is only invoked on directory authorities. It's responsible for:
The main entry points are in dirvote_act(), which handles scheduled actions; and dirvote_add_vote() and dirvote_add_signatures(), which handle uploaded and downloaded votes and signatures.
(See dir-spec.txt from torspec.git for a complete specification of the directory protocol and voting algorithms.)
Definition in file dirvote.c.
#define CMP_FIELD | ( | utype, | |
itype, | |||
field | |||
) |
#define ENDIF |
#define get_most_frequent_member | ( | lst | ) | smartlist_get_most_frequent_string(lst) |
#define IF_TIME_FOR_NEXT_ACTION | ( | when_field, | |
done_field | |||
) |
#define MIN_VOTES_FOR_PARAM 3 |
#define RANGE_CHECK | ( | a, | |
b, | |||
c, | |||
d, | |||
e, | |||
f, | |||
g, | |||
mx | |||
) |
STATIC authority_cert_t* authority_cert_dup | ( | authority_cert_t * | cert | ) |
Allocate and return a new authority_cert_t with the same contents as cert.
|
static |
Routerstatus rs is part of a group of routers that are on too narrow an IP-space. Clear out its flags since we don't want it be used because of its Sybil-like appearance.
Leave its BadExit flag alone though, since if we think it's a bad exit, we want to vote that way in case all the other authorities are voting Running and Exit.
Also set the Sybil flag in order to let a relay operator know that's why their relay hasn't been voted on.
|
static |
|
static |
|
static |
|
static |
Helper: compare the address of family family
in a
with the address in b
. The family must be one of AF_INET
and AF_INET6
.
Definition at line 4249 of file dirvote.c.
Referenced by compare_routerinfo_by_ipv4(), and compare_routerinfo_by_ipv6().
STATIC int compare_routerinfo_by_ipv4 | ( | const void ** | a, |
const void ** | b | ||
) |
STATIC int compare_routerinfo_by_ipv6 | ( | const void ** | a, |
const void ** | b | ||
) |
STATIC int compare_routerinfo_usefulness | ( | const routerinfo_t * | first, |
const routerinfo_t * | second | ||
) |
Compare routerinfos by descending order of "usefulness" : An authority is more useful than a non-authority; a running router is more useful than a non-running router; and a router with more bandwidth is more useful than one with less.
Definition at line 4300 of file dirvote.c.
Referenced by compare_routerinfo_by_ipv4(), and compare_routerinfo_by_ipv6().
|
static |
Return 0 if and only if a and b are routerstatuses that come from the same routerinfo, with the same derived elements.
Definition at line 604 of file dirvote.c.
Referenced by compare_vote_rs_(), and compute_routerstatus_consensus().
|
static |
Helper for sorting routerlists based on compare_vote_rs.
Definition at line 649 of file dirvote.c.
Referenced by compute_routerstatus_consensus().
|
static |
Helper for sorting networkstatus_t votes (not consensuses) by the hash of their voters' identity digests.
|
static |
Given a list of networkstatus_t votes, determine and return the number of the highest consensus method that is supported by 2/3 of the voters.
STATIC char* compute_consensus_package_lines | ( | smartlist_t * | votes | ) |
Given a list of networkstatus_t for each vote, return a newly allocated string containing the "package" lines for the vote.
|
static |
|
static |
|
static |
Given a list of vote_routerstatus_t, all for the same router identity, return whichever is most frequent, breaking ties in favor of more recently published vote_routerstatus_t and in case of ties there, in favor of smaller descriptor digest.
|
static |
Return true iff method is a consensus method that we support.
Definition at line 827 of file dirvote.c.
Referenced by make_consensus_method_list().
networkstatus_t* dirserv_generate_networkstatus_vote_obj | ( | crypto_pk_t * | private_key, |
authority_cert_t * | cert | ||
) |
uint32_t dirserv_get_bandwidth_for_router_kb | ( | const routerinfo_t * | ri | ) |
time_t dirvote_act | ( | const or_options_t * | options, |
time_t | now | ||
) |
int dirvote_add_signatures | ( | const char * | detached_signatures_body, |
const char * | source, | ||
const char ** | msg | ||
) |
Helper: we just got the detached_signatures_body sent to us as signatures on the currently pending consensus. Add them to the pending consensus (if we have one); otherwise queue them until we have a consensus.
Set *msg to a string constant describing the status, regardless of success or failure.
Return negative on failure, nonnegative on success.
|
static |
Helper: we just got the detached_signatures_body sent to us as signatures on the currently pending consensus. Add them to the pending consensus (if we have one).
Set *msg to a string constant describing the status, regardless of success or failure.
Return negative on failure, nonnegative on success.
|
static |
pending_vote_t* dirvote_add_vote | ( | const char * | vote_body, |
time_t | time_posted, | ||
const char * | where_from, | ||
const char ** | msg_out, | ||
int * | status_out | ||
) |
Called when we have received a networkstatus vote in vote_body. Parse and validate it, and on success store it as a pending vote (which we then return). Return NULL on failure. Sets *msg_out and *status_out to an HTTP response and status code. (V3 authority only)
|
static |
|
static |
Drop all currently pending votes, consensus, and detached signatures.
Definition at line 3089 of file dirvote.c.
Referenced by dirvote_free_all().
|
static |
Try to compute a v3 networkstatus consensus from the currently pending votes. Return 0 on success, -1 on failure. Store the consensus in pending_consensus: it won't be ready to be published until we have everybody else's signatures collected too. (V3 Authority only)
STATIC smartlist_t* dirvote_compute_params | ( | smartlist_t * | votes, |
int | method, | ||
int | total_authorities | ||
) |
Helper: given a list of valid networkstatus_t, return a new smartlist containing the contents of the consensus network parameter set.
STATIC microdesc_t* dirvote_create_microdescriptor | ( | const routerinfo_t * | ri, |
int | consensus_method | ||
) |
|
static |
|
static |
vote_microdesc_hash_t* dirvote_format_all_microdesc_vote_lines | ( | const routerinfo_t * | ri, |
time_t | now, | ||
smartlist_t * | microdescriptors_out | ||
) |
|
static |
void dirvote_free_all | ( | void | ) |
STATIC int32_t dirvote_get_intermediate_param_value | ( | const smartlist_t * | param_list, |
const char * | keyword, | ||
int32_t | default_val | ||
) |
const char* dirvote_get_pending_consensus | ( | consensus_flavor_t | flav | ) |
const char* dirvote_get_pending_detached_signatures | ( | void | ) |
|
static |
const cached_dir_t* dirvote_get_vote | ( | const char * | fp, |
int | flags | ||
) |
Return a given vote specified by fp. If by_id, return the vote for the authority with the v3 authority identity key digest fp; if by_id is false, return the vote whose digest is fp. If fp is NULL, return our own vote. If include_previous is false, do not consider any votes for a consensus that's already been built. If include_pending is false, do not consider any votes for the consensus that's in progress. May return NULL if we have no vote for the authority in question.
|
static |
|
static |
STATIC int64_t extract_param_buggy | ( | const char * | params, |
const char * | param_name, | ||
int64_t | default_value | ||
) |
Extract the value of a parameter from a string encoding a list of parameters, badly.
This is a deliberately buggy implementation, for backward compatibility with versions of Tor affected by #19011. Once all authorities have upgraded to consensus method 31 or later, then we can throw away this function.
|
static |
STATIC char* format_networkstatus_vote | ( | crypto_pk_t * | private_signing_key, |
networkstatus_t * | v3_ns | ||
) |
|
static |
char* format_recommended_version_list | ( | const config_line_t * | ln, |
int | warn | ||
) |
Given a (possibly empty) list of config_line_t, each line of which contains a list of comma-separated version numbers surrounded by optional space, allocate and return a new string containing the version numbers, in order, separated by commas. Used to generate Recommended(Client|Server)?Versions
STATIC digestmap_t* get_all_possible_sybil | ( | const smartlist_t * | routers | ) |
Given a list of routerinfo_t in routers, return a new digestmap_t whose keys are the identity digests of those routers that we're going to exclude for Sybil-like appearance.
|
static |
|
static |
|
static |
STATIC digestmap_t* get_sybil_list_by_ip_version | ( | const smartlist_t * | routers, |
sa_family_t | family | ||
) |
Given a list of routerinfo_t in routers that all use the same IP version, specified in family, return a new digestmap_t whose keys are the identity digests of those routers that we're going to exclude for Sybil-like appearance.
|
static |
Given a vote vote (not a consensus!), return its associated networkstatus_voter_info_t.
Definition at line 530 of file dirvote.c.
Referenced by compare_dir_src_ents_by_authority_id_(), and compare_votes_by_authority_id_().
|
static |
STATIC char* make_consensus_method_list | ( | int | low, |
int | high, | ||
const char * | separator | ||
) |
STATIC int networkstatus_add_detached_signatures | ( | networkstatus_t * | target, |
ns_detached_signatures_t * | sigs, | ||
const char * | source, | ||
int | severity, | ||
const char ** | msg_out | ||
) |
Given a consensus vote target and a set of detached signatures in sigs that correspond to the same consensus, check whether there are any new signatures in src_voter_list that should be added to target. (A signature should be added if we have no signature for that voter in target yet, or if we have no verifiable signature and the new signature is verifiable.)
Return the number of signatures added or changed, or -1 if the document signatures are invalid. Sets *msg_out to a string constant describing the signature status.
Make sure all the digests we know match, and at least one matches.
|
static |
int networkstatus_compute_bw_weights_v10 | ( | smartlist_t * | chunks, |
int64_t | G, | ||
int64_t | M, | ||
int64_t | E, | ||
int64_t | D, | ||
int64_t | T, | ||
int64_t | weight_scale | ||
) |
STATIC char* networkstatus_compute_consensus | ( | smartlist_t * | votes, |
int | total_authorities, | ||
crypto_pk_t * | identity_key, | ||
crypto_pk_t * | signing_key, | ||
const char * | legacy_id_key_digest, | ||
crypto_pk_t * | legacy_signing_key, | ||
consensus_flavor_t | flavor | ||
) |
Given a list of vote networkstatus_t in votes, our public authority identity_key, our private authority signing_key, and the number of total_authorities that we believe exist in our voting quorum, generate the text of a new v3 consensus or microdescriptor consensus (depending on flavor), and return the value in a newly allocated string.
Note: this function DOES NOT check whether the votes are from recognized authorities. (dirvote_add_vote does that.)
WATCH OUT: You need to think before you change the behavior of this function, or of the functions it calls! If some authorities compute the consensus with a different algorithm than others, they will not reach the same result, and they will not all sign the same thing! If you really need to change the algorithm here, you should allocate a new "consensus_method" for the new behavior, and make the new behavior conditional on a new-enough consensus_method.
|
static |
Return a newly allocated string containing all the signatures on consensus by all voters. If for_detached_signatures is true, then the signatures will be put in a detached signatures document, so prefix any non-NS-flavored signatures with "additional-signature" rather than "directory-signature".
STATIC char* networkstatus_get_detached_signatures | ( | smartlist_t * | consensuses | ) |
Return a newly allocated string holding the detached-signatures document corresponding to the signatures on consensuses, which must contain exactly one FLAV_NS consensus, and no more than one consensus for each other flavor.
Definition at line 2751 of file dirvote.c.
Referenced by get_detached_signatures_from_pending_consensuses().
|
static |
|
static |
|
static |
Given a platform string as in a routerinfo_t (possibly null), return a newly allocated version string for a networkstatus document, or NULL if the platform doesn't give a Tor version.
|
static |
const char DIRVOTE_OPTIONAL_FLAGS[] |
const char DIRVOTE_UNIVERSAL_FLAGS[] |
|
static |
|
static |
List of ns_detached_signatures_t: hold signatures that get posted to us before we have generated the consensus on our own.
|
static |
The detached signatures for the consensus that we're currently building.
Definition at line 2955 of file dirvote.c.
Referenced by dirvote_add_signatures_to_all_pending_consensuses(), dirvote_add_signatures_to_pending_consensus(), and dirvote_get_pending_detached_signatures().
|
static |
List of pending_vote_t for the current vote. Before we've used them to build a consensus, the votes go here.
Definition at line 2945 of file dirvote.c.
Referenced by dirvote_add_vote(), dirvote_clear_votes(), and dirvote_compute_consensuses().
|
static |
List of pending_vote_t for the previous vote. After we've used them to build a consensus, the votes go here for the next period.
Definition at line 2948 of file dirvote.c.
Referenced by dirvote_clear_votes().