diff options
Diffstat (limited to 'src/feature')
128 files changed, 3972 insertions, 871 deletions
diff --git a/src/feature/api/feature_api.dox b/src/feature/api/feature_api.dox new file mode 100644 index 0000000000..06112120c3 --- /dev/null +++ b/src/feature/api/feature_api.dox @@ -0,0 +1,4 @@ +/** +@dir /feature/api +@brief feature/api: In-process interface to starting/stopping Tor. +**/ diff --git a/src/feature/api/tor_api_internal.h b/src/feature/api/tor_api_internal.h index 60e0f3aa59..115d33d58e 100644 --- a/src/feature/api/tor_api_internal.h +++ b/src/feature/api/tor_api_internal.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file tor_api_internal.h + * @brief Internal declarations for in-process Tor API. + **/ + #ifndef TOR_API_INTERNAL_H #define TOR_API_INTERNAL_H diff --git a/src/feature/client/addressmap.h b/src/feature/client/addressmap.h index 9179aef1d0..eb9742c50b 100644 --- a/src/feature/client/addressmap.h +++ b/src/feature/client/addressmap.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file addressmap.h + * @brief Header for addressmap.c + **/ + #ifndef TOR_ADDRESSMAP_H #define TOR_ADDRESSMAP_H @@ -62,4 +67,3 @@ STATIC void get_random_virtual_addr(const virtual_addr_conf_t *conf, #endif /* defined(ADDRESSMAP_PRIVATE) */ #endif /* !defined(TOR_ADDRESSMAP_H) */ - diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index 36b575ef20..8af8f14bb0 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -114,7 +114,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "lib/confmgt/confparse.h" +#include "lib/confmgt/confmgt.h" #include "app/config/statefile.h" #include "core/mainloop/connection.h" #include "core/mainloop/mainloop.h" @@ -1038,7 +1038,7 @@ get_max_sample_size(guard_selection_t *gs, * Return a smartlist of the all the guards that are not currently * members of the sample (GUARDS - SAMPLED_GUARDS). The elements of * this list are node_t pointers in the non-bridge case, and - * bridge_info_t pointers in the bridge case. Set *<b>n_guards_out/b> + * bridge_info_t pointers in the bridge case. Set *<b>n_guards_out</b> * to the number of guards that we found in GUARDS, including those * that were already sampled. */ diff --git a/src/feature/client/feature_client.dox b/src/feature/client/feature_client.dox new file mode 100644 index 0000000000..a8263b494c --- /dev/null +++ b/src/feature/client/feature_client.dox @@ -0,0 +1,7 @@ +/** +@dir /feature/client +@brief feature/client: Client-specific code + +(There is also a bunch of client-specific code in other modules.) + +**/ diff --git a/src/feature/client/proxymode.c b/src/feature/client/proxymode.c new file mode 100644 index 0000000000..0682205336 --- /dev/null +++ b/src/feature/client/proxymode.c @@ -0,0 +1,32 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file proxymode.c + * @brief Determine whether we are trying to be a proxy. + **/ + +#include "core/or/or.h" + +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/or/port_cfg_st.h" +#include "feature/client/proxymode.h" + +/** Return true iff we are trying to proxy client connections. */ +int +proxy_mode(const or_options_t *options) +{ + (void)options; + SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { + if (p->type == CONN_TYPE_AP_LISTENER || + p->type == CONN_TYPE_AP_TRANS_LISTENER || + p->type == CONN_TYPE_AP_DNS_LISTENER || + p->type == CONN_TYPE_AP_NATD_LISTENER) + return 1; + } SMARTLIST_FOREACH_END(p); + return 0; +} diff --git a/src/feature/client/proxymode.h b/src/feature/client/proxymode.h new file mode 100644 index 0000000000..770a519155 --- /dev/null +++ b/src/feature/client/proxymode.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file proxymode.h + * \brief Header file for proxymode.c. + **/ + +#ifndef TOR_PROXYMODE_H +#define TOR_PROXYMODE_H + +int proxy_mode(const or_options_t *options); + +#endif /* !defined(TOR_PROXYMODE_H) */ diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c index 3f731ac7d4..6537a4b2da 100644 --- a/src/feature/client/transports.c +++ b/src/feature/client/transports.c @@ -97,6 +97,8 @@ #include "core/or/circuitbuild.h" #include "feature/client/transports.h" #include "feature/relay/router.h" +/* 31851: split the server transport code out of the client module */ +#include "feature/relay/transport_config.h" #include "app/config/statefile.h" #include "core/or/connection_or.h" #include "feature/relay/ext_orport.h" @@ -1279,7 +1281,7 @@ get_transport_options_for_server_proxy(const managed_proxy_t *mp) string. */ SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, const char *, transport) { smartlist_t *options_tmp_sl = NULL; - options_tmp_sl = get_options_for_server_transport(transport); + options_tmp_sl = pt_get_options_for_server_transport(transport); if (!options_tmp_sl) continue; diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index de1bef7e59..e1a8292c9f 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -13,7 +13,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "lib/confmgt/confparse.h" +#include "lib/confmgt/confmgt.h" #include "app/main/main.h" #include "core/mainloop/connection.h" #include "core/or/circuitbuild.h" @@ -590,7 +590,7 @@ control_setconf_helper(control_connection_t *conn, const unsigned flags = CAL_CLEAR_FIRST | (use_defaults ? CAL_USE_DEFAULTS : 0); - // We need a copy here, since confparse.c wants to canonicalize cases. + // We need a copy here, since confmgt.c wants to canonicalize cases. config_line_t *lines = config_lines_dup(args->kwargs); opt_err = options_trial_assign(lines, flags, &errstring); @@ -2248,6 +2248,7 @@ typedef struct control_cmd_def_t { */ #define CMD_FL_WIPE (1u<<0) +#ifndef COCCI /** Macro: declare a command with a one-line argument, a given set of flags, * and a syntax definition. **/ @@ -2280,6 +2281,7 @@ typedef struct control_cmd_def_t { 0, \ &obsolete_syntax, \ } +#endif /* !defined(COCCI) */ /** * An array defining all the recognized controller commands. diff --git a/src/feature/control/control_connection_st.h b/src/feature/control/control_connection_st.h index c9164f03b3..8ecce5ee69 100644 --- a/src/feature/control/control_connection_st.h +++ b/src/feature/control/control_connection_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file control_connection_st.h + * @brief Controller connection structure. + **/ + #ifndef CONTROL_CONNECTION_ST_H #define CONTROL_CONNECTION_ST_H diff --git a/src/feature/control/control_events.c b/src/feature/control/control_events.c index 82ea943999..12b73641b2 100644 --- a/src/feature/control/control_events.c +++ b/src/feature/control/control_events.c @@ -1653,13 +1653,17 @@ control_event_status(int type, int severity, const char *format, va_list args) log_warn(LD_BUG, "Format string too long."); return -1; } - tor_vasprintf(&user_buf, format, args); + if (tor_vasprintf(&user_buf, format, args)<0) { + log_warn(LD_BUG, "Failed to create user buffer."); + return -1; + } send_control_event(type, "%s %s\r\n", format_buf, user_buf); tor_free(user_buf); return 0; } +#ifndef COCCI #define CONTROL_EVENT_STATUS_BODY(event, sev) \ int r; \ do { \ @@ -1671,6 +1675,7 @@ control_event_status(int type, int severity, const char *format, va_list args) r = control_event_status((event), (sev), format, ap); \ va_end(ap); \ } while (0) +#endif /* !defined(COCCI) */ /** Format and send an EVENT_STATUS_GENERAL event whose main text is obtained * by formatting the arguments using the printf-style <b>format</b>. */ diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c index 3e31bb9e8f..979fa4480d 100644 --- a/src/feature/control/control_getinfo.c +++ b/src/feature/control/control_getinfo.c @@ -325,6 +325,41 @@ getinfo_helper_current_time(control_connection_t *control_conn, return 0; } +/** GETINFO helper for dumping different consensus flavors + * returns: 0 on success -1 on error. */ +STATIC int +getinfo_helper_current_consensus(consensus_flavor_t flavor, + char** answer, + const char** errmsg) +{ + const char *flavor_name = networkstatus_get_flavor_name(flavor); + if (BUG(!strcmp(flavor_name, "??"))) { + *errmsg = "Internal error: unrecognized flavor name."; + return -1; + } + if (we_want_to_fetch_flavor(get_options(), flavor)) { + /** Check from the cache */ + const cached_dir_t *consensus = dirserv_get_consensus(flavor_name); + if (consensus) { + *answer = tor_strdup(consensus->dir); + } + } + if (!*answer) { /* try loading it from disk */ + + tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name); + if (mapped) { + *answer = tor_memdup_nulterm(mapped->data, mapped->size); + tor_munmap_file(mapped); + } + if (!*answer) { /* generate an error */ + *errmsg = "Could not open cached consensus. " + "Make sure FetchUselessDescriptors is set to 1."; + return -1; + } + } + return 0; +} + /** Implementation helper for GETINFO: knows the answers for questions about * directory information. */ STATIC int @@ -576,23 +611,18 @@ getinfo_helper_dir(control_connection_t *control_conn, smartlist_free(descs); } else if (!strcmpstart(question, "dir/status/")) { *answer = tor_strdup(""); - } else if (!strcmp(question, "dir/status-vote/current/consensus")) { /* v3 */ - if (we_want_to_fetch_flavor(get_options(), FLAV_NS)) { - const cached_dir_t *consensus = dirserv_get_consensus("ns"); - if (consensus) - *answer = tor_strdup(consensus->dir); + } else if (!strcmp(question, "dir/status-vote/current/consensus")) { + int consensus_result = getinfo_helper_current_consensus(FLAV_NS, + answer, errmsg); + if (consensus_result < 0) { + return -1; } - if (!*answer) { /* try loading it from disk */ - tor_mmap_t *mapped = networkstatus_map_cached_consensus("ns"); - if (mapped) { - *answer = tor_memdup_nulterm(mapped->data, mapped->size); - tor_munmap_file(mapped); - } - if (!*answer) { /* generate an error */ - *errmsg = "Could not open cached consensus. " - "Make sure FetchUselessDescriptors is set to 1."; - return -1; - } + } else if (!strcmp(question, + "dir/status-vote/current/consensus-microdesc")) { + int consensus_result = getinfo_helper_current_consensus(FLAV_MICRODESC, + answer, errmsg); + if (consensus_result < 0) { + return -1; } } else if (!strcmp(question, "network-status")) { /* v1 */ static int network_status_warned = 0; @@ -1513,6 +1543,8 @@ static const getinfo_item_t getinfo_items[] = { "v2 networkstatus docs as retrieved from a DirPort."), ITEM("dir/status-vote/current/consensus", dir, "v3 Networkstatus consensus as retrieved from a DirPort."), + ITEM("dir/status-vote/current/consensus-microdesc", dir, + "v3 Microdescriptor consensus as retrieved from a DirPort."), ITEM("exit-policy/default", policies, "The default value appended to the configured exit policy."), ITEM("exit-policy/reject-private/default", policies, diff --git a/src/feature/control/control_getinfo.h b/src/feature/control/control_getinfo.h index 52978686d8..86aaf7c4f7 100644 --- a/src/feature/control/control_getinfo.h +++ b/src/feature/control/control_getinfo.h @@ -48,6 +48,10 @@ STATIC int getinfo_helper_downloads( control_connection_t *control_conn, const char *question, char **answer, const char **errmsg); +STATIC int getinfo_helper_current_consensus( + consensus_flavor_t flavor, + char **answer, + const char **errmsg); STATIC int getinfo_helper_dir( control_connection_t *control_conn, const char *question, char **answer, diff --git a/src/feature/control/feature_control.dox b/src/feature/control/feature_control.dox new file mode 100644 index 0000000000..a0bf9413a1 --- /dev/null +++ b/src/feature/control/feature_control.dox @@ -0,0 +1,10 @@ +/** +@dir /feature/control +@brief feature/control: Controller API. + +The Controller API is a text-based protocol that another program (or another +thread, if you're running Tor in-process) can use to configure and control +Tor while it is running. The current protocol is documented in +[control-spec.txt](https://gitweb.torproject.org/torspec.git/tree/control-spec.txt). + +**/ diff --git a/src/feature/control/fmt_serverstatus.c b/src/feature/control/fmt_serverstatus.c index 33c5ba1336..92db70758f 100644 --- a/src/feature/control/fmt_serverstatus.c +++ b/src/feature/control/fmt_serverstatus.c @@ -3,6 +3,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file fmt_serverstatus.c + * @brief Format relay info for a controller. + **/ + #include "core/or/or.h" #include "feature/control/fmt_serverstatus.h" diff --git a/src/feature/control/getinfo_geoip.c b/src/feature/control/getinfo_geoip.c index d188725fa3..4636ede039 100644 --- a/src/feature/control/getinfo_geoip.c +++ b/src/feature/control/getinfo_geoip.c @@ -1,3 +1,12 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file getinfo_geoip.c + * @brief GEOIP-related contoller GETINFO commands. + **/ #include "core/or/or.h" #include "core/mainloop/connection.h" diff --git a/src/feature/control/getinfo_geoip.h b/src/feature/control/getinfo_geoip.h index 94759d0d18..f6bc86cb53 100644 --- a/src/feature/control/getinfo_geoip.h +++ b/src/feature/control/getinfo_geoip.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file getinfo_geoip.h + * @brief Header for getinfo_geoip.c + **/ + #ifndef TOR_GETINFO_GEOIP_H #define TOR_GETINFO_GEOIP_H diff --git a/src/feature/dirauth/authmode.h b/src/feature/dirauth/authmode.h index bfd5f4dc04..11bc40d8d1 100644 --- a/src/feature/dirauth/authmode.h +++ b/src/feature/dirauth/authmode.h @@ -27,6 +27,7 @@ authdir_mode_v3(const or_options_t *options) return authdir_mode(options) && options->V3AuthoritativeDir != 0; } +/* Is the dirauth module enabled? */ #define have_module_dirauth() (1) #else /* !defined(HAVE_MODULE_DIRAUTH) */ diff --git a/src/feature/dirauth/bridgeauth.c b/src/feature/dirauth/bridgeauth.c index 4aaefc7a6d..56782011c2 100644 --- a/src/feature/dirauth/bridgeauth.c +++ b/src/feature/dirauth/bridgeauth.c @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file bridgeauth.c + * @brief Bridge authority code + **/ + #include "core/or/or.h" #include "feature/dirauth/bridgeauth.h" #include "feature/dirauth/voteflags.h" diff --git a/src/feature/dirauth/bridgeauth.h b/src/feature/dirauth/bridgeauth.h index 4905e9c3ee..76676e8db5 100644 --- a/src/feature/dirauth/bridgeauth.h +++ b/src/feature/dirauth/bridgeauth.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file bridgeauth.h + * @brief Header for bridgeauth.c + **/ + #ifndef TOR_DIRAUTH_BRIDGEAUTH_H #define TOR_DIRAUTH_BRIDGEAUTH_H diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c new file mode 100644 index 0000000000..552f851461 --- /dev/null +++ b/src/feature/dirauth/dirauth_config.c @@ -0,0 +1,440 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file dirauth_config.c + * @brief Code to interpret the user's configuration of Tor's directory + * authority module. + **/ + +#include "orconfig.h" +#include "feature/dirauth/dirauth_config.h" + +#include "lib/encoding/confline.h" +#include "lib/confmgt/confmgt.h" + +/* Required for dirinfo_type_t in or_options_t */ +#include "core/or/or.h" +#include "app/config/config.h" + +#include "feature/dircommon/voting_schedule.h" +#include "feature/stats/rephist.h" + +#include "feature/dirauth/authmode.h" +#include "feature/dirauth/bwauth.h" +#include "feature/dirauth/dirauth_periodic.h" +#include "feature/dirauth/dirvote.h" +#include "feature/dirauth/guardfraction.h" + +/* Copied from config.c, we will refactor later in 29211. */ +#define REJECT(arg) \ + STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END +#if defined(__GNUC__) && __GNUC__ <= 3 +#define COMPLAIN(args...) \ + STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END +#else +#define COMPLAIN(args, ...) \ + STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END +#endif /* defined(__GNUC__) && __GNUC__ <= 3 */ + +#define YES_IF_CHANGED_INT(opt) \ + if (!CFG_EQ_INT(old_options, new_options, opt)) return 1; + +/** + * Legacy validation/normalization function for the dirauth mode options in + * options. Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_dirauth_mode(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (!authdir_mode(options)) + return 0; + + /* confirm that our address isn't broken, so we can complain now */ + uint32_t tmp; + if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0) + REJECT("Failed to resolve/guess local address. See logs for details."); + + if (!options->ContactInfo && !options->TestingTorNetwork) + REJECT("Authoritative directory servers must set ContactInfo"); + if (!options->RecommendedClientVersions) + options->RecommendedClientVersions = + config_lines_dup(options->RecommendedVersions); + if (!options->RecommendedServerVersions) + options->RecommendedServerVersions = + config_lines_dup(options->RecommendedVersions); + if (options->VersioningAuthoritativeDir && + (!options->RecommendedClientVersions || + !options->RecommendedServerVersions)) + REJECT("Versioning authoritative dir servers must set " + "Recommended*Versions."); + + char *t; + /* Call these functions to produce warnings only. */ + t = format_recommended_version_list(options->RecommendedClientVersions, 1); + tor_free(t); + t = format_recommended_version_list(options->RecommendedServerVersions, 1); + tor_free(t); + + if (options->UseEntryGuards) { + log_info(LD_CONFIG, "Authoritative directory servers can't set " + "UseEntryGuards. Disabling."); + options->UseEntryGuards = 0; + } + if (!options->DownloadExtraInfo && authdir_mode_v3(options)) { + log_info(LD_CONFIG, "Authoritative directories always try to download " + "extra-info documents. Setting DownloadExtraInfo."); + options->DownloadExtraInfo = 1; + } + if (!(options->BridgeAuthoritativeDir || + options->V3AuthoritativeDir)) + REJECT("AuthoritativeDir is set, but none of " + "(Bridge/V3)AuthoritativeDir is set."); + + /* If we have a v3bandwidthsfile and it's broken, complain on startup */ + if (options->V3BandwidthsFile && !old_options) { + dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL, NULL, + NULL); + } + /* same for guardfraction file */ + if (options->GuardfractionFile && !old_options) { + dirserv_read_guardfraction_file(options->GuardfractionFile, NULL); + } + + if (!options->DirPort_set) + REJECT("Running as authoritative directory, but no DirPort set."); + + if (!options->ORPort_set) + REJECT("Running as authoritative directory, but no ORPort set."); + + if (options->ClientOnly) + REJECT("Running as authoritative directory, but ClientOnly also set."); + + if (options->MinUptimeHidServDirectoryV2 < 0) { + log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at " + "least 0 seconds. Changing to 0."); + options->MinUptimeHidServDirectoryV2 = 0; + } + + return 0; +} + +/** + * Legacy validation/normalization function for the dirauth bandwidth options + * in options. Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_dirauth_bandwidth(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (!authdir_mode(options)) + return 0; + + if (config_ensure_bandwidth_cap(&options->AuthDirFastGuarantee, + "AuthDirFastGuarantee", msg) < 0) + return -1; + if (config_ensure_bandwidth_cap(&options->AuthDirGuardBWGuarantee, + "AuthDirGuardBWGuarantee", msg) < 0) + return -1; + + return 0; +} + +/** + * Legacy validation/normalization function for the dirauth schedule options + * in options. Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_dirauth_schedule(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (!authdir_mode_v3(options)) + return 0; + + if (options->V3AuthVoteDelay + options->V3AuthDistDelay >= + options->V3AuthVotingInterval/2) { + REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half " + "V3AuthVotingInterval"); + } + + if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS) { + if (options->TestingTorNetwork) { + if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS_TESTING) { + REJECT("V3AuthVoteDelay is way too low."); + } else { + COMPLAIN("V3AuthVoteDelay is very low. " + "This may lead to failure to vote for a consensus."); + } + } else { + REJECT("V3AuthVoteDelay is way too low."); + } + } + + if (options->V3AuthDistDelay < MIN_DIST_SECONDS) { + if (options->TestingTorNetwork) { + if (options->V3AuthDistDelay < MIN_DIST_SECONDS_TESTING) { + REJECT("V3AuthDistDelay is way too low."); + } else { + COMPLAIN("V3AuthDistDelay is very low. " + "This may lead to missing votes in a consensus."); + } + } else { + REJECT("V3AuthDistDelay is way too low."); + } + } + + if (options->V3AuthNIntervalsValid < 2) + REJECT("V3AuthNIntervalsValid must be at least 2."); + + if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) { + if (options->TestingTorNetwork) { + if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL_TESTING) { + /* Unreachable, covered by earlier checks */ + REJECT("V3AuthVotingInterval is insanely low."); /* LCOV_EXCL_LINE */ + } else { + COMPLAIN("V3AuthVotingInterval is very low. " + "This may lead to failure to synchronise for a consensus."); + } + } else { + REJECT("V3AuthVotingInterval is insanely low."); + } + } else if (options->V3AuthVotingInterval > 24*60*60) { + REJECT("V3AuthVotingInterval is insanely high."); + } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) { + COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours."); + } + + return 0; +} + +/** + * Legacy validation/normalization function for the dirauth testing options + * in options. Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_dirauth_testing(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (!authdir_mode(options)) + return 0; + + if (options->TestingAuthDirTimeToLearnReachability < 0) { + REJECT("TestingAuthDirTimeToLearnReachability must be non-negative."); + } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) { + COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high."); + } + + if (!authdir_mode_v3(options)) + return 0; + + if (options->TestingV3AuthInitialVotingInterval + < MIN_VOTE_INTERVAL_TESTING_INITIAL) { + REJECT("TestingV3AuthInitialVotingInterval is insanely low."); + } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) { + REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into " + "30 minutes."); + } + + if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS_TESTING) { + REJECT("TestingV3AuthInitialVoteDelay is way too low."); + } + + if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS_TESTING) { + REJECT("TestingV3AuthInitialDistDelay is way too low."); + } + + if (options->TestingV3AuthInitialVoteDelay + + options->TestingV3AuthInitialDistDelay >= + options->TestingV3AuthInitialVotingInterval) { + REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay " + "must be less than TestingV3AuthInitialVotingInterval"); + } + + if (options->TestingV3AuthVotingStartOffset > + MIN(options->TestingV3AuthInitialVotingInterval, + options->V3AuthVotingInterval)) { + REJECT("TestingV3AuthVotingStartOffset is higher than the voting " + "interval."); + } else if (options->TestingV3AuthVotingStartOffset < 0) { + REJECT("TestingV3AuthVotingStartOffset must be non-negative."); + } + + return 0; +} + +/** + * Return true if changing the configuration from <b>old</b> to <b>new</b> + * affects the timing of the voting subsystem + */ +static int +options_transition_affects_dirauth_timing(const or_options_t *old_options, + const or_options_t *new_options) +{ + tor_assert(old_options); + tor_assert(new_options); + + if (authdir_mode_v3(old_options) != authdir_mode_v3(new_options)) + return 1; + if (! authdir_mode_v3(new_options)) + return 0; + + YES_IF_CHANGED_INT(V3AuthVotingInterval); + YES_IF_CHANGED_INT(V3AuthVoteDelay); + YES_IF_CHANGED_INT(V3AuthDistDelay); + YES_IF_CHANGED_INT(TestingV3AuthInitialVotingInterval); + YES_IF_CHANGED_INT(TestingV3AuthInitialVoteDelay); + YES_IF_CHANGED_INT(TestingV3AuthInitialDistDelay); + YES_IF_CHANGED_INT(TestingV3AuthVotingStartOffset); + + return 0; +} + +/** Fetch the active option list, and take dirauth actions based on it. All of + * the things we do should survive being done repeatedly. If present, + * <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_dirauth(const or_options_t *old_options) +{ + const or_options_t *options = get_options(); + + /* We may need to reschedule some dirauth stuff if our status changed. */ + if (old_options) { + if (options_transition_affects_dirauth_timing(old_options, options)) { + voting_schedule_recalculate_timing(options, time(NULL)); + reschedule_dirvote(options); + } + } + + return 0; +} + +/** Fetch the active option list, and take dirauth mtbf actions based on it. + * All of the things we do should survive being done repeatedly. If present, + * <b>old_options</b> contains the previous value of the options. + * + * Must be called immediately after a successful or_state_load(). + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_dirauth_mtbf(const or_options_t *old_options) +{ + (void)old_options; + + const or_options_t *options = get_options(); + int running_tor = options->command == CMD_RUN_TOR; + + if (!authdir_mode(options)) + return 0; + + /* Load dirauth state */ + if (running_tor) { + rep_hist_load_mtbf_data(time(NULL)); + } + + return 0; +} + +/** Fetch the active option list, and take dirauth statistics actions based + * on it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Sets <b>*print_notice_out</b> if we enabled stats, and need to print + * a stats log using options_act_relay_stats_msg(). + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_dirauth_stats(const or_options_t *old_options, + bool *print_notice_out) +{ + if (BUG(!print_notice_out)) + return -1; + + const or_options_t *options = get_options(); + + if (authdir_mode_bridge(options)) { + time_t now = time(NULL); + int print_notice = 0; + + if (!old_options || !authdir_mode_bridge(old_options)) { + rep_hist_desc_stats_init(now); + print_notice = 1; + } + if (print_notice) + *print_notice_out = 1; + } + + /* If we used to have statistics enabled but we just disabled them, + stop gathering them. */ + if (old_options && authdir_mode_bridge(old_options) && + !authdir_mode_bridge(options)) + rep_hist_desc_stats_term(); + + return 0; +} diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h new file mode 100644 index 0000000000..655ab0a7fa --- /dev/null +++ b/src/feature/dirauth/dirauth_config.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file dirauth_config.h + * @brief Header for feature/dirauth/dirauth_config.c + **/ + +#ifndef TOR_FEATURE_DIRAUTH_DIRAUTH_CONFIG_H +#define TOR_FEATURE_DIRAUTH_DIRAUTH_CONFIG_H + +typedef struct or_options_t or_options_t; + +#ifdef HAVE_MODULE_DIRAUTH + +#include "lib/cc/torint.h" + +int options_validate_dirauth_mode(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_dirauth_bandwidth(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_dirauth_schedule(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_dirauth_testing(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_act_dirauth(const or_options_t *old_options); +int options_act_dirauth_mtbf(const or_options_t *old_options); +int options_act_dirauth_stats(const or_options_t *old_options, + bool *print_notice_out); + +#else /* !defined(HAVE_MODULE_DIRAUTH) */ + +/** When tor is compiled with the dirauth module disabled, it can't be + * configured as a directory authority. + * + * Returns -1 and sets msg to a newly allocated string, if AuthoritativeDir + * is set in options. Otherwise returns 0. */ +static inline int +options_validate_dirauth_mode(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + /* Only check the primary option for now, #29211 will disable more + * options. */ + if (options->AuthoritativeDir) { + /* REJECT() this configuration */ + *msg = tor_strdup("This tor was built with dirauth mode disabled. " + "It can not be configured with AuthoritativeDir 1."); + return -1; + } + + return 0; +} + +#define options_validate_dirauth_bandwidth(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_dirauth_schedule(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_dirauth_testing(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_dirauth_testing(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) + +#define options_act_dirauth(old_options) \ + (((void)(old_options)),0) +#define options_act_dirauth_mtbf(old_options) \ + (((void)(old_options)),0) + +#define options_act_dirauth_stats(old_options, print_notice_out) \ + (((void)(old_options)),((void)(print_notice_out)),0) + +#endif /* defined(HAVE_MODULE_DIRAUTH) */ + +#endif /* !defined(TOR_FEATURE_DIRAUTH_DIRAUTH_CONFIG_H) */ diff --git a/src/feature/dirauth/dirauth_periodic.c b/src/feature/dirauth/dirauth_periodic.c index 02727d61b4..96194b4677 100644 --- a/src/feature/dirauth/dirauth_periodic.c +++ b/src/feature/dirauth/dirauth_periodic.c @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dirauth_periodic.c + * @brief Peridoic events for directory authorities. + **/ + #include "core/or/or.h" #include "app/config/or_options_st.h" @@ -18,11 +23,13 @@ #include "core/mainloop/periodic.h" +#ifndef COCCI #define DECLARE_EVENT(name, roles, flags) \ static periodic_event_item_t name ## _event = \ PERIODIC_EVENT(name, \ PERIODIC_EVENT_ROLE_##roles, \ flags) +#endif /* !defined(COCCI) */ #define FL(name) (PERIODIC_EVENT_FLAG_##name) diff --git a/src/feature/dirauth/dirauth_periodic.h b/src/feature/dirauth/dirauth_periodic.h index 866fbd35de..de4a799d37 100644 --- a/src/feature/dirauth/dirauth_periodic.h +++ b/src/feature/dirauth/dirauth_periodic.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dirauth_periodic.h + * @brief Header for dirauth_periodic.c + **/ + #ifndef DIRVOTE_PERIODIC_H #define DIRVOTE_PERIODIC_H diff --git a/src/feature/dirauth/dirauth_sys.c b/src/feature/dirauth/dirauth_sys.c index e38d391300..090e9129f2 100644 --- a/src/feature/dirauth/dirauth_sys.c +++ b/src/feature/dirauth/dirauth_sys.c @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dirauth_sys.c + * @brief Directory authority subsystem declarations + **/ + #include "core/or/or.h" #include "feature/dirauth/bwauth.h" diff --git a/src/feature/dirauth/dirauth_sys.h b/src/feature/dirauth/dirauth_sys.h index 4e9b6a2ab4..2d5a0cb3e7 100644 --- a/src/feature/dirauth/dirauth_sys.h +++ b/src/feature/dirauth/dirauth_sys.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dirauth_sys.h + * @brief Header for dirauth_sys.c + **/ + #ifndef DIRAUTH_SYS_H #define DIRAUTH_SYS_H diff --git a/src/feature/dirauth/feature_dirauth.dox b/src/feature/dirauth/feature_dirauth.dox new file mode 100644 index 0000000000..9ee2d04589 --- /dev/null +++ b/src/feature/dirauth/feature_dirauth.dox @@ -0,0 +1,11 @@ +/** +@dir /feature/dirauth +@brief feature/dirauth: Directory authority implementation. + +This module handles running Tor as a directory authority. + +The directory protocol is specified in +[dir-spec.txt](https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt). + + +**/ diff --git a/src/feature/dirauth/keypin.h b/src/feature/dirauth/keypin.h index 1de84f6d4a..d77f6fc5f3 100644 --- a/src/feature/dirauth/keypin.h +++ b/src/feature/dirauth/keypin.h @@ -1,6 +1,11 @@ /* Copyright (c) 2014-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file keypin.h + * @brief Header for keypin.c + **/ + #ifndef TOR_KEYPIN_H #define TOR_KEYPIN_H diff --git a/src/feature/dirauth/ns_detached_signatures_st.h b/src/feature/dirauth/ns_detached_signatures_st.h index 61d20b7525..7c50cda40a 100644 --- a/src/feature/dirauth/ns_detached_signatures_st.h +++ b/src/feature/dirauth/ns_detached_signatures_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file ns_detached_signatures_st.h + * @brief Detached consensus signatures structure. + **/ + #ifndef NS_DETACHED_SIGNATURES_ST_H #define NS_DETACHED_SIGNATURES_ST_H @@ -19,4 +24,3 @@ struct ns_detached_signatures_t { }; #endif /* !defined(NS_DETACHED_SIGNATURES_ST_H) */ - diff --git a/src/feature/dirauth/shared_random.c b/src/feature/dirauth/shared_random.c index a45f0a29c3..ebc595e517 100644 --- a/src/feature/dirauth/shared_random.c +++ b/src/feature/dirauth/shared_random.c @@ -90,7 +90,7 @@ #include "core/or/or.h" #include "feature/dirauth/shared_random.h" #include "app/config/config.h" -#include "lib/confmgt/confparse.h" +#include "lib/confmgt/confmgt.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/nodelist/networkstatus.h" @@ -107,19 +107,19 @@ #include "feature/nodelist/authority_cert_st.h" #include "feature/nodelist/networkstatus_st.h" -/* String prefix of shared random values in votes/consensuses. */ +/** String prefix of shared random values in votes/consensuses. */ static const char previous_srv_str[] = "shared-rand-previous-value"; static const char current_srv_str[] = "shared-rand-current-value"; static const char commit_ns_str[] = "shared-rand-commit"; static const char sr_flag_ns_str[] = "shared-rand-participate"; -/* The value of the consensus param AuthDirNumSRVAgreements found in the +/** The value of the consensus param AuthDirNumSRVAgreements found in the * vote. This is set once the consensus creation subsystem requests the * SRV(s) that should be put in the consensus. We use this value to decide * if we keep or not an SRV. */ static int32_t num_srv_agreements_from_vote; -/* Return a heap allocated copy of the SRV <b>orig</b>. */ +/** Return a heap allocated copy of the SRV <b>orig</b>. */ sr_srv_t * sr_srv_dup(const sr_srv_t *orig) { @@ -135,7 +135,7 @@ sr_srv_dup(const sr_srv_t *orig) return duplicate; } -/* Allocate a new commit object and initializing it with <b>rsa_identity</b> +/** Allocate a new commit object and initializing it with <b>rsa_identity</b> * that MUST be provided. The digest algorithm is set to the default one * that is supported. The rest is uninitialized. This never returns NULL. */ static sr_commit_t * @@ -153,7 +153,7 @@ commit_new(const char *rsa_identity) return commit; } -/* Issue a log message describing <b>commit</b>. */ +/** Issue a log message describing <b>commit</b>. */ static void commit_log(const sr_commit_t *commit) { @@ -166,7 +166,7 @@ commit_log(const sr_commit_t *commit) commit->reveal_ts, safe_str(commit->encoded_reveal)); } -/* Make sure that the commitment and reveal information in <b>commit</b> +/** Make sure that the commitment and reveal information in <b>commit</b> * match. If they match return 0, return -1 otherwise. This function MUST be * used everytime we receive a new reveal value. Furthermore, the commit * object MUST have a reveal value and the hash of the reveal value. */ @@ -220,7 +220,7 @@ verify_commit_and_reveal(const sr_commit_t *commit) return -1; } -/* Return true iff the commit contains an encoded reveal value. */ +/** Return true iff the commit contains an encoded reveal value. */ STATIC int commit_has_reveal_value(const sr_commit_t *commit) { @@ -228,7 +228,7 @@ commit_has_reveal_value(const sr_commit_t *commit) sizeof(commit->encoded_reveal)); } -/* Parse the encoded commit. The format is: +/** Parse the encoded commit. The format is: * base64-encode( TIMESTAMP || H(REVEAL) ) * * If successfully decoded and parsed, commit is updated and 0 is returned. @@ -283,7 +283,7 @@ commit_decode(const char *encoded, sr_commit_t *commit) return -1; } -/* Parse the b64 blob at <b>encoded</b> containing reveal information and +/** Parse the b64 blob at <b>encoded</b> containing reveal information and * store the information in-place in <b>commit</b>. Return 0 on success else * a negative value. */ STATIC int @@ -333,7 +333,7 @@ reveal_decode(const char *encoded, sr_commit_t *commit) return -1; } -/* Encode a reveal element using a given commit object to dst which is a +/** Encode a reveal element using a given commit object to dst which is a * buffer large enough to put the base64-encoded reveal construction. The * format is as follow: * REVEAL = base64-encode( TIMESTAMP || H(RN) ) @@ -362,7 +362,7 @@ reveal_encode(const sr_commit_t *commit, char *dst, size_t len) return ret; } -/* Encode the given commit object to dst which is a buffer large enough to +/** Encode the given commit object to dst which is a buffer large enough to * put the base64-encoded commit. The format is as follow: * COMMIT = base64-encode( TIMESTAMP || H(H(RN)) ) * Return base64 encoded length on success else a negative value. @@ -388,14 +388,14 @@ commit_encode(const sr_commit_t *commit, char *dst, size_t len) return base64_encode(dst, len, buf, sizeof(buf), 0); } -/* Cleanup both our global state and disk state. */ +/** Cleanup both our global state and disk state. */ static void sr_cleanup(void) { sr_state_free_all(); } -/* Using <b>commit</b>, return a newly allocated string containing the commit +/** Using <b>commit</b>, return a newly allocated string containing the commit * information that should be used during SRV calculation. It's the caller * responsibility to free the memory. Return NULL if this is not a commit to be * used for SRV calculation. */ @@ -414,7 +414,7 @@ get_srv_element_from_commit(const sr_commit_t *commit) return element; } -/* Return a srv object that is built with the construction: +/** Return a srv object that is built with the construction: * SRV = SHA3-256("shared-random" | INT_8(reveal_num) | * INT_4(version) | HASHED_REVEALS | previous_SRV) * This function cannot fail. */ @@ -456,7 +456,7 @@ generate_srv(const char *hashed_reveals, uint64_t reveal_num, return srv; } -/* Compare reveal values and return the result. This should exclusively be +/** Compare reveal values and return the result. This should exclusively be * used by smartlist_sort(). */ static int compare_reveal_(const void **_a, const void **_b) @@ -466,7 +466,7 @@ compare_reveal_(const void **_a, const void **_b) sizeof(a->hashed_reveal)); } -/* Given <b>commit</b> give the line that we should place in our votes. +/** Given <b>commit</b> give the line that we should place in our votes. * It's the responsibility of the caller to free the string. */ static char * get_vote_line_from_commit(const sr_commit_t *commit, sr_phase_t phase) @@ -506,7 +506,7 @@ get_vote_line_from_commit(const sr_commit_t *commit, sr_phase_t phase) return vote_line; } -/* Return a heap allocated string that contains the given <b>srv</b> string +/** Return a heap allocated string that contains the given <b>srv</b> string * representation formatted for a networkstatus document using the * <b>key</b> as the start of the line. This doesn't return NULL. */ static char * @@ -524,7 +524,7 @@ srv_to_ns_string(const sr_srv_t *srv, const char *key) return srv_str; } -/* Given the previous SRV and the current SRV, return a heap allocated +/** Given the previous SRV and the current SRV, return a heap allocated * string with their data that could be put in a vote or a consensus. Caller * must free the returned string. Return NULL if no SRVs were provided. */ static char * @@ -557,7 +557,7 @@ get_ns_str_from_sr_values(const sr_srv_t *prev_srv, const sr_srv_t *cur_srv) return srv_str; } -/* Return 1 iff the two commits have the same commitment values. This +/** Return 1 iff the two commits have the same commitment values. This * function does not care about reveal values. */ STATIC int commitments_are_the_same(const sr_commit_t *commit_one, @@ -572,7 +572,7 @@ commitments_are_the_same(const sr_commit_t *commit_one, return 1; } -/* We just received a commit from the vote of authority with +/** We just received a commit from the vote of authority with * <b>identity_digest</b>. Return 1 if this commit is authorititative that * is, it belongs to the authority that voted it. Else return 0 if not. */ STATIC int @@ -586,7 +586,7 @@ commit_is_authoritative(const sr_commit_t *commit, sizeof(commit->rsa_identity)); } -/* Decide if the newly received <b>commit</b> should be kept depending on +/** Decide if the newly received <b>commit</b> should be kept depending on * the current phase and state of the protocol. The <b>voter_key</b> is the * RSA identity key fingerprint of the authority's vote from which the * commit comes from. The <b>phase</b> is the phase we should be validating @@ -705,7 +705,7 @@ should_keep_commit(const sr_commit_t *commit, const char *voter_key, return 0; } -/* We are in reveal phase and we found a valid and verified <b>commit</b> in +/** We are in reveal phase and we found a valid and verified <b>commit</b> in * a vote that contains reveal values that we could use. Update the commit * we have in our state. Never call this with an unverified commit. */ STATIC void @@ -726,7 +726,7 @@ save_commit_during_reveal_phase(const sr_commit_t *commit) sr_state_copy_reveal_info(saved_commit, commit); } -/* Save <b>commit</b> to our persistent state. Depending on the current +/** Save <b>commit</b> to our persistent state. Depending on the current * phase, different actions are taken. Steals reference of <b>commit</b>. * The commit object MUST be valid and verified before adding it to the * state. */ @@ -751,7 +751,7 @@ save_commit_to_state(sr_commit_t *commit) } } -/* Return 1 if we should we keep an SRV voted by <b>n_agreements</b> auths. +/** Return 1 if we should we keep an SRV voted by <b>n_agreements</b> auths. * Return 0 if we should ignore it. */ static int should_keep_srv(int n_agreements) @@ -781,7 +781,7 @@ should_keep_srv(int n_agreements) return 1; } -/* Helper: compare two DIGEST256_LEN digests. */ +/** Helper: compare two DIGEST256_LEN digests. */ static int compare_srvs_(const void **_a, const void **_b) { @@ -789,7 +789,7 @@ compare_srvs_(const void **_a, const void **_b) return tor_memcmp(a->value, b->value, sizeof(a->value)); } -/* Return the most frequent member of the sorted list of DIGEST256_LEN +/** Return the most frequent member of the sorted list of DIGEST256_LEN * digests in <b>sl</b> with the count of that most frequent element. */ static sr_srv_t * smartlist_get_most_frequent_srv(const smartlist_t *sl, int *count_out) @@ -806,7 +806,7 @@ compare_srv_(const void **_a, const void **_b) sizeof(a->value)); } -/* Using a list of <b>votes</b>, return the SRV object from them that has +/** Using a list of <b>votes</b>, return the SRV object from them that has * been voted by the majority of dirauths. If <b>current</b> is set, we look * for the current SRV value else the previous one. The returned pointer is * an object located inside a vote. NULL is returned if no appropriate value @@ -868,7 +868,7 @@ get_majority_srv_from_votes(const smartlist_t *votes, int current) return the_srv; } -/* Free a commit object. */ +/** Free a commit object. */ void sr_commit_free_(sr_commit_t *commit) { @@ -880,7 +880,7 @@ sr_commit_free_(sr_commit_t *commit) tor_free(commit); } -/* Generate the commitment/reveal value for the protocol run starting at +/** Generate the commitment/reveal value for the protocol run starting at * <b>timestamp</b>. <b>my_rsa_cert</b> is our authority RSA certificate. */ sr_commit_t * sr_generate_our_commit(time_t timestamp, const authority_cert_t *my_rsa_cert) @@ -937,7 +937,8 @@ sr_generate_our_commit(time_t timestamp, const authority_cert_t *my_rsa_cert) return NULL; } -/* Compute the shared random value based on the active commits in our state. */ +/** Compute the shared random value based on the active commits in our + * state. */ void sr_compute_srv(void) { @@ -1010,7 +1011,7 @@ sr_compute_srv(void) tor_free(reveals); } -/* Parse a commit from a vote or from our disk state and return a newly +/** Parse a commit from a vote or from our disk state and return a newly * allocated commit object. NULL is returned on error. * * The commit's data is in <b>args</b> and the order matters very much: @@ -1082,7 +1083,7 @@ sr_parse_commit(const smartlist_t *args) return NULL; } -/* Called when we are done parsing a vote by <b>voter_key</b> that might +/** Called when we are done parsing a vote by <b>voter_key</b> that might * contain some useful <b>commits</b>. Find if any of them should be kept * and update our state accordingly. Once done, the list of commitments will * be empty. */ @@ -1120,7 +1121,7 @@ sr_handle_received_commits(smartlist_t *commits, crypto_pk_t *voter_key) } SMARTLIST_FOREACH_END(commit); } -/* Return a heap-allocated string containing commits that should be put in +/** Return a heap-allocated string containing commits that should be put in * the votes. It's the responsibility of the caller to free the string. * This always return a valid string, either empty or with line(s). */ char * @@ -1178,7 +1179,7 @@ sr_get_string_for_vote(void) return vote_str; } -/* Return a heap-allocated string that should be put in the consensus and +/** Return a heap-allocated string that should be put in the consensus and * contains the shared randomness values. It's the responsibility of the * caller to free the string. NULL is returned if no SRV(s) available. * @@ -1222,7 +1223,7 @@ sr_get_string_for_consensus(const smartlist_t *votes, return NULL; } -/* We just computed a new <b>consensus</b>. Update our state with the SRVs +/** We just computed a new <b>consensus</b>. Update our state with the SRVs * from the consensus (might be NULL as well). Register the SRVs in our SR * state and prepare for the upcoming protocol round. */ void @@ -1261,7 +1262,7 @@ sr_act_post_consensus(const networkstatus_t *consensus) sr_state_update(voting_schedule_get_next_valid_after_time()); } -/* Initialize shared random subsystem. This MUST be called early in the boot +/** Initialize shared random subsystem. This MUST be called early in the boot * process of tor. Return 0 on success else -1 on error. */ int sr_init(int save_to_disk) @@ -1269,7 +1270,7 @@ sr_init(int save_to_disk) return sr_state_init(save_to_disk, 1); } -/* Save our state to disk and cleanup everything. */ +/** Save our state to disk and cleanup everything. */ void sr_save_and_cleanup(void) { @@ -1279,7 +1280,7 @@ sr_save_and_cleanup(void) #ifdef TOR_UNIT_TESTS -/* Set the global value of number of SRV agreements so the test can play +/** Set the global value of number of SRV agreements so the test can play * along by calling specific functions that don't parse the votes prior for * the AuthDirNumSRVAgreements value. */ void diff --git a/src/feature/dirauth/shared_random.h b/src/feature/dirauth/shared_random.h index 7ff9f15512..b3b4b3a2aa 100644 --- a/src/feature/dirauth/shared_random.h +++ b/src/feature/dirauth/shared_random.h @@ -4,83 +4,85 @@ #ifndef TOR_SHARED_RANDOM_H #define TOR_SHARED_RANDOM_H -/* - * This file contains ABI/API of the shared random protocol defined in +/** + * \file shared_random.h + * + * \brief This file contains ABI/API of the shared random protocol defined in * proposal #250. Every public functions and data structure are namespaced * with "sr_" which stands for shared random. */ #include "core/or/or.h" -/* Protocol version */ +/** Protocol version */ #define SR_PROTO_VERSION 1 -/* Default digest algorithm. */ +/** Default digest algorithm. */ #define SR_DIGEST_ALG DIGEST_SHA3_256 -/* Invariant token in the SRV calculation. */ +/** Invariant token in the SRV calculation. */ #define SR_SRV_TOKEN "shared-random" -/* Don't count the NUL terminated byte even though the TOKEN has it. */ +/** Don't count the NUL terminated byte even though the TOKEN has it. */ #define SR_SRV_TOKEN_LEN (sizeof(SR_SRV_TOKEN) - 1) -/* Length of the random number (in bytes). */ +/** Length of the random number (in bytes). */ #define SR_RANDOM_NUMBER_LEN 32 -/* Size of a decoded commit value in a vote or state. It's a hash and a +/** Size of a decoded commit value in a vote or state. It's a hash and a * timestamp. It adds up to 40 bytes. */ #define SR_COMMIT_LEN (sizeof(uint64_t) + DIGEST256_LEN) -/* Size of a decoded reveal value from a vote or state. It's a 64 bit +/** Size of a decoded reveal value from a vote or state. It's a 64 bit * timestamp and the hashed random number. This adds up to 40 bytes. */ #define SR_REVEAL_LEN (sizeof(uint64_t) + DIGEST256_LEN) -/* Size of SRV message length. The construction is has follow: +/** Size of SRV message length. The construction is has follow: * "shared-random" | INT_8(reveal_num) | INT_4(version) | PREV_SRV */ #define SR_SRV_MSG_LEN \ (SR_SRV_TOKEN_LEN + sizeof(uint64_t) + sizeof(uint32_t) + DIGEST256_LEN) -/* Length of base64 encoded commit NOT including the NUL terminated byte. +/** Length of base64 encoded commit NOT including the NUL terminated byte. * Formula is taken from base64_encode_size. This adds up to 56 bytes. */ #define SR_COMMIT_BASE64_LEN (BASE64_LEN(SR_COMMIT_LEN)) -/* Length of base64 encoded reveal NOT including the NUL terminated byte. +/** Length of base64 encoded reveal NOT including the NUL terminated byte. * Formula is taken from base64_encode_size. This adds up to 56 bytes. */ #define SR_REVEAL_BASE64_LEN (BASE64_LEN(SR_REVEAL_LEN)) -/* Length of base64 encoded shared random value. It's 32 bytes long so 44 +/** Length of base64 encoded shared random value. It's 32 bytes long so 44 * bytes from the base64_encode_size formula. That includes the '=' * character at the end. */ #define SR_SRV_VALUE_BASE64_LEN (BASE64_LEN(DIGEST256_LEN)) -/* Assert if commit valid flag is not set. */ +/** Assert if commit valid flag is not set. */ #define ASSERT_COMMIT_VALID(c) tor_assert((c)->valid) -/* Protocol phase. */ +/** Protocol phase. */ typedef enum { - /* Commitment phase */ + /** Commitment phase */ SR_PHASE_COMMIT = 1, - /* Reveal phase */ + /** Reveal phase */ SR_PHASE_REVEAL = 2, } sr_phase_t; -/* A shared random value (SRV). */ +/** A shared random value (SRV). */ typedef struct sr_srv_t { - /* The number of reveal values used to derive this SRV. */ + /** The number of reveal values used to derive this SRV. */ uint64_t num_reveals; - /* The actual value. This is the stored result of SHA3-256. */ + /** The actual value. This is the stored result of SHA3-256. */ uint8_t value[DIGEST256_LEN]; } sr_srv_t; -/* A commit (either ours or from another authority). */ +/** A commit (either ours or from another authority). */ typedef struct sr_commit_t { - /* Hashing algorithm used. */ + /** Hashing algorithm used. */ digest_algorithm_t alg; - /* Indicate if this commit has been verified thus valid. */ + /** Indicate if this commit has been verified thus valid. */ unsigned int valid:1; /* Commit owner info */ - /* The RSA identity key of the authority and its base16 representation, + /** The RSA identity key of the authority and its base16 representation, * which includes the NUL terminated byte. */ char rsa_identity[DIGEST_LEN]; char rsa_identity_hex[HEX_DIGEST_LEN + 1]; /* Commitment information */ - /* Timestamp of reveal. Correspond to TIMESTAMP. */ + /** Timestamp of reveal. Correspond to TIMESTAMP. */ uint64_t reveal_ts; /* H(REVEAL) as found in COMMIT message. */ char hashed_reveal[DIGEST256_LEN]; @@ -89,13 +91,13 @@ typedef struct sr_commit_t { /* Reveal information */ - /* H(RN) which is what we used as the random value for this commit. We + /** H(RN) which is what we used as the random value for this commit. We * don't use the raw bytes since those are sent on the network thus * avoiding possible information leaks of our PRNG. */ uint8_t random_number[SR_RANDOM_NUMBER_LEN]; - /* Timestamp of commit. Correspond to TIMESTAMP. */ + /** Timestamp of commit. Correspond to TIMESTAMP. */ uint64_t commit_ts; - /* This is the whole reveal message. We use it during verification */ + /** This is the whole reveal message. We use it during verification */ char encoded_reveal[SR_REVEAL_BASE64_LEN + 1]; } sr_commit_t; @@ -191,4 +193,3 @@ void set_num_srv_agreements(int32_t value); #endif /* TOR_UNIT_TESTS */ #endif /* !defined(TOR_SHARED_RANDOM_H) */ - diff --git a/src/feature/dirauth/shared_random_state.c b/src/feature/dirauth/shared_random_state.c index 76befb0f5f..759b3b8104 100644 --- a/src/feature/dirauth/shared_random_state.c +++ b/src/feature/dirauth/shared_random_state.c @@ -12,7 +12,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "lib/confmgt/confparse.h" +#include "lib/confmgt/confmgt.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/dirauth/dirvote.h" #include "feature/nodelist/networkstatus.h" @@ -26,18 +26,18 @@ #include "app/config/or_state_st.h" -/* Default filename of the shared random state on disk. */ +/** Default filename of the shared random state on disk. */ static const char default_fname[] = "sr-state"; -/* String representation of a protocol phase. */ +/** String representation of a protocol phase. */ static const char *phase_str[] = { "unknown", "commit", "reveal" }; -/* Our shared random protocol state. There is only one possible state per +/** Our shared random protocol state. There is only one possible state per * protocol run so this is the global state which is reset at every run once * the shared random value has been computed. */ static sr_state_t *sr_state = NULL; -/* Representation of our persistent state on disk. The sr_state above +/** Representation of our persistent state on disk. The sr_state above * contains the data parsed from this state. When we save to disk, we * translate the sr_state to this sr_disk_state. */ static sr_disk_state_t *sr_disk_state = NULL; @@ -56,14 +56,10 @@ DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t); #define V(member,conftype,initvalue) \ VAR(#member, conftype, member, initvalue) -/* Our persistent state magic number. */ +/** Our persistent state magic number. */ #define SR_DISK_STATE_MAGIC 0x98AB1254 -static int -disk_state_validate_cb(void *old_state, void *state, void *default_state, - int from_setconf, char **msg); - -/* Array of variables that are saved to disk as a persistent state. */ +/** Array of variables that are saved to disk as a persistent state. */ static const config_var_t state_vars[] = { V(Version, POSINT, "0"), V(TorVersion, STRING, NULL), @@ -78,7 +74,7 @@ static const config_var_t state_vars[] = { END_OF_CONFIG_VARS }; -/* "Extra" variable in the state that receives lines we can't parse. This +/** "Extra" variable in the state that receives lines we can't parse. This * lets us preserve options from versions of Tor newer than us. */ static const struct_member_t state_extra_var = { .name = "__extra", @@ -86,24 +82,20 @@ static const struct_member_t state_extra_var = { .offset = offsetof(sr_disk_state_t, ExtraLines), }; -/* Configuration format of sr_disk_state_t. */ +/** Configuration format of sr_disk_state_t. */ static const config_format_t state_format = { - sizeof(sr_disk_state_t), - { + .size = sizeof(sr_disk_state_t), + .magic = { "sr_disk_state_t", SR_DISK_STATE_MAGIC, offsetof(sr_disk_state_t, magic_), }, - NULL, - NULL, - state_vars, - disk_state_validate_cb, - NULL, - &state_extra_var, - -1, + .vars = state_vars, + .extra = &state_extra_var, + .config_suite_offset = -1, }; -/* Global configuration manager for the shared-random state file */ +/** Global configuration manager for the shared-random state file */ static config_mgr_t *shared_random_state_mgr = NULL; /** Return the configuration manager for the shared-random state file. */ @@ -119,7 +111,7 @@ get_srs_mgr(void) static void state_query_del_(sr_state_object_t obj_type, void *data); -/* Return a string representation of a protocol phase. */ +/** Return a string representation of a protocol phase. */ STATIC const char * get_phase_str(sr_phase_t phase) { @@ -137,7 +129,7 @@ get_phase_str(sr_phase_t phase) return the_string; } -/* Return the time we should expire the state file created at <b>now</b>. +/** Return the time we should expire the state file created at <b>now</b>. * We expire the state file in the beginning of the next protocol run. */ STATIC time_t get_state_valid_until_time(time_t now) @@ -168,7 +160,7 @@ get_state_valid_until_time(time_t now) return valid_until; } -/* Given the consensus 'valid-after' time, return the protocol phase we should +/** Given the consensus 'valid-after' time, return the protocol phase we should * be in. */ STATIC sr_phase_t get_sr_protocol_phase(time_t valid_after) @@ -188,7 +180,7 @@ get_sr_protocol_phase(time_t valid_after) } } -/* Add the given <b>commit</b> to <b>state</b>. It MUST be a valid commit +/** Add the given <b>commit</b> to <b>state</b>. It MUST be a valid commit * and there shouldn't be a commit from the same authority in the state * already else verification hasn't been done prior. This takes ownership of * the commit once in our state. */ @@ -213,7 +205,7 @@ commit_add_to_state(sr_commit_t *commit, sr_state_t *state) } } -/* Helper: deallocate a commit object. (Used with digestmap_free(), which +/** Helper: deallocate a commit object. (Used with digestmap_free(), which * requires a function pointer whose argument is void *). */ static void commit_free_(void *p) @@ -224,7 +216,7 @@ commit_free_(void *p) #define state_free(val) \ FREE_AND_NULL(sr_state_t, state_free_, (val)) -/* Free a state that was allocated with state_new(). */ +/** Free a state that was allocated with state_new(). */ static void state_free_(sr_state_t *state) { @@ -238,7 +230,7 @@ state_free_(sr_state_t *state) tor_free(state); } -/* Allocate an sr_state_t object and returns it. If no <b>fname</b>, the +/** Allocate an sr_state_t object and returns it. If no <b>fname</b>, the * default file name is used. This function does NOT initialize the state * timestamp, phase or shared random value. NULL is never returned. */ static sr_state_t * @@ -257,7 +249,7 @@ state_new(const char *fname, time_t now) return new_state; } -/* Set our global state pointer with the one given. */ +/** Set our global state pointer with the one given. */ static void state_set(sr_state_t *state) { @@ -271,7 +263,7 @@ state_set(sr_state_t *state) #define disk_state_free(val) \ FREE_AND_NULL(sr_disk_state_t, disk_state_free_, (val)) -/* Free an allocated disk state. */ +/** Free an allocated disk state. */ static void disk_state_free_(sr_disk_state_t *state) { @@ -281,7 +273,7 @@ disk_state_free_(sr_disk_state_t *state) config_free(get_srs_mgr(), state); } -/* Allocate a new disk state, initialize it and return it. */ +/** Allocate a new disk state, initialize it and return it. */ static sr_disk_state_t * disk_state_new(time_t now) { @@ -297,7 +289,7 @@ disk_state_new(time_t now) return new_state; } -/* Set our global disk state with the given state. */ +/** Set our global disk state with the given state. */ static void disk_state_set(sr_disk_state_t *state) { @@ -308,7 +300,7 @@ disk_state_set(sr_disk_state_t *state) sr_disk_state = state; } -/* Return -1 if the disk state is invalid (something in there that we can't or +/** Return -1 if the disk state is invalid (something in there that we can't or * shouldn't use). Return 0 if everything checks out. */ static int disk_state_validate(const sr_disk_state_t *state) @@ -343,25 +335,7 @@ disk_state_validate(const sr_disk_state_t *state) return -1; } -/* Validate the disk state (NOP for now). */ -static int -disk_state_validate_cb(void *old_state, void *state, void *default_state, - int from_setconf, char **msg) -{ - /* We don't use these; only options do. */ - (void) from_setconf; - (void) default_state; - (void) old_state; - - /* This is called by config_dump which is just before we are about to - * write it to disk. At that point, our global memory state has been - * copied to the disk state so it's fair to assume it's trustable. */ - (void) state; - (void) msg; - return 0; -} - -/* Parse the Commit line(s) in the disk state and translate them to the +/** Parse the Commit line(s) in the disk state and translate them to the * the memory state. Return 0 on success else -1 on error. */ static int disk_state_parse_commits(sr_state_t *state, @@ -416,7 +390,7 @@ disk_state_parse_commits(sr_state_t *state, return -1; } -/* Parse a share random value line from the disk state and save it to dst +/** Parse a share random value line from the disk state and save it to dst * which is an allocated srv object. Return 0 on success else -1. */ static int disk_state_parse_srv(const char *value, sr_srv_t *dst) @@ -451,7 +425,7 @@ disk_state_parse_srv(const char *value, sr_srv_t *dst) return ret; } -/* Parse both SharedRandCurrentValue and SharedRandPreviousValue line from +/** Parse both SharedRandCurrentValue and SharedRandPreviousValue line from * the state. Return 0 on success else -1. */ static int disk_state_parse_sr_values(sr_state_t *state, @@ -502,7 +476,7 @@ disk_state_parse_sr_values(sr_state_t *state, return -1; } -/* Parse the given disk state and set a newly allocated state. On success, +/** Parse the given disk state and set a newly allocated state. On success, * return that state else NULL. */ static sr_state_t * disk_state_parse(const sr_disk_state_t *new_disk_state) @@ -536,7 +510,7 @@ disk_state_parse(const sr_disk_state_t *new_disk_state) return NULL; } -/* From a valid commit object and an allocated config line, set the line's +/** From a valid commit object and an allocated config line, set the line's * value to the state string representation of a commit. */ static void disk_state_put_commit_line(const sr_commit_t *commit, config_line_t *line) @@ -563,7 +537,7 @@ disk_state_put_commit_line(const sr_commit_t *commit, config_line_t *line) } } -/* From a valid srv object and an allocated config line, set the line's +/** From a valid srv object and an allocated config line, set the line's * value to the state string representation of a shared random value. */ static void disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line) @@ -581,7 +555,7 @@ disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line) tor_asprintf(&line->value, "%" PRIu64 " %s", srv->num_reveals, encoded); } -/* Reset disk state that is free allocated memory and zeroed the object. */ +/** Reset disk state that is free allocated memory and zeroed the object. */ static void disk_state_reset(void) { @@ -600,7 +574,7 @@ disk_state_reset(void) sr_disk_state->TorVersion = tor_strdup(get_version()); } -/* Update our disk state based on our global SR state. */ +/** Update our disk state based on our global SR state. */ static void disk_state_update(void) { @@ -644,7 +618,7 @@ disk_state_update(void) } DIGESTMAP_FOREACH_END; } -/* Load state from disk and put it into our disk state. If the state passes +/** Load state from disk and put it into our disk state. If the state passes * validation, our global state will be updated with it. Return 0 on * success. On error, -EINVAL is returned if the state on disk did contained * something malformed or is unreadable. -ENOENT is returned indicating that @@ -662,7 +636,7 @@ disk_state_load_from_disk(void) return ret; } -/* Helper for disk_state_load_from_disk(). */ +/** Helper for disk_state_load_from_disk(). */ STATIC int disk_state_load_from_disk_impl(const char *fname) { @@ -724,7 +698,7 @@ disk_state_load_from_disk_impl(const char *fname) return ret; } -/* Save the disk state to disk but before that update it from the current +/** Save the disk state to disk but before that update it from the current * state so we always have the latest. Return 0 on success else -1. */ static int disk_state_save_to_disk(void) @@ -768,7 +742,7 @@ disk_state_save_to_disk(void) return ret; } -/* Reset our state to prepare for a new protocol run. Once this returns, all +/** Reset our state to prepare for a new protocol run. Once this returns, all * commits in the state will be removed and freed. */ STATIC void reset_state_for_new_protocol_run(time_t valid_after) @@ -789,7 +763,7 @@ reset_state_for_new_protocol_run(time_t valid_after) sr_state_delete_commits(); } -/* This is the first round of the new protocol run starting at +/** This is the first round of the new protocol run starting at * <b>valid_after</b>. Do the necessary housekeeping. */ STATIC void new_protocol_run(time_t valid_after) @@ -823,7 +797,7 @@ new_protocol_run(time_t valid_after) } } -/* Return 1 iff the <b>next_phase</b> is a phase transition from the current +/** Return 1 iff the <b>next_phase</b> is a phase transition from the current * phase that is it's different. */ STATIC int is_phase_transition(sr_phase_t next_phase) @@ -831,7 +805,7 @@ is_phase_transition(sr_phase_t next_phase) return sr_state->phase != next_phase; } -/* Helper function: return a commit using the RSA fingerprint of the +/** Helper function: return a commit using the RSA fingerprint of the * authority or NULL if no such commit is known. */ static sr_commit_t * state_query_get_commit(const char *rsa_fpr) @@ -840,7 +814,7 @@ state_query_get_commit(const char *rsa_fpr) return digestmap_get(sr_state->commits, rsa_fpr); } -/* Helper function: This handles the GET state action using an +/** Helper function: This handles the GET state action using an * <b>obj_type</b> and <b>data</b> needed for the action. */ static void * state_query_get_(sr_state_object_t obj_type, const void *data) @@ -875,7 +849,7 @@ state_query_get_(sr_state_object_t obj_type, const void *data) return obj; } -/* Helper function: This handles the PUT state action using an +/** Helper function: This handles the PUT state action using an * <b>obj_type</b> and <b>data</b> needed for the action. * PUT frees the previous data before replacing it, if needed. */ static void @@ -928,7 +902,7 @@ state_query_put_(sr_state_object_t obj_type, void *data) } } -/* Helper function: This handles the DEL_ALL state action using an +/** Helper function: This handles the DEL_ALL state action using an * <b>obj_type</b> and <b>data</b> needed for the action. */ static void state_query_del_all_(sr_state_object_t obj_type) @@ -957,7 +931,7 @@ state_query_del_all_(sr_state_object_t obj_type) } } -/* Helper function: This handles the DEL state action using an +/** Helper function: This handles the DEL state action using an * <b>obj_type</b> and <b>data</b> needed for the action. */ static void state_query_del_(sr_state_object_t obj_type, void *data) @@ -983,7 +957,7 @@ state_query_del_(sr_state_object_t obj_type, void *data) } } -/* Query state using an <b>action</b> for an object type <b>obj_type</b>. +/** Query state using an <b>action</b> for an object type <b>obj_type</b>. * The <b>data</b> pointer needs to point to an object that the action needs * to use and if anything is required to be returned, it is stored in * <b>out</b>. @@ -1025,7 +999,7 @@ state_query(sr_state_action_t action, sr_state_object_t obj_type, } } -/* Delete the current SRV value from the state freeing it and the value is set +/** Delete the current SRV value from the state freeing it and the value is set * to NULL meaning empty. */ STATIC void state_del_current_srv(void) @@ -1033,7 +1007,7 @@ state_del_current_srv(void) state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_CURSRV, NULL, NULL); } -/* Delete the previous SRV value from the state freeing it and the value is +/** Delete the previous SRV value from the state freeing it and the value is * set to NULL meaning empty. */ STATIC void state_del_previous_srv(void) @@ -1041,7 +1015,7 @@ state_del_previous_srv(void) state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_PREVSRV, NULL, NULL); } -/* Rotate SRV value by setting the previous SRV to the current SRV, and +/** Rotate SRV value by setting the previous SRV to the current SRV, and * clearing the current SRV. */ STATIC void state_rotate_srv(void) @@ -1054,7 +1028,7 @@ state_rotate_srv(void) sr_state_set_current_srv(NULL); } -/* Set valid after time in the our state. */ +/** Set valid after time in the our state. */ void sr_state_set_valid_after(time_t valid_after) { @@ -1062,7 +1036,7 @@ sr_state_set_valid_after(time_t valid_after) (void *) &valid_after, NULL); } -/* Return the phase we are currently in according to our state. */ +/** Return the phase we are currently in according to our state. */ sr_phase_t sr_state_get_phase(void) { @@ -1071,7 +1045,7 @@ sr_state_get_phase(void) return *(sr_phase_t *) ptr; } -/* Return the previous SRV value from our state. Value CAN be NULL. +/** Return the previous SRV value from our state. Value CAN be NULL. * The state object owns the SRV, so the calling code should not free the SRV. * Use sr_srv_dup() if you want to keep a copy of the SRV. */ const sr_srv_t * @@ -1083,7 +1057,7 @@ sr_state_get_previous_srv(void) return srv; } -/* Set the current SRV value from our state. Value CAN be NULL. The srv +/** Set the current SRV value from our state. Value CAN be NULL. The srv * object ownership is transferred to the state object. */ void sr_state_set_previous_srv(const sr_srv_t *srv) @@ -1092,7 +1066,7 @@ sr_state_set_previous_srv(const sr_srv_t *srv) NULL); } -/* Return the current SRV value from our state. Value CAN be NULL. +/** Return the current SRV value from our state. Value CAN be NULL. * The state object owns the SRV, so the calling code should not free the SRV. * Use sr_srv_dup() if you want to keep a copy of the SRV. */ const sr_srv_t * @@ -1104,7 +1078,7 @@ sr_state_get_current_srv(void) return srv; } -/* Set the current SRV value from our state. Value CAN be NULL. The srv +/** Set the current SRV value from our state. Value CAN be NULL. The srv * object ownership is transferred to the state object. */ void sr_state_set_current_srv(const sr_srv_t *srv) @@ -1113,7 +1087,7 @@ sr_state_set_current_srv(const sr_srv_t *srv) NULL); } -/* Clean all the SRVs in our state. */ +/** Clean all the SRVs in our state. */ void sr_state_clean_srvs(void) { @@ -1122,7 +1096,7 @@ sr_state_clean_srvs(void) state_del_current_srv(); } -/* Return a pointer to the commits map from our state. CANNOT be NULL. */ +/** Return a pointer to the commits map from our state. CANNOT be NULL. */ digestmap_t * sr_state_get_commits(void) { @@ -1133,7 +1107,7 @@ sr_state_get_commits(void) return commits; } -/* Update the current SR state as needed for the upcoming voting round at +/** Update the current SR state as needed for the upcoming voting round at * <b>valid_after</b>. */ void sr_state_update(time_t valid_after) @@ -1197,7 +1171,7 @@ sr_state_update(time_t valid_after) } } -/* Return commit object from the given authority digest <b>rsa_identity</b>. +/** Return commit object from the given authority digest <b>rsa_identity</b>. * Return NULL if not found. */ sr_commit_t * sr_state_get_commit(const char *rsa_identity) @@ -1211,7 +1185,7 @@ sr_state_get_commit(const char *rsa_identity) return commit; } -/* Add <b>commit</b> to the permanent state. The commit object ownership is +/** Add <b>commit</b> to the permanent state. The commit object ownership is * transferred to the state so the caller MUST not free it. */ void sr_state_add_commit(sr_commit_t *commit) @@ -1226,14 +1200,14 @@ sr_state_add_commit(sr_commit_t *commit) sr_commit_get_rsa_fpr(commit)); } -/* Remove all commits from our state. */ +/** Remove all commits from our state. */ void sr_state_delete_commits(void) { state_query(SR_STATE_ACTION_DEL_ALL, SR_STATE_OBJ_COMMIT, NULL, NULL); } -/* Copy the reveal information from <b>commit</b> into <b>saved_commit</b>. +/** Copy the reveal information from <b>commit</b> into <b>saved_commit</b>. * This <b>saved_commit</b> MUST come from our current SR state. Once modified, * the disk state is updated. */ void @@ -1254,7 +1228,7 @@ sr_state_copy_reveal_info(sr_commit_t *saved_commit, const sr_commit_t *commit) sr_commit_get_rsa_fpr(saved_commit)); } -/* Set the fresh SRV flag from our state. This doesn't need to trigger a +/** Set the fresh SRV flag from our state. This doesn't need to trigger a * disk state synchronization so we directly change the state. */ void sr_state_set_fresh_srv(void) @@ -1262,7 +1236,7 @@ sr_state_set_fresh_srv(void) sr_state->is_srv_fresh = 1; } -/* Unset the fresh SRV flag from our state. This doesn't need to trigger a +/** Unset the fresh SRV flag from our state. This doesn't need to trigger a * disk state synchronization so we directly change the state. */ void sr_state_unset_fresh_srv(void) @@ -1270,14 +1244,14 @@ sr_state_unset_fresh_srv(void) sr_state->is_srv_fresh = 0; } -/* Return the value of the fresh SRV flag. */ +/** Return the value of the fresh SRV flag. */ unsigned int sr_state_srv_is_fresh(void) { return sr_state->is_srv_fresh; } -/* Cleanup and free our disk and memory state. */ +/** Cleanup and free our disk and memory state. */ void sr_state_free_all(void) { @@ -1289,7 +1263,7 @@ sr_state_free_all(void) config_mgr_free(shared_random_state_mgr); } -/* Save our current state in memory to disk. */ +/** Save our current state in memory to disk. */ void sr_state_save(void) { @@ -1297,7 +1271,7 @@ sr_state_save(void) state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL); } -/* Return 1 iff the state has been initialized that is it exists in memory. +/** Return 1 iff the state has been initialized that is it exists in memory. * Return 0 otherwise. */ int sr_state_is_initialized(void) @@ -1305,7 +1279,7 @@ sr_state_is_initialized(void) return sr_state == NULL ? 0 : 1; } -/* Initialize the disk and memory state. +/** Initialize the disk and memory state. * * If save_to_disk is set to 1, the state is immediately saved to disk after * creation else it's not thus only kept in memory. @@ -1368,7 +1342,7 @@ sr_state_init(int save_to_disk, int read_from_disk) #ifdef TOR_UNIT_TESTS -/* Set the current phase of the protocol. Used only by unit tests. */ +/** Set the current phase of the protocol. Used only by unit tests. */ void set_sr_phase(sr_phase_t phase) { @@ -1377,7 +1351,7 @@ set_sr_phase(sr_phase_t phase) sr_state->phase = phase; } -/* Get the SR state. Used only by unit tests */ +/** Get the SR state. Used only by unit tests */ sr_state_t * get_sr_state(void) { diff --git a/src/feature/dirauth/shared_random_state.h b/src/feature/dirauth/shared_random_state.h index 08f999f9d4..74792967a7 100644 --- a/src/feature/dirauth/shared_random_state.h +++ b/src/feature/dirauth/shared_random_state.h @@ -1,12 +1,17 @@ /* Copyright (c) 2016-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file shared_random_state.h + * @brief Header for shared_random_state.c + **/ + #ifndef TOR_SHARED_RANDOM_STATE_H #define TOR_SHARED_RANDOM_STATE_H #include "feature/dirauth/shared_random.h" -/* Action that can be performed on the state for any objects. */ +/** Action that can be performed on the state for any objects. */ typedef enum { SR_STATE_ACTION_GET = 1, SR_STATE_ACTION_PUT = 2, @@ -15,52 +20,53 @@ typedef enum { SR_STATE_ACTION_SAVE = 5, } sr_state_action_t; -/* Object in the state that can be queried through the state API. */ +/** Object in the state that can be queried through the state API. */ typedef enum { - /* Will return a single commit using an authority identity key. */ + /** Will return a single commit using an authority identity key. */ SR_STATE_OBJ_COMMIT, - /* Returns the entire list of commits from the state. */ + /** Returns the entire list of commits from the state. */ SR_STATE_OBJ_COMMITS, - /* Return the current SRV object pointer. */ + /** Return the current SRV object pointer. */ SR_STATE_OBJ_CURSRV, - /* Return the previous SRV object pointer. */ + /** Return the previous SRV object pointer. */ SR_STATE_OBJ_PREVSRV, - /* Return the phase. */ + /** Return the phase. */ SR_STATE_OBJ_PHASE, - /* Get or Put the valid after time. */ + /** Get or Put the valid after time. */ SR_STATE_OBJ_VALID_AFTER, } sr_state_object_t; -/* State of the protocol. It's also saved on disk in fname. This data +/** State of the protocol. It's also saved on disk in fname. This data * structure MUST be synchronized at all time with the one on disk. */ typedef struct sr_state_t { - /* Filename of the state file on disk. */ + /** Filename of the state file on disk. */ char *fname; - /* Version of the protocol. */ + /** Version of the protocol. */ uint32_t version; - /* The valid-after of the voting period we have prepared the state for. */ + /** The valid-after of the voting period we have prepared the state for. */ time_t valid_after; - /* Until when is this state valid? */ + /** Until when is this state valid? */ time_t valid_until; - /* Protocol phase. */ + /** Protocol phase. */ sr_phase_t phase; - /* Number of runs completed. */ + /** Number of runs completed. */ uint64_t n_protocol_runs; - /* The number of commitment rounds we've performed in this protocol run. */ + /** The number of commitment rounds we've performed in this protocol run. */ unsigned int n_commit_rounds; - /* The number of reveal rounds we've performed in this protocol run. */ + /** The number of reveal rounds we've performed in this protocol run. */ unsigned int n_reveal_rounds; - /* A map of all the received commitments for this protocol run. This is + /** A map of all the received commitments for this protocol run. This is * indexed by authority RSA identity digest. */ digestmap_t *commits; - /* Current and previous shared random value. */ + /** Current shared random value. */ sr_srv_t *previous_srv; + /** Previous shared random value. */ sr_srv_t *current_srv; - /* Indicate if the state contains an SRV that was _just_ generated. This is + /** Indicate if the state contains an SRV that was _just_ generated. This is * used during voting so that we know whether to use the super majority rule * or not when deciding on keeping it for the consensus. It is _always_ set * to 0 post consensus. @@ -73,22 +79,22 @@ typedef struct sr_state_t { unsigned int is_srv_fresh:1; } sr_state_t; -/* Persistent state of the protocol, as saved to disk. */ +/** Persistent state of the protocol, as saved to disk. */ typedef struct sr_disk_state_t { uint32_t magic_; - /* Version of the protocol. */ + /** Version of the protocol. */ int Version; - /* Version of our running tor. */ + /** Version of our running tor. */ char *TorVersion; - /* Creation time of this state */ + /** Creation time of this state */ time_t ValidAfter; - /* State valid until? */ + /** State valid until? */ time_t ValidUntil; - /* All commits seen that are valid. */ + /** All commits seen that are valid. */ struct config_line_t *Commit; - /* Previous and current shared random value. */ + /** Previous and current shared random value. */ struct config_line_t *SharedRandValues; - /* Extra Lines for configuration we might not know. */ + /** Extra Lines for configuration we might not know. */ struct config_line_t *ExtraLines; } sr_disk_state_t; diff --git a/src/feature/dirauth/vote_microdesc_hash_st.h b/src/feature/dirauth/vote_microdesc_hash_st.h index 7869f92b4f..24c7443b36 100644 --- a/src/feature/dirauth/vote_microdesc_hash_st.h +++ b/src/feature/dirauth/vote_microdesc_hash_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file vote_microdesc_hash_st.h + * @brief Microdescriptor-hash voting strcture. + **/ + #ifndef VOTE_MICRODESC_HASH_ST_H #define VOTE_MICRODESC_HASH_ST_H @@ -19,4 +24,3 @@ struct vote_microdesc_hash_t { }; #endif /* !defined(VOTE_MICRODESC_HASH_ST_H) */ - diff --git a/src/feature/dircache/cached_dir_st.h b/src/feature/dircache/cached_dir_st.h index a28802f905..e086f5b11d 100644 --- a/src/feature/dircache/cached_dir_st.h +++ b/src/feature/dircache/cached_dir_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file cached_dir_st.h + * @brief Cached large directory object structure. + **/ + #ifndef CACHED_DIR_ST_H #define CACHED_DIR_ST_H @@ -22,4 +27,3 @@ struct cached_dir_t { }; #endif /* !defined(CACHED_DIR_ST_H) */ - diff --git a/src/feature/dircache/conscache.c b/src/feature/dircache/conscache.c index 2ec9981c03..903fa5bc0a 100644 --- a/src/feature/dircache/conscache.c +++ b/src/feature/dircache/conscache.c @@ -1,6 +1,11 @@ /* Copyright (c) 2017-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file conscache.c + * @brief Consensus and diff on-disk cache. + **/ + #include "core/or/or.h" #include "app/config/config.h" @@ -246,7 +251,7 @@ consensus_cache_find_first(consensus_cache_t *cache, } /** - * Given a <b>cache</b>, add every entry to <b>out<b> for which + * Given a <b>cache</b>, add every entry to <b>out</b> for which * <b>key</b>=<b>value</b>. If <b>key</b> is NULL, add every entry. * * Do not add any entry that has been marked for removal. diff --git a/src/feature/dircache/conscache.h b/src/feature/dircache/conscache.h index d848e57617..54c081c068 100644 --- a/src/feature/dircache/conscache.h +++ b/src/feature/dircache/conscache.h @@ -1,6 +1,11 @@ /* Copyright (c) 2017-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file conscache.h + * @brief Header for conscache.c + **/ + #ifndef TOR_CONSCACHE_H #define TOR_CONSCACHE_H diff --git a/src/feature/dircache/consdiffmgr.c b/src/feature/dircache/consdiffmgr.c index 397efa0341..058ff1f500 100644 --- a/src/feature/dircache/consdiffmgr.c +++ b/src/feature/dircache/consdiffmgr.c @@ -2,7 +2,7 @@ /* See LICENSE for licensing information */ /** - * \file consdiffmsr.c + * \file consdiffmgr.c * * \brief consensus diff manager functions * @@ -1293,7 +1293,7 @@ typedef struct compressed_result_t { /** * Compress the bytestring <b>input</b> of length <b>len</b> using the - * <n>n_methods</b> compression methods listed in the array <b>methods</b>. + * <b>n_methods</b> compression methods listed in the array <b>methods</b>. * * For each successful compression, set the fields in the <b>results_out</b> * array in the position corresponding to the compression method. Use diff --git a/src/feature/dircache/consdiffmgr.h b/src/feature/dircache/consdiffmgr.h index b1b3323b6c..7222353650 100644 --- a/src/feature/dircache/consdiffmgr.h +++ b/src/feature/dircache/consdiffmgr.h @@ -1,6 +1,11 @@ /* Copyright (c) 2017-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file consdiffmgr.h + * @brief Header for consdiffmgr.c + **/ + #ifndef TOR_CONSDIFFMGR_H #define TOR_CONSDIFFMGR_H diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index d4d0ad9939..9938f9426c 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -3,6 +3,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dircache.c + * @brief Cache directories and serve them to clients. + **/ + #define DIRCACHE_PRIVATE #include "core/or/or.h" @@ -23,6 +28,7 @@ #include "feature/nodelist/authcert.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/routerlist.h" +#include "feature/relay/relay_config.h" #include "feature/relay/routermode.h" #include "feature/rend/rendcache.h" #include "feature/stats/geoip_stats.h" @@ -473,7 +479,7 @@ static int handle_get_frontpage(dir_connection_t *conn, const get_handler_args_t *args) { (void) args; /* unused */ - const char *frontpage = get_dirportfrontpage(); + const char *frontpage = relay_get_dirportfrontpage(); if (frontpage) { size_t dlen; @@ -560,7 +566,7 @@ parse_one_diff_hash(uint8_t *digest, const char *hex, const char *location, } /** If there is an X-Or-Diff-From-Consensus header included in <b>headers</b>, - * set <b>digest_out<b> to a new smartlist containing every 256-bit + * set <b>digest_out</b> to a new smartlist containing every 256-bit * hex-encoded digest listed in that header and return 0. Otherwise return * -1. */ static int @@ -1379,7 +1385,7 @@ handle_get_hs_descriptor_v2(dir_connection_t *conn, return 0; } -/** Helper function for GET /tor/hs/3/<z>. Only for version 3. +/** Helper function for GET `/tor/hs/3/...`. Only for version 3. */ STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn, diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index 79400bf15f..85331bfeaa 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -259,8 +259,8 @@ dirserv_set_cached_consensus_networkstatus(const char *networkstatus, /** Return the latest downloaded consensus networkstatus in encoded, signed, * optionally compressed format, suitable for sending to clients. */ -cached_dir_t * -dirserv_get_consensus(const char *flavor_name) +MOCK_IMPL(cached_dir_t *, +dirserv_get_consensus,(const char *flavor_name)) { if (!cached_consensuses) return NULL; diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index 7f944459da..0c15c9ad19 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -82,7 +82,7 @@ int directory_permits_begindir_requests(const or_options_t *options); int directory_too_idle_to_fetch_descriptors(const or_options_t *options, time_t now); -cached_dir_t *dirserv_get_consensus(const char *flavor_name); +MOCK_DECL(cached_dir_t *, dirserv_get_consensus, (const char *flavor_name)); void dirserv_set_cached_consensus_networkstatus(const char *consensus, size_t consensus_len, const char *flavor_name, diff --git a/src/feature/dircache/feature_dircache.dox b/src/feature/dircache/feature_dircache.dox new file mode 100644 index 0000000000..ef8a51aa9e --- /dev/null +++ b/src/feature/dircache/feature_dircache.dox @@ -0,0 +1,8 @@ +/** +@dir /feature/dircache +@brief feature/dircache: Run as a directory cache server + +This module handles the directory caching functionality that all relays may +provide, for serving cached directory objects to objects. + +**/ diff --git a/src/feature/dirclient/dir_server_st.h b/src/feature/dirclient/dir_server_st.h index 8e35532435..69c3856185 100644 --- a/src/feature/dirclient/dir_server_st.h +++ b/src/feature/dirclient/dir_server_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dir_server_st.h + * @brief Trusted/fallback directory server structure. + **/ + #ifndef DIR_SERVER_ST_H #define DIR_SERVER_ST_H diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 1ea50fd350..a97b425944 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -3,6 +3,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dirclient.c + * @brief Download directory information + **/ + #define DIRCLIENT_PRIVATE #include "core/or/or.h" diff --git a/src/feature/dirclient/dlstatus.c b/src/feature/dirclient/dlstatus.c index 0842a2c676..c6fdbebed9 100644 --- a/src/feature/dirclient/dlstatus.c +++ b/src/feature/dirclient/dlstatus.c @@ -3,6 +3,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dlstatus.c + * @brief Track status and retry schedule of a downloadable object. + **/ + #define DLSTATUS_PRIVATE #include "core/or/or.h" diff --git a/src/feature/dirclient/download_status_st.h b/src/feature/dirclient/download_status_st.h index 39a5ad2860..29d0dd5d5f 100644 --- a/src/feature/dirclient/download_status_st.h +++ b/src/feature/dirclient/download_status_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file download_status_st.h + * @brief Directory download status/schedule structure. + **/ + #ifndef DOWNLOAD_STATUS_ST_H #define DOWNLOAD_STATUS_ST_H @@ -62,4 +67,3 @@ struct download_status_t { }; #endif /* !defined(DOWNLOAD_STATUS_ST_H) */ - diff --git a/src/feature/dirclient/feature_dirclient.dox b/src/feature/dirclient/feature_dirclient.dox new file mode 100644 index 0000000000..0cbae69111 --- /dev/null +++ b/src/feature/dirclient/feature_dirclient.dox @@ -0,0 +1,9 @@ +/** +@dir /feature/dirclient +@brief feature/dirclient: Directory client implementation. + +The code here is used by all Tor instances that need to download directory +information. Currently, that is all of them, since even authorities need to +launch downloads to learn about relays that other authorities have listed. + +**/ diff --git a/src/feature/dircommon/consdiff.c b/src/feature/dircommon/consdiff.c index 8e93953f73..fbfa9e0c0a 100644 --- a/src/feature/dircommon/consdiff.c +++ b/src/feature/dircommon/consdiff.c @@ -530,10 +530,12 @@ typedef struct router_id_iterator_t { cdline_t hash; } router_id_iterator_t; +#ifndef COCCI /** * Initializer for a router_id_iterator_t. */ #define ROUTER_ID_ITERATOR_INIT { { NULL, 0 }, { NULL, 0 } } +#endif /* !defined(COCCI) */ /** Given an index *<b>idxp</b> into the consensus at <b>cons</b>, advance * the index to the next router line ("r ...") in the consensus, or to @@ -570,7 +572,7 @@ find_next_router_line(const smartlist_t *cons, /** Pre-process a consensus in <b>cons</b> (represented as a list of cdline_t) * to remove the signatures from it. If the footer is removed, return a * cdline_t containing a delete command to delete the footer, allocated in - * <b>area</>. If no footer is removed, return NULL. + * <b>area</b>. If no footer is removed, return NULL. * * We remove the signatures here because they are not themselves signed, and * as such there might be different encodings for them. diff --git a/src/feature/dircommon/consdiff.h b/src/feature/dircommon/consdiff.h index b63fcb2cc6..0e8c4b4d8e 100644 --- a/src/feature/dircommon/consdiff.h +++ b/src/feature/dircommon/consdiff.h @@ -2,6 +2,11 @@ * Copyright (c) 2014-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file consdiff.h + * @brief Header for consdiff.c + **/ + #ifndef TOR_CONSDIFF_H #define TOR_CONSDIFF_H diff --git a/src/feature/dircommon/dir_connection_st.h b/src/feature/dircommon/dir_connection_st.h index a858560c29..ba978e142a 100644 --- a/src/feature/dircommon/dir_connection_st.h +++ b/src/feature/dircommon/dir_connection_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dir_connection_st.h + * @brief Client/server directory connection structure. + **/ + #ifndef DIR_CONNECTION_ST_H #define DIR_CONNECTION_ST_H diff --git a/src/feature/dircommon/feature_dircommon.dox b/src/feature/dircommon/feature_dircommon.dox new file mode 100644 index 0000000000..2d9866da01 --- /dev/null +++ b/src/feature/dircommon/feature_dircommon.dox @@ -0,0 +1,9 @@ +/** +@dir /feature/dircommon +@brief feature/dircommon: Directory client and server shared code + +This module has the code that directory clients (anybody who download +information about relays) and directory servers (anybody who serves such +information) share in common. + +**/ diff --git a/src/feature/dircommon/vote_timing_st.h b/src/feature/dircommon/vote_timing_st.h index 814a325314..352a69b2dd 100644 --- a/src/feature/dircommon/vote_timing_st.h +++ b/src/feature/dircommon/vote_timing_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file vote_timing_st.h + * @brief Directory voting schedule structure. + **/ + #ifndef VOTE_TIMING_ST_H #define VOTE_TIMING_ST_H @@ -21,4 +26,3 @@ struct vote_timing_t { }; #endif /* !defined(VOTE_TIMING_ST_H) */ - diff --git a/src/feature/dircommon/voting_schedule.h b/src/feature/dircommon/voting_schedule.h index d78c7ee2da..fd677fc836 100644 --- a/src/feature/dircommon/voting_schedule.h +++ b/src/feature/dircommon/voting_schedule.h @@ -26,15 +26,15 @@ typedef struct { /** When do we publish the consensus? */ time_t interval_starts; - /* True iff we have generated and distributed our vote. */ + /** True iff we have generated and distributed our vote. */ int have_voted; - /* True iff we've requested missing votes. */ + /** True iff we've requested missing votes. */ int have_fetched_missing_votes; - /* True iff we have built a consensus and sent the signatures around. */ + /** True iff we have built a consensus and sent the signatures around. */ int have_built_consensus; - /* True iff we've fetched missing signatures. */ + /** True iff we've fetched missing signatures. */ int have_fetched_missing_signatures; - /* True iff we have published our consensus. */ + /** True iff we have published our consensus. */ int have_published_consensus; /* True iff this voting schedule was set on demand meaning not through the @@ -62,4 +62,3 @@ time_t voting_schedule_get_start_of_next_interval(time_t now, time_t voting_schedule_get_next_valid_after_time(void); #endif /* !defined(TOR_VOTING_SCHEDULE_H) */ - diff --git a/src/feature/dirparse/authcert_members.h b/src/feature/dirparse/authcert_members.h new file mode 100644 index 0000000000..3b44c3eb02 --- /dev/null +++ b/src/feature/dirparse/authcert_members.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file authcert_members.h + * + * @brief List of tokens common to V3 authority certificates and V3 + * consensuses. + **/ + +#ifndef TOR_AUTHCERT_MEMBERS_H +#define TOR_AUTHCERT_MEMBERS_H + +#define AUTHCERT_MEMBERS \ + T1("dir-key-certificate-version", K_DIR_KEY_CERTIFICATE_VERSION, \ + GE(1), NO_OBJ ), \ + T1("dir-identity-key", K_DIR_IDENTITY_KEY, NO_ARGS, NEED_KEY ),\ + T1("dir-key-published",K_DIR_KEY_PUBLISHED, CONCAT_ARGS, NO_OBJ),\ + T1("dir-key-expires", K_DIR_KEY_EXPIRES, CONCAT_ARGS, NO_OBJ),\ + T1("dir-signing-key", K_DIR_SIGNING_KEY, NO_ARGS, NEED_KEY ),\ + T1("dir-key-crosscert", K_DIR_KEY_CROSSCERT, NO_ARGS, NEED_OBJ ),\ + T1("dir-key-certification", K_DIR_KEY_CERTIFICATION,\ + NO_ARGS, NEED_OBJ),\ + T01("dir-address", K_DIR_ADDRESS, GE(1), NO_OBJ) + +#endif /* !defined(TOR_AUTHCERT_MEMBERS_H) */ diff --git a/src/feature/dirparse/authcert_members.i b/src/feature/dirparse/authcert_members.i deleted file mode 100644 index 08cffca97a..0000000000 --- a/src/feature/dirparse/authcert_members.i +++ /dev/null @@ -1,13 +0,0 @@ -/* - * List of tokens common to V3 authority certificates and V3 consensuses. - */ - T1("dir-key-certificate-version", K_DIR_KEY_CERTIFICATE_VERSION, - GE(1), NO_OBJ ), - T1("dir-identity-key", K_DIR_IDENTITY_KEY, NO_ARGS, NEED_KEY ), - T1("dir-key-published",K_DIR_KEY_PUBLISHED, CONCAT_ARGS, NO_OBJ), - T1("dir-key-expires", K_DIR_KEY_EXPIRES, CONCAT_ARGS, NO_OBJ), - T1("dir-signing-key", K_DIR_SIGNING_KEY, NO_ARGS, NEED_KEY ), - T1("dir-key-crosscert", K_DIR_KEY_CROSSCERT, NO_ARGS, NEED_OBJ ), - T1("dir-key-certification", K_DIR_KEY_CERTIFICATION, - NO_ARGS, NEED_OBJ), - T01("dir-address", K_DIR_ADDRESS, GE(1), NO_OBJ), diff --git a/src/feature/dirparse/authcert_parse.c b/src/feature/dirparse/authcert_parse.c index 8ba5a53981..b18e1159f3 100644 --- a/src/feature/dirparse/authcert_parse.c +++ b/src/feature/dirparse/authcert_parse.c @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file authcert_parse.c + * @brief Authority certificate parsing. + **/ + #include "core/or/or.h" #include "feature/dirparse/authcert_parse.h" #include "feature/dirparse/parsecommon.h" @@ -13,10 +18,11 @@ #include "lib/memarea/memarea.h" #include "feature/nodelist/authority_cert_st.h" +#include "feature/dirparse/authcert_members.h" /** List of tokens recognized in V3 authority certificates. */ static token_rule_t dir_key_certificate_table[] = { -#include "feature/dirparse/authcert_members.i" + AUTHCERT_MEMBERS, T1("fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ), END_OF_TABLE }; diff --git a/src/feature/dirparse/feature_dirparse.dox b/src/feature/dirparse/feature_dirparse.dox new file mode 100644 index 0000000000..4f2136b02b --- /dev/null +++ b/src/feature/dirparse/feature_dirparse.dox @@ -0,0 +1,10 @@ +/** +@dir /feature/dirparse +@brief feature/dirparse: Parsing Tor directory objects + +We define a number of "directory objects" in +[dir-spec.txt](https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt), +all of them using a common line-oriented meta-format. This module is used by +other parts of Tor to parse them. + +**/ diff --git a/src/feature/dirparse/microdesc_parse.c b/src/feature/dirparse/microdesc_parse.c index 4bb4db7821..e526a355c1 100644 --- a/src/feature/dirparse/microdesc_parse.c +++ b/src/feature/dirparse/microdesc_parse.c @@ -164,7 +164,7 @@ microdesc_extract_body(microdesc_t *md, /** * Parse a microdescriptor which begins at <b>s</b> and ends at - * <b>start_of_next_microdesc. Store its fields into <b>md</b>. Use + * <b>start_of_next_microdesc</b>. Store its fields into <b>md</b>. Use * <b>where</b> for generating log information. If <b>allow_annotations</b> * is true, then one or more annotations may precede the microdescriptor body * proper. Use <b>area</b> for memory management, clearing it when done. diff --git a/src/feature/dirparse/ns_parse.c b/src/feature/dirparse/ns_parse.c index d5405e6464..4bb5798094 100644 --- a/src/feature/dirparse/ns_parse.c +++ b/src/feature/dirparse/ns_parse.c @@ -36,6 +36,7 @@ #include "feature/nodelist/networkstatus_st.h" #include "feature/nodelist/networkstatus_voter_info_st.h" #include "feature/nodelist/vote_routerstatus_st.h" +#include "feature/dirparse/authcert_members.h" #undef log #include <math.h> @@ -84,7 +85,7 @@ static token_rule_t networkstatus_token_table[] = { T01("required-relay-protocols", K_REQUIRED_RELAY_PROTOCOLS, CONCAT_ARGS, NO_OBJ ), -#include "feature/dirparse/authcert_members.i" + AUTHCERT_MEMBERS, T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ), T1( "contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ), diff --git a/src/feature/dirparse/unparseable.c b/src/feature/dirparse/unparseable.c index 941b5a1f6d..3b96df9e30 100644 --- a/src/feature/dirparse/unparseable.c +++ b/src/feature/dirparse/unparseable.c @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file unparseable.c + * @brief Dump unparseable objects to disk. + **/ + #define UNPARSEABLE_PRIVATE #include "core/or/or.h" diff --git a/src/feature/feature.dox b/src/feature/feature.dox new file mode 100644 index 0000000000..03759f9a17 --- /dev/null +++ b/src/feature/feature.dox @@ -0,0 +1,9 @@ +/** +@dir /feature +@brief feature: domain-specific modules + +The "feature" directory has modules that Tor uses only for a particular +role or service, such as maintaining/using an onion service, operating as a +relay or a client, or being a directory authority. + +**/ diff --git a/src/feature/hibernate/feature_hibernate.dox b/src/feature/hibernate/feature_hibernate.dox new file mode 100644 index 0000000000..eebb2d51a2 --- /dev/null +++ b/src/feature/hibernate/feature_hibernate.dox @@ -0,0 +1,16 @@ +/** +@dir /feature/hibernate +@brief feature/hibernate: Bandwidth accounting and hibernation (!) + +This module implements two features that are only somewhat related, and +should probably be separated in the future. One feature is bandwidth +accounting (making sure we use no more than so many gigabytes in a day) and +hibernation (avoiding network activity while we have used up all/most of our +configured gigabytes). The other feature is clean shutdown, where we stop +accepting new connections for a while and give the old ones time to close. + +The two features are related only in the sense that "soft hibernation" (being +almost out of ) is very close to the "shutting down" state. But it would be +better in the long run to make the two completely separate. + +**/ diff --git a/src/feature/hs/feature_hs.dox b/src/feature/hs/feature_hs.dox new file mode 100644 index 0000000000..32f44d57fb --- /dev/null +++ b/src/feature/hs/feature_hs.dox @@ -0,0 +1,10 @@ +/** +@dir /feature/hs +@brief feature/hs: v3 (current) onion service protocol + +This directory implements the v3 onion service protocol, +as specified in +[rend-spec-v3.txt](https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt). + + +**/ diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c index 9817113b23..395839fce0 100644 --- a/src/feature/hs/hs_cache.c +++ b/src/feature/hs/hs_cache.c @@ -29,10 +29,10 @@ static int cached_client_descriptor_has_expired(time_t now, /********************** Directory HS cache ******************/ -/* Directory descriptor cache. Map indexed by blinded key. */ +/** Directory descriptor cache. Map indexed by blinded key. */ static digest256map_t *hs_cache_v3_dir; -/* Remove a given descriptor from our cache. */ +/** Remove a given descriptor from our cache. */ static void remove_v3_desc_as_dir(const hs_cache_dir_descriptor_t *desc) { @@ -40,7 +40,7 @@ remove_v3_desc_as_dir(const hs_cache_dir_descriptor_t *desc) digest256map_remove(hs_cache_v3_dir, desc->key); } -/* Store a given descriptor in our cache. */ +/** Store a given descriptor in our cache. */ static void store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc) { @@ -48,7 +48,7 @@ store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc) digest256map_set(hs_cache_v3_dir, desc->key, desc); } -/* Query our cache and return the entry or NULL if not found. */ +/** Query our cache and return the entry or NULL if not found. */ static hs_cache_dir_descriptor_t * lookup_v3_desc_as_dir(const uint8_t *key) { @@ -59,7 +59,7 @@ lookup_v3_desc_as_dir(const uint8_t *key) #define cache_dir_desc_free(val) \ FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val)) -/* Free a directory descriptor object. */ +/** Free a directory descriptor object. */ static void cache_dir_desc_free_(hs_cache_dir_descriptor_t *desc) { @@ -71,7 +71,7 @@ cache_dir_desc_free_(hs_cache_dir_descriptor_t *desc) tor_free(desc); } -/* Helper function: Use by the free all function using the digest256map +/** Helper function: Use by the free all function using the digest256map * interface to cache entries. */ static void cache_dir_desc_free_void(void *ptr) @@ -79,7 +79,7 @@ cache_dir_desc_free_void(void *ptr) cache_dir_desc_free_(ptr); } -/* Create a new directory cache descriptor object from a encoded descriptor. +/** Create a new directory cache descriptor object from a encoded descriptor. * On success, return the heap-allocated cache object, otherwise return NULL if * we can't decode the descriptor. */ static hs_cache_dir_descriptor_t * @@ -109,7 +109,7 @@ cache_dir_desc_new(const char *desc) return NULL; } -/* Return the size of a cache entry in bytes. */ +/** Return the size of a cache entry in bytes. */ static size_t cache_get_dir_entry_size(const hs_cache_dir_descriptor_t *entry) { @@ -117,7 +117,7 @@ cache_get_dir_entry_size(const hs_cache_dir_descriptor_t *entry) + strlen(entry->encoded_desc)); } -/* Try to store a valid version 3 descriptor in the directory cache. Return 0 +/** Try to store a valid version 3 descriptor in the directory cache. Return 0 * on success else a negative value is returned indicating that we have a * newer version in our cache. On error, caller is responsible to free the * given descriptor desc. */ @@ -167,7 +167,7 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc) return -1; } -/* Using the query which is the base64 encoded blinded key of a version 3 +/** Using the query which is the base64 encoded blinded key of a version 3 * descriptor, lookup in our directory cache the entry. If found, 1 is * returned and desc_out is populated with a newly allocated string being the * encoded descriptor. If not found, 0 is returned and desc_out is untouched. @@ -202,7 +202,7 @@ cache_lookup_v3_as_dir(const char *query, const char **desc_out) return -1; } -/* Clean the v3 cache by removing any entry that has expired using the +/** Clean the v3 cache by removing any entry that has expired using the * <b>global_cutoff</b> value. If <b>global_cutoff</b> is 0, the cleaning * process will use the lifetime found in the plaintext data section. Return * the number of bytes cleaned. */ @@ -252,7 +252,7 @@ cache_clean_v3_as_dir(time_t now, time_t global_cutoff) return bytes_removed; } -/* Given an encoded descriptor, store it in the directory cache depending on +/** Given an encoded descriptor, store it in the directory cache depending on * which version it is. Return a negative value on error. On success, 0 is * returned. */ int @@ -287,7 +287,7 @@ hs_cache_store_as_dir(const char *desc) return -1; } -/* Using the query, lookup in our directory cache the entry. If found, 1 is +/** Using the query, lookup in our directory cache the entry. If found, 1 is * returned and desc_out is populated with a newly allocated string being * the encoded descriptor. If not found, 0 is returned and desc_out is * untouched. On error, a negative value is returned and desc_out is @@ -312,7 +312,7 @@ hs_cache_lookup_as_dir(uint32_t version, const char *query, return found; } -/* Clean all directory caches using the current time now. */ +/** Clean all directory caches using the current time now. */ void hs_cache_clean_as_dir(time_t now) { @@ -329,15 +329,15 @@ hs_cache_clean_as_dir(time_t now) /********************** Client-side HS cache ******************/ -/* Client-side HS descriptor cache. Map indexed by service identity key. */ +/** Client-side HS descriptor cache. Map indexed by service identity key. */ static digest256map_t *hs_cache_v3_client; -/* Client-side introduction point state cache. Map indexed by service public +/** Client-side introduction point state cache. Map indexed by service public * identity key (onion address). It contains hs_cache_client_intro_state_t * objects all related to a specific service. */ static digest256map_t *hs_cache_client_intro_state; -/* Return the size of a client cache entry in bytes. */ +/** Return the size of a client cache entry in bytes. */ static size_t cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry) { @@ -345,7 +345,7 @@ cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry) strlen(entry->encoded_desc) + hs_desc_obj_size(entry->desc); } -/* Remove a given descriptor from our cache. */ +/** Remove a given descriptor from our cache. */ static void remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc) { @@ -355,7 +355,7 @@ remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc) rend_cache_decrement_allocation(cache_get_client_entry_size(desc)); } -/* Store a given descriptor in our cache. */ +/** Store a given descriptor in our cache. */ static void store_v3_desc_as_client(hs_cache_client_descriptor_t *desc) { @@ -365,7 +365,7 @@ store_v3_desc_as_client(hs_cache_client_descriptor_t *desc) rend_cache_increment_allocation(cache_get_client_entry_size(desc)); } -/* Query our cache and return the entry or NULL if not found or if expired. */ +/** Query our cache and return the entry or NULL if not found or if expired. */ STATIC hs_cache_client_descriptor_t * lookup_v3_desc_as_client(const uint8_t *key) { @@ -388,8 +388,8 @@ lookup_v3_desc_as_client(const uint8_t *key) return cached_desc; } -/* Parse the encoded descriptor in <b>desc_str</b> using - * <b>service_identity_pk<b> to decrypt it first. +/** Parse the encoded descriptor in <b>desc_str</b> using + * <b>service_identity_pk</b> to decrypt it first. * * If everything goes well, allocate and return a new * hs_cache_client_descriptor_t object. In case of error, return NULL. */ @@ -448,7 +448,7 @@ cache_client_desc_free_void(void *ptr) cache_client_desc_free(desc); } -/* Return a newly allocated and initialized hs_cache_intro_state_t object. */ +/** Return a newly allocated and initialized hs_cache_intro_state_t object. */ static hs_cache_intro_state_t * cache_intro_state_new(void) { @@ -460,21 +460,21 @@ cache_intro_state_new(void) #define cache_intro_state_free(val) \ FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val)) -/* Free an hs_cache_intro_state_t object. */ +/** Free an hs_cache_intro_state_t object. */ static void cache_intro_state_free_(hs_cache_intro_state_t *state) { tor_free(state); } -/* Helper function: used by the free all function. */ +/** Helper function: used by the free all function. */ static void cache_intro_state_free_void(void *state) { cache_intro_state_free_(state); } -/* Return a newly allocated and initialized hs_cache_client_intro_state_t +/** Return a newly allocated and initialized hs_cache_client_intro_state_t * object. */ static hs_cache_client_intro_state_t * cache_client_intro_state_new(void) @@ -488,7 +488,7 @@ cache_client_intro_state_new(void) FREE_AND_NULL(hs_cache_client_intro_state_t, \ cache_client_intro_state_free_, (val)) -/* Free a cache_client_intro_state object. */ +/** Free a cache_client_intro_state object. */ static void cache_client_intro_state_free_(hs_cache_client_intro_state_t *cache) { @@ -499,14 +499,14 @@ cache_client_intro_state_free_(hs_cache_client_intro_state_t *cache) tor_free(cache); } -/* Helper function: used by the free all function. */ +/** Helper function: used by the free all function. */ static void cache_client_intro_state_free_void(void *entry) { cache_client_intro_state_free_(entry); } -/* For the given service identity key service_pk and an introduction +/** For the given service identity key service_pk and an introduction * authentication key auth_key, lookup the intro state object. Return 1 if * found and put it in entry if not NULL. Return 0 if not found and entry is * untouched. */ @@ -541,7 +541,7 @@ cache_client_intro_state_lookup(const ed25519_public_key_t *service_pk, return 0; } -/* Note the given failure in state. */ +/** Note the given failure in state. */ static void cache_client_intro_state_note(hs_cache_intro_state_t *state, rend_intro_point_failure_t failure) @@ -563,7 +563,7 @@ cache_client_intro_state_note(hs_cache_intro_state_t *state, } } -/* For the given service identity key service_pk and an introduction +/** For the given service identity key service_pk and an introduction * authentication key auth_key, add an entry in the client intro state cache * If no entry exists for the service, it will create one. If state is non * NULL, it will point to the new intro state entry. */ @@ -597,7 +597,7 @@ cache_client_intro_state_add(const ed25519_public_key_t *service_pk, } } -/* Remove every intro point state entry from cache that has been created +/** Remove every intro point state entry from cache that has been created * before or at the cutoff. */ static void cache_client_intro_state_clean(time_t cutoff, @@ -614,7 +614,7 @@ cache_client_intro_state_clean(time_t cutoff, } DIGEST256MAP_FOREACH_END; } -/* Return true iff no intro points are in this cache. */ +/** Return true iff no intro points are in this cache. */ static int cache_client_intro_state_is_empty(const hs_cache_client_intro_state_t *cache) { @@ -664,7 +664,7 @@ cache_store_as_client(hs_cache_client_descriptor_t *client_desc) return 0; } -/* Return true iff the cached client descriptor at <b>cached_desc</b has +/** Return true iff the cached client descriptor at <b>cached_desc</b> has * expired. */ static int cached_client_descriptor_has_expired(time_t now, @@ -687,7 +687,7 @@ cached_client_descriptor_has_expired(time_t now, return 0; } -/* clean the client cache using now as the current time. Return the total size +/** clean the client cache using now as the current time. Return the total size * of removed bytes from the cache. */ static size_t cache_clean_v3_as_client(time_t now) @@ -800,7 +800,7 @@ hs_cache_store_as_client(const char *desc_str, return -1; } -/* Clean all client caches using the current time now. */ +/** Clean all client caches using the current time now. */ void hs_cache_clean_as_client(time_t now) { @@ -811,7 +811,7 @@ hs_cache_clean_as_client(time_t now) cache_clean_v3_as_client(now); } -/* Purge the client descriptor cache. */ +/** Purge the client descriptor cache. */ void hs_cache_purge_as_client(void) { @@ -828,7 +828,7 @@ hs_cache_purge_as_client(void) log_info(LD_REND, "Hidden service client descriptor cache purged."); } -/* For a given service identity public key and an introduction authentication +/** For a given service identity public key and an introduction authentication * key, note the given failure in the client intro state cache. */ void hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk, @@ -850,7 +850,7 @@ hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk, cache_client_intro_state_note(entry, failure); } -/* For a given service identity public key and an introduction authentication +/** For a given service identity public key and an introduction authentication * key, return true iff it is present in the failure cache. */ const hs_cache_intro_state_t * hs_cache_client_intro_state_find(const ed25519_public_key_t *service_pk, @@ -861,7 +861,7 @@ hs_cache_client_intro_state_find(const ed25519_public_key_t *service_pk, return state; } -/* Cleanup the client introduction state cache. */ +/** Cleanup the client introduction state cache. */ void hs_cache_client_intro_state_clean(time_t now) { @@ -881,7 +881,7 @@ hs_cache_client_intro_state_clean(time_t now) } DIGEST256MAP_FOREACH_END; } -/* Purge the client introduction state cache. */ +/** Purge the client introduction state cache. */ void hs_cache_client_intro_state_purge(void) { @@ -897,7 +897,7 @@ hs_cache_client_intro_state_purge(void) /**************** Generics *********************************/ -/* Do a round of OOM cleanup on all directory caches. Return the amount of +/** Do a round of OOM cleanup on all directory caches. Return the amount of * removed bytes. It is possible that the returned value is lower than * min_remove_bytes if the caches get emptied out so the caller should be * aware of this. */ @@ -951,7 +951,7 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes) return bytes_removed; } -/* Return the maximum size of a v3 HS descriptor. */ +/** Return the maximum size of a v3 HS descriptor. */ unsigned int hs_cache_get_max_descriptor_size(void) { @@ -960,7 +960,7 @@ hs_cache_get_max_descriptor_size(void) HS_DESC_MAX_LEN, 1, INT32_MAX); } -/* Initialize the hidden service cache subsystem. */ +/** Initialize the hidden service cache subsystem. */ void hs_cache_init(void) { @@ -975,7 +975,7 @@ hs_cache_init(void) hs_cache_client_intro_state = digest256map_new(); } -/* Cleanup the hidden service cache subsystem. */ +/** Cleanup the hidden service cache subsystem. */ void hs_cache_free_all(void) { diff --git a/src/feature/hs/hs_cache.h b/src/feature/hs/hs_cache.h index 079d31d437..5df7e54fc0 100644 --- a/src/feature/hs/hs_cache.h +++ b/src/feature/hs/hs_cache.h @@ -18,47 +18,47 @@ struct ed25519_public_key_t; -/* This is the maximum time an introduction point state object can stay in the +/** This is the maximum time an introduction point state object can stay in the * client cache in seconds (2 mins or 120 seconds). */ #define HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE (2 * 60) -/* Introduction point state. */ +/** Introduction point state. */ typedef struct hs_cache_intro_state_t { - /* When this entry was created and put in the cache. */ + /** When this entry was created and put in the cache. */ time_t created_ts; - /* Did it suffered a generic error? */ + /** Did it suffered a generic error? */ unsigned int error : 1; - /* Did it timed out? */ + /** Did it timed out? */ unsigned int timed_out : 1; - /* How many times we tried to reached it and it was unreachable. */ + /** How many times we tried to reached it and it was unreachable. */ uint32_t unreachable_count; } hs_cache_intro_state_t; typedef struct hs_cache_client_intro_state_t { - /* Contains hs_cache_intro_state_t object indexed by introduction point + /** Contains hs_cache_intro_state_t object indexed by introduction point * authentication key. */ digest256map_t *intro_points; } hs_cache_client_intro_state_t; -/* Descriptor representation on the directory side which is a subset of +/** Descriptor representation on the directory side which is a subset of * information that the HSDir can decode and serve it. */ typedef struct hs_cache_dir_descriptor_t { - /* This object is indexed using the blinded pubkey located in the plaintext + /** This object is indexed using the blinded pubkey located in the plaintext * data which is populated only once the descriptor has been successfully * decoded and validated. This simply points to that pubkey. */ const uint8_t *key; - /* When does this entry has been created. Used to expire entries. */ + /** When does this entry has been created. Used to expire entries. */ time_t created_ts; - /* Descriptor plaintext information. Obviously, we can't decrypt the + /** Descriptor plaintext information. Obviously, we can't decrypt the * encrypted part of the descriptor. */ hs_desc_plaintext_data_t *plaintext_data; - /* Encoded descriptor which is basically in text form. It's a NUL terminated + /** Encoded descriptor which is basically in text form. It's a NUL terminated * string thus safe to strlen(). */ char *encoded_desc; } hs_cache_dir_descriptor_t; @@ -104,19 +104,19 @@ void hs_cache_client_intro_state_purge(void); /** Represents a locally cached HS descriptor on a hidden service client. */ typedef struct hs_cache_client_descriptor_t { - /* This object is indexed using the service identity public key */ + /** This object is indexed using the service identity public key */ struct ed25519_public_key_t key; - /* When will this entry expire? We expire cached client descriptors in the + /** When will this entry expire? We expire cached client descriptors in the * start of the next time period, since that's when clients need to start * using the next blinded key of the service. */ time_t expiration_ts; - /* The cached descriptor, this object is the owner. It can't be NULL. A + /** The cached descriptor, this object is the owner. It can't be NULL. A * cache object without a valid descriptor is not possible. */ hs_descriptor_t *desc; - /* Encoded descriptor in string form. Can't be NULL. */ + /** Encoded descriptor in string form. Can't be NULL. */ char *encoded_desc; } hs_cache_client_descriptor_t; diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c index df59f73c1b..eaf8820e9f 100644 --- a/src/feature/hs/hs_cell.c +++ b/src/feature/hs/hs_cell.c @@ -24,7 +24,7 @@ #include "trunnel/hs/cell_introduce1.h" #include "trunnel/hs/cell_rendezvous.h" -/* Compute the MAC of an INTRODUCE cell in mac_out. The encoded_cell param is +/** Compute the MAC of an INTRODUCE cell in mac_out. The encoded_cell param is * the cell content up to the ENCRYPTED section of length encoded_cell_len. * The encrypted param is the start of the ENCRYPTED section of length * encrypted_len. The mac_key is the key needed for the computation of the MAC @@ -67,7 +67,7 @@ compute_introduce_mac(const uint8_t *encoded_cell, size_t encoded_cell_len, memwipe(mac_msg, 0, sizeof(mac_msg)); } -/* From a set of keys, subcredential and the ENCRYPTED section of an +/** From a set of keys, subcredential and the ENCRYPTED section of an * INTRODUCE2 cell, return a newly allocated intro cell keys structure. * Finally, the client public key is copied in client_pk. On error, return * NULL. */ @@ -101,7 +101,7 @@ get_introduce2_key_material(const ed25519_public_key_t *auth_key, return keys; } -/* Using the given encryption key, decrypt the encrypted_section of length +/** Using the given encryption key, decrypt the encrypted_section of length * encrypted_section_len of an INTRODUCE2 cell and return a newly allocated * buffer containing the decrypted data. On decryption failure, NULL is * returned. */ @@ -136,7 +136,7 @@ decrypt_introduce2(const uint8_t *enc_key, const uint8_t *encrypted_section, return decrypted; } -/* Given a pointer to the decrypted data of the ENCRYPTED section of an +/** Given a pointer to the decrypted data of the ENCRYPTED section of an * INTRODUCE2 cell of length decrypted_len, parse and validate the cell * content. Return a newly allocated cell structure or NULL on error. The * circuit and service object are only used for logging purposes. */ @@ -188,7 +188,7 @@ parse_introduce2_encrypted(const uint8_t *decrypted_data, return NULL; } -/* Build a legacy ESTABLISH_INTRO cell with the given circuit nonce and RSA +/** Build a legacy ESTABLISH_INTRO cell with the given circuit nonce and RSA * encryption key. The encoded cell is put in cell_out that MUST at least be * of the size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on * success else a negative value and cell_out is untouched. */ @@ -210,7 +210,7 @@ build_legacy_establish_intro(const char *circ_nonce, crypto_pk_t *enc_key, return cell_len; } -/* Parse an INTRODUCE2 cell from payload of size payload_len for the given +/** Parse an INTRODUCE2 cell from payload of size payload_len for the given * service and circuit which are used only for logging purposes. The resulting * parsed cell is put in cell_ptr_out. * @@ -249,7 +249,7 @@ parse_introduce2_cell(const hs_service_t *service, return -1; } -/* Set the onion public key onion_pk in cell, the encrypted section of an +/** Set the onion public key onion_pk in cell, the encrypted section of an * INTRODUCE1 cell. */ static void introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell, @@ -266,7 +266,7 @@ introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell, trn_cell_introduce_encrypted_getlen_onion_key(cell)); } -/* Set the link specifiers in lspecs in cell, the encrypted section of an +/** Set the link specifiers in lspecs in cell, the encrypted section of an * INTRODUCE1 cell. */ static void introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell, @@ -286,7 +286,7 @@ introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell, trn_cell_introduce_encrypted_add_nspecs(cell, ls)); } -/* Set padding in the enc_cell only if needed that is the total length of both +/** Set padding in the enc_cell only if needed that is the total length of both * sections are below the mininum required for an INTRODUCE1 cell. */ static void introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell, @@ -306,7 +306,7 @@ introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell, } } -/* Encrypt the ENCRYPTED payload and encode it in the cell using the enc_cell +/** Encrypt the ENCRYPTED payload and encode it in the cell using the enc_cell * and the INTRODUCE1 data. * * This can't fail but it is very important that the caller sets every field @@ -394,7 +394,7 @@ introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell, tor_free(encrypted); } -/* Using the INTRODUCE1 data, setup the ENCRYPTED section in cell. This means +/** Using the INTRODUCE1 data, setup the ENCRYPTED section in cell. This means * set it, encrypt it and encode it. */ static void introduce1_set_encrypted(trn_cell_introduce1_t *cell, @@ -435,7 +435,7 @@ introduce1_set_encrypted(trn_cell_introduce1_t *cell, trn_cell_introduce_encrypted_free(enc_cell); } -/* Set the authentication key in the INTRODUCE1 cell from the given data. */ +/** Set the authentication key in the INTRODUCE1 cell from the given data. */ static void introduce1_set_auth_key(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data) @@ -451,7 +451,7 @@ introduce1_set_auth_key(trn_cell_introduce1_t *cell, data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell)); } -/* Set the legacy ID field in the INTRODUCE1 cell from the given data. */ +/** Set the legacy ID field in the INTRODUCE1 cell from the given data. */ static void introduce1_set_legacy_id(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data) @@ -473,7 +473,7 @@ introduce1_set_legacy_id(trn_cell_introduce1_t *cell, } } -/* Build and add to the given DoS cell extension the given parameter type and +/** Build and add to the given DoS cell extension the given parameter type and * value. */ static void build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext, @@ -493,7 +493,7 @@ build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext, /* Not freeing the trunnel object because it is now owned by dos_ext. */ } -/* Build the DoS defense cell extension and put it in the given extensions +/** Build the DoS defense cell extension and put it in the given extensions * object. Return 0 on success, -1 on failure. (Right now, failure is only * possible if there is a bug.) */ static int @@ -568,7 +568,7 @@ build_establish_intro_dos_extension(const hs_service_config_t *service_config, /* Public API */ /* ========== */ -/* Allocate and build all the ESTABLISH_INTRO cell extension. The given +/** Allocate and build all the ESTABLISH_INTRO cell extension. The given * extensions pointer is always set to a valid cell extension object. */ STATIC trn_cell_extension_t * build_establish_intro_extensions(const hs_service_config_t *service_config, @@ -599,7 +599,7 @@ build_establish_intro_extensions(const hs_service_config_t *service_config, return extensions; } -/* Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point +/** Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point * object. The encoded cell is put in cell_out that MUST at least be of the * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else * a negative value and cell_out is untouched. This function also supports @@ -725,7 +725,7 @@ hs_cell_build_establish_intro(const char *circ_nonce, return cell_len; } -/* Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we +/** Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we * are successful at parsing it, return the length of the parsed cell else a * negative value on error. */ ssize_t @@ -747,7 +747,7 @@ hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len) return ret; } -/* Parse the INTRODUCE2 cell using data which contains everything we need to +/** Parse the INTRODUCE2 cell using data which contains everything we need to * do so and contains the destination buffers of information we extract and * compute from the cell. Return 0 on success else a negative value. The * service and circ are only used for logging purposes. */ @@ -908,7 +908,7 @@ hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data, return ret; } -/* Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake +/** Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake * info. The encoded cell is put in cell_out and the length of the data is * returned. This can't fail. */ ssize_t @@ -942,7 +942,7 @@ hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie, return cell_len; } -/* Build an INTRODUCE1 cell from the given data. The encoded cell is put in +/** Build an INTRODUCE1 cell from the given data. The encoded cell is put in * cell_out which must be of at least size RELAY_PAYLOAD_SIZE. On success, the * encoded length is returned else a negative value and the content of * cell_out should be ignored. */ @@ -983,7 +983,7 @@ hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, return cell_len; } -/* Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The +/** Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The * encoded cell is put in cell_out which must be of at least * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the * caller should clear up the content of the cell. @@ -1000,7 +1000,7 @@ hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, return HS_REND_COOKIE_LEN; } -/* Handle an INTRODUCE_ACK cell encoded in payload of length payload_len. +/** Handle an INTRODUCE_ACK cell encoded in payload of length payload_len. * Return the status code on success else a negative value if the cell as not * decodable. */ int @@ -1035,7 +1035,7 @@ hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len) return ret; } -/* Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On +/** Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On * success, handshake_info contains the data in the HANDSHAKE_INFO field, and * 0 is returned. On error, a negative value is returned. */ int @@ -1067,7 +1067,7 @@ hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len, return ret; } -/* Clear the given INTRODUCE1 data structure data. */ +/** Clear the given INTRODUCE1 data structure data. */ void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data) { diff --git a/src/feature/hs/hs_cell.h b/src/feature/hs/hs_cell.h index 864b6fda5f..5ee4347944 100644 --- a/src/feature/hs/hs_cell.h +++ b/src/feature/hs/hs_cell.h @@ -12,35 +12,35 @@ #include "core/or/or.h" #include "feature/hs/hs_service.h" -/* An INTRODUCE1 cell requires at least this amount of bytes (see section +/** An INTRODUCE1 cell requires at least this amount of bytes (see section * 3.2.2 of the specification). Below this value, the cell must be padded. */ #define HS_CELL_INTRODUCE1_MIN_SIZE 246 -/* This data structure contains data that we need to build an INTRODUCE1 cell +/** This data structure contains data that we need to build an INTRODUCE1 cell * used by the INTRODUCE1 build function. */ typedef struct hs_cell_introduce1_data_t { - /* Is this a legacy introduction point? */ + /** Is this a legacy introduction point? */ unsigned int is_legacy : 1; - /* (Legacy only) The encryption key for a legacy intro point. Only set if + /** (Legacy only) The encryption key for a legacy intro point. Only set if * is_legacy is true. */ const crypto_pk_t *legacy_key; - /* Introduction point authentication public key. */ + /** Introduction point authentication public key. */ const ed25519_public_key_t *auth_pk; - /* Introduction point encryption public key. */ + /** Introduction point encryption public key. */ const curve25519_public_key_t *enc_pk; - /* Subcredentials of the service. */ + /** Subcredentials of the service. */ const uint8_t *subcredential; - /* Onion public key for the ntor handshake. */ + /** Onion public key for the ntor handshake. */ const curve25519_public_key_t *onion_pk; - /* Rendezvous cookie. */ + /** Rendezvous cookie. */ const uint8_t *rendezvous_cookie; - /* Public key put before the encrypted data (CLIENT_PK). */ + /** Public key put before the encrypted data (CLIENT_PK). */ const curve25519_keypair_t *client_kp; - /* Rendezvous point link specifiers. */ + /** Rendezvous point link specifiers. */ smartlist_t *link_specifiers; } hs_cell_introduce1_data_t; -/* This data structure contains data that we need to parse an INTRODUCE2 cell +/** This data structure contains data that we need to parse an INTRODUCE2 cell * which is used by the INTRODUCE2 cell parsing function. On a successful * parsing, the onion_pk and rendezvous_cookie will be populated with the * computed key material from the cell data. This structure is only used during @@ -48,32 +48,32 @@ typedef struct hs_cell_introduce1_data_t { typedef struct hs_cell_introduce2_data_t { /*** Immutable Section: Set on structure init. ***/ - /* Introduction point authentication public key. Pointer owned by the + /** Introduction point authentication public key. Pointer owned by the introduction point object through which we received the INTRO2 cell. */ const ed25519_public_key_t *auth_pk; - /* Introduction point encryption keypair for the ntor handshake. Pointer + /** Introduction point encryption keypair for the ntor handshake. Pointer owned by the introduction point object through which we received the INTRO2 cell*/ const curve25519_keypair_t *enc_kp; - /* Subcredentials of the service. Pointer owned by the descriptor that owns + /** Subcredentials of the service. Pointer owned by the descriptor that owns the introduction point through which we received the INTRO2 cell. */ const uint8_t *subcredential; - /* Payload of the received encoded cell. */ + /** Payload of the received encoded cell. */ const uint8_t *payload; - /* Size of the payload of the received encoded cell. */ + /** Size of the payload of the received encoded cell. */ size_t payload_len; /*** Mutable Section: Set upon parsing INTRODUCE2 cell. ***/ - /* Onion public key computed using the INTRODUCE2 encrypted section. */ + /** Onion public key computed using the INTRODUCE2 encrypted section. */ curve25519_public_key_t onion_pk; - /* Rendezvous cookie taken from the INTRODUCE2 encrypted section. */ + /** Rendezvous cookie taken from the INTRODUCE2 encrypted section. */ uint8_t rendezvous_cookie[REND_COOKIE_LEN]; - /* Client public key from the INTRODUCE2 encrypted section. */ + /** Client public key from the INTRODUCE2 encrypted section. */ curve25519_public_key_t client_pk; - /* Link specifiers of the rendezvous point. Contains link_specifier_t. */ + /** Link specifiers of the rendezvous point. Contains link_specifier_t. */ smartlist_t *link_specifiers; - /* Replay cache of the introduction point. */ + /** Replay cache of the introduction point. */ replaycache_t *replay_cache; } hs_cell_introduce2_data_t; @@ -117,4 +117,3 @@ build_establish_intro_extensions(const hs_service_config_t *service_config, #endif /* defined(TOR_UNIT_TESTS) */ #endif /* !defined(TOR_HS_CELL_H) */ - diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index 5e213b5aba..e1e9c7c790 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -637,6 +637,27 @@ hs_circ_service_get_intro_circ(const hs_service_intro_point_t *ip) } } +/* Return an introduction point established circuit matching the given intro + * point object. The circuit purpose has to be CIRCUIT_PURPOSE_S_INTRO. NULL + * is returned is no such circuit can be found. */ +origin_circuit_t * +hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip) +{ + origin_circuit_t *circ; + + tor_assert(ip); + + if (ip->base.is_only_legacy) { + circ = hs_circuitmap_get_intro_circ_v2_service_side(ip->legacy_key_digest); + } else { + circ = hs_circuitmap_get_intro_circ_v3_service_side( + &ip->auth_key_kp.pubkey); + } + + /* Only return circuit if it is established. */ + return (TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_INTRO) ? circ : NULL; +} + /* Called when we fail building a rendezvous circuit at some point other than * the last hop: launches a new circuit to the same rendezvous point. This * supports legacy service. diff --git a/src/feature/hs/hs_circuit.h b/src/feature/hs/hs_circuit.h index e168b301f1..c817f3e37a 100644 --- a/src/feature/hs/hs_circuit.h +++ b/src/feature/hs/hs_circuit.h @@ -35,6 +35,8 @@ void hs_circ_retry_service_rendezvous_point(origin_circuit_t *circ); origin_circuit_t *hs_circ_service_get_intro_circ( const hs_service_intro_point_t *ip); +origin_circuit_t *hs_circ_service_get_established_intro_circ( + const hs_service_intro_point_t *ip); /* Cell API. */ int hs_circ_handle_intro_established(const hs_service_t *service, diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index 492e77faff..c79bc63393 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -43,13 +43,13 @@ #include "core/or/extend_info_st.h" #include "core/or/origin_circuit_st.h" -/* Client-side authorizations for hidden services; map of service identity +/** Client-side authorizations for hidden services; map of service identity * public key to hs_client_service_authorization_t *. */ static digest256map_t *client_auths = NULL; #include "trunnel/hs/cell_introduce1.h" -/* Return a human-readable string for the client fetch status code. */ +/** Return a human-readable string for the client fetch status code. */ static const char * fetch_status_to_string(hs_client_fetch_status_t status) { @@ -73,7 +73,7 @@ fetch_status_to_string(hs_client_fetch_status_t status) } } -/* Return true iff tor should close the SOCKS request(s) for the descriptor +/** Return true iff tor should close the SOCKS request(s) for the descriptor * fetch that ended up with this given status code. */ static int fetch_status_should_close_socks(hs_client_fetch_status_t status) @@ -100,7 +100,7 @@ fetch_status_should_close_socks(hs_client_fetch_status_t status) return 1; } -/* Cancel all descriptor fetches currently in progress. */ +/** Cancel all descriptor fetches currently in progress. */ static void cancel_descriptor_fetches(void) { @@ -124,7 +124,7 @@ cancel_descriptor_fetches(void) log_info(LD_REND, "Hidden service client descriptor fetches cancelled."); } -/* Get all connections that are waiting on a circuit and flag them back to +/** Get all connections that are waiting on a circuit and flag them back to * waiting for a hidden service descriptor for the given service key * service_identity_pk. */ static void @@ -151,7 +151,7 @@ flag_all_conn_wait_desc(const ed25519_public_key_t *service_identity_pk) smartlist_free(conns); } -/* Remove tracked HSDir requests from our history for this hidden service +/** Remove tracked HSDir requests from our history for this hidden service * identity public key. */ static void purge_hid_serv_request(const ed25519_public_key_t *identity_pk) @@ -172,7 +172,7 @@ purge_hid_serv_request(const ed25519_public_key_t *identity_pk) hs_purge_hid_serv_from_last_hid_serv_requests(base64_blinded_pk); } -/* Return true iff there is at least one pending directory descriptor request +/** Return true iff there is at least one pending directory descriptor request * for the service identity_pk. */ static int directory_request_is_pending(const ed25519_public_key_t *identity_pk) @@ -200,7 +200,7 @@ directory_request_is_pending(const ed25519_public_key_t *identity_pk) return ret; } -/* Helper function that changes the state of an entry connection to waiting +/** Helper function that changes the state of an entry connection to waiting * for a circuit. For this to work properly, the connection timestamps are set * to now and the connection is then marked as pending for a circuit. */ static void @@ -220,7 +220,7 @@ mark_conn_as_waiting_for_circuit(connection_t *conn, time_t now) connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn)); } -/* We failed to fetch a descriptor for the service with <b>identity_pk</b> +/** We failed to fetch a descriptor for the service with <b>identity_pk</b> * because of <b>status</b>. Find all pending SOCKS connections for this * service that are waiting on the descriptor and close them with * <b>reason</b>. */ @@ -265,7 +265,7 @@ close_all_socks_conns_waiting_for_desc(const ed25519_public_key_t *identity_pk, smartlist_free(conns); } -/* Find all pending SOCKS connection waiting for a descriptor and retry them +/** Find all pending SOCKS connection waiting for a descriptor and retry them * all. This is called when the directory information changed. */ STATIC void retry_all_socks_conn_waiting_for_desc(void) @@ -321,7 +321,7 @@ retry_all_socks_conn_waiting_for_desc(void) smartlist_free(conns); } -/* A v3 HS circuit successfully connected to the hidden service. Update the +/** A v3 HS circuit successfully connected to the hidden service. Update the * stream state at <b>hs_conn_ident</b> appropriately. */ static void note_connection_attempt_succeeded(const hs_ident_edge_conn_t *hs_conn_ident) @@ -343,7 +343,7 @@ note_connection_attempt_succeeded(const hs_ident_edge_conn_t *hs_conn_ident) * will be reset and thus possible to be retried. */ } -/* Given the pubkey of a hidden service in <b>onion_identity_pk</b>, fetch its +/** Given the pubkey of a hidden service in <b>onion_identity_pk</b>, fetch its * descriptor by launching a dir connection to <b>hsdir</b>. Return a * hs_client_fetch_status_t status code depending on how it went. */ static hs_client_fetch_status_t @@ -451,7 +451,7 @@ fetch_v3_desc, (const ed25519_public_key_t *onion_identity_pk)) return directory_launch_v3_desc_fetch(onion_identity_pk, hsdir_rs); } -/* With a given <b>onion_identity_pk</b>, fetch its descriptor. If +/** With a given <b>onion_identity_pk</b>, fetch its descriptor. If * <b>hsdirs</b> is specified, use the directory servers specified in the list. * Else, use a random server. */ void @@ -469,7 +469,7 @@ hs_client_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk, } } -/* Make sure that the given v3 origin circuit circ is a valid correct +/** Make sure that the given v3 origin circuit circ is a valid correct * introduction circuit. This will BUG() on any problems and hard assert if * the anonymity of the circuit is not ok. Return 0 on success else -1 where * the circuit should be mark for closed immediately. */ @@ -498,7 +498,7 @@ intro_circ_is_ok(const origin_circuit_t *circ) return ret; } -/* Find a descriptor intro point object that matches the given ident in the +/** Find a descriptor intro point object that matches the given ident in the * given descriptor desc. Return NULL if not found. */ static const hs_desc_intro_point_t * find_desc_intro_point_by_ident(const hs_ident_circuit_t *ident, @@ -521,7 +521,7 @@ find_desc_intro_point_by_ident(const hs_ident_circuit_t *ident, return intro_point; } -/* Find a descriptor intro point object from the descriptor object desc that +/** Find a descriptor intro point object from the descriptor object desc that * matches the given legacy identity digest in legacy_id. Return NULL if not * found. */ static hs_desc_intro_point_t * @@ -559,7 +559,7 @@ find_desc_intro_point_by_legacy_id(const char *legacy_id, return ret_ip; } -/* Send an INTRODUCE1 cell along the intro circuit and populate the rend +/** Send an INTRODUCE1 cell along the intro circuit and populate the rend * circuit identifier with the needed key material for the e2e encryption. * Return 0 on success, -1 if there is a transient error such that an action * has been taken to recover and -2 if there is a permanent error indicating @@ -671,7 +671,7 @@ send_introduce1(origin_circuit_t *intro_circ, return status; } -/* Using the introduction circuit circ, setup the authentication key of the +/** Using the introduction circuit circ, setup the authentication key of the * intro point this circuit has extended to. */ static void setup_intro_circ_auth_key(origin_circuit_t *circ) @@ -710,7 +710,7 @@ setup_intro_circ_auth_key(origin_circuit_t *circ) return; } -/* Called when an introduction circuit has opened. */ +/** Called when an introduction circuit has opened. */ static void client_intro_circ_has_opened(origin_circuit_t *circ) { @@ -727,7 +727,7 @@ client_intro_circ_has_opened(origin_circuit_t *circ) connection_ap_attach_pending(1); } -/* Called when a rendezvous circuit has opened. */ +/** Called when a rendezvous circuit has opened. */ static void client_rendezvous_circ_has_opened(origin_circuit_t *circ) { @@ -761,7 +761,7 @@ client_rendezvous_circ_has_opened(origin_circuit_t *circ) } } -/* This is an helper function that convert a descriptor intro point object ip +/** This is an helper function that convert a descriptor intro point object ip * to a newly allocated extend_info_t object fully initialized. Return NULL if * we can't convert it for which chances are that we are missing or malformed * link specifiers. */ @@ -779,7 +779,7 @@ desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip) return ei; } -/* Return true iff the intro point ip for the service service_pk is usable. +/** Return true iff the intro point ip for the service service_pk is usable. * This function checks if the intro point is in the client intro state cache * and checks at the failures. It is considered usable if: * - No error happened (INTRO_POINT_FAILURE_GENERIC) @@ -824,7 +824,7 @@ intro_point_is_usable(const ed25519_public_key_t *service_pk, return 0; } -/* Using a descriptor desc, return a newly allocated extend_info_t object of a +/** Using a descriptor desc, return a newly allocated extend_info_t object of a * randomly picked introduction point from its list. Return NULL if none are * usable. */ STATIC extend_info_t * @@ -929,7 +929,7 @@ client_get_random_intro(const ed25519_public_key_t *service_pk) return ei; } -/* For this introduction circuit, we'll look at if we have any usable +/** For this introduction circuit, we'll look at if we have any usable * introduction point left for this service. If so, we'll use the circuit to * re-extend to a new intro point. Else, we'll close the circuit and its * corresponding rendezvous circuit. Return 0 if we are re-extending else -1 @@ -986,7 +986,7 @@ close_or_reextend_intro_circ(origin_circuit_t *intro_circ) return ret; } -/* Called when we get an INTRODUCE_ACK success status code. Do the appropriate +/** Called when we get an INTRODUCE_ACK success status code. Do the appropriate * actions for the rendezvous point and finally close intro_circ. */ static void handle_introduce_ack_success(origin_circuit_t *intro_circ) @@ -1032,7 +1032,7 @@ handle_introduce_ack_success(origin_circuit_t *intro_circ) return; } -/* Called when we get an INTRODUCE_ACK failure status code. Depending on our +/** Called when we get an INTRODUCE_ACK failure status code. Depending on our * failure cache status, either close the circuit or re-extend to a new * introduction point. */ static void @@ -1054,7 +1054,7 @@ handle_introduce_ack_bad(origin_circuit_t *circ, int status) INTRO_POINT_FAILURE_GENERIC); } -/* Called when we get an INTRODUCE_ACK on the intro circuit circ. The encoded +/** Called when we get an INTRODUCE_ACK on the intro circuit circ. The encoded * cell is in payload of length payload_len. Return 0 on success else a * negative value. The circuit is either close or reuse to re-extend to a new * introduction point. */ @@ -1093,7 +1093,7 @@ handle_introduce_ack(origin_circuit_t *circ, const uint8_t *payload, return ret; } -/* Called when we get a RENDEZVOUS2 cell on the rendezvous circuit circ. The +/** Called when we get a RENDEZVOUS2 cell on the rendezvous circuit circ. The * encoded cell is in payload of length payload_len. Return 0 on success or a * negative value on error. On error, the circuit is marked for close. */ STATIC int @@ -1155,7 +1155,7 @@ handle_rendezvous2(origin_circuit_t *circ, const uint8_t *payload, return ret; } -/* Return true iff the client can fetch a descriptor for this service public +/** Return true iff the client can fetch a descriptor for this service public * identity key and status_out if not NULL is untouched. If the client can * _not_ fetch the descriptor and if status_out is not NULL, it is set with * the fetch status code. */ @@ -1222,7 +1222,7 @@ can_client_refetch_desc(const ed25519_public_key_t *identity_pk, return 0; } -/* Return the client auth in the map using the service identity public key. +/** Return the client auth in the map using the service identity public key. * Return NULL if it does not exist in the map. */ static hs_client_service_authorization_t * find_client_auth(const ed25519_public_key_t *service_identity_pk) @@ -1260,7 +1260,7 @@ hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn) } } -/* With the given encoded descriptor in desc_str and the service key in +/** With the given encoded descriptor in desc_str and the service key in * service_identity_pk, decode the descriptor and set the desc pointer with a * newly allocated descriptor object. * @@ -1319,7 +1319,7 @@ hs_client_decode_descriptor(const char *desc_str, return -1; } -/* Return true iff there are at least one usable intro point in the service +/** Return true iff there are at least one usable intro point in the service * descriptor desc. */ int hs_client_any_intro_points_usable(const ed25519_public_key_t *service_pk, @@ -1368,7 +1368,7 @@ hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk) return status; } -/* This is called when we are trying to attach an AP connection to these +/** This is called when we are trying to attach an AP connection to these * hidden service circuits from connection_ap_handshake_attach_circuit(). * Return 0 on success, -1 for a transient error that is actions were * triggered to recover or -2 for a permenent error where both circuits will @@ -1384,7 +1384,7 @@ hs_client_send_introduce1(origin_circuit_t *intro_circ, rend_circ); } -/* Called when the client circuit circ has been established. It can be either +/** Called when the client circuit circ has been established. It can be either * an introduction or rendezvous circuit. This function handles all hidden * service versions. */ void @@ -1414,7 +1414,7 @@ hs_client_circuit_has_opened(origin_circuit_t *circ) } } -/* Called when we receive a RENDEZVOUS_ESTABLISHED cell. Change the state of +/** Called when we receive a RENDEZVOUS_ESTABLISHED cell. Change the state of * the circuit to CIRCUIT_PURPOSE_C_REND_READY. Return 0 on success else a * negative value and the circuit marked for close. */ int @@ -1485,7 +1485,7 @@ client_service_authorization_free_all(void) digest256map_free(client_auths, client_service_authorization_free_void); } -/* Check if the auth key file name is valid or not. Return 1 if valid, +/** Check if the auth key file name is valid or not. Return 1 if valid, * otherwise return 0. */ STATIC int auth_key_filename_is_valid(const char *filename) @@ -1570,7 +1570,7 @@ parse_auth_file_content(const char *client_key_str) return auth; } -/* From a set of <b>options</b>, setup every client authorization detail +/** From a set of <b>options</b>, setup every client authorization detail * found. Return 0 on success or -1 on failure. If <b>validate_only</b> * is set, parse, warn and return as normal, but don't actually change * the configuration. */ @@ -1685,7 +1685,7 @@ hs_config_client_authorization(const or_options_t *options, return ret; } -/* This is called when a descriptor has arrived following a fetch request and +/** This is called when a descriptor has arrived following a fetch request and * has been stored in the client cache. Every entry connection that matches * the service identity key in the ident will get attached to the hidden * service circuit. */ @@ -1743,7 +1743,7 @@ hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident) smartlist_free(conns); } -/* Return a newly allocated extend_info_t for a randomly chosen introduction +/** Return a newly allocated extend_info_t for a randomly chosen introduction * point for the given edge connection identifier ident. Return NULL if we * can't pick any usable introduction points. */ extend_info_t * @@ -1756,7 +1756,7 @@ hs_client_get_random_intro_from_edge(const edge_connection_t *edge_conn) rend_client_get_random_intro(edge_conn->rend_data); } -/* Called when get an INTRODUCE_ACK cell on the introduction circuit circ. +/** Called when get an INTRODUCE_ACK cell on the introduction circuit circ. * Return 0 on success else a negative value is returned. The circuit will be * closed or reuse to extend again to another intro point. */ int @@ -1785,7 +1785,7 @@ hs_client_receive_introduce_ack(origin_circuit_t *circ, return ret; } -/* Called when get a RENDEZVOUS2 cell on the rendezvous circuit circ. Return +/** Called when get a RENDEZVOUS2 cell on the rendezvous circuit circ. Return * 0 on success else a negative value is returned. The circuit will be closed * on error. */ int @@ -1818,7 +1818,7 @@ hs_client_receive_rendezvous2(origin_circuit_t *circ, return ret; } -/* Extend the introduction circuit circ to another valid introduction point +/** Extend the introduction circuit circ to another valid introduction point * for the hidden service it is trying to connect to, or mark it and launch a * new circuit if we can't extend it. Return 0 on success or possible * success. Return -1 and mark the introduction circuit for close on permanent @@ -1868,7 +1868,7 @@ hs_client_reextend_intro_circuit(origin_circuit_t *circ) return ret; } -/* Close all client introduction circuits related to the given descriptor. +/** Close all client introduction circuits related to the given descriptor. * This is called with a descriptor that is about to get replaced in the * client cache. * @@ -1900,7 +1900,7 @@ hs_client_close_intro_circuits_from_desc(const hs_descriptor_t *desc) } } -/* Release all the storage held by the client subsystem. */ +/** Release all the storage held by the client subsystem. */ void hs_client_free_all(void) { @@ -1909,7 +1909,7 @@ hs_client_free_all(void) client_service_authorization_free_all(); } -/* Purge all potentially remotely-detectable state held in the hidden +/** Purge all potentially remotely-detectable state held in the hidden * service client code. Called on SIGNAL NEWNYM. */ void hs_client_purge_state(void) @@ -1930,7 +1930,7 @@ hs_client_purge_state(void) log_info(LD_REND, "Hidden service client state has been purged."); } -/* Called when our directory information has changed. */ +/** Called when our directory information has changed. */ void hs_client_dir_info_changed(void) { diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h index 96a96755fd..69e48ca31b 100644 --- a/src/feature/hs/hs_client.h +++ b/src/feature/hs/hs_client.h @@ -13,31 +13,31 @@ #include "feature/hs/hs_descriptor.h" #include "feature/hs/hs_ident.h" -/* Status code of a descriptor fetch request. */ +/** Status code of a descriptor fetch request. */ typedef enum { - /* Something internally went wrong. */ + /** Something internally went wrong. */ HS_CLIENT_FETCH_ERROR = -1, - /* The fetch request has been launched successfully. */ + /** The fetch request has been launched successfully. */ HS_CLIENT_FETCH_LAUNCHED = 0, - /* We already have a usable descriptor. No fetch. */ + /** We already have a usable descriptor. No fetch. */ HS_CLIENT_FETCH_HAVE_DESC = 1, - /* No more HSDir available to query. */ + /** No more HSDir available to query. */ HS_CLIENT_FETCH_NO_HSDIRS = 2, - /* The fetch request is not allowed. */ + /** The fetch request is not allowed. */ HS_CLIENT_FETCH_NOT_ALLOWED = 3, - /* We are missing information to be able to launch a request. */ + /** We are missing information to be able to launch a request. */ HS_CLIENT_FETCH_MISSING_INFO = 4, - /* There is a pending fetch for the requested service. */ + /** There is a pending fetch for the requested service. */ HS_CLIENT_FETCH_PENDING = 5, } hs_client_fetch_status_t; /** Client-side configuration of authorization for a service. */ typedef struct hs_client_service_authorization_t { - /* An curve25519 secret key used to compute decryption keys that + /** An curve25519 secret key used to compute decryption keys that * allow the client to decrypt the hidden service descriptor. */ curve25519_secret_key_t enc_seckey; - /* An onion address that is used to connect to the onion service. */ + /** An onion address that is used to connect to the onion service. */ char onion_address[HS_SERVICE_ADDR_LEN_BASE32+1]; } hs_client_service_authorization_t; @@ -120,4 +120,3 @@ STATIC digest256map_t *get_hs_client_auths_map(void); #endif /* defined(HS_CLIENT_PRIVATE) */ #endif /* !defined(TOR_HS_CLIENT_H) */ - diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index 036d23a6b0..cf98bea320 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -44,7 +44,7 @@ /* Trunnel */ #include "trunnel/ed25519_cert.h" -/* Ed25519 Basepoint value. Taken from section 5 of +/** Ed25519 Basepoint value. Taken from section 5 of * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03 */ static const char *str_ed25519_basepoint = "(15112221349535400772501151409588531511" @@ -106,7 +106,7 @@ add_unix_port(smartlist_t *ports, rend_service_port_config_t *p) #endif /* defined(HAVE_SYS_UN_H) */ -/* Helper function: The key is a digest that we compare to a node_t object +/** Helper function: The key is a digest that we compare to a node_t object * current hsdir_index. */ static int compare_digest_to_fetch_hsdir_index(const void *_key, const void **_member) @@ -116,7 +116,7 @@ compare_digest_to_fetch_hsdir_index(const void *_key, const void **_member) return tor_memcmp(key, node->hsdir_index.fetch, DIGEST256_LEN); } -/* Helper function: The key is a digest that we compare to a node_t object +/** Helper function: The key is a digest that we compare to a node_t object * next hsdir_index. */ static int compare_digest_to_store_first_hsdir_index(const void *_key, @@ -127,7 +127,7 @@ compare_digest_to_store_first_hsdir_index(const void *_key, return tor_memcmp(key, node->hsdir_index.store_first, DIGEST256_LEN); } -/* Helper function: The key is a digest that we compare to a node_t object +/** Helper function: The key is a digest that we compare to a node_t object * next hsdir_index. */ static int compare_digest_to_store_second_hsdir_index(const void *_key, @@ -138,7 +138,7 @@ compare_digest_to_store_second_hsdir_index(const void *_key, return tor_memcmp(key, node->hsdir_index.store_second, DIGEST256_LEN); } -/* Helper function: Compare two node_t objects current hsdir_index. */ +/** Helper function: Compare two node_t objects current hsdir_index. */ static int compare_node_fetch_hsdir_index(const void **a, const void **b) { @@ -149,7 +149,7 @@ compare_node_fetch_hsdir_index(const void **a, const void **b) DIGEST256_LEN); } -/* Helper function: Compare two node_t objects next hsdir_index. */ +/** Helper function: Compare two node_t objects next hsdir_index. */ static int compare_node_store_first_hsdir_index(const void **a, const void **b) { @@ -160,7 +160,7 @@ compare_node_store_first_hsdir_index(const void **a, const void **b) DIGEST256_LEN); } -/* Helper function: Compare two node_t objects next hsdir_index. */ +/** Helper function: Compare two node_t objects next hsdir_index. */ static int compare_node_store_second_hsdir_index(const void **a, const void **b) { @@ -171,7 +171,7 @@ compare_node_store_second_hsdir_index(const void **a, const void **b) DIGEST256_LEN); } -/* Allocate and return a string containing the path to filename in directory. +/** Allocate and return a string containing the path to filename in directory. * This function will never return NULL. The caller must free this path. */ char * hs_path_from_filename(const char *directory, const char *filename) @@ -185,8 +185,9 @@ hs_path_from_filename(const char *directory, const char *filename) return file_path; } -/* Make sure that the directory for <b>service</b> is private, using the config - * <b>username</b>. +/** Make sure that the directory for <b>service</b> is private, using the + * config <b>username</b>. + * * If <b>create</b> is true: * - if the directory exists, change permissions if needed, * - if the directory does not exist, create it with the correct permissions. @@ -313,9 +314,9 @@ hs_get_previous_time_period_num(time_t now) return hs_get_time_period_num(now) - 1; } -/* Return the start time of the upcoming time period based on <b>now</b>. If - <b>now</b> is not set, we try to get the time ourselves from a live - consensus. */ +/** Return the start time of the upcoming time period based on <b>now</b>. If + * <b>now</b> is not set, we try to get the time ourselves from a live + * consensus. */ time_t hs_get_start_time_of_next_time_period(time_t now) { @@ -330,7 +331,7 @@ hs_get_start_time_of_next_time_period(time_t now) return (time_t)(start_of_next_tp_in_mins * 60 + time_period_rotation_offset); } -/* Create a new rend_data_t for a specific given <b>version</b>. +/** Create a new rend_data_t for a specific given <b>version</b>. * Return a pointer to the newly allocated data structure. */ static rend_data_t * rend_data_alloc(uint32_t version) @@ -379,7 +380,7 @@ rend_data_free_(rend_data_t *data) } } -/* Allocate and return a deep copy of <b>data</b>. */ +/** Allocate and return a deep copy of <b>data</b>. */ rend_data_t * rend_data_dup(const rend_data_t *data) { @@ -409,7 +410,7 @@ rend_data_dup(const rend_data_t *data) return data_dup; } -/* Compute the descriptor ID for each HS descriptor replica and save them. A +/** Compute the descriptor ID for each HS descriptor replica and save them. A * valid onion address must be present in the <b>rend_data</b>. * * Return 0 on success else -1. */ @@ -447,7 +448,7 @@ compute_desc_id(rend_data_t *rend_data) return ret; } -/* Allocate and initialize a rend_data_t object for a service using the +/** Allocate and initialize a rend_data_t object for a service using the * provided arguments. All arguments are optional (can be NULL), except from * <b>onion_address</b> which MUST be set. The <b>pk_digest</b> is the hash of * the service private key. The <b>cookie</b> is the rendezvous cookie and @@ -479,7 +480,7 @@ rend_data_service_create(const char *onion_address, const char *pk_digest, return rend_data; } -/* Allocate and initialize a rend_data_t object for a client request using the +/** Allocate and initialize a rend_data_t object for a client request using the * given arguments. Either an onion address or a descriptor ID is needed. Both * can be given but in this case only the onion address will be used to make * the descriptor fetch. The <b>cookie</b> is the rendezvous cookie and @@ -520,7 +521,7 @@ rend_data_client_create(const char *onion_address, const char *desc_id, return NULL; } -/* Return the onion address from the rend data. Depending on the version, +/** Return the onion address from the rend data. Depending on the version, * the size of the address can vary but it's always NUL terminated. */ const char * rend_data_get_address(const rend_data_t *rend_data) @@ -536,7 +537,7 @@ rend_data_get_address(const rend_data_t *rend_data) } } -/* Return the descriptor ID for a specific replica number from the rend +/** Return the descriptor ID for a specific replica number from the rend * data. The returned data is a binary digest and depending on the version its * size can vary. The size of the descriptor ID is put in <b>len_out</b> if * non NULL. */ @@ -559,7 +560,7 @@ rend_data_get_desc_id(const rend_data_t *rend_data, uint8_t replica, } } -/* Return the public key digest using the given <b>rend_data</b>. The size of +/** Return the public key digest using the given <b>rend_data</b>. The size of * the digest is put in <b>len_out</b> (if set) which can differ depending on * the version. */ const uint8_t * @@ -582,7 +583,7 @@ rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out) } } -/* Using the given time period number, compute the disaster shared random +/** Using the given time period number, compute the disaster shared random * value and put it in srv_out. It MUST be at least DIGEST256_LEN bytes. */ static void compute_disaster_srv(uint64_t time_period_num, uint8_t *srv_out) @@ -670,7 +671,7 @@ get_second_cached_disaster_srv(void) #endif /* defined(TOR_UNIT_TESTS) */ -/* When creating a blinded key, we need a parameter which construction is as +/** When creating a blinded key, we need a parameter which construction is as * follow: H(pubkey | [secret] | ed25519-basepoint | nonce). * * The nonce has a pre-defined format which uses the time period number @@ -751,7 +752,7 @@ build_hs_checksum(const ed25519_public_key_t *key, uint8_t version, DIGEST_SHA3_256); } -/* Using an ed25519 public key, checksum and version to build the binary +/** Using an ed25519 public key, checksum and version to build the binary * representation of a service address. Put in addr_out. Format is: * addr_out = PUBKEY || CHECKSUM || VERSION * @@ -774,7 +775,7 @@ build_hs_address(const ed25519_public_key_t *key, const uint8_t *checksum, tor_assert(offset == HS_SERVICE_ADDR_LEN); } -/* Helper for hs_parse_address(): Using a binary representation of a service +/** Helper for hs_parse_address(): Using a binary representation of a service * address, parse its content into the key_out, checksum_out and version_out. * Any out variable can be NULL in case the caller would want only one field. * checksum_out MUST at least be 2 bytes long. address must be at least @@ -806,7 +807,7 @@ hs_parse_address_impl(const char *address, ed25519_public_key_t *key_out, tor_assert(offset == HS_SERVICE_ADDR_LEN); } -/* Using the given identity public key and a blinded public key, compute the +/** Using the given identity public key and a blinded public key, compute the * subcredential and put it in subcred_out (must be of size DIGEST256_LEN). * This can't fail. */ void @@ -846,7 +847,7 @@ hs_get_subcredential(const ed25519_public_key_t *identity_pk, memwipe(credential, 0, sizeof(credential)); } -/* From the given list of hidden service ports, find the ones that match the +/** From the given list of hidden service ports, find the ones that match the * given edge connection conn, pick one at random and use it to set the * connection address. Return 0 on success or -1 if none. */ int @@ -903,7 +904,7 @@ hs_set_conn_addr_port(const smartlist_t *ports, edge_connection_t *conn) return (chosen_port) ? 0 : -1; } -/* Using a base32 representation of a service address, parse its content into +/** Using a base32 representation of a service address, parse its content into * the key_out, checksum_out and version_out. Any out variable can be NULL in * case the caller would want only one field. checksum_out MUST at least be 2 * bytes long. @@ -943,7 +944,7 @@ hs_parse_address(const char *address, ed25519_public_key_t *key_out, return -1; } -/* Validate a given onion address. The length, the base32 decoding, and +/** Validate a given onion address. The length, the base32 decoding, and * checksum are validated. Return 1 if valid else 0. */ int hs_address_is_valid(const char *address) @@ -982,7 +983,7 @@ hs_address_is_valid(const char *address) return 0; } -/* Build a service address using an ed25519 public key and a given version. +/** Build a service address using an ed25519 public key and a given version. * The returned address is base32 encoded and put in addr_out. The caller MUST * make sure the addr_out is at least HS_SERVICE_ADDR_LEN_BASE32 + 1 long. * @@ -1012,7 +1013,7 @@ hs_build_address(const ed25519_public_key_t *key, uint8_t version, tor_assert(hs_address_is_valid(addr_out)); } -/* From a given ed25519 public key pk and an optional secret, compute a +/** From a given ed25519 public key pk and an optional secret, compute a * blinded public key and put it in blinded_pk_out. This is only useful to * the client side because the client only has access to the identity public * key of the service. */ @@ -1036,7 +1037,7 @@ hs_build_blinded_pubkey(const ed25519_public_key_t *pk, memwipe(param, 0, sizeof(param)); } -/* From a given ed25519 keypair kp and an optional secret, compute a blinded +/** From a given ed25519 keypair kp and an optional secret, compute a blinded * keypair for the current time period and put it in blinded_kp_out. This is * only useful by the service side because the client doesn't have access to * the identity secret key. */ @@ -1062,7 +1063,7 @@ hs_build_blinded_keypair(const ed25519_keypair_t *kp, memwipe(param, 0, sizeof(param)); } -/* Return true if we are currently in the time segment between a new time +/** Return true if we are currently in the time segment between a new time * period and a new SRV (in the real network that happens between 12:00 and * 00:00 UTC). Here is a diagram showing exactly when this returns true: * @@ -1102,7 +1103,7 @@ hs_in_period_between_tp_and_srv,(const networkstatus_t *consensus, time_t now)) return 1; } -/* Return 1 if any virtual port in ports needs a circuit with good uptime. +/** Return 1 if any virtual port in ports needs a circuit with good uptime. * Else return 0. */ int hs_service_requires_uptime_circ(const smartlist_t *ports) @@ -1118,7 +1119,7 @@ hs_service_requires_uptime_circ(const smartlist_t *ports) return 0; } -/* Build hs_index which is used to find the responsible hsdirs. This index +/** Build hs_index which is used to find the responsible hsdirs. This index * value is used to select the responsible HSDir where their hsdir_index is * closest to this value. * SHA3-256("store-at-idx" | blinded_public_key | @@ -1160,7 +1161,7 @@ hs_build_hs_index(uint64_t replica, const ed25519_public_key_t *blinded_pk, crypto_digest_free(digest); } -/* Build hsdir_index which is used to find the responsible hsdirs. This is the +/** Build hsdir_index which is used to find the responsible hsdirs. This is the * index value that is compare to the hs_index when selecting an HSDir. * SHA3-256("node-idx" | node_identity | * shared_random_value | INT_8(period_length) | INT_8(period_num) ) @@ -1201,7 +1202,7 @@ hs_build_hsdir_index(const ed25519_public_key_t *identity_pk, crypto_digest_free(digest); } -/* Return a newly allocated buffer containing the current shared random value +/** Return a newly allocated buffer containing the current shared random value * or if not present, a disaster value is computed using the given time period * number. If a consensus is provided in <b>ns</b>, use it to get the SRV * value. This function can't fail. */ @@ -1220,7 +1221,7 @@ hs_get_current_srv(uint64_t time_period_num, const networkstatus_t *ns) return sr_value; } -/* Return a newly allocated buffer containing the previous shared random +/** Return a newly allocated buffer containing the previous shared random * value or if not present, a disaster value is computed using the given time * period number. This function can't fail. */ uint8_t * @@ -1238,7 +1239,7 @@ hs_get_previous_srv(uint64_t time_period_num, const networkstatus_t *ns) return sr_value; } -/* Return the number of replicas defined by a consensus parameter or the +/** Return the number of replicas defined by a consensus parameter or the * default value. */ int32_t hs_get_hsdir_n_replicas(void) @@ -1248,7 +1249,7 @@ hs_get_hsdir_n_replicas(void) HS_DEFAULT_HSDIR_N_REPLICAS, 1, 16); } -/* Return the spread fetch value defined by a consensus parameter or the +/** Return the spread fetch value defined by a consensus parameter or the * default value. */ int32_t hs_get_hsdir_spread_fetch(void) @@ -1258,7 +1259,7 @@ hs_get_hsdir_spread_fetch(void) HS_DEFAULT_HSDIR_SPREAD_FETCH, 1, 128); } -/* Return the spread store value defined by a consensus parameter or the +/** Return the spread store value defined by a consensus parameter or the * default value. */ int32_t hs_get_hsdir_spread_store(void) @@ -1301,7 +1302,7 @@ node_has_hsdir_index(const node_t *node) return 1; } -/* For a given blinded key and time period number, get the responsible HSDir +/** For a given blinded key and time period number, get the responsible HSDir * and put their routerstatus_t object in the responsible_dirs list. If * 'use_second_hsdir_index' is true, use the second hsdir_index of the node_t * is used. If 'for_fetching' is true, the spread fetch consensus parameter is @@ -1674,7 +1675,7 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str, return hs_dir; } -/* Given a list of link specifiers lspecs, a curve 25519 onion_key, and +/** Given a list of link specifiers lspecs, a curve 25519 onion_key, and * a direct connection boolean direct_conn (true for single onion services), * return a newly allocated extend_info_t object. * @@ -1787,7 +1788,7 @@ hs_get_extend_info_from_lspecs(const smartlist_t *lspecs, /***********************************************************************/ -/* Initialize the entire HS subsytem. This is called in tor_init() before any +/** Initialize the entire HS subsytem. This is called in tor_init() before any * torrc options are loaded. Only for >= v3. */ void hs_init(void) @@ -1797,7 +1798,7 @@ hs_init(void) hs_cache_init(); } -/* Release and cleanup all memory of the HS subsystem (all version). This is +/** Release and cleanup all memory of the HS subsystem (all version). This is * called by tor_free_all(). */ void hs_free_all(void) @@ -1808,7 +1809,7 @@ hs_free_all(void) hs_client_free_all(); } -/* For the given origin circuit circ, decrement the number of rendezvous +/** For the given origin circuit circ, decrement the number of rendezvous * stream counter. This handles every hidden service version. */ void hs_dec_rdv_stream_counter(origin_circuit_t *circ) @@ -1825,7 +1826,7 @@ hs_dec_rdv_stream_counter(origin_circuit_t *circ) } } -/* For the given origin circuit circ, increment the number of rendezvous +/** For the given origin circuit circ, increment the number of rendezvous * stream counter. This handles every hidden service version. */ void hs_inc_rdv_stream_counter(origin_circuit_t *circ) @@ -1842,7 +1843,7 @@ hs_inc_rdv_stream_counter(origin_circuit_t *circ) } } -/* Return a newly allocated link specifier object that is a copy of dst. */ +/** Return a newly allocated link specifier object that is a copy of dst. */ link_specifier_t * link_specifier_dup(const link_specifier_t *src) { diff --git a/src/feature/hs/hs_common.h b/src/feature/hs/hs_common.h index 3009780d90..1a3c563261 100644 --- a/src/feature/hs/hs_common.h +++ b/src/feature/hs/hs_common.h @@ -19,13 +19,14 @@ struct ed25519_keypair_t; /* Trunnel */ #include "trunnel/ed25519_cert.h" -/* Protocol version 2. Use this instead of hardcoding "2" in the code base, +/** Protocol version 2. Use this instead of hardcoding "2" in the code base, * this adds a clearer semantic to the value when used. */ #define HS_VERSION_TWO 2 -/* Version 3 of the protocol (prop224). */ +/** Version 3 of the protocol (prop224). */ #define HS_VERSION_THREE 3 -/* Earliest and latest version we support. */ +/** Earliest version we support. */ #define HS_VERSION_MIN HS_VERSION_TWO +/** Latest version we support. */ #define HS_VERSION_MAX HS_VERSION_THREE /** Try to maintain this many intro points per service by default. */ @@ -48,94 +49,95 @@ struct ed25519_keypair_t; * rendezvous point before giving up? */ #define MAX_REND_TIMEOUT 30 -/* String prefix for the signature of ESTABLISH_INTRO */ +/** String prefix for the signature of ESTABLISH_INTRO */ #define ESTABLISH_INTRO_SIG_PREFIX "Tor establish-intro cell v1" -/* The default HS time period length */ +/** The default HS time period length */ #define HS_TIME_PERIOD_LENGTH_DEFAULT 1440 /* 1440 minutes == one day */ -/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */ +/** The minimum time period length as seen in prop224 section [TIME-PERIODS] */ #define HS_TIME_PERIOD_LENGTH_MIN 30 /* minutes */ -/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */ +/** The minimum time period length as seen in prop224 section [TIME-PERIODS] */ #define HS_TIME_PERIOD_LENGTH_MAX (60 * 24 * 10) /* 10 days or 14400 minutes */ -/* Prefix of the onion address checksum. */ +/** Prefix of the onion address checksum. */ #define HS_SERVICE_ADDR_CHECKSUM_PREFIX ".onion checksum" -/* Length of the checksum prefix minus the NUL terminated byte. */ +/** Length of the checksum prefix minus the NUL terminated byte. */ #define HS_SERVICE_ADDR_CHECKSUM_PREFIX_LEN \ (sizeof(HS_SERVICE_ADDR_CHECKSUM_PREFIX) - 1) -/* Length of the resulting checksum of the address. The construction of this +/** Length of the resulting checksum of the address. The construction of this * checksum looks like: * CHECKSUM = ".onion checksum" || PUBKEY || VERSION * where VERSION is 1 byte. This is pre-hashing. */ #define HS_SERVICE_ADDR_CHECKSUM_INPUT_LEN \ (HS_SERVICE_ADDR_CHECKSUM_PREFIX_LEN + ED25519_PUBKEY_LEN + sizeof(uint8_t)) -/* The amount of bytes we use from the address checksum. */ +/** The amount of bytes we use from the address checksum. */ #define HS_SERVICE_ADDR_CHECKSUM_LEN_USED 2 -/* Length of the binary encoded service address which is of course before the +/** Length of the binary encoded service address which is of course before the * base32 encoding. Construction is: * PUBKEY || CHECKSUM || VERSION * with 1 byte VERSION and 2 bytes CHECKSUM. The following is 35 bytes. */ #define HS_SERVICE_ADDR_LEN \ (ED25519_PUBKEY_LEN + HS_SERVICE_ADDR_CHECKSUM_LEN_USED + sizeof(uint8_t)) -/* Length of 'y' portion of 'y.onion' URL. This is base32 encoded and the +/** Length of 'y' portion of 'y.onion' URL. This is base32 encoded and the * length ends up to 56 bytes (not counting the terminated NUL byte.) */ #define HS_SERVICE_ADDR_LEN_BASE32 \ (CEIL_DIV(HS_SERVICE_ADDR_LEN * 8, 5)) -/* The default HS time period length */ +/** The default HS time period length */ #define HS_TIME_PERIOD_LENGTH_DEFAULT 1440 /* 1440 minutes == one day */ -/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */ +/** The minimum time period length as seen in prop224 section [TIME-PERIODS] */ #define HS_TIME_PERIOD_LENGTH_MIN 30 /* minutes */ -/* The minimum time period length as seen in prop224 section [TIME-PERIODS] */ +/** The minimum time period length as seen in prop224 section [TIME-PERIODS] */ #define HS_TIME_PERIOD_LENGTH_MAX (60 * 24 * 10) /* 10 days or 14400 minutes */ -/* The time period rotation offset as seen in prop224 section [TIME-PERIODS] */ +/** The time period rotation offset as seen in prop224 section + * [TIME-PERIODS] */ #define HS_TIME_PERIOD_ROTATION_OFFSET (12 * 60) /* minutes */ -/* Keyblinding parameter construction is as follow: +/** Keyblinding parameter construction is as follow: * "key-blind" || INT_8(period_num) || INT_8(start_period_sec) */ #define HS_KEYBLIND_NONCE_PREFIX "key-blind" #define HS_KEYBLIND_NONCE_PREFIX_LEN (sizeof(HS_KEYBLIND_NONCE_PREFIX) - 1) #define HS_KEYBLIND_NONCE_LEN \ (HS_KEYBLIND_NONCE_PREFIX_LEN + sizeof(uint64_t) + sizeof(uint64_t)) -/* Credential and subcredential prefix value. */ +/** Credential and subcredential prefix value. */ #define HS_CREDENTIAL_PREFIX "credential" #define HS_CREDENTIAL_PREFIX_LEN (sizeof(HS_CREDENTIAL_PREFIX) - 1) #define HS_SUBCREDENTIAL_PREFIX "subcredential" #define HS_SUBCREDENTIAL_PREFIX_LEN (sizeof(HS_SUBCREDENTIAL_PREFIX) - 1) -/* Node hidden service stored at index prefix value. */ +/** Node hidden service stored at index prefix value. */ #define HS_INDEX_PREFIX "store-at-idx" #define HS_INDEX_PREFIX_LEN (sizeof(HS_INDEX_PREFIX) - 1) -/* Node hidden service directory index prefix value. */ +/** Node hidden service directory index prefix value. */ #define HSDIR_INDEX_PREFIX "node-idx" #define HSDIR_INDEX_PREFIX_LEN (sizeof(HSDIR_INDEX_PREFIX) - 1) -/* Prefix of the shared random value disaster mode. */ +/** Prefix of the shared random value disaster mode. */ #define HS_SRV_DISASTER_PREFIX "shared-random-disaster" #define HS_SRV_DISASTER_PREFIX_LEN (sizeof(HS_SRV_DISASTER_PREFIX) - 1) -/* Default value of number of hsdir replicas (hsdir_n_replicas). */ +/** Default value of number of hsdir replicas (hsdir_n_replicas). */ #define HS_DEFAULT_HSDIR_N_REPLICAS 2 -/* Default value of hsdir spread store (hsdir_spread_store). */ +/** Default value of hsdir spread store (hsdir_spread_store). */ #define HS_DEFAULT_HSDIR_SPREAD_STORE 4 -/* Default value of hsdir spread fetch (hsdir_spread_fetch). */ +/** Default value of hsdir spread fetch (hsdir_spread_fetch). */ #define HS_DEFAULT_HSDIR_SPREAD_FETCH 3 -/* The size of a legacy RENDEZVOUS1 cell which adds up to 168 bytes. It is +/** The size of a legacy RENDEZVOUS1 cell which adds up to 168 bytes. It is * bigger than the 84 bytes needed for version 3 so we need to pad up to that * length so it is indistinguishable between versions. */ #define HS_LEGACY_RENDEZVOUS_CELL_SIZE \ (REND_COOKIE_LEN + DH1024_KEY_LEN + DIGEST_LEN) -/* Type of authentication key used by an introduction point. */ +/** Type of authentication key used by an introduction point. */ typedef enum { HS_AUTH_KEY_TYPE_LEGACY = 1, HS_AUTH_KEY_TYPE_ED25519 = 2, } hs_auth_key_type_t; -/* Return value when adding an ephemeral service through the ADD_ONION +/** Return value when adding an ephemeral service through the ADD_ONION * control port command. Both v2 and v3 share these. */ typedef enum { RSAE_BADAUTH = -5, /**< Invalid auth_type/auth_clients */ @@ -146,18 +148,18 @@ typedef enum { RSAE_OKAY = 0 /**< Service added as expected */ } hs_service_add_ephemeral_status_t; -/* Represents the mapping from a virtual port of a rendezvous service to a +/** Represents the mapping from a virtual port of a rendezvous service to a * real port on some IP. */ typedef struct rend_service_port_config_t { - /* The incoming HS virtual port we're mapping */ + /** The incoming HS virtual port we're mapping */ uint16_t virtual_port; - /* Is this an AF_UNIX port? */ + /** Is this an AF_UNIX port? */ unsigned int is_unix_addr:1; - /* The outgoing TCP port to use, if !is_unix_addr */ + /** The outgoing TCP port to use, if !is_unix_addr */ uint16_t real_port; - /* The outgoing IPv4 or IPv6 address to use, if !is_unix_addr */ + /** The outgoing IPv4 or IPv6 address to use, if !is_unix_addr */ tor_addr_t real_addr; - /* The socket path to connect to, if is_unix_addr */ + /** The socket path to connect to, if is_unix_addr */ char unix_addr[FLEXIBLE_ARRAY_MEMBER]; } rend_service_port_config_t; diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c index 924ab3115e..60f2bfb0de 100644 --- a/src/feature/hs/hs_descriptor.c +++ b/src/feature/hs/hs_descriptor.c @@ -102,7 +102,7 @@ #define str_desc_auth_client "auth-client" #define str_encrypted "encrypted" -/* Authentication supported types. */ +/** Authentication supported types. */ static const struct { hs_desc_auth_type_t type; const char *identifier; @@ -112,7 +112,7 @@ static const struct { { 0, NULL } }; -/* Descriptor ruleset. */ +/** Descriptor ruleset. */ static token_rule_t hs_desc_v3_token_table[] = { T1_START(str_hs_desc, R_HS_DESCRIPTOR, EQ(1), NO_OBJ), T1(str_lifetime, R3_DESC_LIFETIME, EQ(1), NO_OBJ), @@ -123,7 +123,7 @@ static token_rule_t hs_desc_v3_token_table[] = { END_OF_TABLE }; -/* Descriptor ruleset for the superencrypted section. */ +/** Descriptor ruleset for the superencrypted section. */ static token_rule_t hs_desc_superencrypted_v3_token_table[] = { T1_START(str_desc_auth_type, R3_DESC_AUTH_TYPE, GE(1), NO_OBJ), T1(str_desc_auth_key, R3_DESC_AUTH_KEY, GE(1), NO_OBJ), @@ -132,7 +132,7 @@ static token_rule_t hs_desc_superencrypted_v3_token_table[] = { END_OF_TABLE }; -/* Descriptor ruleset for the encrypted section. */ +/** Descriptor ruleset for the encrypted section. */ static token_rule_t hs_desc_encrypted_v3_token_table[] = { T1_START(str_create2_formats, R3_CREATE2_FORMATS, CONCAT_ARGS, NO_OBJ), T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, ARGS, NO_OBJ), @@ -140,7 +140,7 @@ static token_rule_t hs_desc_encrypted_v3_token_table[] = { END_OF_TABLE }; -/* Descriptor ruleset for the introduction points section. */ +/** Descriptor ruleset for the introduction points section. */ static token_rule_t hs_desc_intro_point_v3_token_table[] = { T1_START(str_intro_point, R3_INTRODUCTION_POINT, EQ(1), NO_OBJ), T1N(str_ip_onion_key, R3_INTRO_ONION_KEY, GE(2), OBJ_OK), @@ -152,7 +152,7 @@ static token_rule_t hs_desc_intro_point_v3_token_table[] = { END_OF_TABLE }; -/* Using a key, salt and encrypted payload, build a MAC and put it in mac_out. +/** Using a key, salt and encrypted payload, build a MAC and put it in mac_out. * We use SHA3-256 for the MAC computation. * This function can't fail. */ static void @@ -184,7 +184,7 @@ build_mac(const uint8_t *mac_key, size_t mac_key_len, crypto_digest_free(digest); } -/* Using a secret data and a given decriptor object, build the secret +/** Using a secret data and a given decriptor object, build the secret * input needed for the KDF. * * secret_input = SECRET_DATA | subcredential | INT_8(revision_counter) @@ -224,7 +224,7 @@ build_secret_input(const hs_descriptor_t *desc, return secret_input_len; } -/* Do the KDF construction and put the resulting data in key_out which is of +/** Do the KDF construction and put the resulting data in key_out which is of * key_out_len length. It uses SHAKE-256 as specified in the spec. */ static void build_kdf_key(const hs_descriptor_t *desc, @@ -269,7 +269,7 @@ build_kdf_key(const hs_descriptor_t *desc, tor_free(secret_input); } -/* Using the given descriptor, secret data, and salt, run it through our +/** Using the given descriptor, secret data, and salt, run it through our * KDF function and then extract a secret key in key_out, the IV in iv_out * and MAC in mac_out. This function can't fail. */ static void @@ -308,7 +308,7 @@ build_secret_key_iv_mac(const hs_descriptor_t *desc, /* === ENCODING === */ -/* Encode the given link specifier objects into a newly allocated string. +/** Encode the given link specifier objects into a newly allocated string. * This can't fail so caller can always assume a valid string being * returned. */ STATIC char * @@ -355,7 +355,7 @@ encode_link_specifiers(const smartlist_t *specs) return encoded_b64; } -/* Encode an introduction point legacy key and certificate. Return a newly +/** Encode an introduction point legacy key and certificate. Return a newly * allocated string with it. On failure, return NULL. */ static char * encode_legacy_key(const hs_desc_intro_point_t *ip) @@ -392,7 +392,7 @@ encode_legacy_key(const hs_desc_intro_point_t *ip) return encoded; } -/* Encode an introduction point encryption key and certificate. Return a newly +/** Encode an introduction point encryption key and certificate. Return a newly * allocated string with it. On failure, return NULL. */ static char * encode_enc_key(const hs_desc_intro_point_t *ip) @@ -418,7 +418,7 @@ encode_enc_key(const hs_desc_intro_point_t *ip) return encoded; } -/* Encode an introduction point onion key. Return a newly allocated string +/** Encode an introduction point onion key. Return a newly allocated string * with it. Can not fail. */ static char * encode_onion_key(const hs_desc_intro_point_t *ip) @@ -435,7 +435,7 @@ encode_onion_key(const hs_desc_intro_point_t *ip) return encoded; } -/* Encode an introduction point object and return a newly allocated string +/** Encode an introduction point object and return a newly allocated string * with it. On failure, return NULL. */ static char * encode_intro_point(const ed25519_public_key_t *sig_key, @@ -505,7 +505,7 @@ encode_intro_point(const ed25519_public_key_t *sig_key, return encoded_ip; } -/* Given a source length, return the new size including padding for the +/** Given a source length, return the new size including padding for the * plaintext encryption. */ static size_t compute_padded_plaintext_length(size_t plaintext_len) @@ -525,7 +525,7 @@ compute_padded_plaintext_length(size_t plaintext_len) return plaintext_padded_len; } -/* Given a buffer, pad it up to the encrypted section padding requirement. Set +/** Given a buffer, pad it up to the encrypted section padding requirement. Set * the newly allocated string in padded_out and return the length of the * padded buffer. */ STATIC size_t @@ -548,7 +548,7 @@ build_plaintext_padding(const char *plaintext, size_t plaintext_len, return padded_len; } -/* Using a key, IV and plaintext data of length plaintext_len, create the +/** Using a key, IV and plaintext data of length plaintext_len, create the * encrypted section by encrypting it and setting encrypted_out with the * data. Return size of the encrypted data buffer. */ static size_t @@ -593,7 +593,7 @@ build_encrypted(const uint8_t *key, const uint8_t *iv, const char *plaintext, return encrypted_len; } -/* Encrypt the given <b>plaintext</b> buffer using <b>desc</b> and +/** Encrypt the given <b>plaintext</b> buffer using <b>desc</b> and * <b>secret_data</b> to get the keys. Set encrypted_out with the encrypted * data and return the length of it. <b>is_superencrypted_layer</b> is set * if this is the outer encrypted layer of the descriptor. */ @@ -663,7 +663,7 @@ encrypt_descriptor_data(const hs_descriptor_t *desc, return final_blob_len; } -/* Create and return a string containing a client-auth entry. It's the +/** Create and return a string containing a client-auth entry. It's the * responsibility of the caller to free the returned string. This function * will never fail. */ static char * @@ -733,7 +733,7 @@ get_all_auth_client_lines(const hs_descriptor_t *desc) return auth_client_lines_str; } -/* Create the inner layer of the descriptor (which includes the intro points, +/** Create the inner layer of the descriptor (which includes the intro points, * etc.). Return a newly-allocated string with the layer plaintext, or NULL if * an error occurred. It's the responsibility of the caller to free the * returned string. */ @@ -789,7 +789,7 @@ get_inner_encrypted_layer_plaintext(const hs_descriptor_t *desc) return encoded_str; } -/* Create the middle layer of the descriptor, which includes the client auth +/** Create the middle layer of the descriptor, which includes the client auth * data and the encrypted inner layer (provided as a base64 string at * <b>layer2_b64_ciphertext</b>). Return a newly-allocated string with the * layer plaintext. It's the responsibility of the caller to free the returned @@ -845,7 +845,7 @@ get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc, return layer1_str; } -/* Encrypt <b>encoded_str</b> into an encrypted blob and then base64 it before +/** Encrypt <b>encoded_str</b> into an encrypted blob and then base64 it before * returning it. <b>desc</b> is provided to derive the encryption * keys. <b>secret_data</b> is also proved to derive the encryption keys. * <b>is_superencrypted_layer</b> is set if <b>encoded_str</b> is the @@ -878,7 +878,7 @@ encrypt_desc_data_and_base64(const hs_descriptor_t *desc, return enc_b64; } -/* Generate the secret data which is used to encrypt/decrypt the descriptor. +/** Generate the secret data which is used to encrypt/decrypt the descriptor. * * SECRET_DATA = blinded-public-key * SECRET_DATA = blinded-public-key | descriptor_cookie @@ -925,7 +925,7 @@ build_secret_data(const ed25519_public_key_t *blinded_pubkey, return secret_data_len; } -/* Generate and encode the superencrypted portion of <b>desc</b>. This also +/** Generate and encode the superencrypted portion of <b>desc</b>. This also * involves generating the encrypted portion of the descriptor, and performing * the superencryption. A newly allocated NUL-terminated string pointer * containing the encrypted encoded blob is put in encrypted_blob_out. Return 0 @@ -999,7 +999,7 @@ encode_superencrypted_data(const hs_descriptor_t *desc, return ret; } -/* Encode a v3 HS descriptor. Return 0 on success and set encoded_out to the +/** Encode a v3 HS descriptor. Return 0 on success and set encoded_out to the * newly allocated string of the encoded descriptor. On error, -1 is returned * and encoded_out is untouched. */ static int @@ -1111,7 +1111,7 @@ desc_encode_v3(const hs_descriptor_t *desc, /* === DECODING === */ -/* Given the token tok for an auth client, decode it as +/** Given the token tok for an auth client, decode it as * hs_desc_authorized_client_t. tok->args MUST contain at least 3 elements * Return 0 on success else -1 on failure. */ static int @@ -1147,7 +1147,7 @@ decode_auth_client(const directory_token_t *tok, return ret; } -/* Given an encoded string of the link specifiers, return a newly allocated +/** Given an encoded string of the link specifiers, return a newly allocated * list of decoded link specifiers. Return NULL on error. */ STATIC smartlist_t * decode_link_specifiers(const char *encoded) @@ -1201,7 +1201,7 @@ decode_link_specifiers(const char *encoded) return results; } -/* Given a list of authentication types, decode it and put it in the encrypted +/** Given a list of authentication types, decode it and put it in the encrypted * data section. Return 1 if we at least know one of the type or 0 if we know * none of them. */ static int @@ -1229,7 +1229,7 @@ decode_auth_type(hs_desc_encrypted_data_t *desc, const char *list) return match; } -/* Parse a space-delimited list of integers representing CREATE2 formats into +/** Parse a space-delimited list of integers representing CREATE2 formats into * the bitfield in hs_desc_encrypted_data_t. Ignore unrecognized values. */ static void decode_create2_list(hs_desc_encrypted_data_t *desc, const char *list) @@ -1263,7 +1263,7 @@ decode_create2_list(hs_desc_encrypted_data_t *desc, const char *list) smartlist_free(tokens); } -/* Given a certificate, validate the certificate for certain conditions which +/** Given a certificate, validate the certificate for certain conditions which * are if the given type matches the cert's one, if the signing key is * included and if the that key was actually used to sign the certificate. * @@ -1300,7 +1300,7 @@ cert_is_valid(tor_cert_t *cert, uint8_t type, const char *log_obj_type) return 0; } -/* Given some binary data, try to parse it to get a certificate object. If we +/** Given some binary data, try to parse it to get a certificate object. If we * have a valid cert, validate it using the given wanted type. On error, print * a log using the err_msg has the certificate identifier adding semantic to * the log and cert_out is set to NULL. On success, 0 is returned and cert_out @@ -1337,7 +1337,7 @@ cert_parse_and_validate(tor_cert_t **cert_out, const char *data, return -1; } -/* Return true iff the given length of the encrypted data of a descriptor +/** Return true iff the given length of the encrypted data of a descriptor * passes validation. */ STATIC int encrypted_data_length_is_valid(size_t len) @@ -1356,7 +1356,7 @@ encrypted_data_length_is_valid(size_t len) return 0; } -/* Build the KEYS component for the authorized client computation. The format +/** Build the KEYS component for the authorized client computation. The format * of the construction is: * * SECRET_SEED = x25519(sk, pk) @@ -1400,7 +1400,7 @@ build_descriptor_cookie_keys(const uint8_t *subcredential, return keystream_len; } -/* Decrypt the descriptor cookie given the descriptor, the auth client, +/** Decrypt the descriptor cookie given the descriptor, the auth client, * and the client secret key. On sucess, return 0 and a newly allocated * descriptor cookie descriptor_cookie_out. On error or if the client id * is invalid, return -1 and descriptor_cookie_out is set to @@ -1592,7 +1592,7 @@ decrypt_desc_layer,(const hs_descriptor_t *desc, return result_len; } -/* Decrypt the superencrypted section of the descriptor using the given +/** Decrypt the superencrypted section of the descriptor using the given * descriptor object <b>desc</b>. A newly allocated NUL terminated string is * put in decrypted_out which contains the superencrypted layer of the * descriptor. Return the length of decrypted_out on success else 0 is @@ -1624,7 +1624,7 @@ desc_decrypt_superencrypted(const hs_descriptor_t *desc, char **decrypted_out) return superencrypted_len; } -/* Decrypt the encrypted section of the descriptor using the given descriptor +/** Decrypt the encrypted section of the descriptor using the given descriptor * object <b>desc</b>. A newly allocated NUL terminated string is put in * decrypted_out which contains the encrypted layer of the descriptor. * Return the length of decrypted_out on success else 0 is returned and @@ -1677,7 +1677,7 @@ desc_decrypt_encrypted(const hs_descriptor_t *desc, return encrypted_len; } -/* Given the token tok for an intro point legacy key, the list of tokens, the +/** Given the token tok for an intro point legacy key, the list of tokens, the * introduction point ip being decoded and the descriptor desc from which it * comes from, decode the legacy key and set the intro point object. Return 0 * on success else -1 on failure. */ @@ -1735,7 +1735,7 @@ decode_intro_legacy_key(const directory_token_t *tok, return -1; } -/* Dig into the descriptor <b>tokens</b> to find the onion key we should use +/** Dig into the descriptor <b>tokens</b> to find the onion key we should use * for this intro point, and set it into <b>onion_key_out</b>. Return 0 if it * was found and well-formed, otherwise return -1 in case of errors. */ static int @@ -1779,7 +1779,7 @@ set_intro_point_onion_key(curve25519_public_key_t *onion_key_out, return retval; } -/* Given the start of a section and the end of it, decode a single +/** Given the start of a section and the end of it, decode a single * introduction point from that section. Return a newly allocated introduction * point object containing the decoded data. Return NULL if the section can't * be decoded. */ @@ -1908,7 +1908,7 @@ decode_introduction_point(const hs_descriptor_t *desc, const char *start) return ip; } -/* Given a descriptor string at <b>data</b>, decode all possible introduction +/** Given a descriptor string at <b>data</b>, decode all possible introduction * points that we can find. Add the introduction point object to desc_enc as we * find them. This function can't fail and it is possible that zero * introduction points can be decoded. */ @@ -1972,7 +1972,7 @@ decode_intro_points(const hs_descriptor_t *desc, smartlist_free(intro_points); } -/* Return 1 iff the given base64 encoded signature in b64_sig from the encoded +/** Return 1 iff the given base64 encoded signature in b64_sig from the encoded * descriptor in encoded_desc validates the descriptor content. */ STATIC int desc_sig_is_valid(const char *b64_sig, @@ -2031,7 +2031,7 @@ desc_sig_is_valid(const char *b64_sig, return ret; } -/* Decode descriptor plaintext data for version 3. Given a list of tokens, an +/** Decode descriptor plaintext data for version 3. Given a list of tokens, an * allocated plaintext object that will be populated and the encoded * descriptor with its length. The last one is needed for signature * verification. Unknown tokens are simply ignored so this won't error on @@ -2134,7 +2134,7 @@ desc_decode_plaintext_v3(smartlist_t *tokens, return -1; } -/* Decode the version 3 superencrypted section of the given descriptor desc. +/** Decode the version 3 superencrypted section of the given descriptor desc. * The desc_superencrypted_out will be populated with the decoded data. * Return 0 on success else -1. */ static int @@ -2249,7 +2249,7 @@ desc_decode_superencrypted_v3(const hs_descriptor_t *desc, return ret; } -/* Decode the version 3 encrypted section of the given descriptor desc. The +/** Decode the version 3 encrypted section of the given descriptor desc. The * desc_encrypted_out will be populated with the decoded data. Return 0 on * success else -1. */ static int @@ -2364,7 +2364,7 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc, return ret; } -/* Table of encrypted decode function version specific. The function are +/** Table of encrypted decode function version specific. The function are * indexed by the version number so v3 callback is at index 3 in the array. */ static int (*decode_encrypted_handlers[])( @@ -2376,7 +2376,7 @@ static int desc_decode_encrypted_v3, }; -/* Decode the encrypted data section of the given descriptor and store the +/** Decode the encrypted data section of the given descriptor and store the * data in the given encrypted data object. Return 0 on success else a * negative value on error. */ int @@ -2417,7 +2417,7 @@ hs_desc_decode_encrypted(const hs_descriptor_t *desc, return ret; } -/* Table of superencrypted decode function version specific. The function are +/** Table of superencrypted decode function version specific. The function are * indexed by the version number so v3 callback is at index 3 in the array. */ static int (*decode_superencrypted_handlers[])( @@ -2428,9 +2428,9 @@ static int desc_decode_superencrypted_v3, }; -/* Decode the superencrypted data section of the given descriptor and store the - * data in the given superencrypted data object. Return 0 on success else a - * negative value on error. */ +/** Decode the superencrypted data section of the given descriptor and store + * the data in the given superencrypted data object. Return 0 on success else + * a negative value on error. */ int hs_desc_decode_superencrypted(const hs_descriptor_t *desc, hs_desc_superencrypted_data_t * @@ -2468,7 +2468,7 @@ hs_desc_decode_superencrypted(const hs_descriptor_t *desc, return ret; } -/* Table of plaintext decode function version specific. The function are +/** Table of plaintext decode function version specific. The function are * indexed by the version number so v3 callback is at index 3 in the array. */ static int (*decode_plaintext_handlers[])( @@ -2481,7 +2481,7 @@ static int desc_decode_plaintext_v3, }; -/* Fully decode the given descriptor plaintext and store the data in the +/** Fully decode the given descriptor plaintext and store the data in the * plaintext data object. Returns 0 on success else a negative value. */ int hs_desc_decode_plaintext(const char *encoded, @@ -2554,7 +2554,7 @@ hs_desc_decode_plaintext(const char *encoded, return ret; } -/* Fully decode an encoded descriptor and set a newly allocated descriptor +/** Fully decode an encoded descriptor and set a newly allocated descriptor * object in desc_out. Client secret key is used to decrypt the "encrypted" * section if not NULL else it's ignored. * @@ -2614,7 +2614,7 @@ hs_desc_decode_descriptor(const char *encoded, return ret; } -/* Table of encode function version specific. The functions are indexed by the +/** Table of encode function version specific. The functions are indexed by the * version number so v3 callback is at index 3 in the array. */ static int (*encode_handlers[])( @@ -2627,7 +2627,7 @@ static int desc_encode_v3, }; -/* Encode the given descriptor desc including signing with the given key pair +/** Encode the given descriptor desc including signing with the given key pair * signing_kp and encrypting with the given descriptor cookie. * * If the client authorization is enabled, descriptor_cookie must be the same @@ -2684,7 +2684,7 @@ hs_desc_encode_descriptor,(const hs_descriptor_t *desc, return ret; } -/* Free the content of the plaintext section of a descriptor. */ +/** Free the content of the plaintext section of a descriptor. */ void hs_desc_plaintext_data_free_contents(hs_desc_plaintext_data_t *desc) { @@ -2700,7 +2700,7 @@ hs_desc_plaintext_data_free_contents(hs_desc_plaintext_data_t *desc) memwipe(desc, 0, sizeof(*desc)); } -/* Free the content of the superencrypted section of a descriptor. */ +/** Free the content of the superencrypted section of a descriptor. */ void hs_desc_superencrypted_data_free_contents(hs_desc_superencrypted_data_t *desc) { @@ -2720,7 +2720,7 @@ hs_desc_superencrypted_data_free_contents(hs_desc_superencrypted_data_t *desc) memwipe(desc, 0, sizeof(*desc)); } -/* Free the content of the encrypted section of a descriptor. */ +/** Free the content of the encrypted section of a descriptor. */ void hs_desc_encrypted_data_free_contents(hs_desc_encrypted_data_t *desc) { @@ -2740,7 +2740,7 @@ hs_desc_encrypted_data_free_contents(hs_desc_encrypted_data_t *desc) memwipe(desc, 0, sizeof(*desc)); } -/* Free the descriptor plaintext data object. */ +/** Free the descriptor plaintext data object. */ void hs_desc_plaintext_data_free_(hs_desc_plaintext_data_t *desc) { @@ -2748,7 +2748,7 @@ hs_desc_plaintext_data_free_(hs_desc_plaintext_data_t *desc) tor_free(desc); } -/* Free the descriptor plaintext data object. */ +/** Free the descriptor plaintext data object. */ void hs_desc_superencrypted_data_free_(hs_desc_superencrypted_data_t *desc) { @@ -2756,7 +2756,7 @@ hs_desc_superencrypted_data_free_(hs_desc_superencrypted_data_t *desc) tor_free(desc); } -/* Free the descriptor encrypted data object. */ +/** Free the descriptor encrypted data object. */ void hs_desc_encrypted_data_free_(hs_desc_encrypted_data_t *desc) { @@ -2764,7 +2764,7 @@ hs_desc_encrypted_data_free_(hs_desc_encrypted_data_t *desc) tor_free(desc); } -/* Free the given descriptor object. */ +/** Free the given descriptor object. */ void hs_descriptor_free_(hs_descriptor_t *desc) { @@ -2778,7 +2778,7 @@ hs_descriptor_free_(hs_descriptor_t *desc) tor_free(desc); } -/* Return the size in bytes of the given plaintext data object. A sizeof() is +/** Return the size in bytes of the given plaintext data object. A sizeof() is * not enough because the object contains pointers and the encrypted blob. * This is particularly useful for our OOM subsystem that tracks the HSDir * cache size for instance. */ @@ -2790,7 +2790,7 @@ hs_desc_plaintext_obj_size(const hs_desc_plaintext_data_t *data) data->superencrypted_blob_size); } -/* Return the size in bytes of the given encrypted data object. Used by OOM +/** Return the size in bytes of the given encrypted data object. Used by OOM * subsystem. */ static size_t hs_desc_encrypted_obj_size(const hs_desc_encrypted_data_t *data) @@ -2810,7 +2810,7 @@ hs_desc_encrypted_obj_size(const hs_desc_encrypted_data_t *data) return sizeof(*data) + intro_size; } -/* Return the size in bytes of the given descriptor object. Used by OOM +/** Return the size in bytes of the given descriptor object. Used by OOM * subsystem. */ size_t hs_desc_obj_size(const hs_descriptor_t *data) @@ -2821,7 +2821,7 @@ hs_desc_obj_size(const hs_descriptor_t *data) sizeof(data->subcredential)); } -/* Return a newly allocated descriptor intro point. */ +/** Return a newly allocated descriptor intro point. */ hs_desc_intro_point_t * hs_desc_intro_point_new(void) { @@ -2830,7 +2830,7 @@ hs_desc_intro_point_new(void) return ip; } -/* Free a descriptor intro point object. */ +/** Free a descriptor intro point object. */ void hs_desc_intro_point_free_(hs_desc_intro_point_t *ip) { @@ -2849,7 +2849,7 @@ hs_desc_intro_point_free_(hs_desc_intro_point_t *ip) tor_free(ip); } -/* Allocate and build a new fake client info for the descriptor. Return a +/** Allocate and build a new fake client info for the descriptor. Return a * newly allocated object. This can't fail. */ hs_desc_authorized_client_t * hs_desc_build_fake_authorized_client(void) @@ -2867,7 +2867,7 @@ hs_desc_build_fake_authorized_client(void) return client_auth; } -/* Using the service's subcredential, client public key, auth ephemeral secret +/** Using the service's subcredential, client public key, auth ephemeral secret * key, and descriptor cookie, build the auth client so we can then encode the * descriptor for publication. client_out must be already allocated. */ void @@ -2925,14 +2925,14 @@ hs_desc_build_authorized_client(const uint8_t *subcredential, crypto_cipher_free(cipher); } -/* Free an authoriezd client object. */ +/** Free an authoriezd client object. */ void hs_desc_authorized_client_free_(hs_desc_authorized_client_t *client) { tor_free(client); } -/* From the given descriptor, remove and free every introduction point. */ +/** From the given descriptor, remove and free every introduction point. */ void hs_descriptor_clear_intro_points(hs_descriptor_t *desc) { diff --git a/src/feature/hs/hs_descriptor.h b/src/feature/hs/hs_descriptor.h index 0a843f4f3c..731e0c5ce9 100644 --- a/src/feature/hs/hs_descriptor.h +++ b/src/feature/hs/hs_descriptor.h @@ -18,88 +18,88 @@ /* Trunnel */ struct link_specifier_t; -/* The earliest descriptor format version we support. */ +/** The earliest descriptor format version we support. */ #define HS_DESC_SUPPORTED_FORMAT_VERSION_MIN 3 -/* The latest descriptor format version we support. */ +/** The latest descriptor format version we support. */ #define HS_DESC_SUPPORTED_FORMAT_VERSION_MAX 3 -/* Default lifetime of a descriptor in seconds. The valus is set at 3 hours +/** Default lifetime of a descriptor in seconds. The valus is set at 3 hours * which is 180 minutes or 10800 seconds. */ #define HS_DESC_DEFAULT_LIFETIME (3 * 60 * 60) -/* Maximum lifetime of a descriptor in seconds. The value is set at 12 hours +/** Maximum lifetime of a descriptor in seconds. The value is set at 12 hours * which is 720 minutes or 43200 seconds. */ #define HS_DESC_MAX_LIFETIME (12 * 60 * 60) -/* Lifetime of certificate in the descriptor. This defines the lifetime of the +/** Lifetime of certificate in the descriptor. This defines the lifetime of the * descriptor signing key and the cross certification cert of that key. It is * set to 54 hours because a descriptor can be around for 48 hours and because * consensuses are used after the hour, add an extra 6 hours to give some time * for the service to stop using it. */ #define HS_DESC_CERT_LIFETIME (54 * 60 * 60) -/* Length of the salt needed for the encrypted section of a descriptor. */ +/** Length of the salt needed for the encrypted section of a descriptor. */ #define HS_DESC_ENCRYPTED_SALT_LEN 16 -/* Length of the KDF output value which is the length of the secret key, +/** Length of the KDF output value which is the length of the secret key, * the secret IV and MAC key length which is the length of H() output. */ #define HS_DESC_ENCRYPTED_KDF_OUTPUT_LEN \ CIPHER256_KEY_LEN + CIPHER_IV_LEN + DIGEST256_LEN -/* Pad plaintext of superencrypted data section before encryption so that its +/** Pad plaintext of superencrypted data section before encryption so that its * length is a multiple of this value. */ #define HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE 10000 -/* Maximum length in bytes of a full hidden service descriptor. */ +/** Maximum length in bytes of a full hidden service descriptor. */ #define HS_DESC_MAX_LEN 50000 /* 50kb max size */ -/* Key length for the descriptor symmetric encryption. As specified in the +/** Key length for the descriptor symmetric encryption. As specified in the * protocol, we use AES-256 for the encrypted section of the descriptor. The * following is the length in bytes and the bit size. */ #define HS_DESC_ENCRYPTED_KEY_LEN CIPHER256_KEY_LEN #define HS_DESC_ENCRYPTED_BIT_SIZE (HS_DESC_ENCRYPTED_KEY_LEN * 8) -/* Length of each components in the auth client section in the descriptor. */ +/** Length of each components in the auth client section in the descriptor. */ #define HS_DESC_CLIENT_ID_LEN 8 #define HS_DESC_DESCRIPTOR_COOKIE_LEN 16 #define HS_DESC_COOKIE_KEY_LEN 32 #define HS_DESC_COOKIE_KEY_BIT_SIZE (HS_DESC_COOKIE_KEY_LEN * 8) #define HS_DESC_ENCRYPED_COOKIE_LEN HS_DESC_DESCRIPTOR_COOKIE_LEN -/* The number of auth client entries in the descriptor must be the multiple +/** The number of auth client entries in the descriptor must be the multiple * of this constant. */ #define HS_DESC_AUTH_CLIENT_MULTIPLE 16 -/* Type of authentication in the descriptor. */ +/** Type of authentication in the descriptor. */ typedef enum { HS_DESC_AUTH_ED25519 = 1 } hs_desc_auth_type_t; -/* Introduction point information located in a descriptor. */ +/** Introduction point information located in a descriptor. */ typedef struct hs_desc_intro_point_t { - /* Link specifier(s) which details how to extend to the relay. This list + /** Link specifier(s) which details how to extend to the relay. This list * contains link_specifier_t objects. It MUST have at least one. */ smartlist_t *link_specifiers; - /* Onion key of the introduction point used to extend to it for the ntor + /** Onion key of the introduction point used to extend to it for the ntor * handshake. */ curve25519_public_key_t onion_key; - /* Authentication key used to establish the introduction point circuit and + /** Authentication key used to establish the introduction point circuit and * cross-certifies the blinded public key for the replica thus signed by * the blinded key and in turn signs it. */ tor_cert_t *auth_key_cert; - /* Encryption key for the "ntor" type. */ + /** Encryption key for the "ntor" type. */ curve25519_public_key_t enc_key; - /* Certificate cross certifying the descriptor signing key by the encryption + /** Certificate cross certifying the descriptor signing key by the encryption * curve25519 key. This certificate contains the signing key and is of type * CERT_TYPE_CROSS_HS_IP_KEYS [0B]. */ tor_cert_t *enc_key_cert; - /* (Optional): If this introduction point is a legacy one that is version <= + /** (Optional): If this introduction point is a legacy one that is version <= * 0.2.9.x (HSIntro=3), we use this extra key for the intro point to be able * to relay the cells to the service correctly. */ struct { - /* RSA public key. */ + /** RSA public key. */ crypto_pk_t *key; - /* Cross certified cert with the descriptor signing key (RSA->Ed). Because + /** Cross certified cert with the descriptor signing key (RSA->Ed). Because * of the cross certification API, we need to keep the certificate binary * blob and its length in order to properly encode it after. */ struct { @@ -108,115 +108,115 @@ typedef struct hs_desc_intro_point_t { } cert; } legacy; - /* True iff the introduction point has passed the cross certification. Upon + /** True iff the introduction point has passed the cross certification. Upon * decoding an intro point, this must be true. */ unsigned int cross_certified : 1; } hs_desc_intro_point_t; -/* Authorized client information located in a descriptor. */ +/** Authorized client information located in a descriptor. */ typedef struct hs_desc_authorized_client_t { - /* An identifier that the client will use to identify which auth client + /** An identifier that the client will use to identify which auth client * entry it needs to use. */ uint8_t client_id[HS_DESC_CLIENT_ID_LEN]; - /* An IV that is used to decrypt the encrypted descriptor cookie. */ + /** An IV that is used to decrypt the encrypted descriptor cookie. */ uint8_t iv[CIPHER_IV_LEN]; - /* An encrypted descriptor cookie that the client needs to decrypt to use + /** An encrypted descriptor cookie that the client needs to decrypt to use * it to decrypt the descriptor. */ uint8_t encrypted_cookie[HS_DESC_ENCRYPED_COOKIE_LEN]; } hs_desc_authorized_client_t; -/* The encrypted data section of a descriptor. Obviously the data in this is +/** The encrypted data section of a descriptor. Obviously the data in this is * in plaintext but encrypted once encoded. */ typedef struct hs_desc_encrypted_data_t { - /* Bitfield of CREATE2 cell supported formats. The only currently supported + /** Bitfield of CREATE2 cell supported formats. The only currently supported * format is ntor. */ unsigned int create2_ntor : 1; - /* A list of authentication types that a client must at least support one + /** A list of authentication types that a client must at least support one * in order to contact the service. Contains NULL terminated strings. */ smartlist_t *intro_auth_types; - /* Is this descriptor a single onion service? */ + /** Is this descriptor a single onion service? */ unsigned int single_onion_service : 1; - /* A list of intro points. Contains hs_desc_intro_point_t objects. */ + /** A list of intro points. Contains hs_desc_intro_point_t objects. */ smartlist_t *intro_points; } hs_desc_encrypted_data_t; -/* The superencrypted data section of a descriptor. Obviously the data in +/** The superencrypted data section of a descriptor. Obviously the data in * this is in plaintext but encrypted once encoded. */ typedef struct hs_desc_superencrypted_data_t { - /* This field contains ephemeral x25519 public key which is used by + /** This field contains ephemeral x25519 public key which is used by * the encryption scheme in the client authorization. */ curve25519_public_key_t auth_ephemeral_pubkey; - /* A list of authorized clients. Contains hs_desc_authorized_client_t + /** A list of authorized clients. Contains hs_desc_authorized_client_t * objects. */ smartlist_t *clients; - /* Decoding only: The b64-decoded encrypted blob from the descriptor */ + /** Decoding only: The b64-decoded encrypted blob from the descriptor */ uint8_t *encrypted_blob; - /* Decoding only: Size of the encrypted_blob */ + /** Decoding only: Size of the encrypted_blob */ size_t encrypted_blob_size; } hs_desc_superencrypted_data_t; -/* Plaintext data that is unencrypted information of the descriptor. */ +/** Plaintext data that is unencrypted information of the descriptor. */ typedef struct hs_desc_plaintext_data_t { - /* Version of the descriptor format. Spec specifies this field as a + /** Version of the descriptor format. Spec specifies this field as a * positive integer. */ uint32_t version; - /* The lifetime of the descriptor in seconds. */ + /** The lifetime of the descriptor in seconds. */ uint32_t lifetime_sec; - /* Certificate with the short-term ed22519 descriptor signing key for the + /** Certificate with the short-term ed22519 descriptor signing key for the * replica which is signed by the blinded public key for that replica. */ tor_cert_t *signing_key_cert; - /* Signing public key which is used to sign the descriptor. Same public key + /** Signing public key which is used to sign the descriptor. Same public key * as in the signing key certificate. */ ed25519_public_key_t signing_pubkey; - /* Blinded public key used for this descriptor derived from the master + /** Blinded public key used for this descriptor derived from the master * identity key and generated for a specific replica number. */ ed25519_public_key_t blinded_pubkey; - /* Revision counter is incremented at each upload, regardless of whether + /** Revision counter is incremented at each upload, regardless of whether * the descriptor has changed. This avoids leaking whether the descriptor * has changed. Spec specifies this as a 8 bytes positive integer. */ uint64_t revision_counter; - /* Decoding only: The b64-decoded superencrypted blob from the descriptor */ + /** Decoding only: The b64-decoded superencrypted blob from the descriptor */ uint8_t *superencrypted_blob; - /* Decoding only: Size of the superencrypted_blob */ + /** Decoding only: Size of the superencrypted_blob */ size_t superencrypted_blob_size; } hs_desc_plaintext_data_t; -/* Service descriptor in its decoded form. */ +/** Service descriptor in its decoded form. */ typedef struct hs_descriptor_t { - /* Contains the plaintext part of the descriptor. */ + /** Contains the plaintext part of the descriptor. */ hs_desc_plaintext_data_t plaintext_data; - /* The following contains what's in the superencrypted part of the + /** The following contains what's in the superencrypted part of the * descriptor. It's only encrypted in the encoded version of the descriptor * thus the data contained in that object is in plaintext. */ hs_desc_superencrypted_data_t superencrypted_data; - /* The following contains what's in the encrypted part of the descriptor. + /** The following contains what's in the encrypted part of the descriptor. * It's only encrypted in the encoded version of the descriptor thus the * data contained in that object is in plaintext. */ hs_desc_encrypted_data_t encrypted_data; - /* Subcredentials of a service, used by the client and service to decrypt + /** Subcredentials of a service, used by the client and service to decrypt * the encrypted data. */ uint8_t subcredential[DIGEST256_LEN]; } hs_descriptor_t; -/* Return true iff the given descriptor format version is supported. */ +/** Return true iff the given descriptor format version is supported. */ static inline int hs_desc_is_supported_version(uint32_t version) { diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index 18c38ebc0a..d0fb77fdaa 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -67,7 +67,8 @@ #include <unistd.h> #endif -/* Helper macro. Iterate over every service in the global map. The var is the +#ifndef COCCI +/** Helper macro. Iterate over every service in the global map. The var is the * name of the service pointer. */ #define FOR_EACH_SERVICE_BEGIN(var) \ STMT_BEGIN \ @@ -76,7 +77,7 @@ var = *var##_iter; #define FOR_EACH_SERVICE_END } STMT_END ; -/* Helper macro. Iterate over both current and previous descriptor of a +/** Helper macro. Iterate over both current and previous descriptor of a * service. The var is the name of the descriptor pointer. This macro skips * any descriptor object of the service that is NULL. */ #define FOR_EACH_DESCRIPTOR_BEGIN(service, var) \ @@ -88,6 +89,7 @@ (var = service->desc_next); \ if (var == NULL) continue; #define FOR_EACH_DESCRIPTOR_END } STMT_END ; +#endif /* !defined(COCCI) */ /* Onion service directory file names. */ static const char fname_keyfile_prefix[] = "hs_ed25519"; @@ -95,7 +97,7 @@ static const char dname_client_pubkeys[] = "authorized_clients"; static const char fname_hostname[] = "hostname"; static const char address_tld[] = "onion"; -/* Staging list of service object. When configuring service, we add them to +/** Staging list of service object. When configuring service, we add them to * this list considered a staging area and they will get added to our global * map once the keys have been loaded. These two steps are separated because * loading keys requires that we are an actual running tor process. */ @@ -118,7 +120,7 @@ static int service_encode_descriptor(const hs_service_t *service, const ed25519_keypair_t *signing_kp, char **encoded_out); -/* Helper: Function to compare two objects in the service map. Return 1 if the +/** Helper: Function to compare two objects in the service map. Return 1 if the * two service have the same master public identity key. */ static inline int hs_service_ht_eq(const hs_service_t *first, const hs_service_t *second) @@ -130,7 +132,7 @@ hs_service_ht_eq(const hs_service_t *first, const hs_service_t *second) &second->keys.identity_pk); } -/* Helper: Function for the service hash table code below. The key used is the +/** Helper: Function for the service hash table code below. The key used is the * master public identity key which is ultimately the onion address. */ static inline unsigned int hs_service_ht_hash(const hs_service_t *service) @@ -140,7 +142,7 @@ hs_service_ht_hash(const hs_service_t *service) sizeof(service->keys.identity_pk.pubkey)); } -/* This is _the_ global hash map of hidden services which indexed the service +/** This is _the_ global hash map of hidden services which indexed the service * contained in it by master public identity key which is roughly the onion * address of the service. */ static struct hs_service_ht *hs_service_map; @@ -156,7 +158,7 @@ HT_GENERATE2(hs_service_ht, hs_service_t, hs_service_node, hs_service_ht_hash, hs_service_ht_eq, 0.6, tor_reallocarray, tor_free_) -/* Query the given service map with a public key and return a service object +/** Query the given service map with a public key and return a service object * if found else NULL. It is also possible to set a directory path in the * search query. If pk is NULL, then it will be set to zero indicating the * hash table to compare the directory path instead. */ @@ -171,7 +173,7 @@ find_service(hs_service_ht *map, const ed25519_public_key_t *pk) return HT_FIND(hs_service_ht, map, &dummy_service); } -/* Register the given service in the given map. If the service already exists +/** Register the given service in the given map. If the service already exists * in the map, -1 is returned. On success, 0 is returned and the service * ownership has been transferred to the global map. */ STATIC int @@ -196,7 +198,7 @@ register_service(hs_service_ht *map, hs_service_t *service) return 0; } -/* Remove a given service from the given map. If service is NULL or the +/** Remove a given service from the given map. If service is NULL or the * service key is unset, return gracefully. */ STATIC void remove_service(hs_service_ht *map, hs_service_t *service) @@ -226,7 +228,7 @@ remove_service(hs_service_ht *map, hs_service_t *service) } } -/* Set the default values for a service configuration object <b>c</b>. */ +/** Set the default values for a service configuration object <b>c</b>. */ static void set_service_default_config(hs_service_config_t *c, const or_options_t *options) @@ -247,7 +249,7 @@ set_service_default_config(hs_service_config_t *c, c->intro_dos_burst_per_sec = HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT; } -/* From a service configuration object config, clear everything from it +/** From a service configuration object config, clear everything from it * meaning free allocated pointers and reset the values. */ STATIC void service_clear_config(hs_service_config_t *config) @@ -269,7 +271,7 @@ service_clear_config(hs_service_config_t *config) memset(config, 0, sizeof(*config)); } -/* Helper function to return a human readable description of the given intro +/** Helper function to return a human readable description of the given intro * point object. * * This function is not thread-safe. Each call to this invalidates the @@ -301,7 +303,7 @@ describe_intro_point(const hs_service_intro_point_t *ip) return buf; } -/* Return the lower bound of maximum INTRODUCE2 cells per circuit before we +/** Return the lower bound of maximum INTRODUCE2 cells per circuit before we * rotate intro point (defined by a consensus parameter or the default * value). */ static int32_t @@ -314,7 +316,7 @@ get_intro_point_min_introduce2(void) 0, INT32_MAX); } -/* Return the upper bound of maximum INTRODUCE2 cells per circuit before we +/** Return the upper bound of maximum INTRODUCE2 cells per circuit before we * rotate intro point (defined by a consensus parameter or the default * value). */ static int32_t @@ -327,8 +329,8 @@ get_intro_point_max_introduce2(void) 0, INT32_MAX); } -/* Return the minimum lifetime in seconds of an introduction point defined by a - * consensus parameter or the default value. */ +/** Return the minimum lifetime in seconds of an introduction point defined by + * a consensus parameter or the default value. */ static int32_t get_intro_point_min_lifetime(void) { @@ -344,8 +346,8 @@ get_intro_point_min_lifetime(void) 0, INT32_MAX); } -/* Return the maximum lifetime in seconds of an introduction point defined by a - * consensus parameter or the default value. */ +/** Return the maximum lifetime in seconds of an introduction point defined by + * a consensus parameter or the default value. */ static int32_t get_intro_point_max_lifetime(void) { @@ -361,7 +363,7 @@ get_intro_point_max_lifetime(void) 0, INT32_MAX); } -/* Return the number of extra introduction point defined by a consensus +/** Return the number of extra introduction point defined by a consensus * parameter or the default value. */ static int32_t get_intro_point_num_extra(void) @@ -372,7 +374,7 @@ get_intro_point_num_extra(void) NUM_INTRO_POINTS_EXTRA, 0, 128); } -/* Helper: Function that needs to return 1 for the HT for each loop which +/** Helper: Function that needs to return 1 for the HT for each loop which * frees every service in an hash map. */ static int ht_free_service_(struct hs_service_t *service, void *data) @@ -384,7 +386,7 @@ ht_free_service_(struct hs_service_t *service, void *data) return 1; } -/* Free every service that can be found in the global map. Once done, clear +/** Free every service that can be found in the global map. Once done, clear * and free the global map. */ static void service_free_all(void) @@ -406,7 +408,7 @@ service_free_all(void) } } -/* Free a given service intro point object. */ +/** Free a given service intro point object. */ STATIC void service_intro_point_free_(hs_service_intro_point_t *ip) { @@ -421,7 +423,7 @@ service_intro_point_free_(hs_service_intro_point_t *ip) tor_free(ip); } -/* Helper: free an hs_service_intro_point_t object. This function is used by +/** Helper: free an hs_service_intro_point_t object. This function is used by * digest256map_free() which requires a void * pointer. */ static void service_intro_point_free_void(void *obj) @@ -429,7 +431,7 @@ service_intro_point_free_void(void *obj) service_intro_point_free_(obj); } -/* Return a newly allocated service intro point and fully initialized from the +/** Return a newly allocated service intro point and fully initialized from the * given node_t node, if non NULL. * * If node is NULL, returns a hs_service_intro_point_t with an empty link @@ -523,7 +525,7 @@ service_intro_point_add(digest256map_t *map, hs_service_intro_point_t *ip) tor_assert_nonfatal(!old_ip_entry); } -/* For a given service, remove the intro point from that service's descriptors +/** For a given service, remove the intro point from that service's descriptors * (check both current and next descriptor) */ STATIC void service_intro_point_remove(const hs_service_t *service, @@ -541,7 +543,7 @@ service_intro_point_remove(const hs_service_t *service, } FOR_EACH_DESCRIPTOR_END; } -/* For a given service and authentication key, return the intro point or NULL +/** For a given service and authentication key, return the intro point or NULL * if not found. This will check both descriptors in the service. */ STATIC hs_service_intro_point_t * service_intro_point_find(const hs_service_t *service, @@ -572,7 +574,7 @@ service_intro_point_find(const hs_service_t *service, return ip; } -/* For a given service and intro point, return the descriptor for which the +/** For a given service and intro point, return the descriptor for which the * intro point is assigned to. NULL is returned if not found. */ STATIC hs_service_descriptor_t * service_desc_find_by_intro(const hs_service_t *service, @@ -594,7 +596,7 @@ service_desc_find_by_intro(const hs_service_t *service, return descp; } -/* From a circuit identifier, get all the possible objects associated with the +/** From a circuit identifier, get all the possible objects associated with the * ident. If not NULL, service, ip or desc are set if the object can be found. * They are untouched if they can't be found. * @@ -627,7 +629,7 @@ get_objects_from_ident(const hs_ident_circuit_t *ident, } } -/* From a given intro point, return the first link specifier of type +/** From a given intro point, return the first link specifier of type * encountered in the link specifier list. Return NULL if it can't be found. * * The caller does NOT have ownership of the object, the intro point does. */ @@ -650,7 +652,7 @@ get_link_spec_by_type(const hs_service_intro_point_t *ip, uint8_t type) return lnk_spec; } -/* Given a service intro point, return the node_t associated to it. This can +/** Given a service intro point, return the node_t associated to it. This can * return NULL if the given intro point has no legacy ID or if the node can't * be found in the consensus. */ STATIC const node_t * @@ -669,7 +671,7 @@ get_node_from_intro_point(const hs_service_intro_point_t *ip) (const char *) link_specifier_getconstarray_un_legacy_id(ls)); } -/* Given a service intro point, return the extend_info_t for it. This can +/** Given a service intro point, return the extend_info_t for it. This can * return NULL if the node can't be found for the intro point or the extend * info can't be created for the found node. If direct_conn is set, the extend * info is validated on if we can connect directly. */ @@ -698,7 +700,7 @@ get_extend_info_from_intro_point(const hs_service_intro_point_t *ip, return info; } -/* Return the number of introduction points that are established for the +/** Return the number of introduction points that are established for the * given descriptor. */ static unsigned int count_desc_circuit_established(const hs_service_descriptor_t *desc) @@ -709,13 +711,13 @@ count_desc_circuit_established(const hs_service_descriptor_t *desc) DIGEST256MAP_FOREACH(desc->intro_points.map, key, const hs_service_intro_point_t *, ip) { - count += ip->circuit_established; + count += !!hs_circ_service_get_established_intro_circ(ip); } DIGEST256MAP_FOREACH_END; return count; } -/* For a given service and descriptor of that service, close all active +/** For a given service and descriptor of that service, close all active * directory connections. */ static void close_directory_connections(const hs_service_t *service, @@ -750,7 +752,7 @@ close_directory_connections(const hs_service_t *service, smartlist_free(dir_conns); } -/* Close all rendezvous circuits for the given service. */ +/** Close all rendezvous circuits for the given service. */ static void close_service_rp_circuits(hs_service_t *service) { @@ -780,7 +782,7 @@ close_service_rp_circuits(hs_service_t *service) } } -/* Close the circuit(s) for the given map of introduction points. */ +/** Close the circuit(s) for the given map of introduction points. */ static void close_intro_circuits(hs_service_intropoints_t *intro_points) { @@ -798,7 +800,7 @@ close_intro_circuits(hs_service_intropoints_t *intro_points) } DIGEST256MAP_FOREACH_END; } -/* Close all introduction circuits for the given service. */ +/** Close all introduction circuits for the given service. */ static void close_service_intro_circuits(hs_service_t *service) { @@ -809,7 +811,7 @@ close_service_intro_circuits(hs_service_t *service) } FOR_EACH_DESCRIPTOR_END; } -/* Close any circuits related to the given service. */ +/** Close any circuits related to the given service. */ static void close_service_circuits(hs_service_t *service) { @@ -825,7 +827,7 @@ close_service_circuits(hs_service_t *service) close_service_rp_circuits(service); } -/* Move every ephemeral services from the src service map to the dst service +/** Move every ephemeral services from the src service map to the dst service * map. It is possible that a service can't be register to the dst map which * won't stop the process of moving them all but will trigger a log warn. */ static void @@ -855,7 +857,7 @@ move_ephemeral_services(hs_service_ht *src, hs_service_ht *dst) } } -/* Return a const string of the directory path escaped. If this is an +/** Return a const string of the directory path escaped. If this is an * ephemeral service, it returns "[EPHEMERAL]". This can only be called from * the main thread because escaped() uses a static variable. */ static const char * @@ -889,7 +891,7 @@ move_hs_state(hs_service_t *src_service, hs_service_t *dst_service) src->replay_cache_rend_cookie = NULL; /* steal pointer reference */ } -/* Register services that are in the staging list. Once this function returns, +/** Register services that are in the staging list. Once this function returns, * the global service map will be set with the right content and all non * surviving services will be cleaned up. */ static void @@ -957,7 +959,7 @@ register_all_services(void) hs_service_map_has_changed(); } -/* Write the onion address of a given service to the given filename fname_ in +/** Write the onion address of a given service to the given filename fname_ in * the service directory. Return 0 on success else -1 on error. */ STATIC int write_address_to_file(const hs_service_t *service, const char *fname_) @@ -998,7 +1000,7 @@ write_address_to_file(const hs_service_t *service, const char *fname_) return ret; } -/* Load and/or generate private keys for the given service. On success, the +/** Load and/or generate private keys for the given service. On success, the * hostname file will be written to disk along with the master private key iff * the service is not configured for offline keys. Return 0 on success else -1 * on failure. */ @@ -1096,7 +1098,7 @@ client_filename_is_valid(const char *filename) return ret; } -/* Parse an authorized client from a string. The format of a client string +/** Parse an authorized client from a string. The format of a client string * looks like (see rend-spec-v3.txt): * * <auth-type>:<key-type>:<base32-encoded-public-key> @@ -1178,7 +1180,7 @@ parse_authorized_client(const char *client_key_str) return client; } -/* Load all the client public keys for the given service. Return 0 on +/** Load all the client public keys for the given service. Return 0 on * success else -1 on failure. */ static int load_client_keys(hs_service_t *service) @@ -1281,6 +1283,7 @@ load_client_keys(hs_service_t *service) return ret; } +/** Release all storage held in <b>client</b>. */ STATIC void service_authorized_client_free_(hs_service_authorized_client_t *client) { @@ -1291,7 +1294,7 @@ service_authorized_client_free_(hs_service_authorized_client_t *client) tor_free(client); } -/* Free a given service descriptor object and all key material is wiped. */ +/** Free a given service descriptor object and all key material is wiped. */ STATIC void service_descriptor_free_(hs_service_descriptor_t *desc) { @@ -1312,7 +1315,7 @@ service_descriptor_free_(hs_service_descriptor_t *desc) tor_free(desc); } -/* Return a newly allocated service descriptor object. */ +/** Return a newly allocated service descriptor object. */ STATIC hs_service_descriptor_t * service_descriptor_new(void) { @@ -1325,7 +1328,7 @@ service_descriptor_new(void) return sdesc; } -/* Allocate and return a deep copy of client. */ +/** Allocate and return a deep copy of client. */ static hs_service_authorized_client_t * service_authorized_client_dup(const hs_service_authorized_client_t *client) { @@ -1343,7 +1346,7 @@ service_authorized_client_dup(const hs_service_authorized_client_t *client) return client_dup; } -/* If two authorized clients are equal, return 0. If the first one should come +/** If two authorized clients are equal, return 0. If the first one should come * before the second, return less than zero. If the first should come after * the second, return greater than zero. */ static int @@ -1360,7 +1363,7 @@ service_authorized_client_cmp(const hs_service_authorized_client_t *client1, CURVE25519_PUBKEY_LEN); } -/* Helper for sorting authorized clients. */ +/** Helper for sorting authorized clients. */ static int compare_service_authorzized_client_(const void **_a, const void **_b) { @@ -1368,7 +1371,7 @@ compare_service_authorzized_client_(const void **_a, const void **_b) return service_authorized_client_cmp(a, b); } -/* If the list of hs_service_authorized_client_t's is different between +/** If the list of hs_service_authorized_client_t's is different between * src and dst, return 1. Otherwise, return 0. */ STATIC int service_authorized_client_config_equal(const hs_service_config_t *config1, @@ -1429,7 +1432,7 @@ service_authorized_client_config_equal(const hs_service_config_t *config1, return ret; } -/* Move descriptor(s) from the src service to the dst service and modify their +/** Move descriptor(s) from the src service to the dst service and modify their * content if necessary. We do this during SIGHUP when we re-create our * hidden services. */ static void @@ -1488,7 +1491,7 @@ move_descriptors(hs_service_t *src, hs_service_t *dst) service_descriptor_free(dst->desc_next); } -/* From the given service, remove all expired failing intro points for each +/** From the given service, remove all expired failing intro points for each * descriptor. */ static void remove_expired_failing_intro(hs_service_t *service, time_t now) @@ -1507,7 +1510,7 @@ remove_expired_failing_intro(hs_service_t *service, time_t now) } FOR_EACH_DESCRIPTOR_END; } -/* For the given descriptor desc, put all node_t object found from its failing +/** For the given descriptor desc, put all node_t object found from its failing * intro point list and put them in the given node_list. */ static void setup_intro_point_exclude_list(const hs_service_descriptor_t *desc, @@ -1525,7 +1528,7 @@ setup_intro_point_exclude_list(const hs_service_descriptor_t *desc, } DIGESTMAP_FOREACH_END; } -/* For the given failing intro point ip, we add its time of failure to the +/** For the given failing intro point ip, we add its time of failure to the * failed map and index it by identity digest (legacy ID) in the descriptor * desc failed id map. */ static void @@ -1549,7 +1552,7 @@ remember_failing_intro_point(const hs_service_intro_point_t *ip, tor_free(prev_ptr); } -/* Using a given descriptor signing keypair signing_kp, a service intro point +/** Using a given descriptor signing keypair signing_kp, a service intro point * object ip and the time now, setup the content of an already allocated * descriptor intro desc_ip. * @@ -1638,7 +1641,7 @@ setup_desc_intro_point(const ed25519_keypair_t *signing_kp, return ret; } -/* Using the given descriptor from the given service, build the descriptor +/** Using the given descriptor from the given service, build the descriptor * intro point list so we can then encode the descriptor for publication. This * function does not pick intro points, they have to be in the descriptor * current map. Cryptographic material (keys) must be initialized in the @@ -1659,7 +1662,7 @@ build_desc_intro_points(const hs_service_t *service, DIGEST256MAP_FOREACH(desc->intro_points.map, key, const hs_service_intro_point_t *, ip) { - if (!ip->circuit_established) { + if (!hs_circ_service_get_established_intro_circ(ip)) { /* Ignore un-established intro points. They can linger in that list * because their circuit has not opened and they haven't been removed * yet even though we have enough intro circuits. @@ -1678,7 +1681,7 @@ build_desc_intro_points(const hs_service_t *service, } DIGEST256MAP_FOREACH_END; } -/* Build the descriptor signing key certificate. */ +/** Build the descriptor signing key certificate. */ static void build_desc_signing_key_cert(hs_service_descriptor_t *desc, time_t now) { @@ -1704,7 +1707,7 @@ build_desc_signing_key_cert(hs_service_descriptor_t *desc, time_t now) tor_assert_nonfatal(plaintext->signing_key_cert); } -/* Populate the descriptor encrypted section from the given service object. +/** Populate the descriptor encrypted section from the given service object. * This will generate a valid list of introduction points that can be used * after for circuit creation. Return 0 on success else -1 on error. */ static int @@ -1817,7 +1820,7 @@ build_service_desc_superencrypted(const hs_service_t *service, return 0; } -/* Populate the descriptor plaintext section from the given service object. +/** Populate the descriptor plaintext section from the given service object. * The caller must make sure that the keys in the descriptors are valid that * is are non-zero. This can't fail. */ static void @@ -1868,7 +1871,7 @@ generate_ope_cipher_for_desc(const hs_service_descriptor_t *hs_desc) return crypto_ope_new(key); } -/* For the given service and descriptor object, create the key material which +/** For the given service and descriptor object, create the key material which * is the blinded keypair, the descriptor signing keypair, the ephemeral * keypair, and the descriptor cookie. Return 0 on success else -1 on error * where the generated keys MUST be ignored. */ @@ -1930,7 +1933,7 @@ build_service_desc_keys(const hs_service_t *service, return ret; } -/* Given a service and the current time, build a descriptor for the service. +/** Given a service and the current time, build a descriptor for the service. * This function does not pick introduction point, this needs to be done by * the update function. On success, desc_out will point to the newly allocated * descriptor object. @@ -1987,7 +1990,7 @@ build_service_descriptor(hs_service_t *service, uint64_t time_period_num, service_descriptor_free(desc); } -/* Build both descriptors for the given service that has just booted up. +/** Build both descriptors for the given service that has just booted up. * Because it's a special case, it deserves its special function ;). */ static void build_descriptors_for_new_service(hs_service_t *service, time_t now) @@ -2037,7 +2040,7 @@ build_descriptors_for_new_service(hs_service_t *service, time_t now) safe_str_client(service->onion_address)); } -/* Build descriptors for each service if needed. There are conditions to build +/** Build descriptors for each service if needed. There are conditions to build * a descriptor which are details in the function. */ STATIC void build_all_descriptors(time_t now) @@ -2070,7 +2073,7 @@ build_all_descriptors(time_t now) } FOR_EACH_DESCRIPTOR_END; } -/* Randomly pick a node to become an introduction point but not present in the +/** Randomly pick a node to become an introduction point but not present in the * given exclude_nodes list. The chosen node is put in the exclude list * regardless of success or not because in case of failure, the node is simply * unsusable from that point on. @@ -2131,7 +2134,7 @@ pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes) return NULL; } -/* For a given descriptor from the given service, pick any needed intro points +/** For a given descriptor from the given service, pick any needed intro points * and update the current map with those newly picked intro points. Return the * number node that might have been added to the descriptor current map. */ static unsigned int @@ -2255,7 +2258,7 @@ service_desc_schedule_upload(hs_service_descriptor_t *desc, } } -/* Pick missing intro points for this descriptor if needed. */ +/** Pick missing intro points for this descriptor if needed. */ static void update_service_descriptor_intro_points(hs_service_t *service, hs_service_descriptor_t *desc, time_t now) @@ -2296,7 +2299,7 @@ update_service_descriptor_intro_points(hs_service_t *service, } } -/* Update descriptor intro points for each service if needed. We do this as +/** Update descriptor intro points for each service if needed. We do this as * part of the periodic event because we need to establish intro point circuits * before we publish descriptors. */ STATIC void @@ -2311,7 +2314,7 @@ update_all_descriptors_intro_points(time_t now) } FOR_EACH_SERVICE_END; } -/* Return true iff the given intro point has expired that is it has been used +/** Return true iff the given intro point has expired that is it has been used * for too long or we've reached our max seen INTRODUCE2 cell. */ STATIC int intro_point_should_expire(const hs_service_intro_point_t *ip, @@ -2333,7 +2336,7 @@ intro_point_should_expire(const hs_service_intro_point_t *ip, return 1; } -/* Return true iff we should remove the intro point ip from its service. +/** Return true iff we should remove the intro point ip from its service. * * We remove an intro point from the service descriptor list if one of * these criteria is met: @@ -2369,10 +2372,6 @@ should_remove_intro_point(hs_service_intro_point_t *ip, time_t now) * remove it because it might simply be valid and opened at the previous * scheduled event for the last retry. */ - /* Did we established already? */ - if (ip->circuit_established) { - goto end; - } /* Do we simply have an existing circuit regardless of its state? */ if (hs_circ_service_get_intro_circ(ip)) { goto end; @@ -2395,7 +2394,7 @@ should_remove_intro_point(hs_service_intro_point_t *ip, time_t now) return ret; } -/* Go over the given set of intro points for each service and remove any +/** Go over the given set of intro points for each service and remove any * invalid ones. * * If an intro point is removed, the circuit (if any) is immediately close. @@ -2458,7 +2457,7 @@ cleanup_intro_points(hs_service_t *service, time_t now) smartlist_free(ips_to_free); } -/* Set the next rotation time of the descriptors for the given service for the +/** Set the next rotation time of the descriptors for the given service for the * time now. */ static void set_rotation_time(hs_service_t *service) @@ -2477,7 +2476,7 @@ set_rotation_time(hs_service_t *service) } } -/* Return true iff the service should rotate its descriptor. The time now is +/** Return true iff the service should rotate its descriptor. The time now is * only used to fetch the live consensus and if none can be found, this * returns false. */ static unsigned int @@ -2529,7 +2528,7 @@ should_rotate_descriptors(hs_service_t *service, time_t now) return 1; } -/* Rotate the service descriptors of the given service. The current descriptor +/** Rotate the service descriptors of the given service. The current descriptor * will be freed, the next one put in as the current and finally the next * descriptor pointer is NULLified. */ static void @@ -2551,7 +2550,7 @@ rotate_service_descriptors(hs_service_t *service) set_rotation_time(service); } -/* Rotate descriptors for each service if needed. A non existing current +/** Rotate descriptors for each service if needed. A non existing current * descriptor will trigger a descriptor build for the next time period. */ STATIC void rotate_all_descriptors(time_t now) @@ -2580,7 +2579,7 @@ rotate_all_descriptors(time_t now) } FOR_EACH_SERVICE_END; } -/* Scheduled event run from the main loop. Make sure all our services are up +/** Scheduled event run from the main loop. Make sure all our services are up * to date and ready for the other scheduled events. This includes looking at * the introduction points status and descriptor rotation time. */ STATIC void @@ -2615,7 +2614,7 @@ run_housekeeping_event(time_t now) } FOR_EACH_SERVICE_END; } -/* Scheduled event run from the main loop. Make sure all descriptors are up to +/** Scheduled event run from the main loop. Make sure all descriptors are up to * date. Once this returns, each service descriptor needs to be considered for * new introduction circuits and then for upload. */ static void @@ -2692,7 +2691,7 @@ launch_intro_point_circuits(hs_service_t *service) } FOR_EACH_DESCRIPTOR_END; } -/* Don't try to build more than this many circuits before giving up for a +/** Don't try to build more than this many circuits before giving up for a * while. Dynamically calculated based on the configured number of intro * points for the given service and how many descriptor exists. The default * use case of 3 introduction points and two descriptors will allow 28 @@ -2708,7 +2707,7 @@ get_max_intro_circ_per_period(const hs_service_t *service) tor_assert(service->config.num_intro_points <= HS_CONFIG_V3_MAX_INTRO_POINTS); -/* For a testing network, allow to do it for the maximum amount so circuit +/** For a testing network, allow to do it for the maximum amount so circuit * creation and rotation and so on can actually be tested without limit. */ #define MAX_INTRO_POINT_CIRCUIT_RETRIES_TESTING -1 if (get_options()->TestingTorNetwork) { @@ -2737,7 +2736,7 @@ get_max_intro_circ_per_period(const hs_service_t *service) return (count * multiplier); } -/* For the given service, return 1 if the service is allowed to launch more +/** For the given service, return 1 if the service is allowed to launch more * introduction circuits else 0 if the maximum has been reached for the retry * period of INTRO_CIRC_RETRY_PERIOD. */ STATIC int @@ -2783,7 +2782,7 @@ can_service_launch_intro_circuit(hs_service_t *service, time_t now) return 1; } -/* Scheduled event run from the main loop. Make sure we have all the circuits +/** Scheduled event run from the main loop. Make sure we have all the circuits * we need for each service. */ static void run_build_circuit_event(time_t now) @@ -2813,7 +2812,7 @@ run_build_circuit_event(time_t now) } FOR_EACH_SERVICE_END; } -/* Encode and sign the service descriptor desc and upload it to the given +/** Encode and sign the service descriptor desc and upload it to the given * hidden service directory. This does nothing if PublishHidServDescriptors * is false. */ static void @@ -2949,7 +2948,7 @@ set_descriptor_revision_counter(hs_service_descriptor_t *hs_desc, time_t now, hs_desc->desc->plaintext_data.revision_counter = rev_counter; } -/* Encode and sign the service descriptor desc and upload it to the +/** Encode and sign the service descriptor desc and upload it to the * responsible hidden service directories. If for_next_period is true, the set * of directories are selected using the next hsdir_index. This does nothing * if PublishHidServDescriptors is false. */ @@ -3046,7 +3045,7 @@ service_desc_hsdirs_changed(const hs_service_t *service, return should_reupload; } -/* Return 1 if the given descriptor from the given service can be uploaded +/** Return 1 if the given descriptor from the given service can be uploaded * else return 0 if it can not. */ static int should_service_upload_descriptor(const hs_service_t *service, @@ -3103,7 +3102,7 @@ should_service_upload_descriptor(const hs_service_t *service, return 0; } -/* Refresh the given service descriptor meaning this will update every mutable +/** Refresh the given service descriptor meaning this will update every mutable * field that needs to be updated before we upload. * * This should ONLY be called before uploading a descriptor. It assumes that @@ -3134,7 +3133,7 @@ refresh_service_descriptor(const hs_service_t *service, set_descriptor_revision_counter(desc, now, service->desc_current == desc); } -/* Scheduled event run from the main loop. Try to upload the descriptor for +/** Scheduled event run from the main loop. Try to upload the descriptor for * each service. */ STATIC void run_upload_descriptor_event(time_t now) @@ -3183,7 +3182,7 @@ run_upload_descriptor_event(time_t now) consider_republishing_hs_descriptors = 0; } -/* Called when the introduction point circuit is done building and ready to be +/** Called when the introduction point circuit is done building and ready to be * used. */ static void service_intro_circ_has_opened(origin_circuit_t *circ) @@ -3241,7 +3240,7 @@ service_intro_circ_has_opened(origin_circuit_t *circ) return; } -/* Called when a rendezvous circuit is done building and ready to be used. */ +/** Called when a rendezvous circuit is done building and ready to be used. */ static void service_rendezvous_circ_has_opened(origin_circuit_t *circ) { @@ -3282,7 +3281,7 @@ service_rendezvous_circ_has_opened(origin_circuit_t *circ) return; } -/* We've been expecting an INTRO_ESTABLISHED cell on this circuit and it just +/** We've been expecting an INTRO_ESTABLISHED cell on this circuit and it just * arrived. Handle the INTRO_ESTABLISHED cell arriving on the given * introduction circuit. Return 0 on success else a negative value. */ static int @@ -3325,11 +3324,6 @@ service_handle_intro_established(origin_circuit_t *circ, goto err; } - /* Flag that we have an established circuit for this intro point. This value - * is what indicates the upload scheduled event if we are ready to build the - * intro point into the descriptor and upload. */ - ip->circuit_established = 1; - log_info(LD_REND, "Successfully received an INTRO_ESTABLISHED cell " "on circuit %u for service %s", TO_CIRCUIT(circ)->n_circ_id, @@ -3340,7 +3334,7 @@ service_handle_intro_established(origin_circuit_t *circ, return -1; } -/* We just received an INTRODUCE2 cell on the established introduction circuit +/** We just received an INTRODUCE2 cell on the established introduction circuit * circ. Handle the cell and return 0 on success else a negative value. */ static int service_handle_introduce2(origin_circuit_t *circ, const uint8_t *payload, @@ -3388,7 +3382,7 @@ service_handle_introduce2(origin_circuit_t *circ, const uint8_t *payload, return -1; } -/* Add to list every filename used by service. This is used by the sandbox +/** Add to list every filename used by service. This is used by the sandbox * subsystem. */ static void service_add_fnames_to_list(const hs_service_t *service, smartlist_t *list) @@ -3410,7 +3404,7 @@ service_add_fnames_to_list(const hs_service_t *service, smartlist_t *list) smartlist_add(list, hs_path_from_filename(s_dir, fname)); } -/* Return true iff the given service identity key is present on disk. */ +/** Return true iff the given service identity key is present on disk. */ static int service_key_on_disk(const char *directory_path) { @@ -3434,7 +3428,7 @@ service_key_on_disk(const char *directory_path) return ret; } -/* This is a proxy function before actually calling hs_desc_encode_descriptor +/** This is a proxy function before actually calling hs_desc_encode_descriptor * because we need some preprocessing here */ static int service_encode_descriptor(const hs_service_t *service, @@ -3465,7 +3459,7 @@ service_encode_descriptor(const hs_service_t *service, /* Public API */ /* ========== */ -/* This is called everytime the service map (v2 or v3) changes that is if an +/** This is called everytime the service map (v2 or v3) changes that is if an * element is added or removed. */ void hs_service_map_has_changed(void) @@ -3476,7 +3470,7 @@ hs_service_map_has_changed(void) rescan_periodic_events(get_options()); } -/* Upload an encoded descriptor in encoded_desc of the given version. This +/** Upload an encoded descriptor in encoded_desc of the given version. This * descriptor is for the service identity_pk and blinded_pk used to setup the * directory connection identifier. It is uploaded to the directory hsdir_rs * routerstatus_t object. @@ -3524,7 +3518,7 @@ hs_service_upload_desc_to_dir(const char *encoded_desc, directory_request_free(dir_req); } -/* Add the ephemeral service using the secret key sk and ports. Both max +/** Add the ephemeral service using the secret key sk and ports. Both max * streams parameter will be set in the newly created service. * * Ownership of sk and ports is passed to this routine. Regardless of @@ -3604,7 +3598,7 @@ hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports, return ret; } -/* For the given onion address, delete the ephemeral service. Return 0 on +/** For the given onion address, delete the ephemeral service. Return 0 on * success else -1 on error. */ int hs_service_del_ephemeral(const char *address) @@ -3654,7 +3648,7 @@ hs_service_del_ephemeral(const char *address) return -1; } -/* Using the ed25519 public key pk, find a service for that key and return the +/** Using the ed25519 public key pk, find a service for that key and return the * current encoded descriptor as a newly allocated string or NULL if not * found. This is used by the control port subsystem. */ char * @@ -3680,7 +3674,7 @@ hs_service_lookup_current_desc(const ed25519_public_key_t *pk) return NULL; } -/* Return the number of service we have configured and usable. */ +/** Return the number of service we have configured and usable. */ MOCK_IMPL(unsigned int, hs_service_get_num_services,(void)) { @@ -3690,7 +3684,7 @@ hs_service_get_num_services,(void)) return HT_SIZE(hs_service_map); } -/* Called once an introduction circuit is closed. If the circuit doesn't have +/** Called once an introduction circuit is closed. If the circuit doesn't have * a v3 identifier, it is ignored. */ void hs_service_intro_circ_has_closed(origin_circuit_t *circ) @@ -3724,15 +3718,11 @@ hs_service_intro_circ_has_closed(origin_circuit_t *circ) /* Can't have an intro point object without a descriptor. */ tor_assert(desc); - /* Circuit disappeared so make sure the intro point is updated. By - * keeping the object in the descriptor, we'll be able to retry. */ - ip->circuit_established = 0; - end: return; } -/* Given conn, a rendezvous edge connection acting as an exit stream, look up +/** Given conn, a rendezvous edge connection acting as an exit stream, look up * the hidden service for the circuit circ, and look up the port and address * based on the connection port. Assign the actual connection address. * @@ -3830,7 +3820,7 @@ hs_service_exports_circuit_id(const ed25519_public_key_t *pk) return service->config.circuit_id_protocol; } -/* Add to file_list every filename used by a configured hidden service, and to +/** Add to file_list every filename used by a configured hidden service, and to * dir_list every directory path used by a configured hidden service. This is * used by the sandbox subsystem to whitelist those. */ void @@ -3855,7 +3845,7 @@ hs_service_lists_fnames_for_sandbox(smartlist_t *file_list, } FOR_EACH_DESCRIPTOR_END; } -/* Called when our internal view of the directory has changed. We might have +/** Called when our internal view of the directory has changed. We might have * received a new batch of descriptors which might affect the shape of the * HSDir hash ring. Signal that we should reexamine the hash ring and * re-upload our HS descriptors if needed. */ @@ -3872,7 +3862,7 @@ hs_service_dir_info_changed(void) } } -/* Called when we get an INTRODUCE2 cell on the circ. Respond to the cell and +/** Called when we get an INTRODUCE2 cell on the circ. Respond to the cell and * launch a circuit to the rendezvous point. */ int hs_service_receive_introduce2(origin_circuit_t *circ, const uint8_t *payload, @@ -3903,7 +3893,7 @@ hs_service_receive_introduce2(origin_circuit_t *circ, const uint8_t *payload, return ret; } -/* Called when we get an INTRO_ESTABLISHED cell. Mark the circuit as an +/** Called when we get an INTRO_ESTABLISHED cell. Mark the circuit as an * established introduction point. Return 0 on success else a negative value * and the circuit is closed. */ int @@ -3940,7 +3930,7 @@ hs_service_receive_intro_established(origin_circuit_t *circ, return -1; } -/* Called when any kind of hidden service circuit is done building thus +/** Called when any kind of hidden service circuit is done building thus * opened. This is the entry point from the circuit subsystem. */ void hs_service_circuit_has_opened(origin_circuit_t *circ) @@ -3969,7 +3959,7 @@ hs_service_circuit_has_opened(origin_circuit_t *circ) } } -/* Return the service version by looking at the key in the service directory. +/** Return the service version by looking at the key in the service directory. * If the key is not found or unrecognized, -1 is returned. Else, the service * version is returned. */ int @@ -3999,7 +3989,7 @@ hs_service_get_version_from_key(const hs_service_t *service) return version; } -/* Load and/or generate keys for all onion services including the client +/** Load and/or generate keys for all onion services including the client * authorization if any. Return 0 on success, -1 on failure. */ int hs_service_load_all_keys(void) @@ -4035,7 +4025,7 @@ hs_service_load_all_keys(void) return -1; } -/* Put all service object in the given service list. After this, the caller +/** Put all service object in the given service list. After this, the caller * looses ownership of every elements in the list and responsible to free the * list pointer. */ void @@ -4052,7 +4042,7 @@ hs_service_stage_services(const smartlist_t *service_list) smartlist_add_all(hs_service_staging_list, service_list); } -/* Allocate and initilize a service object. The service configuration will +/** Allocate and initilize a service object. The service configuration will * contain the default values. Return the newly allocated object pointer. This * function can't fail. */ hs_service_t * @@ -4070,7 +4060,7 @@ hs_service_new(const or_options_t *options) return service; } -/* Free the given <b>service</b> object and all its content. This function +/** Free the given <b>service</b> object and all its content. This function * also takes care of wiping service keys from memory. It is safe to pass a * NULL pointer. */ void @@ -4099,7 +4089,7 @@ hs_service_free_(hs_service_t *service) tor_free(service); } -/* Periodic callback. Entry point from the main loop to the HS service +/** Periodic callback. Entry point from the main loop to the HS service * subsystem. This is call every second. This is skipped if tor can't build a * circuit or the network is disabled. */ void @@ -4122,7 +4112,7 @@ hs_service_run_scheduled_events(time_t now) run_upload_descriptor_event(now); } -/* Initialize the service HS subsystem. */ +/** Initialize the service HS subsystem. */ void hs_service_init(void) { @@ -4139,7 +4129,7 @@ hs_service_init(void) hs_service_staging_list = smartlist_new(); } -/* Release all global storage of the hidden service subsystem. */ +/** Release all global storage of the hidden service subsystem. */ void hs_service_free_all(void) { @@ -4149,14 +4139,14 @@ hs_service_free_all(void) #ifdef TOR_UNIT_TESTS -/* Return the global service map size. Only used by unit test. */ +/** Return the global service map size. Only used by unit test. */ STATIC unsigned int get_hs_service_map_size(void) { return HT_SIZE(hs_service_map); } -/* Return the staging list size. Only used by unit test. */ +/** Return the staging list size. Only used by unit test. */ STATIC int get_hs_service_staging_list_size(void) { diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h index c4bbb293bb..193e08546f 100644 --- a/src/feature/hs/hs_service.h +++ b/src/feature/hs/hs_service.h @@ -21,92 +21,89 @@ /* Trunnel */ #include "trunnel/hs/cell_establish_intro.h" -/* When loading and configuring a service, this is the default version it will +/** When loading and configuring a service, this is the default version it will * be configured for as it is possible that no HiddenServiceVersion is * present. */ #define HS_SERVICE_DEFAULT_VERSION HS_VERSION_THREE -/* As described in the specification, service publishes their next descriptor +/** As described in the specification, service publishes their next descriptor * at a random time between those two values (in seconds). */ #define HS_SERVICE_NEXT_UPLOAD_TIME_MIN (60 * 60) #define HS_SERVICE_NEXT_UPLOAD_TIME_MAX (120 * 60) -/* Service side introduction point. */ +/** Service side introduction point. */ typedef struct hs_service_intro_point_t { - /* Top level intropoint "shared" data between client/service. */ + /** Top level intropoint "shared" data between client/service. */ hs_intropoint_t base; - /* Onion key of the introduction point used to extend to it for the ntor + /** Onion key of the introduction point used to extend to it for the ntor * handshake. */ curve25519_public_key_t onion_key; - /* Authentication keypair used to create the authentication certificate + /** Authentication keypair used to create the authentication certificate * which is published in the descriptor. */ ed25519_keypair_t auth_key_kp; - /* Encryption keypair for the "ntor" type. */ + /** Encryption keypair for the "ntor" type. */ curve25519_keypair_t enc_key_kp; - /* Legacy key if that intro point doesn't support v3. This should be used if + /** Legacy key if that intro point doesn't support v3. This should be used if * the base object legacy flag is set. */ crypto_pk_t *legacy_key; - /* Legacy key SHA1 public key digest. This should be used only if the base + /** Legacy key SHA1 public key digest. This should be used only if the base * object legacy flag is set. */ uint8_t legacy_key_digest[DIGEST_LEN]; - /* Amount of INTRODUCE2 cell accepted from this intro point. */ + /** Amount of INTRODUCE2 cell accepted from this intro point. */ uint64_t introduce2_count; - /* Maximum number of INTRODUCE2 cell this intro point should accept. */ + /** Maximum number of INTRODUCE2 cell this intro point should accept. */ uint64_t introduce2_max; - /* The time at which this intro point should expire and stop being used. */ + /** The time at which this intro point should expire and stop being used. */ time_t time_to_expire; - /* The amount of circuit creation we've made to this intro point. This is + /** The amount of circuit creation we've made to this intro point. This is * incremented every time we do a circuit relaunch on this intro point which * is triggered when the circuit dies but the node is still in the * consensus. After MAX_INTRO_POINT_CIRCUIT_RETRIES, we give up on it. */ uint32_t circuit_retries; - /* Set if this intro point has an established circuit. */ - unsigned int circuit_established : 1; - - /* Replay cache recording the encrypted part of an INTRODUCE2 cell that the + /** Replay cache recording the encrypted part of an INTRODUCE2 cell that the * circuit associated with this intro point has received. This is used to * prevent replay attacks. */ replaycache_t *replay_cache; - /* Support the INTRO2 DoS defense. If set, the DoS extension described by + /** Support the INTRO2 DoS defense. If set, the DoS extension described by * proposal 305 is sent. */ unsigned int support_intro2_dos_defense : 1; } hs_service_intro_point_t; -/* Object handling introduction points of a service. */ +/** Object handling introduction points of a service. */ typedef struct hs_service_intropoints_t { - /* The time at which we've started our retry period to build circuits. We + /** The time at which we've started our retry period to build circuits. We * don't want to stress circuit creation so we can only retry for a certain * time and then after we stop and wait. */ time_t retry_period_started; - /* Number of circuit we've launched during a single retry period. */ + /** Number of circuit we've launched during a single retry period. */ unsigned int num_circuits_launched; - /* Contains the current hs_service_intro_point_t objects indexed by + /** Contains the current hs_service_intro_point_t objects indexed by * authentication public key. */ digest256map_t *map; - /* Contains node's identity key digest that were introduction point for this + /** Contains node's identity key digest that were introduction point for this * descriptor but were retried to many times. We keep those so we avoid * re-picking them over and over for a circuit retry period. * XXX: Once we have #22173, change this to only use ed25519 identity. */ digestmap_t *failed_id; } hs_service_intropoints_t; -/* Representation of a service descriptor. +/** Representation of a service descriptor. * * Some elements of the descriptor are mutable whereas others are immutable: - + * * Immutable elements are initialized once when the descriptor is built (when * service descriptors gets rotated). This means that these elements are * initialized once and then they don't change for the lifetime of the @@ -121,40 +118,42 @@ typedef struct hs_service_intropoints_t { * update_service_descriptor_intro_points(). */ typedef struct hs_service_descriptor_t { - /* Immutable: Client authorization ephemeral keypair. */ + /** Immutable: Client authorization ephemeral keypair. */ curve25519_keypair_t auth_ephemeral_kp; - /* Immutable: Descriptor cookie used to encrypt the descriptor, when the + /** Immutable: Descriptor cookie used to encrypt the descriptor, when the * client authorization is enabled */ uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN]; - /* Immutable: Descriptor signing keypair. */ + /** Immutable: Descriptor signing keypair. */ ed25519_keypair_t signing_kp; - /* Immutable: Blinded keypair derived from the master identity public key. */ + /** Immutable: Blinded keypair derived from the master identity public + * key. */ ed25519_keypair_t blinded_kp; - /* Immutable: The time period number this descriptor has been created for. */ + /** Immutable: The time period number this descriptor has been created + * for. */ uint64_t time_period_num; /** Immutable: The OPE cipher for encrypting revision counters for this * descriptor. Tied to the descriptor blinded key. */ struct crypto_ope_t *ope_cipher; - /* Mutable: Decoded descriptor. This object is used for encoding when the + /** Mutable: Decoded descriptor. This object is used for encoding when the * service publishes the descriptor. */ hs_descriptor_t *desc; - /* Mutable: When is the next time when we should upload the descriptor. */ + /** Mutable: When is the next time when we should upload the descriptor. */ time_t next_upload_time; - /* Mutable: Introduction points assign to this descriptor which contains + /** Mutable: Introduction points assign to this descriptor which contains * hs_service_intropoints_t object indexed by authentication key (the RSA key * if the node is legacy). */ hs_service_intropoints_t intro_points; - /* Mutable: True iff we have missing intro points for this descriptor because - * we couldn't pick any nodes. */ + /** Mutable: True iff we have missing intro points for this descriptor + * because we couldn't pick any nodes. */ unsigned int missing_intro_points : 1; /** Mutable: List of the responsible HSDirs (their b64ed identity digest) @@ -164,20 +163,20 @@ typedef struct hs_service_descriptor_t { smartlist_t *previous_hsdirs; } hs_service_descriptor_t; -/* Service key material. */ +/** Service key material. */ typedef struct hs_service_keys_t { - /* Master identify public key. */ + /** Master identify public key. */ ed25519_public_key_t identity_pk; - /* Master identity private key. */ + /** Master identity private key. */ ed25519_secret_key_t identity_sk; - /* True iff the key is kept offline which means the identity_sk MUST not be + /** True iff the key is kept offline which means the identity_sk MUST not be * used in that case. */ unsigned int is_identify_key_offline : 1; } hs_service_keys_t; /** Service side configuration of client authorization. */ typedef struct hs_service_authorized_client_t { - /* The client auth public key used to encrypt the descriptor cookie. */ + /** The client auth public key used to encrypt the descriptor cookie. */ curve25519_public_key_t client_pk; } hs_service_authorized_client_t; @@ -190,60 +189,60 @@ typedef enum { HS_CIRCUIT_ID_PROTOCOL_HAPROXY } hs_circuit_id_protocol_t; -/* Service configuration. The following are set from the torrc options either +/** Service configuration. The following are set from the torrc options either * set by the configuration file or by the control port. Nothing else should * change those values. */ typedef struct hs_service_config_t { - /* Protocol version of the service. Specified by HiddenServiceVersion + /** Protocol version of the service. Specified by HiddenServiceVersion * option. */ uint32_t version; - /* Have we explicitly set HiddenServiceVersion? */ + /** Have we explicitly set HiddenServiceVersion? */ unsigned int hs_version_explicitly_set : 1; - /* List of rend_service_port_config_t */ + /** List of rend_service_port_config_t */ smartlist_t *ports; - /* Path on the filesystem where the service persistent data is stored. NULL + /** Path on the filesystem where the service persistent data is stored. NULL * if the service is ephemeral. Specified by HiddenServiceDir option. */ char *directory_path; - /* The maximum number of simultaneous streams per rendezvous circuit that + /** The maximum number of simultaneous streams per rendezvous circuit that * are allowed to be created. No limit if 0. Specified by * HiddenServiceMaxStreams option. */ uint64_t max_streams_per_rdv_circuit; - /* If true, we close circuits that exceed the max_streams_per_rdv_circuit + /** If true, we close circuits that exceed the max_streams_per_rdv_circuit * limit. Specified by HiddenServiceMaxStreamsCloseCircuit option. */ unsigned int max_streams_close_circuit : 1; - /* How many introduction points this service has. Specified by + /** How many introduction points this service has. Specified by * HiddenServiceNumIntroductionPoints option. */ unsigned int num_intro_points; - /* True iff the client auth is enabled. */ + /** True iff the client auth is enabled. */ unsigned int is_client_auth_enabled : 1; - /* List of hs_service_authorized_client_t's of clients that may access this + /** List of hs_service_authorized_client_t's of clients that may access this * service. Specified by HiddenServiceAuthorizeClient option. */ smartlist_t *clients; - /* True iff we allow request made on unknown ports. Specified by + /** True iff we allow request made on unknown ports. Specified by * HiddenServiceAllowUnknownPorts option. */ unsigned int allow_unknown_ports : 1; - /* If true, this service is a Single Onion Service. Specified by + /** If true, this service is a Single Onion Service. Specified by * HiddenServiceSingleHopMode and HiddenServiceNonAnonymousMode options. */ unsigned int is_single_onion : 1; - /* If true, allow group read permissions on the directory_path. Specified by + /** If true, allow group read permissions on the directory_path. Specified by * HiddenServiceDirGroupReadable option. */ unsigned int dir_group_readable : 1; - /* Is this service ephemeral? */ + /** Is this service ephemeral? */ unsigned int is_ephemeral : 1; - /* Does this service export the circuit ID of its clients? */ + /** Does this service export the circuit ID of its clients? */ hs_circuit_id_protocol_t circuit_id_protocol; /* DoS defenses. For the ESTABLISH_INTRO cell extension. */ @@ -252,58 +251,58 @@ typedef struct hs_service_config_t { uint32_t intro_dos_burst_per_sec; } hs_service_config_t; -/* Service state. */ +/** Service state. */ typedef struct hs_service_state_t { - /* The time at which we've started our retry period to build circuits. We + /** The time at which we've started our retry period to build circuits. We * don't want to stress circuit creation so we can only retry for a certain * time and then after we stop and wait. */ time_t intro_circ_retry_started_time; - /* Number of circuit we've launched during a single retry period. This + /** Number of circuit we've launched during a single retry period. This * should never go over MAX_INTRO_CIRCS_PER_PERIOD. */ unsigned int num_intro_circ_launched; - /* Replay cache tracking the REND_COOKIE found in INTRODUCE2 cell to detect + /** Replay cache tracking the REND_COOKIE found in INTRODUCE2 cell to detect * repeats. Clients may send INTRODUCE1 cells for the same rendezvous point * through two or more different introduction points; when they do, this * keeps us from launching multiple simultaneous attempts to connect to the * same rend point. */ replaycache_t *replay_cache_rend_cookie; - /* When is the next time we should rotate our descriptors. This is has to be + /** When is the next time we should rotate our descriptors. This is has to be * done at the start time of the next SRV protocol run. */ time_t next_rotation_time; } hs_service_state_t; -/* Representation of a service running on this tor instance. */ +/** Representation of a service running on this tor instance. */ typedef struct hs_service_t { - /* Onion address base32 encoded and NUL terminated. We keep it for logging + /** Onion address base32 encoded and NUL terminated. We keep it for logging * purposes so we don't have to build it everytime. */ char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1]; - /* Hashtable node: use to look up the service by its master public identity + /** Hashtable node: use to look up the service by its master public identity * key in the service global map. */ HT_ENTRY(hs_service_t) hs_service_node; - /* Service state which contains various flags and counters. */ + /** Service state which contains various flags and counters. */ hs_service_state_t state; - /* Key material of the service. */ + /** Key material of the service. */ hs_service_keys_t keys; - /* Configuration of the service. */ + /** Configuration of the service. */ hs_service_config_t config; - /* Current descriptor. */ + /** Current descriptor. */ hs_service_descriptor_t *desc_current; - /* Next descriptor. */ + /** Next descriptor. */ hs_service_descriptor_t *desc_next; /* XXX: Credential (client auth.) #20700. */ } hs_service_t; -/* For the service global hash map, we define a specific type for it which +/** For the service global hash map, we define a specific type for it which * will make it safe to use and specific to some controlled parameters such as * the hashing function and how to compare services. */ typedef HT_HEAD(hs_service_ht, hs_service_t) hs_service_ht; diff --git a/src/feature/hs/hsdir_index_st.h b/src/feature/hs/hsdir_index_st.h index 6c86c02f47..34ff84f91f 100644 --- a/src/feature/hs/hsdir_index_st.h +++ b/src/feature/hs/hsdir_index_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file hsdir_index_st.h + * @brief HS directory index structure + **/ + #ifndef HSDIR_INDEX_ST_H #define HSDIR_INDEX_ST_H @@ -21,4 +26,3 @@ struct hsdir_index_t { }; #endif /* !defined(HSDIR_INDEX_ST_H) */ - diff --git a/src/feature/hs_common/feature_hs_common.dox b/src/feature/hs_common/feature_hs_common.dox new file mode 100644 index 0000000000..85d7585872 --- /dev/null +++ b/src/feature/hs_common/feature_hs_common.dox @@ -0,0 +1,5 @@ +/** +@dir /feature/hs_common +@brief feature/hs_common: Common to v2 (old) and v3 (current) onion services + +**/ diff --git a/src/feature/keymgt/feature_keymgt.dox b/src/feature/keymgt/feature_keymgt.dox new file mode 100644 index 0000000000..acc840eb2e --- /dev/null +++ b/src/feature/keymgt/feature_keymgt.dox @@ -0,0 +1,5 @@ +/** +@dir /feature/keymgt +@brief feature/keymgt: Store keys for relays, authorities, etc. + +**/ diff --git a/src/feature/keymgt/loadkey.c b/src/feature/keymgt/loadkey.c index a8cbf0e582..5c1e6353b8 100644 --- a/src/feature/keymgt/loadkey.c +++ b/src/feature/keymgt/loadkey.c @@ -33,7 +33,7 @@ /** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist * and <b>generate</b> is true, create a new RSA key and save it in * <b>fname</b>. Return the read/created key, or NULL on error. Log all - * errors at level <b>severity</b>. If <b>created_out/b> is non-NULL and a + * errors at level <b>severity</b>. If <b>created_out</b> is non-NULL and a * new key was created, set *<b>created_out</b> to true. */ crypto_pk_t * diff --git a/src/feature/nodelist/authority_cert_st.h b/src/feature/nodelist/authority_cert_st.h index bf9b690c24..6787487c7c 100644 --- a/src/feature/nodelist/authority_cert_st.h +++ b/src/feature/nodelist/authority_cert_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file authority_cert_st.h + * @brief Authority certificate structure. + **/ + #ifndef AUTHORITY_CERT_ST_H #define AUTHORITY_CERT_ST_H @@ -29,4 +34,3 @@ struct authority_cert_t { }; #endif /* !defined(AUTHORITY_CERT_ST_H) */ - diff --git a/src/feature/nodelist/desc_store_st.h b/src/feature/nodelist/desc_store_st.h index 4d1378cdfa..75300ecf97 100644 --- a/src/feature/nodelist/desc_store_st.h +++ b/src/feature/nodelist/desc_store_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file desc_store_st.h + * @brief Routerinfo/extrainfo storage structure. + **/ + #ifndef DESC_STORE_ST_H #define DESC_STORE_ST_H diff --git a/src/feature/nodelist/document_signature_st.h b/src/feature/nodelist/document_signature_st.h index ac2a803252..ba4581c1b8 100644 --- a/src/feature/nodelist/document_signature_st.h +++ b/src/feature/nodelist/document_signature_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file document_signature_st.h + * @brief Authority signature structure + **/ + #ifndef DOCUMENT_SIGNATURE_ST_H #define DOCUMENT_SIGNATURE_ST_H @@ -26,4 +31,3 @@ struct document_signature_t { }; #endif /* !defined(DOCUMENT_SIGNATURE_ST_H) */ - diff --git a/src/feature/nodelist/extrainfo_st.h b/src/feature/nodelist/extrainfo_st.h index 22c708f018..6d707bea05 100644 --- a/src/feature/nodelist/extrainfo_st.h +++ b/src/feature/nodelist/extrainfo_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file extrainfo_st.h + * @brief A relay's extra-info structure. + **/ + #ifndef EXTRAINFO_ST_H #define EXTRAINFO_ST_H @@ -27,4 +32,3 @@ struct extrainfo_t { }; #endif /* !defined(EXTRAINFO_ST_H) */ - diff --git a/src/feature/nodelist/feature_nodelist.dox b/src/feature/nodelist/feature_nodelist.dox new file mode 100644 index 0000000000..0b25dd246d --- /dev/null +++ b/src/feature/nodelist/feature_nodelist.dox @@ -0,0 +1,4 @@ +/** +@dir /feature/nodelist +@brief feature/nodelist: Download and manage a list of relays +**/ diff --git a/src/feature/nodelist/microdesc_st.h b/src/feature/nodelist/microdesc_st.h index e017c46c79..58b0630573 100644 --- a/src/feature/nodelist/microdesc_st.h +++ b/src/feature/nodelist/microdesc_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file microdesc_st.h + * @brief Microdescriptor structure + **/ + #ifndef MICRODESC_ST_H #define MICRODESC_ST_H diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index 496bafb865..b4b98301b0 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -216,10 +216,10 @@ networkstatus_reset_download_failures(void) } /** Return the filename used to cache the consensus of a given flavor */ -static char * -networkstatus_get_cache_fname(int flav, - const char *flavorname, - int unverified_consensus) +MOCK_IMPL(char *, +networkstatus_get_cache_fname,(int flav, + const char *flavorname, + int unverified_consensus)) { char buf[128]; const char *prefix; diff --git a/src/feature/nodelist/networkstatus.h b/src/feature/nodelist/networkstatus.h index 600fd7fbd5..e2c6ba611a 100644 --- a/src/feature/nodelist/networkstatus.h +++ b/src/feature/nodelist/networkstatus.h @@ -16,6 +16,9 @@ void networkstatus_reset_warnings(void); void networkstatus_reset_download_failures(void); +MOCK_DECL(char *,networkstatus_get_cache_fname,(int flav, + const char *flavorname, + int unverified_consensus)); tor_mmap_t *networkstatus_map_cached_consensus(const char *flavorname); int router_reload_consensus_networkstatus(void); void routerstatus_free_(routerstatus_t *rs); diff --git a/src/feature/nodelist/networkstatus_sr_info_st.h b/src/feature/nodelist/networkstatus_sr_info_st.h index 420c3d61e4..1392fa6853 100644 --- a/src/feature/nodelist/networkstatus_sr_info_st.h +++ b/src/feature/nodelist/networkstatus_sr_info_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file networkstatus_sr_info_st.h + * @brief Shared-randomness structure. + **/ + #ifndef NETWORKSTATUS_SR_INFO_ST_H #define NETWORKSTATUS_SR_INFO_ST_H @@ -20,4 +25,3 @@ struct networkstatus_sr_info_t { }; #endif /* !defined(NETWORKSTATUS_SR_INFO_ST_H) */ - diff --git a/src/feature/nodelist/networkstatus_st.h b/src/feature/nodelist/networkstatus_st.h index 6e84c170d6..a23ef0c193 100644 --- a/src/feature/nodelist/networkstatus_st.h +++ b/src/feature/nodelist/networkstatus_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file networkstatus_st.h + * @brief Networkstatus consensus/vote structure. + **/ + #ifndef NETWORKSTATUS_ST_H #define NETWORKSTATUS_ST_H diff --git a/src/feature/nodelist/networkstatus_voter_info_st.h b/src/feature/nodelist/networkstatus_voter_info_st.h index 66af82a8e3..629cb52254 100644 --- a/src/feature/nodelist/networkstatus_voter_info_st.h +++ b/src/feature/nodelist/networkstatus_voter_info_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file networkstatus_voter_info_st.h + * @brief Single consensus voter structure. + **/ + #ifndef NETWORKSTATUS_VOTER_INFO_ST_H #define NETWORKSTATUS_VOTER_INFO_ST_H diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c index 719b4b1b27..8ac0b664c3 100644 --- a/src/feature/nodelist/node_select.c +++ b/src/feature/nodelist/node_select.c @@ -147,7 +147,7 @@ router_pick_dirserver_generic(smartlist_t *sourcelist, try_ip_pref = 0; \ goto retry_label; \ } \ - STMT_END \ + STMT_END /* Common retry code for router_pick_directory_server_impl and * router_pick_trusteddirserver_impl. Retry without excluding nodes, but with diff --git a/src/feature/nodelist/node_st.h b/src/feature/nodelist/node_st.h index c63a535a19..6ad10bb85a 100644 --- a/src/feature/nodelist/node_st.h +++ b/src/feature/nodelist/node_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file node_st.h + * @brief Node information structure. + **/ + #ifndef NODE_ST_H #define NODE_ST_H diff --git a/src/feature/nodelist/nodefamily_st.h b/src/feature/nodelist/nodefamily_st.h index 20390c9308..4aa00b0255 100644 --- a/src/feature/nodelist/nodefamily_st.h +++ b/src/feature/nodelist/nodefamily_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file nodefamily_st.h + * @brief Compact node-family structure + **/ + #ifndef TOR_NODEFAMILY_ST_H #define TOR_NODEFAMILY_ST_H diff --git a/src/feature/nodelist/routerinfo.c b/src/feature/nodelist/routerinfo.c index 975b503615..4e570fcbb2 100644 --- a/src/feature/nodelist/routerinfo.c +++ b/src/feature/nodelist/routerinfo.c @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file routerinfo.c + * @brief Manipulate full router descriptors. + **/ + #include "core/or/or.h" #include "feature/nodelist/nodelist.h" diff --git a/src/feature/nodelist/routerinfo_st.h b/src/feature/nodelist/routerinfo_st.h index 59fd56d0a0..16387f1005 100644 --- a/src/feature/nodelist/routerinfo_st.h +++ b/src/feature/nodelist/routerinfo_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file routerinfo_st.h + * @brief Router descriptor structure. + **/ + #ifndef ROUTERINFO_ST_H #define ROUTERINFO_ST_H diff --git a/src/feature/nodelist/routerlist_st.h b/src/feature/nodelist/routerlist_st.h index 10b919a1bf..d3a3874983 100644 --- a/src/feature/nodelist/routerlist_st.h +++ b/src/feature/nodelist/routerlist_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file routerlist_st.h + * @brief Router descriptor list structure. + **/ + #ifndef ROUTERLIST_ST_H #define ROUTERLIST_ST_H @@ -37,4 +42,3 @@ struct routerlist_t { }; #endif /* !defined(ROUTERLIST_ST_H) */ - diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c index 9a205d39b7..4f2406d10f 100644 --- a/src/feature/nodelist/routerset.c +++ b/src/feature/nodelist/routerset.c @@ -17,7 +17,7 @@ * * Routersets are typically used for user-specified restrictions, and * are created by invoking routerset_new and routerset_parse from - * config.c and confparse.c. To use a routerset, invoke one of + * config.c and confmgt.c. To use a routerset, invoke one of * routerset_contains_...() functions , or use * routerstatus_get_all_nodes() / routerstatus_subtract_nodes() to * manipulate a smartlist of node_t pointers. diff --git a/src/feature/nodelist/routerset.h b/src/feature/nodelist/routerset.h index f3bf4a1f7c..dc6ce0b667 100644 --- a/src/feature/nodelist/routerset.h +++ b/src/feature/nodelist/routerset.h @@ -4,7 +4,7 @@ /* See LICENSE for licensing information */ /** - * \file routerlist.h + * \file routerset.h * \brief Header file for routerset.c **/ diff --git a/src/feature/nodelist/routerstatus_st.h b/src/feature/nodelist/routerstatus_st.h index 46337c9e52..b60e0e41d0 100644 --- a/src/feature/nodelist/routerstatus_st.h +++ b/src/feature/nodelist/routerstatus_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file routerstatus_st.h + * @brief Routerstatus (consensus entry) structure + **/ + #ifndef ROUTERSTATUS_ST_H #define ROUTERSTATUS_ST_H @@ -79,4 +84,3 @@ struct routerstatus_t { }; #endif /* !defined(ROUTERSTATUS_ST_H) */ - diff --git a/src/feature/nodelist/signed_descriptor_st.h b/src/feature/nodelist/signed_descriptor_st.h index 64c28f7440..952fc702f4 100644 --- a/src/feature/nodelist/signed_descriptor_st.h +++ b/src/feature/nodelist/signed_descriptor_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file signed_descriptor_st.h + * @brief Descriptor/extrainfo signature structure + **/ + #ifndef SIGNED_DESCRIPTOR_ST_H #define SIGNED_DESCRIPTOR_ST_H @@ -58,4 +63,3 @@ struct signed_descriptor_t { }; #endif /* !defined(SIGNED_DESCRIPTOR_ST_H) */ - diff --git a/src/feature/nodelist/torcert.h b/src/feature/nodelist/torcert.h index 03d5bdca93..5a1f932392 100644 --- a/src/feature/nodelist/torcert.h +++ b/src/feature/nodelist/torcert.h @@ -1,6 +1,11 @@ /* Copyright (c) 2014-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file torcert.h + * @brief Header for torcert.c + **/ + #ifndef TORCERT_H_INCLUDED #define TORCERT_H_INCLUDED diff --git a/src/feature/nodelist/vote_routerstatus_st.h b/src/feature/nodelist/vote_routerstatus_st.h index 0d909da260..e34b5e5f69 100644 --- a/src/feature/nodelist/vote_routerstatus_st.h +++ b/src/feature/nodelist/vote_routerstatus_st.h @@ -4,6 +4,10 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file vote_routerstatus_st.h + * @brief Routerstatus (vote entry) structure + **/ #ifndef VOTE_ROUTERSTATUS_ST_H #define VOTE_ROUTERSTATUS_ST_H diff --git a/src/feature/relay/ext_orport.h b/src/feature/relay/ext_orport.h index 7313ebd03d..a981ca80c2 100644 --- a/src/feature/relay/ext_orport.h +++ b/src/feature/relay/ext_orport.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file ext_orport.h + * @brief Header for ext_orport.c + **/ + #ifndef EXT_ORPORT_H #define EXT_ORPORT_H diff --git a/src/feature/relay/feature_relay.dox b/src/feature/relay/feature_relay.dox new file mode 100644 index 0000000000..6867818257 --- /dev/null +++ b/src/feature/relay/feature_relay.dox @@ -0,0 +1,6 @@ +/** +@dir /feature/relay +@brief feature/relay: Relay-specific code + +(There is also a bunch of relay-specific code in other modules.) +**/ diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c new file mode 100644 index 0000000000..275e0e6a68 --- /dev/null +++ b/src/feature/relay/relay_config.c @@ -0,0 +1,1440 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_config.c + * @brief Code to interpret the user's configuration of Tor's relay module. + **/ + +#include "orconfig.h" +#define RELAY_CONFIG_PRIVATE +#include "feature/relay/relay_config.h" + +#include "lib/encoding/confline.h" +#include "lib/confmgt/confmgt.h" + +#include "lib/container/smartlist.h" +#include "lib/geoip/geoip.h" +#include "lib/meminfo/meminfo.h" +#include "lib/osinfo/uname.h" +#include "lib/process/setuid.h" + +/* Required for dirinfo_type_t in or_options_t */ +#include "core/or/or.h" +#include "app/config/config.h" + +#include "core/mainloop/connection.h" +#include "core/mainloop/cpuworker.h" +#include "core/mainloop/mainloop.h" +#include "core/or/circuitbuild.h" +#include "core/or/connection_or.h" +#include "core/or/port_cfg_st.h" + +#include "feature/hibernate/hibernate.h" +#include "feature/nodelist/nickname.h" +#include "feature/stats/geoip_stats.h" +#include "feature/stats/predict_ports.h" +#include "feature/stats/rephist.h" + +#include "feature/dirauth/authmode.h" + +#include "feature/dircache/consdiffmgr.h" +#include "feature/relay/dns.h" +#include "feature/relay/routermode.h" + +/** Contents of most recently read DirPortFrontPage file. */ +static char *global_dirfrontpagecontents = NULL; + +/* Copied from config.c, we will refactor later in 29211. */ +#define REJECT(arg) \ + STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END +#if defined(__GNUC__) && __GNUC__ <= 3 +#define COMPLAIN(args...) \ + STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END +#else +#define COMPLAIN(args, ...) \ + STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END +#endif /* defined(__GNUC__) && __GNUC__ <= 3 */ + +/* Used in the various options_transition_affects* functions. */ +#define YES_IF_CHANGED_BOOL(opt) \ + if (!CFG_EQ_BOOL(old_options, new_options, opt)) return 1; +#define YES_IF_CHANGED_INT(opt) \ + if (!CFG_EQ_INT(old_options, new_options, opt)) return 1; +#define YES_IF_CHANGED_STRING(opt) \ + if (!CFG_EQ_STRING(old_options, new_options, opt)) return 1; +#define YES_IF_CHANGED_LINELIST(opt) \ + if (!CFG_EQ_LINELIST(old_options, new_options, opt)) return 1; + +/** Return the contents of our frontpage string, or NULL if not configured. */ +MOCK_IMPL(const char*, +relay_get_dirportfrontpage, (void)) +{ + return global_dirfrontpagecontents; +} + +/** Release all memory and resources held by global relay configuration + * structures. + */ +void +relay_config_free_all(void) +{ + tor_free(global_dirfrontpagecontents); +} + +/** Return the bandwidthrate that we are going to report to the authorities + * based on the config options. */ +uint32_t +relay_get_effective_bwrate(const or_options_t *options) +{ + uint64_t bw = options->BandwidthRate; + if (bw > options->MaxAdvertisedBandwidth) + bw = options->MaxAdvertisedBandwidth; + if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate) + bw = options->RelayBandwidthRate; + /* config_ensure_bandwidth_cap() makes sure that this cast can't overflow. */ + return (uint32_t)bw; +} + +/** Return the bandwidthburst that we are going to report to the authorities + * based on the config options. */ +uint32_t +relay_get_effective_bwburst(const or_options_t *options) +{ + uint64_t bw = options->BandwidthBurst; + if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst) + bw = options->RelayBandwidthBurst; + /* config_ensure_bandwidth_cap() makes sure that this cast can't overflow. */ + return (uint32_t)bw; +} + +/** Warn for every Extended ORPort port in <b>ports</b> that is on a + * publicly routable address. */ +void +port_warn_nonlocal_ext_orports(const smartlist_t *ports, const char *portname) +{ + SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) { + if (port->type != CONN_TYPE_EXT_OR_LISTENER) + continue; + if (port->is_unix_addr) + continue; + /* XXX maybe warn even if address is RFC1918? */ + if (!tor_addr_is_internal(&port->addr, 1)) { + log_warn(LD_CONFIG, "You specified a public address '%s' for %sPort. " + "This is not advised; this address is supposed to only be " + "exposed on localhost so that your pluggable transport " + "proxies can connect to it.", + fmt_addrport(&port->addr, port->port), portname); + } + } SMARTLIST_FOREACH_END(port); +} + +/** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal + * consistency and warn as appropriate. On Unix-based OSes, set + * *<b>n_low_ports_out</b> to the number of sub-1024 ports we will be + * binding, and warn if we may be unable to re-bind after hibernation. */ +static int +check_server_ports(const smartlist_t *ports, + const or_options_t *options, + int *n_low_ports_out) +{ + if (BUG(!ports)) + return -1; + + if (BUG(!options)) + return -1; + + if (BUG(!n_low_ports_out)) + return -1; + + int n_orport_advertised = 0; + int n_orport_advertised_ipv4 = 0; + int n_orport_listeners = 0; + int n_dirport_advertised = 0; + int n_dirport_listeners = 0; + int n_low_port = 0; + int r = 0; + + SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) { + if (port->type == CONN_TYPE_DIR_LISTENER) { + if (! port->server_cfg.no_advertise) + ++n_dirport_advertised; + if (! port->server_cfg.no_listen) + ++n_dirport_listeners; + } else if (port->type == CONN_TYPE_OR_LISTENER) { + if (! port->server_cfg.no_advertise) { + ++n_orport_advertised; + if (port_binds_ipv4(port)) + ++n_orport_advertised_ipv4; + } + if (! port->server_cfg.no_listen) + ++n_orport_listeners; + } else { + continue; + } +#ifndef _WIN32 + if (!port->server_cfg.no_listen && port->port < 1024) + ++n_low_port; +#endif + } SMARTLIST_FOREACH_END(port); + + if (n_orport_advertised && !n_orport_listeners) { + log_warn(LD_CONFIG, "We are advertising an ORPort, but not actually " + "listening on one."); + r = -1; + } + if (n_orport_listeners && !n_orport_advertised) { + log_warn(LD_CONFIG, "We are listening on an ORPort, but not advertising " + "any ORPorts. This will keep us from building a %s " + "descriptor, and make us impossible to use.", + options->BridgeRelay ? "bridge" : "router"); + r = -1; + } + if (n_dirport_advertised && !n_dirport_listeners) { + log_warn(LD_CONFIG, "We are advertising a DirPort, but not actually " + "listening on one."); + r = -1; + } + if (n_dirport_advertised > 1) { + log_warn(LD_CONFIG, "Can't advertise more than one DirPort."); + r = -1; + } + if (n_orport_advertised && !n_orport_advertised_ipv4 && + !options->BridgeRelay) { + log_warn(LD_CONFIG, "Configured public relay to listen only on an IPv6 " + "address. Tor needs to listen on an IPv4 address too."); + r = -1; + } + + if (n_low_port && options->AccountingMax && + (!have_capability_support() || options->KeepBindCapabilities == 0)) { + const char *extra = ""; + if (options->KeepBindCapabilities == 0 && have_capability_support()) + extra = ", and you have disabled KeepBindCapabilities."; + log_warn(LD_CONFIG, + "You have set AccountingMax to use hibernation. You have also " + "chosen a low DirPort or OrPort%s." + "This combination can make Tor stop " + "working when it tries to re-attach the port after a period of " + "hibernation. Please choose a different port or turn off " + "hibernation unless you know this combination will work on your " + "platform.", extra); + } + + if (n_low_ports_out) + *n_low_ports_out = n_low_port; + + return r; +} + +/** Parse all relay ports from <b>options</b>. On success, add parsed ports to + * <b>ports</b>, and return 0. On failure, set *<b>msg</b> to a description + * of the problem and return -1. + **/ +int +port_parse_ports_relay(or_options_t *options, + char **msg, + smartlist_t *ports_out, + int *have_low_ports_out) +{ + int retval = -1; + smartlist_t *ports = smartlist_new(); + int n_low_ports = 0; + + if (BUG(!options)) + goto err; + + if (BUG(!msg)) + goto err; + + if (BUG(!ports_out)) + goto err; + + if (BUG(!have_low_ports_out)) + goto err; + + if (options->ClientOnly) { + retval = 0; + goto err; + } + + if (port_parse_config(ports, + options->ORPort_lines, + "OR", CONN_TYPE_OR_LISTENER, + "0.0.0.0", 0, + CL_PORT_SERVER_OPTIONS) < 0) { + *msg = tor_strdup("Invalid ORPort configuration"); + goto err; + } + if (port_parse_config(ports, + options->ExtORPort_lines, + "ExtOR", CONN_TYPE_EXT_OR_LISTENER, + "127.0.0.1", 0, + CL_PORT_SERVER_OPTIONS|CL_PORT_WARN_NONLOCAL) < 0) { + *msg = tor_strdup("Invalid ExtORPort configuration"); + goto err; + } + if (port_parse_config(ports, + options->DirPort_lines, + "Dir", CONN_TYPE_DIR_LISTENER, + "0.0.0.0", 0, + CL_PORT_SERVER_OPTIONS) < 0) { + *msg = tor_strdup("Invalid DirPort configuration"); + goto err; + } + + if (check_server_ports(ports, options, &n_low_ports) < 0) { + *msg = tor_strdup("Misconfigured server ports"); + goto err; + } + + smartlist_add_all(ports_out, ports); + smartlist_free(ports); + ports = NULL; + retval = 0; + + err: + if (*have_low_ports_out < 0) + *have_low_ports_out = (n_low_ports > 0); + if (ports) { + SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p)); + smartlist_free(ports); + } + return retval; +} + +/** Update the relay *Port_set values in <b>options</b> from <b>ports</b>. */ +void +port_update_port_set_relay(or_options_t *options, + const smartlist_t *ports) +{ + if (BUG(!options)) + return; + + if (BUG(!ports)) + return; + + if (options->ClientOnly) + return; + + /* Update the relay *Port_set options. The !! here is to force a boolean + * out of an integer. */ + options->ORPort_set = + !! port_count_real_listeners(ports, CONN_TYPE_OR_LISTENER, 0); + options->DirPort_set = + !! port_count_real_listeners(ports, CONN_TYPE_DIR_LISTENER, 0); + options->ExtORPort_set = + !! port_count_real_listeners(ports, CONN_TYPE_EXT_OR_LISTENER, 0); +} + +/** + * Legacy validation function, which checks that the current OS is usable in + * relay mode, if options is set to a relay mode. + * + * Warns about OSes with potential issues. Always returns 0. + */ +int +options_validate_relay_os(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (!server_mode(options)) + return 0; + + const char *uname = get_uname(); + + if (!strcmpstart(uname, "Windows 95") || + !strcmpstart(uname, "Windows 98") || + !strcmpstart(uname, "Windows Me")) { + log_warn(LD_CONFIG, "Tor is running as a server, but you are " + "running %s; this probably won't work. See " + "https://www.torproject.org/docs/faq.html#BestOSForRelay " + "for details.", uname); + } + + return 0; +} + +/** + * Legacy validation/normalization function for the relay info options. + * Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_relay_info(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (options->Nickname == NULL) { + if (server_mode(options)) { + options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME); + } + } else { + if (!is_legal_nickname(options->Nickname)) { + tor_asprintf(msg, + "Nickname '%s', nicknames must be between 1 and 19 characters " + "inclusive, and must contain only the characters [a-zA-Z0-9].", + options->Nickname); + return -1; + } + } + + if (server_mode(options) && !options->ContactInfo) + log_notice(LD_CONFIG, "Your ContactInfo config option is not set. " + "Please consider setting it, so we can contact you if your server is " + "misconfigured or something else goes wrong."); + + const char *ContactInfo = options->ContactInfo; + if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo))) + REJECT("ContactInfo config option must be UTF-8."); + + return 0; +} + +/** Parse an authority type from <b>options</b>-\>PublishServerDescriptor + * and write it to <b>options</b>-\>PublishServerDescriptor_. Treat "1" + * as "v3" unless BridgeRelay is 1, in which case treat it as "bridge". + * Treat "0" as "". + * Return 0 on success or -1 if not a recognized authority type (in which + * case the value of PublishServerDescriptor_ is undefined). */ +static int +compute_publishserverdescriptor(or_options_t *options) +{ + smartlist_t *list = options->PublishServerDescriptor; + dirinfo_type_t *auth = &options->PublishServerDescriptor_; + *auth = NO_DIRINFO; + if (!list) /* empty list, answer is none */ + return 0; + SMARTLIST_FOREACH_BEGIN(list, const char *, string) { + if (!strcasecmp(string, "v1")) + log_warn(LD_CONFIG, "PublishServerDescriptor v1 has no effect, because " + "there are no v1 directory authorities anymore."); + else if (!strcmp(string, "1")) + if (options->BridgeRelay) + *auth |= BRIDGE_DIRINFO; + else + *auth |= V3_DIRINFO; + else if (!strcasecmp(string, "v2")) + log_warn(LD_CONFIG, "PublishServerDescriptor v2 has no effect, because " + "there are no v2 directory authorities anymore."); + else if (!strcasecmp(string, "v3")) + *auth |= V3_DIRINFO; + else if (!strcasecmp(string, "bridge")) + *auth |= BRIDGE_DIRINFO; + else if (!strcasecmp(string, "hidserv")) + log_warn(LD_CONFIG, + "PublishServerDescriptor hidserv is invalid. See " + "PublishHidServDescriptors."); + else if (!strcasecmp(string, "") || !strcmp(string, "0")) + /* no authority */; + else + return -1; + } SMARTLIST_FOREACH_END(string); + return 0; +} + +/** + * Validate the configured bridge distribution method from a BridgeDistribution + * config line. + * + * The input <b>bd</b>, is a string taken from the BridgeDistribution config + * line (if present). If the option wasn't set, return 0 immediately. The + * BridgeDistribution option is then validated. Currently valid, recognised + * options are: + * + * - "none" + * - "any" + * - "https" + * - "email" + * - "moat" + * - "hyphae" + * + * If the option string is unrecognised, a warning will be logged and 0 is + * returned. If the option string contains an invalid character, -1 is + * returned. + **/ +STATIC int +check_bridge_distribution_setting(const char *bd) +{ + if (bd == NULL) + return 0; + + const char *RECOGNIZED[] = { + "none", "any", "https", "email", "moat", "hyphae" + }; + unsigned i; + for (i = 0; i < ARRAY_LENGTH(RECOGNIZED); ++i) { + if (!strcmp(bd, RECOGNIZED[i])) + return 0; + } + + const char *cp = bd; + // Method = (KeywordChar | "_") + + while (TOR_ISALNUM(*cp) || *cp == '-' || *cp == '_') + ++cp; + + if (*cp == 0) { + log_warn(LD_CONFIG, "Unrecognized BridgeDistribution value %s. I'll " + "assume you know what you are doing...", escaped(bd)); + return 0; // we reached the end of the string; all is well + } else { + return -1; // we found a bad character in the string. + } +} + +/** + * Legacy validation/normalization function for the bridge relay options. + * Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_publish_server(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (compute_publishserverdescriptor(options) < 0) { + tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor"); + return -1; + } + + if ((options->BridgeRelay + || options->PublishServerDescriptor_ & BRIDGE_DIRINFO) + && (options->PublishServerDescriptor_ & V3_DIRINFO)) { + REJECT("Bridges are not supposed to publish router descriptors to the " + "directory authorities. Please correct your " + "PublishServerDescriptor line."); + } + + if (options->BridgeDistribution) { + if (!options->BridgeRelay) { + REJECT("You set BridgeDistribution, but you didn't set BridgeRelay!"); + } + if (check_bridge_distribution_setting(options->BridgeDistribution) < 0) { + REJECT("Invalid BridgeDistribution value."); + } + } + + if (options->PublishServerDescriptor) + SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, { + if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0")) + if (smartlist_len(options->PublishServerDescriptor) > 1) { + COMPLAIN("You have passed a list of multiple arguments to the " + "PublishServerDescriptor option that includes 0 or 1. " + "0 or 1 should only be used as the sole argument. " + "This configuration will be rejected in a future release."); + break; + } + }); + + return 0; +} + +/** + * Legacy validation/normalization function for the relay padding options. + * Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_relay_padding(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (!server_mode(options)) + return 0; + + if (options->ConnectionPadding != -1) { + REJECT("Relays must use 'auto' for the ConnectionPadding setting."); + } + + if (options->ReducedConnectionPadding != 0) { + REJECT("Relays cannot set ReducedConnectionPadding. "); + } + + if (options->CircuitPadding == 0) { + REJECT("Relays cannot set CircuitPadding to 0. "); + } + + if (options->ReducedCircuitPadding == 1) { + REJECT("Relays cannot set ReducedCircuitPadding. "); + } + + return 0; +} + +/** + * Legacy validation/normalization function for the relay bandwidth options. + * Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_relay_bandwidth(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + /* 31851: the tests expect us to validate bandwidths, even when we are not + * in relay mode. */ + if (config_ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth, + "MaxAdvertisedBandwidth", msg) < 0) + return -1; + if (config_ensure_bandwidth_cap(&options->RelayBandwidthRate, + "RelayBandwidthRate", msg) < 0) + return -1; + if (config_ensure_bandwidth_cap(&options->RelayBandwidthBurst, + "RelayBandwidthBurst", msg) < 0) + return -1; + if (config_ensure_bandwidth_cap(&options->PerConnBWRate, + "PerConnBWRate", msg) < 0) + return -1; + if (config_ensure_bandwidth_cap(&options->PerConnBWBurst, + "PerConnBWBurst", msg) < 0) + return -1; + + if (options->RelayBandwidthRate && !options->RelayBandwidthBurst) + options->RelayBandwidthBurst = options->RelayBandwidthRate; + if (options->RelayBandwidthBurst && !options->RelayBandwidthRate) + options->RelayBandwidthRate = options->RelayBandwidthBurst; + + if (server_mode(options)) { + const unsigned required_min_bw = + public_server_mode(options) ? + RELAY_REQUIRED_MIN_BANDWIDTH : BRIDGE_REQUIRED_MIN_BANDWIDTH; + const char * const optbridge = + public_server_mode(options) ? "" : "bridge "; + if (options->BandwidthRate < required_min_bw) { + tor_asprintf(msg, + "BandwidthRate is set to %d bytes/second. " + "For %sservers, it must be at least %u.", + (int)options->BandwidthRate, optbridge, + required_min_bw); + return -1; + } else if (options->MaxAdvertisedBandwidth < + required_min_bw/2) { + tor_asprintf(msg, + "MaxAdvertisedBandwidth is set to %d bytes/second. " + "For %sservers, it must be at least %u.", + (int)options->MaxAdvertisedBandwidth, optbridge, + required_min_bw/2); + return -1; + } + if (options->RelayBandwidthRate && + options->RelayBandwidthRate < required_min_bw) { + tor_asprintf(msg, + "RelayBandwidthRate is set to %d bytes/second. " + "For %sservers, it must be at least %u.", + (int)options->RelayBandwidthRate, optbridge, + required_min_bw); + return -1; + } + } + + /* 31851: the tests expect us to validate bandwidths, even when we are not + * in relay mode. */ + if (options->RelayBandwidthRate > options->RelayBandwidthBurst) + REJECT("RelayBandwidthBurst must be at least equal " + "to RelayBandwidthRate."); + + /* if they set relaybandwidth* really high but left bandwidth* + * at the default, raise the defaults. */ + if (options->RelayBandwidthRate > options->BandwidthRate) + options->BandwidthRate = options->RelayBandwidthRate; + if (options->RelayBandwidthBurst > options->BandwidthBurst) + options->BandwidthBurst = options->RelayBandwidthBurst; + + return 0; +} + +/** + * Legacy validation/normalization function for the relay bandwidth accounting + * options. Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_relay_accounting(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + /* 31851: the tests expect us to validate accounting, even when we are not + * in relay mode. */ + if (accounting_parse_options(options, 1)<0) + REJECT("Failed to parse accounting options. See logs for details."); + + if (options->AccountingMax) { + if (options->RendConfigLines && server_mode(options)) { + log_warn(LD_CONFIG, "Using accounting with a hidden service and an " + "ORPort is risky: your hidden service(s) and your public " + "address will all turn off at the same time, which may alert " + "observers that they are being run by the same party."); + } else if (config_count_key(options->RendConfigLines, + "HiddenServiceDir") > 1) { + log_warn(LD_CONFIG, "Using accounting with multiple hidden services is " + "risky: they will all turn off at the same time, which may " + "alert observers that they are being run by the same party."); + } + } + + options->AccountingRule = ACCT_MAX; + if (options->AccountingRule_option) { + if (!strcmp(options->AccountingRule_option, "sum")) + options->AccountingRule = ACCT_SUM; + else if (!strcmp(options->AccountingRule_option, "max")) + options->AccountingRule = ACCT_MAX; + else if (!strcmp(options->AccountingRule_option, "in")) + options->AccountingRule = ACCT_IN; + else if (!strcmp(options->AccountingRule_option, "out")) + options->AccountingRule = ACCT_OUT; + else + REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'"); + } + + return 0; +} + +/** Verify whether lst is a list of strings containing valid-looking + * comma-separated nicknames, or NULL. Will normalise <b>lst</b> to prefix '$' + * to any nickname or fingerprint that needs it. Also splits comma-separated + * list elements into multiple elements. Return 0 on success. + * Warn and return -1 on failure. + */ +static int +normalize_nickname_list(config_line_t **normalized_out, + const config_line_t *lst, const char *name, + char **msg) +{ + if (!lst) + return 0; + + config_line_t *new_nicknames = NULL; + config_line_t **new_nicknames_next = &new_nicknames; + + const config_line_t *cl; + for (cl = lst; cl; cl = cl->next) { + const char *line = cl->value; + if (!line) + continue; + + int valid_line = 1; + smartlist_t *sl = smartlist_new(); + smartlist_split_string(sl, line, ",", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0); + SMARTLIST_FOREACH_BEGIN(sl, char *, s) + { + char *normalized = NULL; + if (!is_legal_nickname_or_hexdigest(s)) { + // check if first char is dollar + if (s[0] != '$') { + // Try again but with a dollar symbol prepended + char *prepended; + tor_asprintf(&prepended, "$%s", s); + + if (is_legal_nickname_or_hexdigest(prepended)) { + // The nickname is valid when it's prepended, set it as the + // normalized version + normalized = prepended; + } else { + // Still not valid, free and fallback to error message + tor_free(prepended); + } + } + + if (!normalized) { + tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name); + valid_line = 0; + break; + } + } else { + normalized = tor_strdup(s); + } + + config_line_t *next = tor_malloc_zero(sizeof(*next)); + next->key = tor_strdup(cl->key); + next->value = normalized; + next->next = NULL; + + *new_nicknames_next = next; + new_nicknames_next = &next->next; + } SMARTLIST_FOREACH_END(s); + + SMARTLIST_FOREACH(sl, char *, s, tor_free(s)); + smartlist_free(sl); + + if (!valid_line) { + config_free_lines(new_nicknames); + return -1; + } + } + + *normalized_out = new_nicknames; + + return 0; +} + +#define ONE_MEGABYTE (UINT64_C(1) << 20) + +/* If we have less than 300 MB suggest disabling dircache */ +#define DIRCACHE_MIN_MEM_MB 300 +#define DIRCACHE_MIN_MEM_BYTES (DIRCACHE_MIN_MEM_MB*ONE_MEGABYTE) +#define STRINGIFY(val) #val + +/** Create a warning message for emitting if we are a dircache but may not have + * enough system memory, or if we are not a dircache but probably should be. + * Return -1 when a message is returned in *msg*, else return 0. */ +STATIC int +have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem, + char **msg) +{ + *msg = NULL; + /* XXX We should possibly be looking at MaxMemInQueues here + * unconditionally. Or we should believe total_mem unconditionally. */ + if (total_mem == 0) { + if (get_total_system_memory(&total_mem) < 0) { + total_mem = options->MaxMemInQueues >= SIZE_MAX ? + SIZE_MAX : (size_t)options->MaxMemInQueues; + } + } + if (options->DirCache) { + if (total_mem < DIRCACHE_MIN_MEM_BYTES) { + if (options->BridgeRelay) { + tor_asprintf(msg, "Running a Bridge with less than %d MB of memory " + "is not recommended.", DIRCACHE_MIN_MEM_MB); + } else { + tor_asprintf(msg, "Being a directory cache (default) with less than " + "%d MB of memory is not recommended and may consume " + "most of the available resources. Consider disabling " + "this functionality by setting the DirCache option " + "to 0.", DIRCACHE_MIN_MEM_MB); + } + } + } else { + if (total_mem >= DIRCACHE_MIN_MEM_BYTES) { + *msg = tor_strdup("DirCache is disabled and we are configured as a " + "relay. We will not become a Guard."); + } + } + return *msg == NULL ? 0 : -1; +} +#undef STRINGIFY + +/** + * Legacy validation/normalization function for the relay mode options. + * Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_relay_mode(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (server_mode(options) && options->RendConfigLines) + log_warn(LD_CONFIG, + "Tor is currently configured as a relay and a hidden service. " + "That's not very secure: you should probably run your hidden service " + "in a separate Tor process, at least -- see " + "https://trac.torproject.org/8742"); + + if (options->BridgeRelay && options->DirPort_set) { + log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling " + "DirPort"); + config_free_lines(options->DirPort_lines); + options->DirPort_lines = NULL; + options->DirPort_set = 0; + } + + if (options->DirPort_set && !options->DirCache) { + REJECT("DirPort configured but DirCache disabled. DirPort requires " + "DirCache."); + } + + if (options->BridgeRelay && !options->DirCache) { + REJECT("We're a bridge but DirCache is disabled. BridgeRelay requires " + "DirCache."); + } + + if (options->BridgeRelay == 1 && ! options->ORPort_set) + REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid " + "combination."); + + if (server_mode(options)) { + char *dircache_msg = NULL; + if (have_enough_mem_for_dircache(options, 0, &dircache_msg)) { + log_warn(LD_CONFIG, "%s", dircache_msg); + tor_free(dircache_msg); + } + } + + if (options->MyFamily_lines && options->BridgeRelay) { + log_warn(LD_CONFIG, "Listing a family for a bridge relay is not " + "supported: it can reveal bridge fingerprints to censors. " + "You should also make sure you aren't listing this bridge's " + "fingerprint in any other MyFamily."); + } + if (options->MyFamily_lines && !options->ContactInfo) { + log_warn(LD_CONFIG, "MyFamily is set but ContactInfo is not configured. " + "ContactInfo should always be set when MyFamily option is too."); + } + if (normalize_nickname_list(&options->MyFamily, + options->MyFamily_lines, "MyFamily", msg)) + return -1; + + if (options->ConstrainedSockets) { + if (options->DirPort_set) { + /* Providing cached directory entries while system TCP buffers are scarce + * will exacerbate the socket errors. Suggest that this be disabled. */ + COMPLAIN("You have requested constrained socket buffers while also " + "serving directory entries via DirPort. It is strongly " + "suggested that you disable serving directory requests when " + "system TCP buffer resources are scarce."); + } + } + + return 0; +} + +/** + * Legacy validation/normalization function for the relay testing options + * in options. Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_relay_testing(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2) + REJECT("SigningKeyLifetime is too short."); + if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2) + REJECT("LinkCertLifetime is too short."); + if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2) + REJECT("TestingAuthKeyLifetime is too short."); + + return 0; +} + +/** Return 1 if any change from <b>old_options</b> to <b>new_options</b> + * will require us to rotate the CPU and DNS workers; else return 0. */ +static int +options_transition_affects_workers(const or_options_t *old_options, + const or_options_t *new_options) +{ + YES_IF_CHANGED_STRING(DataDirectory); + YES_IF_CHANGED_INT(NumCPUs); + YES_IF_CHANGED_LINELIST(ORPort_lines); + YES_IF_CHANGED_BOOL(ServerDNSSearchDomains); + YES_IF_CHANGED_BOOL(SafeLogging_); + YES_IF_CHANGED_BOOL(ClientOnly); + YES_IF_CHANGED_BOOL(LogMessageDomains); + YES_IF_CHANGED_LINELIST(Logs); + + if (server_mode(old_options) != server_mode(new_options) || + public_server_mode(old_options) != public_server_mode(new_options) || + dir_server_mode(old_options) != dir_server_mode(new_options)) + return 1; + + /* Nothing that changed matters. */ + return 0; +} + +/** Return 1 if any change from <b>old_options</b> to <b>new_options</b> + * will require us to generate a new descriptor; else return 0. */ +static int +options_transition_affects_descriptor(const or_options_t *old_options, + const or_options_t *new_options) +{ + /* XXX We can be smarter here. If your DirPort isn't being + * published and you just turned it off, no need to republish. Etc. */ + + YES_IF_CHANGED_STRING(DataDirectory); + YES_IF_CHANGED_STRING(Nickname); + YES_IF_CHANGED_STRING(Address); + YES_IF_CHANGED_LINELIST(ExitPolicy); + YES_IF_CHANGED_BOOL(ExitRelay); + YES_IF_CHANGED_BOOL(ExitPolicyRejectPrivate); + YES_IF_CHANGED_BOOL(ExitPolicyRejectLocalInterfaces); + YES_IF_CHANGED_BOOL(IPv6Exit); + YES_IF_CHANGED_LINELIST(ORPort_lines); + YES_IF_CHANGED_LINELIST(DirPort_lines); + YES_IF_CHANGED_LINELIST(DirPort_lines); + YES_IF_CHANGED_BOOL(ClientOnly); + YES_IF_CHANGED_BOOL(DisableNetwork); + YES_IF_CHANGED_BOOL(PublishServerDescriptor_); + YES_IF_CHANGED_STRING(ContactInfo); + YES_IF_CHANGED_STRING(BridgeDistribution); + YES_IF_CHANGED_LINELIST(MyFamily); + YES_IF_CHANGED_STRING(AccountingStart); + YES_IF_CHANGED_INT(AccountingMax); + YES_IF_CHANGED_INT(AccountingRule); + YES_IF_CHANGED_BOOL(DirCache); + YES_IF_CHANGED_BOOL(AssumeReachable); + + if (relay_get_effective_bwrate(old_options) != + relay_get_effective_bwrate(new_options) || + relay_get_effective_bwburst(old_options) != + relay_get_effective_bwburst(new_options) || + public_server_mode(old_options) != public_server_mode(new_options)) + return 1; + + return 0; +} + +/** Fetch the active option list, and take relay actions based on it. All of + * the things we do should survive being done repeatedly. If present, + * <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay(const or_options_t *old_options) +{ + const or_options_t *options = get_options(); + + const int transition_affects_workers = + old_options && options_transition_affects_workers(old_options, options); + + /* We want to reinit keys as needed before we do much of anything else: + keys are important, and other things can depend on them. */ + if (transition_affects_workers || + (authdir_mode_v3(options) && (!old_options || + !authdir_mode_v3(old_options)))) { + if (init_keys() < 0) { + log_warn(LD_BUG,"Error initializing keys; exiting"); + return -1; + } + } + + if (server_mode(options)) { + static int cdm_initialized = 0; + if (cdm_initialized == 0) { + cdm_initialized = 1; + consdiffmgr_configure(NULL); + consdiffmgr_validate(); + } + } + + /* Check for transitions that need action. */ + if (old_options) { + if (transition_affects_workers) { + log_info(LD_GENERAL, + "Worker-related options changed. Rotating workers."); + const int server_mode_turned_on = + server_mode(options) && !server_mode(old_options); + const int dir_server_mode_turned_on = + dir_server_mode(options) && !dir_server_mode(old_options); + + if (server_mode_turned_on || dir_server_mode_turned_on) { + cpu_init(); + } + + if (server_mode_turned_on) { + ip_address_changed(0); + if (have_completed_a_circuit() || !any_predicted_circuits(time(NULL))) + inform_testing_reachability(); + } + cpuworkers_rotate_keyinfo(); + } + } + + return 0; +} + +/** Fetch the active option list, and take relay accounting actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay_accounting(const or_options_t *old_options) +{ + (void)old_options; + + const or_options_t *options = get_options(); + + /* Set up accounting */ + if (accounting_parse_options(options, 0)<0) { + // LCOV_EXCL_START + log_warn(LD_BUG,"Error in previously validated accounting options"); + return -1; + // LCOV_EXCL_STOP + } + if (accounting_is_enabled(options)) + configure_accounting(time(NULL)); + + return 0; +} + +/** Fetch the active option list, and take relay bandwidth actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay_bandwidth(const or_options_t *old_options) +{ + const or_options_t *options = get_options(); + + /* Check for transitions that need action. */ + if (old_options) { + if (options->PerConnBWRate != old_options->PerConnBWRate || + options->PerConnBWBurst != old_options->PerConnBWBurst) + connection_or_update_token_buckets(get_connection_array(), options); + + if (options->RelayBandwidthRate != old_options->RelayBandwidthRate || + options->RelayBandwidthBurst != old_options->RelayBandwidthBurst) + connection_bucket_adjust(options); + } + + return 0; +} + +/** Fetch the active option list, and take bridge statistics actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_bridge_stats(const or_options_t *old_options) +{ + const or_options_t *options = get_options(); + +/* How long should we delay counting bridge stats after becoming a bridge? + * We use this so we don't count clients who used our bridge thinking it is + * a relay. If you change this, don't forget to change the log message + * below. It's 4 hours (the time it takes to stop being used by clients) + * plus some extra time for clock skew. */ +#define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60) + + /* Check for transitions that need action. */ + if (old_options) { + if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) { + int was_relay = 0; + if (options->BridgeRelay) { + time_t int_start = time(NULL); + if (config_lines_eq(old_options->ORPort_lines,options->ORPort_lines)) { + int_start += RELAY_BRIDGE_STATS_DELAY; + was_relay = 1; + } + geoip_bridge_stats_init(int_start); + log_info(LD_CONFIG, "We are acting as a bridge now. Starting new " + "GeoIP stats interval%s.", was_relay ? " in 6 " + "hours from now" : ""); + } else { + geoip_bridge_stats_term(); + log_info(LD_GENERAL, "We are no longer acting as a bridge. " + "Forgetting GeoIP stats."); + } + } + } + + return 0; +} + +/** Fetch the active option list, and take relay statistics actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Sets <b>*print_notice_out</b> if we enabled stats, and need to print + * a stats log using options_act_relay_stats_msg(). + * + * If loading the GeoIP file failed, sets DirReqStatistics and + * EntryStatistics to 0. This breaks the normalization/act ordering + * introduced in 29211. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay_stats(const or_options_t *old_options, + bool *print_notice_out) +{ + if (BUG(!print_notice_out)) + return -1; + + or_options_t *options = get_options_mutable(); + + if (options->CellStatistics || options->DirReqStatistics || + options->EntryStatistics || options->ExitPortStatistics || + options->ConnDirectionStatistics || + options->HiddenServiceStatistics) { + time_t now = time(NULL); + int print_notice = 0; + + if ((!old_options || !old_options->CellStatistics) && + options->CellStatistics) { + rep_hist_buffer_stats_init(now); + print_notice = 1; + } + if ((!old_options || !old_options->DirReqStatistics) && + options->DirReqStatistics) { + if (geoip_is_loaded(AF_INET)) { + geoip_dirreq_stats_init(now); + print_notice = 1; + } else { + /* disable statistics collection since we have no geoip file */ + /* 29211: refactor to avoid the normalisation/act inversion */ + options->DirReqStatistics = 0; + if (options->ORPort_set) + log_notice(LD_CONFIG, "Configured to measure directory request " + "statistics, but no GeoIP database found. " + "Please specify a GeoIP database using the " + "GeoIPFile option."); + } + } + if ((!old_options || !old_options->EntryStatistics) && + options->EntryStatistics && !should_record_bridge_info(options)) { + /* If we get here, we've started recording bridge info when we didn't + * do so before. Note that "should_record_bridge_info()" will + * always be false at this point, because of the earlier block + * that cleared EntryStatistics when public_server_mode() was false. + * We're leaving it in as defensive programming. */ + if (geoip_is_loaded(AF_INET) || geoip_is_loaded(AF_INET6)) { + geoip_entry_stats_init(now); + print_notice = 1; + } else { + options->EntryStatistics = 0; + log_notice(LD_CONFIG, "Configured to measure entry node " + "statistics, but no GeoIP database found. " + "Please specify a GeoIP database using the " + "GeoIPFile option."); + } + } + if ((!old_options || !old_options->ExitPortStatistics) && + options->ExitPortStatistics) { + rep_hist_exit_stats_init(now); + print_notice = 1; + } + if ((!old_options || !old_options->ConnDirectionStatistics) && + options->ConnDirectionStatistics) { + rep_hist_conn_stats_init(now); + } + if ((!old_options || !old_options->HiddenServiceStatistics) && + options->HiddenServiceStatistics) { + log_info(LD_CONFIG, "Configured to measure hidden service statistics."); + rep_hist_hs_stats_init(now); + } + if (print_notice) + *print_notice_out = 1; + } + + /* If we used to have statistics enabled but we just disabled them, + stop gathering them. */ + if (old_options && old_options->CellStatistics && + !options->CellStatistics) + rep_hist_buffer_stats_term(); + if (old_options && old_options->DirReqStatistics && + !options->DirReqStatistics) + geoip_dirreq_stats_term(); + if (old_options && old_options->EntryStatistics && + !options->EntryStatistics) + geoip_entry_stats_term(); + if (old_options && old_options->HiddenServiceStatistics && + !options->HiddenServiceStatistics) + rep_hist_hs_stats_term(); + if (old_options && old_options->ExitPortStatistics && + !options->ExitPortStatistics) + rep_hist_exit_stats_term(); + if (old_options && old_options->ConnDirectionStatistics && + !options->ConnDirectionStatistics) + rep_hist_conn_stats_term(); + + return 0; +} + +/** Print a notice about relay/dirauth stats being enabled. */ +void +options_act_relay_stats_msg(void) +{ + log_notice(LD_CONFIG, "Configured to measure statistics. Look for " + "the *-stats files that will first be written to the " + "data directory in 24 hours from now."); +} + +/** Fetch the active option list, and take relay descriptor actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay_desc(const or_options_t *old_options) +{ + const or_options_t *options = get_options(); + + /* Since our options changed, we might need to regenerate and upload our + * server descriptor. + */ + if (!old_options || + options_transition_affects_descriptor(old_options, options)) + mark_my_descriptor_dirty("config change"); + + return 0; +} + +/** Fetch the active option list, and take relay DoS actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay_dos(const or_options_t *old_options) +{ + const or_options_t *options = get_options(); + + /* DoS mitigation subsystem only applies to public relay. */ + if (public_server_mode(options)) { + /* If we are configured as a relay, initialize the subsystem. Even on HUP, + * this is safe to call as it will load data from the current options + * or/and the consensus. */ + dos_init(); + } else if (old_options && public_server_mode(old_options)) { + /* Going from relay to non relay, clean it up. */ + dos_free_all(); + } + + return 0; +} + +/** Fetch the active option list, and take dirport actions based on + * it. All of the things we do should survive being done repeatedly. If + * present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_relay_dir(const or_options_t *old_options) +{ + (void)old_options; + + const or_options_t *options = get_options(); + + if (!public_server_mode(options)) + return 0; + + /* Load the webpage we're going to serve every time someone asks for '/' on + our DirPort. */ + tor_free(global_dirfrontpagecontents); + if (options->DirPortFrontPage) { + global_dirfrontpagecontents = + read_file_to_str(options->DirPortFrontPage, 0, NULL); + if (!global_dirfrontpagecontents) { + log_warn(LD_CONFIG, + "DirPortFrontPage file '%s' not found. Continuing anyway.", + options->DirPortFrontPage); + } + } + + return 0; +} diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h new file mode 100644 index 0000000000..214f07efc2 --- /dev/null +++ b/src/feature/relay/relay_config.h @@ -0,0 +1,188 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_config.h + * @brief Header for feature/relay/relay_config.c + **/ + +#ifndef TOR_FEATURE_RELAY_RELAY_CONFIG_H +#define TOR_FEATURE_RELAY_RELAY_CONFIG_H + +typedef struct or_options_t or_options_t; + +#ifdef HAVE_MODULE_RELAY + +#include "lib/cc/torint.h" +#include "lib/testsupport/testsupport.h" + +typedef struct smartlist_t smartlist_t; + +int options_validate_relay_mode(const or_options_t *old_options, + or_options_t *options, + char **msg); + +MOCK_DECL(const char*, relay_get_dirportfrontpage, (void)); +void relay_config_free_all(void); + +uint32_t relay_get_effective_bwrate(const or_options_t *options); +uint32_t relay_get_effective_bwburst(const or_options_t *options); + +void port_warn_nonlocal_ext_orports(const smartlist_t *ports, + const char *portname); + +int port_parse_ports_relay(or_options_t *options, + char **msg, + smartlist_t *ports_out, + int *have_low_ports_out); +void port_update_port_set_relay(or_options_t *options, + const smartlist_t *ports); + +int options_validate_relay_os(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_relay_info(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_publish_server(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_relay_padding(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_relay_bandwidth(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_relay_accounting(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_validate_relay_testing(const or_options_t *old_options, + or_options_t *options, + char **msg); + +int options_act_relay(const or_options_t *old_options); +int options_act_relay_accounting(const or_options_t *old_options); +int options_act_relay_bandwidth(const or_options_t *old_options); +int options_act_bridge_stats(const or_options_t *old_options); + +int options_act_relay_stats(const or_options_t *old_options, + bool *print_notice_out); +void options_act_relay_stats_msg(void); + +int options_act_relay_desc(const or_options_t *old_options); +int options_act_relay_dos(const or_options_t *old_options); +int options_act_relay_dir(const or_options_t *old_options); + +#ifdef RELAY_CONFIG_PRIVATE + +STATIC int check_bridge_distribution_setting(const char *bd); +STATIC int have_enough_mem_for_dircache(const or_options_t *options, + size_t total_mem, char **msg); + +#endif /* defined(RELAY_CONFIG_PRIVATE) */ + +#else /* !defined(HAVE_MODULE_RELAY) */ + +#include "lib/cc/compat_compiler.h" + +/** When tor is compiled with the relay module disabled, it can't be + * configured as a relay or bridge. + * + * Always sets ClientOnly to 1. + * + * Returns -1 and sets msg to a newly allocated string, if ORPort, DirPort, + * DirCache, or BridgeRelay are set in options. Otherwise returns 0. */ +static inline int +options_validate_relay_mode(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + /* Only check the primary options for now, #29211 will disable more + * options. These ORPort and DirPort checks are too strict, and will + * reject valid configs that disable ports, like "ORPort 0". */ + if (options->DirCache || + options->BridgeRelay || + options->ORPort_lines || + options->DirPort_lines) { + /* REJECT() this configuration */ + *msg = tor_strdup("This tor was built with relay mode disabled. " + "It can not be configured with an ORPort, a DirPort, " + "DirCache 1, or BridgeRelay 1."); + return -1; + } + + /* 31851 / 29211: Set this option the correct way */ + options->ClientOnly = 1; + + return 0; +} + +#define relay_get_dirportfrontpage() \ + (NULL) +#define relay_config_free_all() \ + STMT_BEGIN STMT_END + +#define relay_get_effective_bwrate(options) \ + (((void)(options)),0) +#define relay_get_effective_bwburst(options) \ + (((void)(options)),0) + +#define port_warn_nonlocal_ext_orports(ports, portname) \ + (((void)(ports)),((void)(portname))) + +#define port_parse_ports_relay(options, msg, ports_out, have_low_ports_out) \ + (((void)(options)),((void)(msg)),((void)(ports_out)), \ + ((void)(have_low_ports_out)),0) +#define port_update_port_set_relay(options, ports) \ + (((void)(options)),((void)(ports))) + +#define options_validate_relay_os(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_relay_info(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_publish_server(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_relay_padding(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_relay_bandwidth(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_relay_accounting(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_validate_relay_testing(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) + +#define options_act_relay(old_options) \ + (((void)(old_options)),0) +#define options_act_relay_accounting(old_options) \ + (((void)(old_options)),0) +#define options_act_relay_bandwidth(old_options) \ + (((void)(old_options)),0) +#define options_act_bridge_stats(old_options) \ + (((void)(old_options)),0) + +#define options_act_relay_stats(old_options, print_notice_out) \ + (((void)(old_options)),((void)(print_notice_out)),0) +#define options_act_relay_stats_msg() \ + STMT_BEGIN STMT_END + +#define options_act_relay_desc(old_options) \ + (((void)(old_options)),0) +#define options_act_relay_dos(old_options) \ + (((void)(old_options)),0) +#define options_act_relay_dir(old_options) \ + (((void)(old_options)),0) + +#endif /* defined(HAVE_MODULE_RELAY) */ + +#endif /* !defined(TOR_FEATURE_RELAY_RELAY_CONFIG_H) */ diff --git a/src/feature/relay/relay_periodic.c b/src/feature/relay/relay_periodic.c index b48b495895..d1b3183953 100644 --- a/src/feature/relay/relay_periodic.c +++ b/src/feature/relay/relay_periodic.c @@ -31,11 +31,13 @@ #include "feature/nodelist/routerinfo_st.h" #include "feature/control/control_events.h" +#ifndef COCCI #define DECLARE_EVENT(name, roles, flags) \ static periodic_event_item_t name ## _event = \ PERIODIC_EVENT(name, \ PERIODIC_EVENT_ROLE_##roles, \ flags) +#endif /* !defined(COCCI) */ #define FL(name) (PERIODIC_EVENT_FLAG_##name) diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index ab0762e17e..7f80b288de 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -35,6 +35,7 @@ #include "feature/nodelist/routerlist.h" #include "feature/nodelist/torcert.h" #include "feature/relay/dns.h" +#include "feature/relay/relay_config.h" #include "feature/relay/router.h" #include "feature/relay/routerkeys.h" #include "feature/relay/routermode.h" @@ -372,6 +373,8 @@ assert_identity_keys_ok(void) } } +#ifdef HAVE_MODULE_RELAY + /** Returns the current server identity key; requires that the key has * been set, and that we are running as a Tor server. */ @@ -384,6 +387,8 @@ get_server_identity_key,(void)) return server_identitykey; } +#endif /* defined(HAVE_MODULE_RELAY) */ + /** Return true iff we are a server and the server identity key * has been set. */ int @@ -1218,7 +1223,7 @@ router_should_be_dirserver(const or_options_t *options, int dir_port) * much larger effect on output than input so there is no reason to turn it * off if using AccountingRule in. */ int interval_length = accounting_get_interval_length(); - uint32_t effective_bw = get_effective_bwrate(options); + uint32_t effective_bw = relay_get_effective_bwrate(options); uint64_t acc_bytes; if (!interval_length) { log_warn(LD_BUG, "An accounting interval is not allowed to be zero " @@ -2037,10 +2042,10 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out)) ri->protocol_list = tor_strdup(protover_get_supported_protocols()); /* compute ri->bandwidthrate as the min of various options */ - ri->bandwidthrate = get_effective_bwrate(options); + ri->bandwidthrate = relay_get_effective_bwrate(options); /* and compute ri->bandwidthburst similarly */ - ri->bandwidthburst = get_effective_bwburst(options); + ri->bandwidthburst = relay_get_effective_bwburst(options); /* Report bandwidth, unless we're hibernating or shutting down */ ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess(); diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index 55b9ef9e68..a708b24889 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -28,7 +28,13 @@ struct ed25519_keypair_t; MOCK_DECL(crypto_pk_t *,get_onion_key,(void)); time_t get_onion_key_set_at(void); void set_server_identity_key(crypto_pk_t *k); +/* Some compilers are clever enough to know that when relay mode is disabled, + * this function never returns. */ +#ifdef HAVE_MODULE_RELAY MOCK_DECL(crypto_pk_t *,get_server_identity_key,(void)); +#else +#define get_server_identity_key() (tor_abort_(),NULL) +#endif int server_identity_key_is_set(void); void set_client_identity_key(crypto_pk_t *k); crypto_pk_t *get_tlsclient_identity_key(void); diff --git a/src/feature/relay/routerkeys.h b/src/feature/relay/routerkeys.h index cde07b52c3..d2860718b2 100644 --- a/src/feature/relay/routerkeys.h +++ b/src/feature/relay/routerkeys.h @@ -1,6 +1,11 @@ /* Copyright (c) 2014-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file routerkeys.h + * @brief Header for routerkeys.c + **/ + #ifndef TOR_ROUTERKEYS_H #define TOR_ROUTERKEYS_H diff --git a/src/feature/relay/routermode.c b/src/feature/relay/routermode.c index 2a9ddeac4d..92bcfaf8fa 100644 --- a/src/feature/relay/routermode.c +++ b/src/feature/relay/routermode.c @@ -4,11 +4,14 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file routermode.c + * @brief Check if we're running as a relay/cache. + **/ + #include "core/or/or.h" #include "app/config/config.h" -#include "core/mainloop/connection.h" -#include "core/or/port_cfg_st.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" @@ -25,21 +28,6 @@ dir_server_mode(const or_options_t *options) (server_mode(options) && router_has_bandwidth_to_be_dirserver(options)); } -/** Return true iff we are trying to proxy client connections. */ -int -proxy_mode(const or_options_t *options) -{ - (void)options; - SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { - if (p->type == CONN_TYPE_AP_LISTENER || - p->type == CONN_TYPE_AP_TRANS_LISTENER || - p->type == CONN_TYPE_AP_DNS_LISTENER || - p->type == CONN_TYPE_AP_NATD_LISTENER) - return 1; - } SMARTLIST_FOREACH_END(p); - return 0; -} - /** Return true iff we are trying to be a server. */ MOCK_IMPL(int, diff --git a/src/feature/relay/routermode.h b/src/feature/relay/routermode.h index be535af478..9891a038ad 100644 --- a/src/feature/relay/routermode.h +++ b/src/feature/relay/routermode.h @@ -12,13 +12,31 @@ #ifndef TOR_ROUTERMODE_H #define TOR_ROUTERMODE_H +#ifdef HAVE_MODULE_RELAY + int dir_server_mode(const or_options_t *options); MOCK_DECL(int, server_mode, (const or_options_t *options)); MOCK_DECL(int, public_server_mode, (const or_options_t *options)); MOCK_DECL(int, advertised_server_mode, (void)); -int proxy_mode(const or_options_t *options); void set_server_advertised(int s); +/** Is the relay module enabled? */ +#define have_module_relay() (1) + +#else /* !defined(HAVE_MODULE_RELAY) */ + +#define dir_server_mode(options) (((void)(options)),0) +#define server_mode(options) (((void)(options)),0) +#define public_server_mode(options) (((void)(options)),0) +#define advertised_server_mode() (0) + +/* We shouldn't be publishing descriptors when relay mode is disabled. */ +#define set_server_advertised(s) tor_assert_nonfatal(!(s)) + +#define have_module_relay() (0) + +#endif /* defined(HAVE_MODULE_RELAY) */ + #endif /* !defined(TOR_ROUTERMODE_H) */ diff --git a/src/feature/relay/transport_config.c b/src/feature/relay/transport_config.c new file mode 100644 index 0000000000..9d6be4bafd --- /dev/null +++ b/src/feature/relay/transport_config.c @@ -0,0 +1,307 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file transport_config.c + * @brief Code to interpret the user's configuration of Tor's server + * pluggable transports. + **/ + +#include "orconfig.h" +#define RELAY_TRANSPORT_CONFIG_PRIVATE +#include "feature/relay/transport_config.h" + +#include "lib/encoding/confline.h" +#include "lib/encoding/keyval.h" + +#include "lib/container/smartlist.h" + +/* Required for dirinfo_type_t in or_options_t */ +#include "core/or/or.h" +#include "app/config/config.h" + +#include "feature/relay/ext_orport.h" +#include "feature/relay/routermode.h" + +/* Copied from config.c, we will refactor later in 29211. */ +#define REJECT(arg) \ + STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END + +/** Given a ServerTransportListenAddr <b>line</b>, return its + * <address:port> string. Return NULL if the line was not + * well-formed. + * + * If <b>transport</b> is set, return NULL if the line is not + * referring to <b>transport</b>. + * + * The returned string is allocated on the heap and it's the + * responsibility of the caller to free it. */ +static char * +get_bindaddr_from_transport_listen_line(const char *line, + const char *transport) +{ + smartlist_t *items = NULL; + const char *parsed_transport = NULL; + char *addrport = NULL; + tor_addr_t addr; + uint16_t port = 0; + + items = smartlist_new(); + smartlist_split_string(items, line, NULL, + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); + + if (smartlist_len(items) < 2) { + log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line."); + goto err; + } + + parsed_transport = smartlist_get(items, 0); + addrport = tor_strdup(smartlist_get(items, 1)); + + /* If 'transport' is given, check if it matches the one on the line */ + if (transport && strcmp(transport, parsed_transport)) + goto err; + + /* Validate addrport */ + if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) { + log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr " + "address '%s'", addrport); + goto err; + } + + goto done; + + err: + tor_free(addrport); + addrport = NULL; + + done: + SMARTLIST_FOREACH(items, char*, s, tor_free(s)); + smartlist_free(items); + + return addrport; +} + +/** Given the name of a pluggable transport in <b>transport</b>, check + * the configuration file to see if the user has explicitly asked for + * it to listen on a specific port. Return a <address:port> string if + * so, otherwise NULL. */ +char * +pt_get_bindaddr_from_config(const char *transport) +{ + config_line_t *cl; + const or_options_t *options = get_options(); + + for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) { + char *bindaddr = + get_bindaddr_from_transport_listen_line(cl->value, transport); + if (bindaddr) + return bindaddr; + } + + return NULL; +} + +/** Given a ServerTransportOptions <b>line</b>, return a smartlist + * with the options. Return NULL if the line was not well-formed. + * + * If <b>transport</b> is set, return NULL if the line is not + * referring to <b>transport</b>. + * + * The returned smartlist and its strings are allocated on the heap + * and it's the responsibility of the caller to free it. */ +STATIC smartlist_t * +get_options_from_transport_options_line(const char *line, + const char *transport) +{ + smartlist_t *items = smartlist_new(); + smartlist_t *pt_options = smartlist_new(); + const char *parsed_transport = NULL; + + smartlist_split_string(items, line, NULL, + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); + + if (smartlist_len(items) < 2) { + log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line."); + goto err; + } + + parsed_transport = smartlist_get(items, 0); + /* If 'transport' is given, check if it matches the one on the line */ + if (transport && strcmp(transport, parsed_transport)) + goto err; + + SMARTLIST_FOREACH_BEGIN(items, const char *, option) { + if (option_sl_idx == 0) /* skip the transport field (first field)*/ + continue; + + /* validate that it's a k=v value */ + if (!string_is_key_value(LOG_WARN, option)) { + log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option)); + goto err; + } + + /* add it to the options smartlist */ + smartlist_add_strdup(pt_options, option); + log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option)); + } SMARTLIST_FOREACH_END(option); + + goto done; + + err: + SMARTLIST_FOREACH(pt_options, char*, s, tor_free(s)); + smartlist_free(pt_options); + pt_options = NULL; + + done: + SMARTLIST_FOREACH(items, char*, s, tor_free(s)); + smartlist_free(items); + + return pt_options; +} + +/** Given the name of a pluggable transport in <b>transport</b>, check + * the configuration file to see if the user has asked us to pass any + * parameters to the pluggable transport. Return a smartlist + * containing the parameters, otherwise NULL. */ +smartlist_t * +pt_get_options_for_server_transport(const char *transport) +{ + config_line_t *cl; + const or_options_t *options = get_options(); + + for (cl = options->ServerTransportOptions; cl; cl = cl->next) { + smartlist_t *options_sl = + get_options_from_transport_options_line(cl->value, transport); + if (options_sl) + return options_sl; + } + + return NULL; +} + +/** + * Legacy validation/normalization function for the server transport options. + * Uses old_options as the previous options. + * + * Returns 0 on success, returns -1 and sets *msg to a newly allocated string + * on error. + */ +int +options_validate_server_transport(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + if (BUG(!options)) + return -1; + + if (BUG(!msg)) + return -1; + + config_line_t *cl; + + if (options->ServerTransportPlugin && !server_mode(options)) { + log_notice(LD_GENERAL, "Tor is not configured as a relay but you specified" + " a ServerTransportPlugin line (%s). The ServerTransportPlugin " + "line will be ignored.", + escaped(options->ServerTransportPlugin->value)); + } + + if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) { + log_notice(LD_GENERAL, "You need at least a single managed-proxy to " + "specify a transport listen address. The " + "ServerTransportListenAddr line will be ignored."); + } + + for (cl = options->ServerTransportPlugin; cl; cl = cl->next) { + if (pt_parse_transport_line(options, cl->value, 1, 1) < 0) + REJECT("Invalid server transport line. See logs for details."); + } + + for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) { + /** If get_bindaddr_from_transport_listen_line() fails with + 'transport' being NULL, it means that something went wrong + while parsing the ServerTransportListenAddr line. */ + char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL); + if (!bindaddr) + REJECT("ServerTransportListenAddr did not parse. See logs for details."); + tor_free(bindaddr); + } + + for (cl = options->ServerTransportOptions; cl; cl = cl->next) { + /** If get_options_from_transport_options_line() fails with + 'transport' being NULL, it means that something went wrong + while parsing the ServerTransportOptions line. */ + smartlist_t *options_sl = + get_options_from_transport_options_line(cl->value, NULL); + if (!options_sl) + REJECT("ServerTransportOptions did not parse. See logs for details."); + + SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp)); + smartlist_free(options_sl); + } + + return 0; +} + +/** Fetch the active option list, and take server pluggable transport actions + * based on it. All of the things we do should survive being done repeatedly. + * If present, <b>old_options</b> contains the previous value of the options. + * + * Return 0 if all goes well, return -1 if it's time to die. + * + * Note: We haven't moved all the "act on new configuration" logic + * into the options_act* functions yet. Some is still in do_hup() and other + * places. + */ +int +options_act_server_transport(const or_options_t *old_options) +{ + (void)old_options; + + config_line_t *cl; + const or_options_t *options = get_options(); + int running_tor = options->command == CMD_RUN_TOR; + + /* If we are a bridge with a pluggable transport proxy but no + Extended ORPort, inform the user that they are missing out. */ + if (options->ServerTransportPlugin && + !options->ExtORPort_lines) { + log_notice(LD_CONFIG, "We use pluggable transports but the Extended " + "ORPort is disabled. Tor and your pluggable transports proxy " + "communicate with each other via the Extended ORPort so it " + "is suggested you enable it: it will also allow your Bridge " + "to collect statistics about its clients that use pluggable " + "transports. Please enable it using the ExtORPort torrc option " + "(e.g. set 'ExtORPort auto')."); + } + + /* If we have an ExtORPort, initialize its auth cookie. */ + if (running_tor && + init_ext_or_cookie_authentication(!!options->ExtORPort_lines) < 0) { + log_warn(LD_CONFIG,"Error creating Extended ORPort cookie file."); + return -1; + } + + if (!options->DisableNetwork) { + if (options->ServerTransportPlugin) { + for (cl = options->ServerTransportPlugin; cl; cl = cl->next) { + if (pt_parse_transport_line(options, cl->value, 0, 1) < 0) { + // LCOV_EXCL_START + log_warn(LD_BUG, + "Previously validated ServerTransportPlugin line " + "could not be added!"); + return -1; + // LCOV_EXCL_STOP + } + } + } + } + + return 0; +} diff --git a/src/feature/relay/transport_config.h b/src/feature/relay/transport_config.h new file mode 100644 index 0000000000..d3cceb3698 --- /dev/null +++ b/src/feature/relay/transport_config.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file transport_config.h + * @brief Header for feature/relay/transport_config.c + **/ + +#ifndef TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H +#define TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H + +#ifdef HAVE_MODULE_RELAY + +#include "lib/testsupport/testsupport.h" + +typedef struct or_options_t or_options_t; +typedef struct smartlist_t smartlist_t; + +int options_validate_server_transport(const or_options_t *old_options, + or_options_t *options, + char **msg); + +char *pt_get_bindaddr_from_config(const char *transport); +smartlist_t *pt_get_options_for_server_transport(const char *transport); + +int options_act_server_transport(const or_options_t *old_options); + +#ifdef RELAY_TRANSPORT_CONFIG_PRIVATE + +STATIC smartlist_t *get_options_from_transport_options_line( + const char *line, + const char *transport); + +#endif /* defined(RELAY_TRANSPORT_CONFIG_PRIVATE) */ + +#else /* !defined(HAVE_MODULE_RELAY) */ + +/** When tor is compiled with the relay module disabled, it can't be + * configured with server pluggable transports. + * + * Returns -1 and sets msg to a newly allocated string, if ExtORPort, + * ServerTransportPlugin, ServerTransportListenAddr, or + * ServerTransportOptions are set in options. Otherwise returns 0. */ +static inline int +options_validate_server_transport(const or_options_t *old_options, + or_options_t *options, + char **msg) +{ + (void)old_options; + + /* These ExtORPort checks are too strict, and will reject valid configs + * that disable ports, like "ExtORPort 0". */ + if (options->ServerTransportPlugin || + options->ServerTransportListenAddr || + options->ServerTransportOptions || + options->ExtORPort_lines) { + /* REJECT() this configuration */ + *msg = tor_strdup("This tor was built with relay mode disabled. " + "It can not be configured with an ExtORPort, " + "a ServerTransportPlugin, a ServerTransportListenAddr, " + "or ServerTransportOptions."); + return -1; + } + + return 0; +} + +#define pt_get_bindaddr_from_config(transport) \ + (((void)(transport)),NULL) + +/* 31851: called from client/transports.c, but only from server code */ +#define pt_get_options_for_server_transport(transport) \ + (((void)(transport)),NULL) + +#define options_validate_server_transport(old_options, options, msg) \ + (((void)(old_options)),((void)(options)),((void)(msg)),0) +#define options_act_server_transport(old_options) \ + (((void)(old_options)),0) + +#endif /* defined(HAVE_MODULE_RELAY) */ + +#endif /* !defined(TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H) */ diff --git a/src/feature/rend/feature_rend.dox b/src/feature/rend/feature_rend.dox new file mode 100644 index 0000000000..ed0784521c --- /dev/null +++ b/src/feature/rend/feature_rend.dox @@ -0,0 +1,9 @@ +/** +@dir /feature/rend +@brief feature/rend: version 2 (old) hidden services + +This directory implements the v2 onion service protocol, +as specified in +[rend-spec-v2.txt](https://gitweb.torproject.org/torspec.git/tree/rend-spec-v2.txt). + +**/ diff --git a/src/feature/rend/rend_authorized_client_st.h b/src/feature/rend/rend_authorized_client_st.h index 51a1798fcb..0819f2134a 100644 --- a/src/feature/rend/rend_authorized_client_st.h +++ b/src/feature/rend/rend_authorized_client_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file rend_authorized_client_st.h + * @brief Hidden-service authorized client structure. + **/ + #ifndef REND_AUTHORIZED_CLIENT_ST_H #define REND_AUTHORIZED_CLIENT_ST_H @@ -15,4 +20,3 @@ struct rend_authorized_client_t { }; #endif /* !defined(REND_AUTHORIZED_CLIENT_ST_H) */ - diff --git a/src/feature/rend/rend_encoded_v2_service_descriptor_st.h b/src/feature/rend/rend_encoded_v2_service_descriptor_st.h index bd8a60f0d9..5eec600fd1 100644 --- a/src/feature/rend/rend_encoded_v2_service_descriptor_st.h +++ b/src/feature/rend/rend_encoded_v2_service_descriptor_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file rend_encoded_v2_service_descriptor_st.h + * @brief Encoded v2 HS descriptor structure. + **/ + #ifndef REND_ENCODED_V2_SERVICE_DESCRIPTOR_ST_H #define REND_ENCODED_V2_SERVICE_DESCRIPTOR_ST_H @@ -14,4 +19,3 @@ struct rend_encoded_v2_service_descriptor_t { }; #endif /* !defined(REND_ENCODED_V2_SERVICE_DESCRIPTOR_ST_H) */ - diff --git a/src/feature/rend/rend_intro_point_st.h b/src/feature/rend/rend_intro_point_st.h index 4882b62752..9acf155708 100644 --- a/src/feature/rend/rend_intro_point_st.h +++ b/src/feature/rend/rend_intro_point_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file rend_intro_point_st.h + * @brief v2 hidden service introduction point structure. + **/ + #ifndef REND_INTRO_POINT_ST_H #define REND_INTRO_POINT_ST_H diff --git a/src/feature/rend/rend_service_descriptor_st.h b/src/feature/rend/rend_service_descriptor_st.h index ff7627ce96..bdfe87dcae 100644 --- a/src/feature/rend/rend_service_descriptor_st.h +++ b/src/feature/rend/rend_service_descriptor_st.h @@ -4,6 +4,11 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file rend_service_descriptor_st.h + * @brief Parsed v2 HS descriptor structure. + **/ + #ifndef REND_SERVICE_DESCRIPTOR_ST_H #define REND_SERVICE_DESCRIPTOR_ST_H @@ -31,4 +36,3 @@ struct rend_service_descriptor_t { }; #endif /* !defined(REND_SERVICE_DESCRIPTOR_ST_H) */ - diff --git a/src/feature/rend/rendcache.c b/src/feature/rend/rendcache.c index c3f86d8c82..2d8de2a80d 100644 --- a/src/feature/rend/rendcache.c +++ b/src/feature/rend/rendcache.c @@ -228,6 +228,17 @@ rend_cache_entry_free_void(void *p) rend_cache_entry_free_(p); } +/** Check if a failure cache entry exists for the given intro point. */ +bool +rend_cache_intro_failure_exists(const char *service_id, + const uint8_t *intro_identity) +{ + tor_assert(service_id); + tor_assert(intro_identity); + + return cache_failure_intro_lookup(intro_identity, service_id, NULL); +} + /** Free all storage held by the service descriptor cache. */ void rend_cache_free_all(void) diff --git a/src/feature/rend/rendcache.h b/src/feature/rend/rendcache.h index aec97eabb8..c83f36d189 100644 --- a/src/feature/rend/rendcache.h +++ b/src/feature/rend/rendcache.h @@ -80,6 +80,8 @@ int rend_cache_store_v2_desc_as_client(const char *desc, rend_cache_entry_t **entry); size_t rend_cache_get_total_allocation(void); +bool rend_cache_intro_failure_exists(const char *service_id, + const uint8_t *intro_identity); void rend_cache_intro_failure_note(rend_intro_point_failure_t failure, const uint8_t *identity, const char *service_id); diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index 2540066dfc..6f4ee8b8c1 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -1048,18 +1048,30 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry, const or_options_t *options = get_options(); smartlist_t *usable_nodes; int n_excluded = 0; + char service_id[REND_SERVICE_ID_LEN_BASE32 + 1]; /* We'll keep a separate list of the usable nodes. If this becomes empty, * no nodes are usable. */ usable_nodes = smartlist_new(); smartlist_add_all(usable_nodes, entry->parsed->intro_nodes); + /* Get service ID so we can use it to query the failure cache. If we fail to + * parse it, this cache entry is no good. */ + if (BUG(rend_get_service_id(entry->parsed->pk, service_id) < 0)) { + smartlist_free(usable_nodes); + return NULL; + } + /* Remove the intro points that have timed out during this HS * connection attempt from our list of usable nodes. */ - SMARTLIST_FOREACH(usable_nodes, rend_intro_point_t *, ip, - if (ip->timed_out) { - SMARTLIST_DEL_CURRENT(usable_nodes, ip); - }); + SMARTLIST_FOREACH_BEGIN(usable_nodes, const rend_intro_point_t *, ip) { + bool failed_intro = + rend_cache_intro_failure_exists(service_id, + (const uint8_t *) ip->extend_info->identity_digest); + if (ip->timed_out || failed_intro) { + SMARTLIST_DEL_CURRENT(usable_nodes, ip); + }; + } SMARTLIST_FOREACH_END(ip); again: if (smartlist_len(usable_nodes) == 0) { diff --git a/src/feature/rend/rendparse.h b/src/feature/rend/rendparse.h index b1ccce9b6c..da2c2e4b7f 100644 --- a/src/feature/rend/rendparse.h +++ b/src/feature/rend/rendparse.h @@ -5,8 +5,8 @@ /* See LICENSE for licensing information */ /** - * \file rend_parse.h - * \brief Header file for rend_parse.c. + * \file rendparse.h + * \brief Header file for rendparse.c. **/ #ifndef TOR_REND_PARSE_H diff --git a/src/feature/stats/feature_stats.dox b/src/feature/stats/feature_stats.dox new file mode 100644 index 0000000000..0ced00ce58 --- /dev/null +++ b/src/feature/stats/feature_stats.dox @@ -0,0 +1,12 @@ +/** +@dir /feature/stats +@brief feature/stats: Relay statistics. Also, port prediction. + +This module collects anonymized relay statistics in order to publish them in +relays' routerinfo and extrainfo documents. + +Additionally, it contains predict_ports.c, which remembers which ports we've +visited recently as a client, so we can make sure we have open circuits that +support them. + +**/ diff --git a/src/feature/stats/predict_ports.h b/src/feature/stats/predict_ports.h index 45b206c23a..a994db1d17 100644 --- a/src/feature/stats/predict_ports.h +++ b/src/feature/stats/predict_ports.h @@ -5,7 +5,7 @@ /* See LICENSE for licensing information */ /** - * \file predict_portst.h + * \file predict_ports.h * \brief Header file for predict_ports.c. **/ |