diff options
Diffstat (limited to 'src/feature/nodelist')
-rw-r--r-- | src/feature/nodelist/fmt_routerstatus.c | 253 | ||||
-rw-r--r-- | src/feature/nodelist/fmt_routerstatus.h | 41 | ||||
-rw-r--r-- | src/feature/nodelist/networkstatus.c | 3 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.c | 1 | ||||
-rw-r--r-- | src/feature/nodelist/routerlist.c | 2 | ||||
-rw-r--r-- | src/feature/nodelist/routerparse.c | 1 |
6 files changed, 300 insertions, 1 deletions
diff --git a/src/feature/nodelist/fmt_routerstatus.c b/src/feature/nodelist/fmt_routerstatus.c new file mode 100644 index 0000000000..d97d4ae6e3 --- /dev/null +++ b/src/feature/nodelist/fmt_routerstatus.c @@ -0,0 +1,253 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file fmt_routerstatus.h + * \brief Format routerstatus entries for controller, vote, or consensus. + * + * (Because controllers consume this format, we can't make this + * code dirauth-only.) + **/ + +#include "core/or/or.h" +#include "feature/nodelist/fmt_routerstatus.h" + +/* #include "lib/container/buffers.h" */ +/* #include "app/config/config.h" */ +/* #include "app/config/confparse.h" */ +/* #include "core/or/channel.h" */ +/* #include "core/or/channeltls.h" */ +/* #include "core/or/command.h" */ +/* #include "core/mainloop/connection.h" */ +/* #include "core/or/connection_or.h" */ +/* #include "feature/dircache/conscache.h" */ +/* #include "feature/dircache/consdiffmgr.h" */ +/* #include "feature/control/control.h" */ +/* #include "feature/dircache/directory.h" */ +/* #include "feature/dircache/dirserv.h" */ +/* #include "feature/hibernate/hibernate.h" */ +/* #include "feature/dirauth/keypin.h" */ +/* #include "core/mainloop/main.h" */ +/* #include "feature/nodelist/microdesc.h" */ +/* #include "feature/nodelist/networkstatus.h" */ +/* #include "feature/nodelist/nodelist.h" */ +#include "core/or/policies.h" +/* #include "core/or/protover.h" */ +/* #include "feature/stats/rephist.h" */ +/* #include "feature/relay/router.h" */ +/* #include "feature/nodelist/dirlist.h" */ +#include "feature/nodelist/routerlist.h" + +/* #include "feature/nodelist/routerparse.h" */ +/* #include "feature/nodelist/routerset.h" */ +/* #include "feature/nodelist/torcert.h" */ +/* #include "feature/dircommon/voting_schedule.h" */ + +#include "feature/dirauth/dirvote.h" + +/* #include "feature/dircache/cached_dir_st.h" */ +/* #include "feature/dircommon/dir_connection_st.h" */ +/* #include "feature/nodelist/extrainfo_st.h" */ +/* #include "feature/nodelist/microdesc_st.h" */ +/* #include "feature/nodelist/node_st.h" */ +#include "feature/nodelist/routerinfo_st.h" +/* #include "feature/nodelist/routerlist_st.h" */ +/* #include "core/or/tor_version_st.h" */ +#include "feature/nodelist/vote_routerstatus_st.h" + +/* #include "lib/compress/compress.h" */ +/* #include "lib/container/order.h" */ +#include "lib/crypt_ops/crypto_format.h" +/* #include "lib/encoding/confline.h" */ + +/* #include "lib/encoding/keyval.h" */ + +/** Helper: write the router-status information in <b>rs</b> into a newly + * allocated character buffer. Use the same format as in network-status + * documents. If <b>version</b> is non-NULL, add a "v" line for the platform. + * + * consensus_method is the current consensus method when format is + * NS_V3_CONSENSUS or NS_V3_CONSENSUS_MICRODESC. It is ignored for other + * formats: pass ROUTERSTATUS_FORMAT_NO_CONSENSUS_METHOD. + * + * Return 0 on success, -1 on failure. + * + * The format argument has one of the following values: + * NS_V2 - Output an entry suitable for a V2 NS opinion document + * NS_V3_CONSENSUS - Output the first portion of a V3 NS consensus entry + * for consensus_method. + * NS_V3_CONSENSUS_MICRODESC - Output the first portion of a V3 microdesc + * consensus entry for consensus_method. + * NS_V3_VOTE - Output a complete V3 NS vote. If <b>vrs</b> is present, + * it contains additional information for the vote. + * NS_CONTROL_PORT - Output a NS document for the control port. + */ +char * +routerstatus_format_entry(const routerstatus_t *rs, const char *version, + const char *protocols, + routerstatus_format_type_t format, + int consensus_method, + const vote_routerstatus_t *vrs) +{ + char *summary; + char *result = NULL; + + char published[ISO_TIME_LEN+1]; + char identity64[BASE64_DIGEST_LEN+1]; + char digest64[BASE64_DIGEST_LEN+1]; + smartlist_t *chunks = smartlist_new(); + + format_iso_time(published, rs->published_on); + digest_to_base64(identity64, rs->identity_digest); + digest_to_base64(digest64, rs->descriptor_digest); + + smartlist_add_asprintf(chunks, + "r %s %s %s%s%s %s %d %d\n", + rs->nickname, + identity64, + (format==NS_V3_CONSENSUS_MICRODESC)?"":digest64, + (format==NS_V3_CONSENSUS_MICRODESC)?"":" ", + published, + fmt_addr32(rs->addr), + (int)rs->or_port, + (int)rs->dir_port); + + /* TODO: Maybe we want to pass in what we need to build the rest of + * this here, instead of in the caller. Then we could use the + * networkstatus_type_t values, with an additional control port value + * added -MP */ + + /* V3 microdesc consensuses only have "a" lines in later consensus methods + */ + if (format == NS_V3_CONSENSUS_MICRODESC && + consensus_method < MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS) + goto done; + + /* Possible "a" line. At most one for now. */ + if (!tor_addr_is_null(&rs->ipv6_addr)) { + smartlist_add_asprintf(chunks, "a %s\n", + fmt_addrport(&rs->ipv6_addr, rs->ipv6_orport)); + } + + if (format == NS_V3_CONSENSUS || format == NS_V3_CONSENSUS_MICRODESC) + goto done; + + smartlist_add_asprintf(chunks, + "s%s%s%s%s%s%s%s%s%s%s\n", + /* These must stay in alphabetical order. */ + rs->is_authority?" Authority":"", + rs->is_bad_exit?" BadExit":"", + rs->is_exit?" Exit":"", + rs->is_fast?" Fast":"", + rs->is_possible_guard?" Guard":"", + rs->is_hs_dir?" HSDir":"", + rs->is_flagged_running?" Running":"", + rs->is_stable?" Stable":"", + rs->is_v2_dir?" V2Dir":"", + rs->is_valid?" Valid":""); + + /* length of "opt v \n" */ +#define V_LINE_OVERHEAD 7 + if (version && strlen(version) < MAX_V_LINE_LEN - V_LINE_OVERHEAD) { + smartlist_add_asprintf(chunks, "v %s\n", version); + } + if (protocols) { + smartlist_add_asprintf(chunks, "pr %s\n", protocols); + } + + if (format != NS_V2) { + const routerinfo_t* desc = router_get_by_id_digest(rs->identity_digest); + uint32_t bw_kb; + + if (format != NS_CONTROL_PORT) { + /* Blow up more or less nicely if we didn't get anything or not the + * thing we expected. + */ + if (!desc) { + char id[HEX_DIGEST_LEN+1]; + char dd[HEX_DIGEST_LEN+1]; + + base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN); + base16_encode(dd, sizeof(dd), rs->descriptor_digest, DIGEST_LEN); + log_warn(LD_BUG, "Cannot get any descriptor for %s " + "(wanted descriptor %s).", + id, dd); + goto err; + } + + /* This assert could fire for the control port, because + * it can request NS documents before all descriptors + * have been fetched. Therefore, we only do this test when + * format != NS_CONTROL_PORT. */ + if (tor_memneq(desc->cache_info.signed_descriptor_digest, + rs->descriptor_digest, + DIGEST_LEN)) { + char rl_d[HEX_DIGEST_LEN+1]; + char rs_d[HEX_DIGEST_LEN+1]; + char id[HEX_DIGEST_LEN+1]; + + base16_encode(rl_d, sizeof(rl_d), + desc->cache_info.signed_descriptor_digest, DIGEST_LEN); + base16_encode(rs_d, sizeof(rs_d), rs->descriptor_digest, DIGEST_LEN); + base16_encode(id, sizeof(id), rs->identity_digest, DIGEST_LEN); + log_err(LD_BUG, "descriptor digest in routerlist does not match " + "the one in routerstatus: %s vs %s " + "(router %s)\n", + rl_d, rs_d, id); + + tor_assert(tor_memeq(desc->cache_info.signed_descriptor_digest, + rs->descriptor_digest, + DIGEST_LEN)); + } + } + + if (format == NS_CONTROL_PORT && rs->has_bandwidth) { + bw_kb = rs->bandwidth_kb; + } else { + tor_assert(desc); + bw_kb = router_get_advertised_bandwidth_capped(desc) / 1000; + } + smartlist_add_asprintf(chunks, + "w Bandwidth=%d", bw_kb); + + if (format == NS_V3_VOTE && vrs && vrs->has_measured_bw) { + smartlist_add_asprintf(chunks, + " Measured=%d", vrs->measured_bw_kb); + } + /* Write down guardfraction information if we have it. */ + if (format == NS_V3_VOTE && vrs && vrs->status.has_guardfraction) { + smartlist_add_asprintf(chunks, + " GuardFraction=%d", + vrs->status.guardfraction_percentage); + } + + smartlist_add_strdup(chunks, "\n"); + + if (desc) { + summary = policy_summarize(desc->exit_policy, AF_INET); + smartlist_add_asprintf(chunks, "p %s\n", summary); + tor_free(summary); + } + + if (format == NS_V3_VOTE && vrs) { + if (tor_mem_is_zero((char*)vrs->ed25519_id, ED25519_PUBKEY_LEN)) { + smartlist_add_strdup(chunks, "id ed25519 none\n"); + } else { + char ed_b64[BASE64_DIGEST256_LEN+1]; + digest256_to_base64(ed_b64, (const char*)vrs->ed25519_id); + smartlist_add_asprintf(chunks, "id ed25519 %s\n", ed_b64); + } + } + } + + done: + result = smartlist_join_strings(chunks, "", 0, NULL); + + err: + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); + + return result; +} diff --git a/src/feature/nodelist/fmt_routerstatus.h b/src/feature/nodelist/fmt_routerstatus.h new file mode 100644 index 0000000000..1a6630d266 --- /dev/null +++ b/src/feature/nodelist/fmt_routerstatus.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file fmt_routerstatus.h + * \brief Header file for fmt_routerstatus.c. + **/ + +#ifndef TOR_FMT_ROUTERSTATUS_H +#define TOR_FMT_ROUTERSTATUS_H + +/** An enum to describe what format we're generating a routerstatus line in. + */ +typedef enum { + /** For use in a v2 opinion */ + NS_V2, + /** For use in a consensus networkstatus document (ns flavor) */ + NS_V3_CONSENSUS, + /** For use in a vote networkstatus document */ + NS_V3_VOTE, + /** For passing to the controlport in response to a GETINFO request */ + NS_CONTROL_PORT, + /** For use in a consensus networkstatus document (microdesc flavor) */ + NS_V3_CONSENSUS_MICRODESC +} routerstatus_format_type_t; + +/** Maximum allowable length of a version line in a networkstatus. */ +#define MAX_V_LINE_LEN 128 + +char *routerstatus_format_entry( + const routerstatus_t *rs, + const char *version, + const char *protocols, + routerstatus_format_type_t format, + int consensus_method, + const vote_routerstatus_t *vrs); + +#endif /* !defined(TOR_FMT_ROUTERSTATUS_H) */ diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index d4340b6caa..c5d8d42c42 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -53,6 +53,7 @@ #include "lib/crypt_ops/crypto_util.h" #include "feature/dircache/directory.h" #include "feature/dircache/dirserv.h" +#include "feature/dirauth/reachability.h" #include "core/or/dos.h" #include "feature/client/entrynodes.h" #include "feature/hibernate/hibernate.h" @@ -73,10 +74,12 @@ #include "feature/nodelist/torcert.h" #include "core/or/channelpadding.h" #include "feature/dircommon/voting_schedule.h" +#include "feature/nodelist/fmt_routerstatus.h" #include "feature/dirauth/dirvote.h" #include "feature/dirauth/mode.h" #include "feature/dirauth/shared_random.h" +#include "feature/dirauth/voteflags.h" #include "feature/nodelist/authority_cert_st.h" #include "feature/dircommon/dir_connection_st.h" diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index c990e69406..9cde06f37e 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -47,6 +47,7 @@ #include "app/config/config.h" #include "feature/control/control.h" #include "feature/dircache/dirserv.h" +#include "feature/dirauth/process_descs.h" #include "feature/client/entrynodes.h" #include "feature/stats/geoip.h" #include "feature/hs/hs_common.h" diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c index 547b54bb93..93597f89b0 100644 --- a/src/feature/nodelist/routerlist.c +++ b/src/feature/nodelist/routerlist.c @@ -71,6 +71,8 @@ #include "feature/dirauth/mode.h" #include "feature/dircache/directory.h" #include "feature/dircache/dirserv.h" +#include "feature/dirauth/reachability.h" +#include "feature/dirauth/process_descs.h" #include "feature/nodelist/authcert.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" diff --git a/src/feature/nodelist/routerparse.c b/src/feature/nodelist/routerparse.c index 5b82c2adf6..a72cf98f56 100644 --- a/src/feature/nodelist/routerparse.c +++ b/src/feature/nodelist/routerparse.c @@ -61,7 +61,6 @@ #include "lib/crypt_ops/crypto_format.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/dirauth/shared_random.h" -#include "feature/dircache/dirserv.h" #include "feature/client/entrynodes.h" #include "lib/memarea/memarea.h" #include "feature/nodelist/microdesc.h" |