diff options
author | Nick Mathewson <nickm@torproject.org> | 2020-04-09 11:50:20 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2020-04-09 11:50:20 -0400 |
commit | 80031db32abebaf4d0a91c01db258fcdbd54a471 (patch) | |
tree | 19bd6af4959027109db5c83ecb0472ba51ab8404 /src/feature | |
parent | 11fbd1f064751e38ccd79e7823adb688b1293e59 (diff) | |
parent | 75aba30abf50b918ef2188354176bbc2ae59c99c (diff) | |
download | tor-80031db32abebaf4d0a91c01db258fcdbd54a471.tar.gz tor-80031db32abebaf4d0a91c01db258fcdbd54a471.zip |
Merge remote-tracking branch 'tor-github/pr/1801/head'
Diffstat (limited to 'src/feature')
-rw-r--r-- | src/feature/nodelist/nodelist.c | 10 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.h | 8 | ||||
-rw-r--r-- | src/feature/relay/circuitbuild_relay.c | 399 | ||||
-rw-r--r-- | src/feature/relay/circuitbuild_relay.h | 84 | ||||
-rw-r--r-- | src/feature/relay/include.am | 2 | ||||
-rw-r--r-- | src/feature/relay/relay_config.c | 2 | ||||
-rw-r--r-- | src/feature/relay/selftest.c | 34 | ||||
-rw-r--r-- | src/feature/relay/selftest.h | 27 |
8 files changed, 549 insertions, 17 deletions
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index fcf27b1a3a..7454f342f9 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -1074,8 +1074,8 @@ node_get_by_nickname,(const char *nickname, unsigned flags)) /** Return the Ed25519 identity key for the provided node, or NULL if it * doesn't have one. */ -const ed25519_public_key_t * -node_get_ed25519_id(const node_t *node) +MOCK_IMPL(const ed25519_public_key_t *, +node_get_ed25519_id,(const node_t *node)) { const ed25519_public_key_t *ri_pk = NULL; const ed25519_public_key_t *md_pk = NULL; @@ -1158,9 +1158,9 @@ node_get_protover_summary_flags(const node_t *node) * by ed25519 ID during the link handshake. If <b>compatible_with_us</b>, * it needs to be using a link authentication method that we understand. * If not, any plausible link authentication method will do. */ -int -node_supports_ed25519_link_authentication(const node_t *node, - int compatible_with_us) +MOCK_IMPL(int, +node_supports_ed25519_link_authentication,(const node_t *node, + int compatible_with_us)) { if (! node_get_ed25519_id(node)) return 0; diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h index 6e854ec879..57ab2d5913 100644 --- a/src/feature/nodelist/nodelist.h +++ b/src/feature/nodelist/nodelist.h @@ -70,11 +70,13 @@ const char *node_get_platform(const node_t *node); uint32_t node_get_prim_addr_ipv4h(const node_t *node); void node_get_address_string(const node_t *node, char *cp, size_t len); long node_get_declared_uptime(const node_t *node); -const struct ed25519_public_key_t *node_get_ed25519_id(const node_t *node); +MOCK_DECL(const struct ed25519_public_key_t *,node_get_ed25519_id, + (const node_t *node)); int node_ed25519_id_matches(const node_t *node, const struct ed25519_public_key_t *id); -int node_supports_ed25519_link_authentication(const node_t *node, - int compatible_with_us); +MOCK_DECL(int,node_supports_ed25519_link_authentication, + (const node_t *node, + int compatible_with_us)); int node_supports_v3_hsdir(const node_t *node); int node_supports_ed25519_hs_intro(const node_t *node); int node_supports_v3_rendezvous_point(const node_t *node); diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c new file mode 100644 index 0000000000..2fa92eeac1 --- /dev/null +++ b/src/feature/relay/circuitbuild_relay.c @@ -0,0 +1,399 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file circuitbuild_relay.c + * @brief Implements the details of exteding circuits (by relaying extend + * cells as create cells, and answering create cells). + * + * On the server side, this module handles the logic of responding to + * RELAY_EXTEND requests, using circuit_extend() and onionskin_answer(). + * + * The shared client and server code is in core/or/circuitbuild.c. + **/ + +#include "orconfig.h" +#include "feature/relay/circuitbuild_relay.h" + +#include "core/or/or.h" +#include "app/config/config.h" + +#include "core/crypto/relay_crypto.h" + +#include "core/or/cell_st.h" +#include "core/or/circuit_st.h" +#include "core/or/extend_info_st.h" +#include "core/or/or_circuit_st.h" + +#include "core/or/channel.h" +#include "core/or/circuitbuild.h" +#include "core/or/circuitlist.h" +#include "core/or/onion.h" +#include "core/or/relay.h" + +#include "feature/nodelist/nodelist.h" + +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" + +/* Before replying to an extend cell, check the state of the circuit + * <b>circ</b>, and the configured tor mode. + * + * <b>circ</b> must not be NULL. + * + * If the state and mode are valid, return 0. + * Otherwise, if they are invalid, log a protocol warning, and return -1. + */ +STATIC int +circuit_extend_state_valid_helper(const struct circuit_t *circ) +{ + if (!server_mode(get_options())) { + circuitbuild_warn_client_extend(); + return -1; + } + + IF_BUG_ONCE(!circ) { + return -1; + } + + if (circ->n_chan) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "n_chan already set. Bug/attack. Closing."); + return -1; + } + + if (circ->n_hop) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "conn to next hop already launched. Bug/attack. Closing."); + return -1; + } + + return 0; +} + +/* Make sure the extend cell <b>ec</b> has an ed25519 link specifier. + * + * First, check that the RSA node id is valid. + * If the node id is valid, add the ed25519 link specifier (if required), + * and return 0. + * + * Otherwise, if the node id is invalid, log a protocol warning, + * and return -1.(And do not modify the extend cell.) + * + * Must be called before circuit_extend_lspec_valid_helper(). + */ +STATIC int +circuit_extend_add_ed25519_helper(struct extend_cell_t *ec) +{ + IF_BUG_ONCE(!ec) { + return -1; + } + + /* Check if they asked us for 0000..0000. We support using + * an empty fingerprint for the first hop (e.g. for a bridge relay), + * but we don't want to let clients send us extend cells for empty + * fingerprints -- a) because it opens the user up to a mitm attack, + * and b) because it lets an attacker force the relay to hold open a + * new TLS connection for each extend request. */ + if (tor_digest_is_zero((const char*)ec->node_id)) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Client asked me to extend without specifying an id_digest."); + return -1; + } + + /* Fill in ed_pubkey if it was not provided and we can infer it from + * our networkstatus */ + if (ed25519_public_key_is_zero(&ec->ed_pubkey)) { + const node_t *node = node_get_by_id((const char*)ec->node_id); + const ed25519_public_key_t *node_ed_id = NULL; + if (node && + node_supports_ed25519_link_authentication(node, 1) && + (node_ed_id = node_get_ed25519_id(node))) { + ed25519_pubkey_copy(&ec->ed_pubkey, node_ed_id); + } + } + + return 0; +} + +/* Before replying to an extend cell, check the link specifiers in the extend + * cell <b>ec</b>, which was received on the circuit <b>circ</b>. + * + * If they are valid, return 0. + * Otherwise, if they are invalid, log a protocol warning, and return -1. + * + * Must be called after circuit_extend_add_ed25519_helper(). + */ +STATIC int +circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec, + const struct circuit_t *circ) +{ + IF_BUG_ONCE(!ec) { + return -1; + } + + IF_BUG_ONCE(!circ) { + return -1; + } + + if (!ec->orport_ipv4.port || tor_addr_is_null(&ec->orport_ipv4.addr)) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Client asked me to extend to zero destination port or addr."); + return -1; + } + + if (tor_addr_is_internal(&ec->orport_ipv4.addr, 0) && + !get_options()->ExtendAllowPrivateAddresses) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Client asked me to extend to a private address."); + return -1; + } + + IF_BUG_ONCE(circ->magic != OR_CIRCUIT_MAGIC) { + return -1; + } + + const channel_t *p_chan = CONST_TO_OR_CIRCUIT(circ)->p_chan; + + IF_BUG_ONCE(!p_chan) { + return -1; + } + + /* Next, check if we're being asked to connect to the hop that the + * extend cell came from. There isn't any reason for that, and it can + * assist circular-path attacks. */ + if (tor_memeq(ec->node_id, p_chan->identity_digest, DIGEST_LEN)) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Client asked me to extend back to the previous hop."); + return -1; + } + + /* Check the previous hop Ed25519 ID too */ + if (! ed25519_public_key_is_zero(&ec->ed_pubkey) && + ed25519_pubkey_eq(&ec->ed_pubkey, &p_chan->ed25519_identity)) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Client asked me to extend back to the previous hop " + "(by Ed25519 ID)."); + return -1; + } + + return 0; +} + +/* When there is no open channel for an extend cell <b>ec</b>, set up the + * circuit <b>circ</b> to wait for a new connection. If <b>should_launch</b> + * is true, open a new connection. (Otherwise, we are already waiting for a + * new connection to the same relay.) + */ +STATIC void +circuit_open_connection_for_extend(const struct extend_cell_t *ec, + struct circuit_t *circ, + int should_launch) +{ + /* We have to check circ first, so we can close it on all other failures */ + IF_BUG_ONCE(!circ) { + /* We can't mark a NULL circuit for close. */ + return; + } + + /* Now we know that circ is not NULL */ + IF_BUG_ONCE(!ec) { + circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED); + return; + } + + circ->n_hop = extend_info_new(NULL /*nickname*/, + (const char*)ec->node_id, + &ec->ed_pubkey, + NULL, /*onion_key*/ + NULL, /*curve25519_key*/ + &ec->orport_ipv4.addr, + ec->orport_ipv4.port); + + circ->n_chan_create_cell = tor_memdup(&ec->create_cell, + sizeof(ec->create_cell)); + + circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT); + + if (should_launch) { + /* we should try to open a connection */ + channel_t *n_chan = channel_connect_for_circuit(&ec->orport_ipv4.addr, + ec->orport_ipv4.port, + (const char*)ec->node_id, + &ec->ed_pubkey); + if (!n_chan) { + log_info(LD_CIRC,"Launching n_chan failed. Closing circuit."); + circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED); + return; + } + log_debug(LD_CIRC,"connecting in progress (or finished). Good."); + } +} + +/** Take the 'extend' <b>cell</b>, pull out addr/port plus the onion + * skin and identity digest for the next hop. If we're already connected, + * pass the onion skin to the next hop using a create cell; otherwise + * launch a new OR connection, and <b>circ</b> will notice when the + * connection succeeds or fails. + * + * Return -1 if we want to warn and tear down the circuit, else return 0. + */ +int +circuit_extend(struct cell_t *cell, struct circuit_t *circ) +{ + channel_t *n_chan; + relay_header_t rh; + extend_cell_t ec; + const char *msg = NULL; + int should_launch = 0; + + IF_BUG_ONCE(!cell) { + return -1; + } + + IF_BUG_ONCE(!circ) { + return -1; + } + + if (circuit_extend_state_valid_helper(circ) < 0) + return -1; + + relay_header_unpack(&rh, cell->payload); + + if (extend_cell_parse(&ec, rh.command, + cell->payload+RELAY_HEADER_SIZE, + rh.length) < 0) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Can't parse extend cell. Closing circuit."); + return -1; + } + + if (circuit_extend_add_ed25519_helper(&ec) < 0) + return -1; + + if (circuit_extend_lspec_valid_helper(&ec, circ) < 0) + return -1; + + n_chan = channel_get_for_extend((const char*)ec.node_id, + &ec.ed_pubkey, + &ec.orport_ipv4.addr, + &msg, + &should_launch); + + if (!n_chan) { + log_debug(LD_CIRC|LD_OR,"Next router (%s): %s.", + fmt_addrport(&ec.orport_ipv4.addr,ec.orport_ipv4.port), + msg?msg:"????"); + + circuit_open_connection_for_extend(&ec, circ, should_launch); + + /* return success. The onion/circuit/etc will be taken care of + * automatically (may already have been) whenever n_chan reaches + * OR_CONN_STATE_OPEN. + */ + return 0; + } else { + /* Connection is already established. + * So we need to extend the circuit to the next hop. */ + tor_assert(!circ->n_hop); + circ->n_chan = n_chan; + log_debug(LD_CIRC, + "n_chan is %s.", + channel_get_canonical_remote_descr(n_chan)); + + if (circuit_deliver_create_cell(circ, &ec.create_cell, 1) < 0) + return -1; + + return 0; + } +} + +/** On a relay, accept a create cell, initialise a circuit, and send a + * created cell back. + * + * Given: + * - a response payload consisting of: + * - the <b>created_cell</b> and + * - an optional <b>rend_circ_nonce</b>, and + * - <b>keys</b> of length <b>keys_len</b>, which must be + * CPATH_KEY_MATERIAL_LEN; + * then: + * - initialize the circuit <b>circ</b>'s cryptographic material, + * - set the circuit's state to open, and + * - send a created cell back on that circuit. + * + * If we haven't found our ORPorts reachable yet, and the channel meets the + * necessary conditions, mark the relevant ORPorts as reachable. + * + * Returns -1 if cell or circuit initialisation fails. + */ +int +onionskin_answer(struct or_circuit_t *circ, + const created_cell_t *created_cell, + const char *keys, size_t keys_len, + const uint8_t *rend_circ_nonce) +{ + cell_t cell; + + IF_BUG_ONCE(!circ) { + return -1; + } + + IF_BUG_ONCE(!created_cell) { + return -1; + } + + IF_BUG_ONCE(!keys) { + return -1; + } + + IF_BUG_ONCE(!rend_circ_nonce) { + return -1; + } + + tor_assert(keys_len == CPATH_KEY_MATERIAL_LEN); + + if (created_cell_format(&cell, created_cell) < 0) { + log_warn(LD_BUG,"couldn't format created cell (type=%d, len=%d).", + (int)created_cell->cell_type, (int)created_cell->handshake_len); + return -1; + } + cell.circ_id = circ->p_circ_id; + + circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN); + + log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", + (unsigned int)get_uint32(keys), + (unsigned int)get_uint32(keys+20)); + if (relay_crypto_init(&circ->crypto, keys, keys_len, 0, 0)<0) { + log_warn(LD_BUG,"Circuit initialization failed."); + return -1; + } + + memcpy(circ->rend_circ_nonce, rend_circ_nonce, DIGEST_LEN); + + int used_create_fast = (created_cell->cell_type == CELL_CREATED_FAST); + + append_cell_to_circuit_queue(TO_CIRCUIT(circ), + circ->p_chan, &cell, CELL_DIRECTION_IN, 0); + log_debug(LD_CIRC,"Finished sending '%s' cell.", + used_create_fast ? "created_fast" : "created"); + + /* Ignore the local bit when ExtendAllowPrivateAddresses is set: + * it violates the assumption that private addresses are local. + * Also, many test networks run on local addresses, and + * TestingTorNetwork sets ExtendAllowPrivateAddresses. */ + if ((!channel_is_local(circ->p_chan) + || get_options()->ExtendAllowPrivateAddresses) + && !channel_is_outgoing(circ->p_chan)) { + /* record that we could process create cells from a non-local conn + * that we didn't initiate; presumably this means that create cells + * can reach us too. */ + router_orport_found_reachable(); + } + + return 0; +} diff --git a/src/feature/relay/circuitbuild_relay.h b/src/feature/relay/circuitbuild_relay.h new file mode 100644 index 0000000000..d14f304f1c --- /dev/null +++ b/src/feature/relay/circuitbuild_relay.h @@ -0,0 +1,84 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file circuitbuild_relay.h + * @brief Header for feature/relay/circuitbuild_relay.c + **/ + +#ifndef TOR_FEATURE_RELAY_CIRCUITBUILD_RELAY_H +#define TOR_FEATURE_RELAY_CIRCUITBUILD_RELAY_H + +#include "lib/cc/torint.h" +#include "lib/log/log.h" + +#include "app/config/config.h" + +struct cell_t; +struct created_cell_t; + +struct circuit_t; +struct or_circuit_t; +struct extend_cell_t; + +/* Log a protocol warning about getting an extend cell on a client. */ +static inline void +circuitbuild_warn_client_extend(void) +{ + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Got an extend cell, but running as a client. Closing."); +} + +#ifdef HAVE_MODULE_RELAY + +int circuit_extend(struct cell_t *cell, struct circuit_t *circ); + +int onionskin_answer(struct or_circuit_t *circ, + const struct created_cell_t *created_cell, + const char *keys, size_t keys_len, + const uint8_t *rend_circ_nonce); + +#else /* !defined(HAVE_MODULE_RELAY) */ + +static inline int +circuit_extend(struct cell_t *cell, struct circuit_t *circ) +{ + (void)cell; + (void)circ; + circuitbuild_warn_client_extend(); + return -1; +} + +static inline int +onionskin_answer(struct or_circuit_t *circ, + const struct created_cell_t *created_cell, + const char *keys, size_t keys_len, + const uint8_t *rend_circ_nonce) +{ + (void)circ; + (void)created_cell; + (void)keys; + (void)keys_len; + (void)rend_circ_nonce; + tor_assert_nonfatal_unreached(); + return -1; +} + +#endif /* defined(HAVE_MODULE_RELAY) */ + +#ifdef TOR_UNIT_TESTS + +STATIC int circuit_extend_state_valid_helper(const struct circuit_t *circ); +STATIC int circuit_extend_add_ed25519_helper(struct extend_cell_t *ec); +STATIC int circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec, + const struct circuit_t *circ); +STATIC void circuit_open_connection_for_extend(const struct extend_cell_t *ec, + struct circuit_t *circ, + int should_launch); + +#endif /* defined(TOR_UNIT_TESTS) */ + +#endif /* !defined(TOR_FEATURE_RELAY_CIRCUITBUILD_RELAY_H) */ diff --git a/src/feature/relay/include.am b/src/feature/relay/include.am index 813ddb8fb1..654432c34b 100644 --- a/src/feature/relay/include.am +++ b/src/feature/relay/include.am @@ -8,6 +8,7 @@ LIBTOR_APP_A_SOURCES += \ # ADD_C_FILE: INSERT SOURCES HERE. MODULE_RELAY_SOURCES = \ + src/feature/relay/circuitbuild_relay.c \ src/feature/relay/dns.c \ src/feature/relay/ext_orport.c \ src/feature/relay/routermode.c \ @@ -21,6 +22,7 @@ MODULE_RELAY_SOURCES = \ # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ + src/feature/relay/circuitbuild_relay.h \ src/feature/relay/dns.h \ src/feature/relay/dns_structs.h \ src/feature/relay/ext_orport.h \ diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c index 3e9961f47e..fac6a2f577 100644 --- a/src/feature/relay/relay_config.c +++ b/src/feature/relay/relay_config.c @@ -29,7 +29,6 @@ #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" @@ -44,6 +43,7 @@ #include "feature/dircache/consdiffmgr.h" #include "feature/relay/dns.h" #include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" /** Contents of most recently read DirPortFrontPage file. */ static char *global_dirfrontpagecontents = NULL; diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c index 29febdee82..8aaf068f9c 100644 --- a/src/feature/relay/selftest.c +++ b/src/feature/relay/selftest.c @@ -213,6 +213,40 @@ router_do_reachability_checks(int test_or, int test_dir) } } +/** We've decided to start our reachability testing. If all + * is set, log this to the user. Return 1 if we did, or 0 if + * we chose not to log anything. */ +int +inform_testing_reachability(void) +{ + char dirbuf[128]; + char *address; + const routerinfo_t *me = router_get_my_routerinfo(); + if (!me) + return 0; + address = tor_dup_ip(me->addr); + control_event_server_status(LOG_NOTICE, + "CHECKING_REACHABILITY ORADDRESS=%s:%d", + address, me->or_port); + if (me->dir_port) { + tor_snprintf(dirbuf, sizeof(dirbuf), " and DirPort %s:%d", + address, me->dir_port); + control_event_server_status(LOG_NOTICE, + "CHECKING_REACHABILITY DIRADDRESS=%s:%d", + address, me->dir_port); + } + log_notice(LD_OR, "Now checking whether ORPort %s:%d%s %s reachable... " + "(this may take up to %d minutes -- look for log " + "messages indicating success)", + address, me->or_port, + me->dir_port ? dirbuf : "", + me->dir_port ? "are" : "is", + TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT/60); + + tor_free(address); + return 1; +} + /** Annotate that we found our ORPort reachable. */ void router_orport_found_reachable(void) diff --git a/src/feature/relay/selftest.h b/src/feature/relay/selftest.h index f3dd698bb7..f5babc95da 100644 --- a/src/feature/relay/selftest.h +++ b/src/feature/relay/selftest.h @@ -13,14 +13,18 @@ #define TOR_SELFTEST_H #ifdef HAVE_MODULE_RELAY + struct or_options_t; int check_whether_orport_reachable(const struct or_options_t *options); int check_whether_dirport_reachable(const struct or_options_t *options); void router_do_reachability_checks(int test_or, int test_dir); +void router_perform_bandwidth_test(int num_circs, time_t now); +int inform_testing_reachability(void); + void router_orport_found_reachable(void); void router_dirport_found_reachable(void); -void router_perform_bandwidth_test(int num_circs, time_t now); + void router_reset_reachability(void); #else /* !defined(HAVE_MODULE_RELAY) */ @@ -30,13 +34,6 @@ void router_reset_reachability(void); #define check_whether_dirport_reachable(opts) \ ((void)(opts), 0) -#define router_orport_found_reachable() \ - STMT_NIL -#define router_dirport_found_reachable() \ - STMT_NIL -#define router_reset_reachability() \ - STMT_NIL - static inline void router_do_reachability_checks(int test_or, int test_dir) { @@ -51,6 +48,20 @@ router_perform_bandwidth_test(int num_circs, time_t now) (void)now; tor_assert_nonfatal_unreached(); } +static inline int +inform_testing_reachability(void) +{ + tor_assert_nonfatal_unreached(); + return 0; +} + +#define router_orport_found_reachable() \ + STMT_NIL +#define router_dirport_found_reachable() \ + STMT_NIL + +#define router_reset_reachability() \ + STMT_NIL #endif /* defined(HAVE_MODULE_RELAY) */ |