|
@@ -7,60 +7,57 @@
|
|
#define ROUTER_PRIVATE
|
|
#define ROUTER_PRIVATE
|
|
|
|
|
|
#include "core/or/or.h"
|
|
#include "core/or/or.h"
|
|
-#include "core/or/circuitbuild.h"
|
|
|
|
-#include "core/or/circuitlist.h"
|
|
|
|
-#include "core/or/circuituse.h"
|
|
|
|
#include "app/config/config.h"
|
|
#include "app/config/config.h"
|
|
-#include "core/mainloop/connection.h"
|
|
+#include "app/config/statefile.h"
|
|
-#include "feature/control/control.h"
|
|
|
|
-#include "lib/crypt_ops/crypto_rand.h"
|
|
|
|
-#include "lib/crypt_ops/crypto_util.h"
|
|
|
|
-#include "lib/crypt_ops/crypto_curve25519.h"
|
|
|
|
-#include "feature/dircommon/directory.h"
|
|
|
|
-#include "feature/dirclient/dirclient.h"
|
|
|
|
-#include "feature/dircache/dirserv.h"
|
|
|
|
-#include "feature/dirauth/process_descs.h"
|
|
|
|
-#include "feature/relay/dns.h"
|
|
|
|
-#include "feature/stats/geoip.h"
|
|
|
|
-#include "feature/hibernate/hibernate.h"
|
|
|
|
#include "app/main/main.h"
|
|
#include "app/main/main.h"
|
|
|
|
+#include "core/mainloop/connection.h"
|
|
#include "core/mainloop/mainloop.h"
|
|
#include "core/mainloop/mainloop.h"
|
|
-#include "feature/nodelist/networkstatus.h"
|
|
+#include "core/mainloop/netstatus.h"
|
|
-#include "feature/nodelist/nodelist.h"
|
|
|
|
#include "core/or/policies.h"
|
|
#include "core/or/policies.h"
|
|
#include "core/or/protover.h"
|
|
#include "core/or/protover.h"
|
|
-#include "core/or/relay.h"
|
|
+#include "feature/client/transports.h"
|
|
-#include "feature/stats/rephist.h"
|
|
+#include "feature/control/control.h"
|
|
-#include "feature/relay/router.h"
|
|
+#include "feature/dirauth/process_descs.h"
|
|
-#include "feature/relay/routerkeys.h"
|
|
+#include "feature/dircache/dirserv.h"
|
|
|
|
+#include "feature/dirclient/dirclient.h"
|
|
|
|
+#include "feature/dircommon/directory.h"
|
|
|
|
+#include "feature/hibernate/hibernate.h"
|
|
|
|
+#include "feature/keymgt/loadkey.h"
|
|
#include "feature/nodelist/authcert.h"
|
|
#include "feature/nodelist/authcert.h"
|
|
#include "feature/nodelist/dirlist.h"
|
|
#include "feature/nodelist/dirlist.h"
|
|
|
|
+#include "feature/nodelist/networkstatus.h"
|
|
|
|
+#include "feature/nodelist/nickname.h"
|
|
|
|
+#include "feature/nodelist/nodelist.h"
|
|
#include "feature/nodelist/routerlist.h"
|
|
#include "feature/nodelist/routerlist.h"
|
|
#include "feature/nodelist/routerparse.h"
|
|
#include "feature/nodelist/routerparse.h"
|
|
-#include "app/config/statefile.h"
|
|
|
|
#include "feature/nodelist/torcert.h"
|
|
#include "feature/nodelist/torcert.h"
|
|
-#include "feature/client/transports.h"
|
|
+#include "feature/relay/dns.h"
|
|
-#include "feature/nodelist/routerset.h"
|
|
+#include "feature/relay/router.h"
|
|
|
|
+#include "feature/relay/routerkeys.h"
|
|
|
|
+#include "feature/relay/routermode.h"
|
|
|
|
+#include "feature/relay/selftest.h"
|
|
|
|
+#include "feature/stats/geoip.h"
|
|
|
|
+#include "feature/stats/rephist.h"
|
|
|
|
+#include "lib/crypt_ops/crypto_ed25519.h"
|
|
|
|
+#include "lib/crypt_ops/crypto_format.h"
|
|
|
|
+#include "lib/crypt_ops/crypto_init.h"
|
|
|
|
+#include "lib/crypt_ops/crypto_rand.h"
|
|
|
|
+#include "lib/crypt_ops/crypto_util.h"
|
|
|
|
+#include "lib/encoding/confline.h"
|
|
|
|
+#include "lib/osinfo/uname.h"
|
|
|
|
+#include "lib/tls/tortls.h"
|
|
|
|
|
|
-#include "feature/dirauth/mode.h"
|
|
+#include "feature/dirauth/authmode.h"
|
|
|
|
|
|
-#include "feature/nodelist/authority_cert_st.h"
|
|
+#include "app/config/or_state_st.h"
|
|
-#include "core/or/crypt_path_st.h"
|
|
+#include "core/or/port_cfg_st.h"
|
|
-#include "feature/dircommon/dir_connection_st.h"
|
|
|
|
#include "feature/dirclient/dir_server_st.h"
|
|
#include "feature/dirclient/dir_server_st.h"
|
|
-#include "core/or/extend_info_st.h"
|
|
+#include "feature/dircommon/dir_connection_st.h"
|
|
|
|
+#include "feature/nodelist/authority_cert_st.h"
|
|
#include "feature/nodelist/extrainfo_st.h"
|
|
#include "feature/nodelist/extrainfo_st.h"
|
|
#include "feature/nodelist/node_st.h"
|
|
#include "feature/nodelist/node_st.h"
|
|
-#include "core/or/origin_circuit_st.h"
|
|
|
|
-#include "app/config/or_state_st.h"
|
|
|
|
-#include "core/or/port_cfg_st.h"
|
|
|
|
#include "feature/nodelist/routerinfo_st.h"
|
|
#include "feature/nodelist/routerinfo_st.h"
|
|
-
|
|
+#include "feature/nodelist/routerstatus_st.h"
|
|
-#include "lib/osinfo/uname.h"
|
|
|
|
-#include "lib/tls/tortls.h"
|
|
|
|
-#include "lib/encoding/confline.h"
|
|
|
|
-#include "lib/crypt_ops/crypto_format.h"
|
|
|
|
-#include "lib/crypt_ops/crypto_init.h"
|
|
|
|
|
|
|
|
|
|
|
|
* \file router.c
|
|
* \file router.c
|
|
@@ -130,13 +127,6 @@ static authority_cert_t *legacy_key_certificate = NULL;
|
|
* used by tor-gencert to sign new signing keys and make new key
|
|
* used by tor-gencert to sign new signing keys and make new key
|
|
* certificates. */
|
|
* certificates. */
|
|
|
|
|
|
-const char *format_node_description(char *buf,
|
|
|
|
- const char *id_digest,
|
|
|
|
- int is_named,
|
|
|
|
- const char *nickname,
|
|
|
|
- const tor_addr_t *addr,
|
|
|
|
- uint32_t addr32h);
|
|
|
|
-
|
|
|
|
|
|
|
|
* of <b>err</b>.
|
|
* of <b>err</b>.
|
|
*/
|
|
*/
|
|
@@ -540,85 +530,6 @@ log_new_relay_greeting(void)
|
|
already_logged = 1;
|
|
already_logged = 1;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * 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>log_greeting</b> is non-zero and a
|
|
|
|
- * new key was created, log_new_relay_greeting() is called.
|
|
|
|
- */
|
|
|
|
-crypto_pk_t *
|
|
|
|
-init_key_from_file(const char *fname, int generate, int severity,
|
|
|
|
- int log_greeting)
|
|
|
|
-{
|
|
|
|
- crypto_pk_t *prkey = NULL;
|
|
|
|
-
|
|
|
|
- if (!(prkey = crypto_pk_new())) {
|
|
|
|
- tor_log(severity, LD_GENERAL,"Error constructing key");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- switch (file_status(fname)) {
|
|
|
|
- case FN_DIR:
|
|
|
|
- case FN_ERROR:
|
|
|
|
- tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname);
|
|
|
|
- goto error;
|
|
|
|
-
|
|
|
|
- * if generate is set, replace the empty file in
|
|
|
|
- * crypto_pk_write_private_key_to_filename() */
|
|
|
|
- case FN_NOENT:
|
|
|
|
- case FN_EMPTY:
|
|
|
|
- if (generate) {
|
|
|
|
- if (!have_lockfile()) {
|
|
|
|
- if (try_locking(get_options(), 0)<0) {
|
|
|
|
-
|
|
|
|
- * if there is no possibility for a deadlock. */
|
|
|
|
- tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". "
|
|
|
|
- "Not writing any new keys.", fname);
|
|
|
|
-
|
|
|
|
- * maybe we should wait for it. */
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.",
|
|
|
|
- fname);
|
|
|
|
- if (crypto_pk_generate_key(prkey)) {
|
|
|
|
- tor_log(severity, LD_GENERAL,"Error generating onion key");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- if (! crypto_pk_is_valid_private_key(prkey)) {
|
|
|
|
- tor_log(severity, LD_GENERAL,"Generated key seems invalid");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- log_info(LD_GENERAL, "Generated key seems valid");
|
|
|
|
- if (log_greeting) {
|
|
|
|
- log_new_relay_greeting();
|
|
|
|
- }
|
|
|
|
- if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
|
|
|
|
- tor_log(severity, LD_FS,
|
|
|
|
- "Couldn't write generated key to \"%s\".", fname);
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname);
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- return prkey;
|
|
|
|
- case FN_FILE:
|
|
|
|
- if (crypto_pk_read_private_key_from_filename(prkey, fname)) {
|
|
|
|
- tor_log(severity, LD_GENERAL,"Error loading private key.");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- return prkey;
|
|
|
|
- default:
|
|
|
|
- tor_assert(0);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- error:
|
|
|
|
- if (prkey)
|
|
|
|
- crypto_pk_free(prkey);
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* <b>keys_out</b>. If the file isn't found, or is empty, and <b>generate</b>
|
|
* <b>keys_out</b>. If the file isn't found, or is empty, and <b>generate</b>
|
|
* is true, create a new keypair and write it into the file. If there are
|
|
* is true, create a new keypair and write it into the file. If there are
|
|
@@ -708,7 +619,7 @@ load_authority_keyset(int legacy, crypto_pk_t **key_out,
|
|
|
|
|
|
fname = get_keydir_fname(
|
|
fname = get_keydir_fname(
|
|
legacy ? "legacy_signing_key" : "authority_signing_key");
|
|
legacy ? "legacy_signing_key" : "authority_signing_key");
|
|
- signing_key = init_key_from_file(fname, 0, LOG_ERR, 0);
|
|
+ signing_key = init_key_from_file(fname, 0, LOG_ERR, NULL);
|
|
if (!signing_key) {
|
|
if (!signing_key) {
|
|
log_warn(LD_DIR, "No version 3 directory key found in %s", fname);
|
|
log_warn(LD_DIR, "No version 3 directory key found in %s", fname);
|
|
goto done;
|
|
goto done;
|
|
@@ -1042,9 +953,12 @@ init_keys(void)
|
|
|
|
|
|
keydir = get_keydir_fname("secret_id_key");
|
|
keydir = get_keydir_fname("secret_id_key");
|
|
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
|
|
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
|
|
- prkey = init_key_from_file(keydir, 1, LOG_ERR, 1);
|
|
+ bool created = false;
|
|
|
|
+ prkey = init_key_from_file(keydir, 1, LOG_ERR, &created);
|
|
tor_free(keydir);
|
|
tor_free(keydir);
|
|
if (!prkey) return -1;
|
|
if (!prkey) return -1;
|
|
|
|
+ if (created)
|
|
|
|
+ log_new_relay_greeting();
|
|
set_server_identity_key(prkey);
|
|
set_server_identity_key(prkey);
|
|
|
|
|
|
|
|
|
|
@@ -1070,7 +984,9 @@ init_keys(void)
|
|
|
|
|
|
keydir = get_keydir_fname("secret_onion_key");
|
|
keydir = get_keydir_fname("secret_onion_key");
|
|
log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir);
|
|
log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir);
|
|
- prkey = init_key_from_file(keydir, 1, LOG_ERR, 1);
|
|
+ prkey = init_key_from_file(keydir, 1, LOG_ERR, &created);
|
|
|
|
+ if (created)
|
|
|
|
+ log_new_relay_greeting();
|
|
tor_free(keydir);
|
|
tor_free(keydir);
|
|
if (!prkey) return -1;
|
|
if (!prkey) return -1;
|
|
set_onion_key(prkey);
|
|
set_onion_key(prkey);
|
|
@@ -1242,68 +1158,6 @@ init_keys(void)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * and what type of server we are.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-static int can_reach_or_port = 0;
|
|
|
|
-
|
|
|
|
-static int can_reach_dir_port = 0;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void
|
|
|
|
-router_reset_reachability(void)
|
|
|
|
-{
|
|
|
|
- can_reach_or_port = can_reach_dir_port = 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * - AssumeReachable is set, or
|
|
|
|
- * - the network is disabled.
|
|
|
|
- * Otherwise, return 0.
|
|
|
|
- */
|
|
|
|
-static int
|
|
|
|
-router_reachability_checks_disabled(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- return options->AssumeReachable ||
|
|
|
|
- net_is_disabled();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * - no reachability check has been done yet, or
|
|
|
|
- * - we've initiated reachability checks, but none have succeeded.
|
|
|
|
- * Return 1 if we don't need to do an ORPort reachability check, because:
|
|
|
|
- * - we've seen a successful reachability check, or
|
|
|
|
- * - AssumeReachable is set, or
|
|
|
|
- * - the network is disabled.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-check_whether_orport_reachable(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- int reach_checks_disabled = router_reachability_checks_disabled(options);
|
|
|
|
- return reach_checks_disabled ||
|
|
|
|
- can_reach_or_port;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * - no reachability check has been done yet, or
|
|
|
|
- * - we've initiated reachability checks, but none have succeeded.
|
|
|
|
- * Return 1 if we don't need to do a DirPort reachability check, because:
|
|
|
|
- * - we've seen a successful reachability check, or
|
|
|
|
- * - there is no DirPort set, or
|
|
|
|
- * - AssumeReachable is set, or
|
|
|
|
- * - the network is disabled.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-check_whether_dirport_reachable(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- int reach_checks_disabled = router_reachability_checks_disabled(options) ||
|
|
|
|
- !options->DirPort_set;
|
|
|
|
- return reach_checks_disabled ||
|
|
|
|
- can_reach_dir_port;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* automatically provide) directory services */
|
|
* automatically provide) directory services */
|
|
|
|
|
|
@@ -1312,7 +1166,7 @@ check_whether_dirport_reachable(const or_options_t *options)
|
|
|
|
|
|
* automatically provide directory services from cache directory
|
|
* automatically provide directory services from cache directory
|
|
* information. */
|
|
* information. */
|
|
-static int
|
|
+int
|
|
router_has_bandwidth_to_be_dirserver(const or_options_t *options)
|
|
router_has_bandwidth_to_be_dirserver(const or_options_t *options)
|
|
{
|
|
{
|
|
if (options->BandwidthRate < MIN_BW_TO_ADVERTISE_DIRSERVER) {
|
|
if (options->BandwidthRate < MIN_BW_TO_ADVERTISE_DIRSERVER) {
|
|
@@ -1392,19 +1246,6 @@ router_should_be_dirserver(const or_options_t *options, int dir_port)
|
|
return advertising;
|
|
return advertising;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * from clients and we aren't at risk of exceeding our bandwidth limits, thus
|
|
|
|
- * we should be a directory server. If not, return 0.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-dir_server_mode(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- if (!options->DirCache)
|
|
|
|
- return 0;
|
|
|
|
- return options->DirPort_set ||
|
|
|
|
- (server_mode(options) && router_has_bandwidth_to_be_dirserver(options));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* advertise the fact that we have a DirPort open or begindir support, else
|
|
* advertise the fact that we have a DirPort open or begindir support, else
|
|
* return 1.
|
|
* return 1.
|
|
@@ -1445,7 +1286,7 @@ decide_to_advertise_dir_impl(const or_options_t *options,
|
|
* advertise the fact that we have a DirPort open, else return the
|
|
* advertise the fact that we have a DirPort open, else return the
|
|
* DirPort we want to advertise.
|
|
* DirPort we want to advertise.
|
|
*/
|
|
*/
|
|
-static int
|
|
+int
|
|
router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port)
|
|
router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port)
|
|
{
|
|
{
|
|
|
|
|
|
@@ -1464,297 +1305,6 @@ router_should_advertise_begindir(const or_options_t *options,
|
|
supports_tunnelled_dir_requests);
|
|
supports_tunnelled_dir_requests);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * a circuit to or through the router <b>r</b>. Uses the primary
|
|
|
|
- * address of the router, so should only be called on a server. */
|
|
|
|
-static extend_info_t *
|
|
|
|
-extend_info_from_router(const routerinfo_t *r)
|
|
|
|
-{
|
|
|
|
- crypto_pk_t *rsa_pubkey;
|
|
|
|
- extend_info_t *info;
|
|
|
|
- tor_addr_port_t ap;
|
|
|
|
- tor_assert(r);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- tor_assert_nonfatal(router_skip_or_reachability(get_options(), 0));
|
|
|
|
-
|
|
|
|
- const ed25519_public_key_t *ed_id_key;
|
|
|
|
- if (r->cache_info.signing_key_cert)
|
|
|
|
- ed_id_key = &r->cache_info.signing_key_cert->signing_key;
|
|
|
|
- else
|
|
|
|
- ed_id_key = NULL;
|
|
|
|
-
|
|
|
|
- router_get_prim_orport(r, &ap);
|
|
|
|
- rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len);
|
|
|
|
- info = extend_info_new(r->nickname, r->cache_info.identity_digest,
|
|
|
|
- ed_id_key,
|
|
|
|
- rsa_pubkey, r->onion_curve25519_pkey,
|
|
|
|
- &ap.addr, ap.port);
|
|
|
|
- crypto_pk_free(rsa_pubkey);
|
|
|
|
- return info;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * unreachable. If so, return 1 else return 0.
|
|
|
|
- */
|
|
|
|
-static int
|
|
|
|
-router_should_check_reachability(int test_or, int test_dir)
|
|
|
|
-{
|
|
|
|
- const routerinfo_t *me = router_get_my_routerinfo();
|
|
|
|
- const or_options_t *options = get_options();
|
|
|
|
-
|
|
|
|
- if (!me)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (routerset_contains_router(options->ExcludeNodes, me, -1) &&
|
|
|
|
- options->StrictNodes) {
|
|
|
|
-
|
|
|
|
- * ourself. */
|
|
|
|
- if (test_or || test_dir) {
|
|
|
|
-#define SELF_EXCLUDED_WARN_INTERVAL 3600
|
|
|
|
- static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL);
|
|
|
|
- log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC,
|
|
|
|
- "Can't peform self-tests for this relay: we have "
|
|
|
|
- "listed ourself in ExcludeNodes, and StrictNodes is set. "
|
|
|
|
- "We cannot learn whether we are usable, and will not "
|
|
|
|
- "be able to advertise ourself.");
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- return 1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * See if we currently believe our ORPort or DirPort to be
|
|
|
|
- * unreachable. If so, launch a new test for it.
|
|
|
|
- *
|
|
|
|
- * For ORPort, we simply try making a circuit that ends at ourselves.
|
|
|
|
- * Success is noticed in onionskin_answer().
|
|
|
|
- *
|
|
|
|
- * For DirPort, we make a connection via Tor to our DirPort and ask
|
|
|
|
- * for our own server descriptor.
|
|
|
|
- * Success is noticed in connection_dir_client_reached_eof().
|
|
|
|
- */
|
|
|
|
-void
|
|
|
|
-router_do_reachability_checks(int test_or, int test_dir)
|
|
|
|
-{
|
|
|
|
- const routerinfo_t *me = router_get_my_routerinfo();
|
|
|
|
- const or_options_t *options = get_options();
|
|
|
|
- int orport_reachable = check_whether_orport_reachable(options);
|
|
|
|
- tor_addr_t addr;
|
|
|
|
-
|
|
|
|
- if (router_should_check_reachability(test_or, test_dir)) {
|
|
|
|
- if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
|
|
|
|
- extend_info_t *ei = extend_info_from_router(me);
|
|
|
|
-
|
|
|
|
- log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
|
|
|
|
- !orport_reachable ? "reachability" : "bandwidth",
|
|
|
|
- fmt_addr32(me->addr), me->or_port);
|
|
|
|
- circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
|
|
|
|
- CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
|
|
|
|
- extend_info_free(ei);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- tor_addr_from_ipv4h(&addr, me->addr);
|
|
|
|
- if (test_dir && !check_whether_dirport_reachable(options) &&
|
|
|
|
- !connection_get_by_type_addr_port_purpose(
|
|
|
|
- CONN_TYPE_DIR, &addr, me->dir_port,
|
|
|
|
- DIR_PURPOSE_FETCH_SERVERDESC)) {
|
|
|
|
- tor_addr_port_t my_orport, my_dirport;
|
|
|
|
- memcpy(&my_orport.addr, &addr, sizeof(addr));
|
|
|
|
- memcpy(&my_dirport.addr, &addr, sizeof(addr));
|
|
|
|
- my_orport.port = me->or_port;
|
|
|
|
- my_dirport.port = me->dir_port;
|
|
|
|
-
|
|
|
|
- directory_request_t *req =
|
|
|
|
- directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC);
|
|
|
|
- directory_request_set_or_addr_port(req, &my_orport);
|
|
|
|
- directory_request_set_dir_addr_port(req, &my_dirport);
|
|
|
|
- directory_request_set_directory_id_digest(req,
|
|
|
|
- me->cache_info.identity_digest);
|
|
|
|
-
|
|
|
|
- directory_request_set_indirection(req, DIRIND_ANON_DIRPORT);
|
|
|
|
- directory_request_set_resource(req, "authority.z");
|
|
|
|
- directory_initiate_request(req);
|
|
|
|
- directory_request_free(req);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void
|
|
|
|
-router_orport_found_reachable(void)
|
|
|
|
-{
|
|
|
|
- const routerinfo_t *me = router_get_my_routerinfo();
|
|
|
|
- const or_options_t *options = get_options();
|
|
|
|
- if (!can_reach_or_port && me) {
|
|
|
|
- char *address = tor_dup_ip(me->addr);
|
|
|
|
- log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
|
|
|
|
- "the outside. Excellent.%s",
|
|
|
|
- options->PublishServerDescriptor_ != NO_DIRINFO
|
|
|
|
- && check_whether_dirport_reachable(options) ?
|
|
|
|
- " Publishing server descriptor." : "");
|
|
|
|
- can_reach_or_port = 1;
|
|
|
|
- mark_my_descriptor_dirty("ORPort found reachable");
|
|
|
|
-
|
|
|
|
- * at least in a test network */
|
|
|
|
- if (options->TestingTorNetwork == 1) {
|
|
|
|
- reschedule_descriptor_update_check();
|
|
|
|
- }
|
|
|
|
- control_event_server_status(LOG_NOTICE,
|
|
|
|
- "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
|
|
|
|
- address, me->or_port);
|
|
|
|
- tor_free(address);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void
|
|
|
|
-router_dirport_found_reachable(void)
|
|
|
|
-{
|
|
|
|
- const routerinfo_t *me = router_get_my_routerinfo();
|
|
|
|
- const or_options_t *options = get_options();
|
|
|
|
- if (!can_reach_dir_port && me) {
|
|
|
|
- char *address = tor_dup_ip(me->addr);
|
|
|
|
- log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
|
|
|
|
- "from the outside. Excellent.%s",
|
|
|
|
- options->PublishServerDescriptor_ != NO_DIRINFO
|
|
|
|
- && check_whether_orport_reachable(options) ?
|
|
|
|
- " Publishing server descriptor." : "");
|
|
|
|
- can_reach_dir_port = 1;
|
|
|
|
- if (router_should_advertise_dirport(options, me->dir_port)) {
|
|
|
|
- mark_my_descriptor_dirty("DirPort found reachable");
|
|
|
|
-
|
|
|
|
- * at least in a test network */
|
|
|
|
- if (options->TestingTorNetwork == 1) {
|
|
|
|
- reschedule_descriptor_update_check();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- control_event_server_status(LOG_NOTICE,
|
|
|
|
- "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
|
|
|
|
- address, me->dir_port);
|
|
|
|
- tor_free(address);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * cells down each of them, to exercise our bandwidth. */
|
|
|
|
-void
|
|
|
|
-router_perform_bandwidth_test(int num_circs, time_t now)
|
|
|
|
-{
|
|
|
|
- int num_cells = (int)(get_options()->BandwidthRate * 10 /
|
|
|
|
- CELL_MAX_NETWORK_SIZE);
|
|
|
|
- int max_cells = num_cells < CIRCWINDOW_START ?
|
|
|
|
- num_cells : CIRCWINDOW_START;
|
|
|
|
- int cells_per_circuit = max_cells / num_circs;
|
|
|
|
- origin_circuit_t *circ = NULL;
|
|
|
|
-
|
|
|
|
- log_notice(LD_OR,"Performing bandwidth self-test...done.");
|
|
|
|
- while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL,
|
|
|
|
- CIRCUIT_PURPOSE_TESTING))) {
|
|
|
|
-
|
|
|
|
- int i = cells_per_circuit;
|
|
|
|
- if (circ->base_.state != CIRCUIT_STATE_OPEN)
|
|
|
|
- continue;
|
|
|
|
- circ->base_.timestamp_dirty = now;
|
|
|
|
- while (i-- > 0) {
|
|
|
|
- if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
|
|
|
|
- RELAY_COMMAND_DROP,
|
|
|
|
- NULL, 0, circ->cpath->prev)<0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * either we're hibernating, entering hibernation, or the network is turned
|
|
|
|
- * off with DisableNetwork. */
|
|
|
|
-int
|
|
|
|
-net_is_disabled(void)
|
|
|
|
-{
|
|
|
|
- return get_options()->DisableNetwork || we_are_hibernating();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * we're fully hibernating or the network is turned off with
|
|
|
|
- * DisableNetwork. */
|
|
|
|
-int
|
|
|
|
-net_is_completely_disabled(void)
|
|
|
|
-{
|
|
|
|
- return get_options()->DisableNetwork || we_are_fully_hibernating();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * directory server.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-authdir_mode(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- return options->AuthoritativeDir != 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
- * authoritative about receiving and serving descriptors of type
|
|
|
|
- * <b>purpose</b> on its dirport.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-authdir_mode_handles_descs(const or_options_t *options, int purpose)
|
|
|
|
-{
|
|
|
|
- if (BUG(purpose < 0))
|
|
|
|
- return authdir_mode(options);
|
|
|
|
- else if (purpose == ROUTER_PURPOSE_GENERAL)
|
|
|
|
- return authdir_mode_v3(options);
|
|
|
|
- else if (purpose == ROUTER_PURPOSE_BRIDGE)
|
|
|
|
- return authdir_mode_bridge(options);
|
|
|
|
- else
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
- * publishes its own network statuses.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-authdir_mode_publishes_statuses(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- if (authdir_mode_bridge(options))
|
|
|
|
- return 0;
|
|
|
|
- return authdir_mode(options);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
- * tests reachability of the descriptors it learns about.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-authdir_mode_tests_reachability(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- return authdir_mode(options);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
- * directory server.
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-authdir_mode_bridge(const or_options_t *options)
|
|
|
|
-{
|
|
|
|
- return authdir_mode(options) && options->BridgeAuthoritativeDir != 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- */
|
|
|
|
-MOCK_IMPL(int,
|
|
|
|
-server_mode,(const or_options_t *options))
|
|
|
|
-{
|
|
|
|
- if (options->ClientOnly) return 0;
|
|
|
|
- return (options->ORPort_set);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- */
|
|
|
|
-MOCK_IMPL(int,
|
|
|
|
-public_server_mode,(const or_options_t *options))
|
|
|
|
-{
|
|
|
|
- if (!server_mode(options)) return 0;
|
|
|
|
- return (!options->BridgeRelay);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* in the consensus mean that we don't want to allow exits from circuits
|
|
* in the consensus mean that we don't want to allow exits from circuits
|
|
* we got from addresses not known to be servers. */
|
|
* we got from addresses not known to be servers. */
|
|
@@ -1768,42 +1318,6 @@ should_refuse_unknown_exits(const or_options_t *options)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-static int server_is_advertised=0;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- */
|
|
|
|
-MOCK_IMPL(int,
|
|
|
|
-advertised_server_mode,(void))
|
|
|
|
-{
|
|
|
|
- return server_is_advertised;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * Called with a boolean: set whether we have recently published our
|
|
|
|
- * descriptor.
|
|
|
|
- */
|
|
|
|
-static void
|
|
|
|
-set_server_advertised(int s)
|
|
|
|
-{
|
|
|
|
- server_is_advertised = s;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-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;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* - We don't have the ClientOnly option set
|
|
* - We don't have the ClientOnly option set
|
|
* and
|
|
* and
|
|
@@ -3267,36 +2781,6 @@ router_dump_exit_policy_to_string(const routerinfo_t *router,
|
|
include_ipv6);
|
|
include_ipv6);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * <b>router</b> into *<b>ap_out</b>. */
|
|
|
|
-void
|
|
|
|
-router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out)
|
|
|
|
-{
|
|
|
|
- tor_assert(ap_out != NULL);
|
|
|
|
- tor_addr_from_ipv4h(&ap_out->addr, router->addr);
|
|
|
|
- ap_out->port = router->or_port;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * Otherwise return 0. */
|
|
|
|
-int
|
|
|
|
-router_has_addr(const routerinfo_t *router, const tor_addr_t *addr)
|
|
|
|
-{
|
|
|
|
- return
|
|
|
|
- tor_addr_eq_ipv4h(addr, router->addr) ||
|
|
|
|
- tor_addr_eq(&router->ipv6_addr, addr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-int
|
|
|
|
-router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport)
|
|
|
|
-{
|
|
|
|
- return
|
|
|
|
- (tor_addr_eq_ipv4h(&orport->addr, router->addr) &&
|
|
|
|
- orport->port == router->or_port) ||
|
|
|
|
- (tor_addr_eq(&orport->addr, &router->ipv6_addr) &&
|
|
|
|
- orport->port == router->ipv6_orport);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
|
|
* <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
|
|
* the past or more than 1 hour in the future with respect to <b>now</b>,
|
|
* the past or more than 1 hour in the future with respect to <b>now</b>,
|
|
@@ -3566,219 +3050,6 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * containing between 1 and MAX_NICKNAME_LEN characters from
|
|
|
|
- * LEGAL_NICKNAME_CHARACTERS.) */
|
|
|
|
-int
|
|
|
|
-is_legal_nickname(const char *s)
|
|
|
|
-{
|
|
|
|
- size_t len;
|
|
|
|
- tor_assert(s);
|
|
|
|
- len = strlen(s);
|
|
|
|
- return len > 0 && len <= MAX_NICKNAME_LEN &&
|
|
|
|
- strspn(s,LEGAL_NICKNAME_CHARACTERS) == len;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * hex-encoded identity-key digest. */
|
|
|
|
-int
|
|
|
|
-is_legal_nickname_or_hexdigest(const char *s)
|
|
|
|
-{
|
|
|
|
- if (*s!='$')
|
|
|
|
- return is_legal_nickname(s);
|
|
|
|
- else
|
|
|
|
- return is_legal_hexdigest(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * digest. (That is, an optional $, followed by 40 hex characters,
|
|
|
|
- * followed by either nothing, or = or ~ followed by a nickname, or
|
|
|
|
- * a character other than =, ~, or a hex character.)
|
|
|
|
- */
|
|
|
|
-int
|
|
|
|
-is_legal_hexdigest(const char *s)
|
|
|
|
-{
|
|
|
|
- size_t len;
|
|
|
|
- tor_assert(s);
|
|
|
|
- if (s[0] == '$') s++;
|
|
|
|
- len = strlen(s);
|
|
|
|
- if (len > HEX_DIGEST_LEN) {
|
|
|
|
- if (s[HEX_DIGEST_LEN] == '=' ||
|
|
|
|
- s[HEX_DIGEST_LEN] == '~') {
|
|
|
|
- if (!is_legal_nickname(s+HEX_DIGEST_LEN+1))
|
|
|
|
- return 0;
|
|
|
|
- } else {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return (len >= HEX_DIGEST_LEN &&
|
|
|
|
- strspn(s,HEX_CHARACTERS)==HEX_DIGEST_LEN);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * Longest allowed output of format_node_description, plus 1 character for
|
|
|
|
- * NUL. This allows space for:
|
|
|
|
- * "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF~xxxxxxxxxxxxxxxxxxx at"
|
|
|
|
- * " [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]"
|
|
|
|
- * plus a terminating NUL.
|
|
|
|
- */
|
|
|
|
-#define NODE_DESC_BUF_LEN (MAX_VERBOSE_NICKNAME_LEN+4+TOR_ADDR_BUF_LEN)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * hold a human-readable description of a node with identity digest
|
|
|
|
- * <b>id_digest</b>, named-status <b>is_named</b>, nickname <b>nickname</b>,
|
|
|
|
- * and address <b>addr</b> or <b>addr32h</b>.
|
|
|
|
- *
|
|
|
|
- * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to
|
|
|
|
- * NULL. The <b>addr32h</b> field is optional and may be set to 0.
|
|
|
|
- *
|
|
|
|
- * Return a pointer to the front of <b>buf</b>.
|
|
|
|
- */
|
|
|
|
-const char *
|
|
|
|
-format_node_description(char *buf,
|
|
|
|
- const char *id_digest,
|
|
|
|
- int is_named,
|
|
|
|
- const char *nickname,
|
|
|
|
- const tor_addr_t *addr,
|
|
|
|
- uint32_t addr32h)
|
|
|
|
-{
|
|
|
|
- char *cp;
|
|
|
|
-
|
|
|
|
- if (!buf)
|
|
|
|
- return "<NULL BUFFER>";
|
|
|
|
-
|
|
|
|
- buf[0] = '$';
|
|
|
|
- base16_encode(buf+1, HEX_DIGEST_LEN+1, id_digest, DIGEST_LEN);
|
|
|
|
- cp = buf+1+HEX_DIGEST_LEN;
|
|
|
|
- if (nickname) {
|
|
|
|
- buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~';
|
|
|
|
- strlcpy(buf+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1);
|
|
|
|
- cp += strlen(cp);
|
|
|
|
- }
|
|
|
|
- if (addr32h || addr) {
|
|
|
|
- memcpy(cp, " at ", 4);
|
|
|
|
- cp += 4;
|
|
|
|
- if (addr) {
|
|
|
|
- tor_addr_to_str(cp, addr, TOR_ADDR_BUF_LEN, 0);
|
|
|
|
- } else {
|
|
|
|
- struct in_addr in;
|
|
|
|
- in.s_addr = htonl(addr32h);
|
|
|
|
- tor_inet_ntoa(&in, cp, INET_NTOA_BUF_LEN);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return buf;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- *
|
|
|
|
- * This function is not thread-safe. Each call to this function invalidates
|
|
|
|
- * previous values returned by this function.
|
|
|
|
- */
|
|
|
|
-const char *
|
|
|
|
-router_describe(const routerinfo_t *ri)
|
|
|
|
-{
|
|
|
|
- static char buf[NODE_DESC_BUF_LEN];
|
|
|
|
-
|
|
|
|
- if (!ri)
|
|
|
|
- return "<null>";
|
|
|
|
- return format_node_description(buf,
|
|
|
|
- ri->cache_info.identity_digest,
|
|
|
|
- 0,
|
|
|
|
- ri->nickname,
|
|
|
|
- NULL,
|
|
|
|
- ri->addr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- *
|
|
|
|
- * This function is not thread-safe. Each call to this function invalidates
|
|
|
|
- * previous values returned by this function.
|
|
|
|
- */
|
|
|
|
-const char *
|
|
|
|
-node_describe(const node_t *node)
|
|
|
|
-{
|
|
|
|
- static char buf[NODE_DESC_BUF_LEN];
|
|
|
|
- const char *nickname = NULL;
|
|
|
|
- uint32_t addr32h = 0;
|
|
|
|
- int is_named = 0;
|
|
|
|
-
|
|
|
|
- if (!node)
|
|
|
|
- return "<null>";
|
|
|
|
-
|
|
|
|
- if (node->rs) {
|
|
|
|
- nickname = node->rs->nickname;
|
|
|
|
- is_named = node->rs->is_named;
|
|
|
|
- addr32h = node->rs->addr;
|
|
|
|
- } else if (node->ri) {
|
|
|
|
- nickname = node->ri->nickname;
|
|
|
|
- addr32h = node->ri->addr;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return format_node_description(buf,
|
|
|
|
- node->identity,
|
|
|
|
- is_named,
|
|
|
|
- nickname,
|
|
|
|
- NULL,
|
|
|
|
- addr32h);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- *
|
|
|
|
- * This function is not thread-safe. Each call to this function invalidates
|
|
|
|
- * previous values returned by this function.
|
|
|
|
- */
|
|
|
|
-const char *
|
|
|
|
-routerstatus_describe(const routerstatus_t *rs)
|
|
|
|
-{
|
|
|
|
- static char buf[NODE_DESC_BUF_LEN];
|
|
|
|
-
|
|
|
|
- if (!rs)
|
|
|
|
- return "<null>";
|
|
|
|
- return format_node_description(buf,
|
|
|
|
- rs->identity_digest,
|
|
|
|
- rs->is_named,
|
|
|
|
- rs->nickname,
|
|
|
|
- NULL,
|
|
|
|
- rs->addr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- *
|
|
|
|
- * This function is not thread-safe. Each call to this function invalidates
|
|
|
|
- * previous values returned by this function.
|
|
|
|
- */
|
|
|
|
-const char *
|
|
|
|
-extend_info_describe(const extend_info_t *ei)
|
|
|
|
-{
|
|
|
|
- static char buf[NODE_DESC_BUF_LEN];
|
|
|
|
-
|
|
|
|
- if (!ei)
|
|
|
|
- return "<null>";
|
|
|
|
- return format_node_description(buf,
|
|
|
|
- ei->identity_digest,
|
|
|
|
- 0,
|
|
|
|
- ei->nickname,
|
|
|
|
- &ei->addr,
|
|
|
|
- 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- * verbose representation of the identity of <b>router</b>. The format is:
|
|
|
|
- * A dollar sign.
|
|
|
|
- * The upper-case hexadecimal encoding of the SHA1 hash of router's identity.
|
|
|
|
- * A "=" if the router is named (no longer implemented); a "~" if it is not.
|
|
|
|
- * The router's nickname.
|
|
|
|
- **/
|
|
|
|
-void
|
|
|
|
-router_get_verbose_nickname(char *buf, const routerinfo_t *router)
|
|
|
|
-{
|
|
|
|
- buf[0] = '$';
|
|
|
|
- base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest,
|
|
|
|
- DIGEST_LEN);
|
|
|
|
- buf[1+HEX_DIGEST_LEN] = '~';
|
|
|
|
- strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* warn again if we see the same errors. */
|
|
* warn again if we see the same errors. */
|
|
void
|
|
void
|
|
@@ -3790,37 +3061,6 @@ router_reset_warnings(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- * ROUTER_PURPOSE_UNKNOWN: The whole point of that value is that we don't
|
|
|
|
- * know its string representation. */
|
|
|
|
-const char *
|
|
|
|
-router_purpose_to_string(uint8_t p)
|
|
|
|
-{
|
|
|
|
- switch (p)
|
|
|
|
- {
|
|
|
|
- case ROUTER_PURPOSE_GENERAL: return "general";
|
|
|
|
- case ROUTER_PURPOSE_BRIDGE: return "bridge";
|
|
|
|
- case ROUTER_PURPOSE_CONTROLLER: return "controller";
|
|
|
|
- default:
|
|
|
|
- tor_assert(0);
|
|
|
|
- }
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-uint8_t
|
|
|
|
-router_purpose_from_string(const char *s)
|
|
|
|
-{
|
|
|
|
- if (!strcmp(s, "general"))
|
|
|
|
- return ROUTER_PURPOSE_GENERAL;
|
|
|
|
- else if (!strcmp(s, "bridge"))
|
|
|
|
- return ROUTER_PURPOSE_BRIDGE;
|
|
|
|
- else if (!strcmp(s, "controller"))
|
|
|
|
- return ROUTER_PURPOSE_CONTROLLER;
|
|
|
|
- else
|
|
|
|
- return ROUTER_PURPOSE_UNKNOWN;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
void
|
|
void
|
|
router_free_all(void)
|
|
router_free_all(void)
|
|
@@ -3846,22 +3086,6 @@ router_free_all(void)
|
|
smartlist_free(warned_nonexistent_family);
|
|
smartlist_free(warned_nonexistent_family);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
- <b>ri</b>. Note that freeing of the items in the list as well as
|
|
|
|
- the smartlist itself is the callers responsibility. */
|
|
|
|
-smartlist_t *
|
|
|
|
-router_get_all_orports(const routerinfo_t *ri)
|
|
|
|
-{
|
|
|
|
- tor_assert(ri);
|
|
|
|
- node_t fake_node;
|
|
|
|
- memset(&fake_node, 0, sizeof(fake_node));
|
|
|
|
-
|
|
|
|
- */
|
|
|
|
- fake_node.ri = (routerinfo_t *)ri;
|
|
|
|
- return node_get_all_orports(&fake_node);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
* the newly allocated object in onion_pkey_out. The length of the key is set
|
|
* the newly allocated object in onion_pkey_out. The length of the key is set
|
|
* in onion_pkey_len_out. */
|
|
* in onion_pkey_len_out. */
|