From 56e33f73f13110fe5eb255bf260a11c8a54d4267 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 30 Jun 2020 15:11:54 -0400 Subject: [PATCH 01/10] Light edits to extend_info_t docs --- src/core/or/extend_info_st.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/or/extend_info_st.h b/src/core/or/extend_info_st.h index a66ce24cfa..7f1187cb83 100644 --- a/src/core/or/extend_info_st.h +++ b/src/core/or/extend_info_st.h @@ -17,7 +17,7 @@ /** Information on router used when extending a circuit. We don't need a * full routerinfo_t to extend: we only need addr:port:keyid to build an OR - * connection, and onion_key to create the onionskin. Note that for onehop + * connection, and onion_key to create the onionskin. Note that for one-hop * general-purpose tunnels, the onion_key is NULL. */ struct extend_info_t { char nickname[MAX_HEX_NICKNAME_LEN+1]; /**< This router's nickname for @@ -28,7 +28,9 @@ struct extend_info_t { ed25519_public_key_t ed_identity; uint16_t port; /**< OR port. */ tor_addr_t addr; /**< IP address. */ - crypto_pk_t *onion_key; /**< Current onionskin key. */ + /** TAP onion key for this hop. */ + crypto_pk_t *onion_key; + /** Ntor onion key for this hop. */ curve25519_public_key_t curve25519_onion_key; }; From 8f362b7bce5ebbba5c8d79cf10c5ec42bbde1519 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 30 Jun 2020 15:31:51 -0400 Subject: [PATCH 02/10] Extract extend_info manipulation functions into a new file. --- scripts/maint/practracker/exceptions.txt | 1 + src/core/crypto/onion_crypto.c | 2 +- src/core/or/circuitbuild.c | 187 +------------------- src/core/or/circuitbuild.h | 15 -- src/core/or/circuitlist.c | 1 + src/core/or/circuituse.c | 1 + src/core/or/crypt_path.c | 2 +- src/core/or/extendinfo.c | 209 +++++++++++++++++++++++ src/core/or/extendinfo.h | 31 ++++ src/core/or/include.am | 2 + src/core/or/relay.c | 1 + src/feature/control/control_cmd.c | 1 + src/feature/hs/hs_circuit.c | 1 + src/feature/hs/hs_client.c | 1 + src/feature/hs/hs_common.c | 1 + src/feature/hs/hs_service.c | 1 + src/feature/relay/circuitbuild_relay.c | 1 + src/feature/relay/selftest.c | 1 + src/feature/rend/rendclient.c | 1 + src/feature/rend/rendcommon.c | 1 + src/feature/rend/rendservice.c | 1 + src/test/test_circuitpadding.c | 1 + src/test/test_hs_client.c | 1 + src/test/test_policy.c | 1 + 24 files changed, 262 insertions(+), 203 deletions(-) create mode 100644 src/core/or/extendinfo.c create mode 100644 src/core/or/extendinfo.h diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt index a5b3ca7242..7c8a17001e 100644 --- a/scripts/maint/practracker/exceptions.txt +++ b/scripts/maint/practracker/exceptions.txt @@ -145,6 +145,7 @@ problem function-size /src/core/or/connection_or.c:connection_or_group_set_badne problem function-size /src/core/or/connection_or.c:connection_or_client_learned_peer_id() 142 problem dependency-violation /src/core/or/connection_or.c 21 problem dependency-violation /src/core/or/dos.c 6 +problem dependency-violation /src/core/or/extendinfo.c 6 problem dependency-violation /src/core/or/onion.c 2 problem file-size /src/core/or/or.h 1150 problem include-count /src/core/or/or.h 48 diff --git a/src/core/crypto/onion_crypto.c b/src/core/crypto/onion_crypto.c index 69b4dc40aa..1f34be1cc1 100644 --- a/src/core/crypto/onion_crypto.c +++ b/src/core/crypto/onion_crypto.c @@ -31,7 +31,7 @@ **/ #include "core/or/or.h" -#include "core/or/circuitbuild.h" +#include "core/or/extendinfo.h" #include "core/crypto/onion_crypto.h" #include "core/crypto/onion_fast.h" #include "core/crypto/onion_ntor.h" diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index e971fb0865..1f9b5050ef 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -45,6 +45,7 @@ #include "core/or/command.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" +#include "core/or/extendinfo.h" #include "core/or/onion.h" #include "core/or/ocirc_event.h" #include "core/or/policies.h" @@ -78,9 +79,6 @@ #include "feature/nodelist/node_st.h" #include "core/or/or_circuit_st.h" #include "core/or/origin_circuit_st.h" -#include "feature/nodelist/microdesc_st.h" -#include "feature/nodelist/routerinfo_st.h" -#include "feature/nodelist/routerstatus_st.h" static int circuit_send_first_onion_skin(origin_circuit_t *circ); static int circuit_build_no_more_hops(origin_circuit_t *circ); @@ -2462,143 +2460,6 @@ onion_extend_cpath(origin_circuit_t *circ) return 0; } -/** Allocate a new extend_info object based on the various arguments. */ -extend_info_t * -extend_info_new(const char *nickname, - const char *rsa_id_digest, - const ed25519_public_key_t *ed_id, - crypto_pk_t *onion_key, - const curve25519_public_key_t *ntor_key, - const tor_addr_t *addr, uint16_t port) -{ - extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t)); - memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN); - if (ed_id && !ed25519_public_key_is_zero(ed_id)) - memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t)); - if (nickname) - strlcpy(info->nickname, nickname, sizeof(info->nickname)); - if (onion_key) - info->onion_key = crypto_pk_dup_key(onion_key); - if (ntor_key) - memcpy(&info->curve25519_onion_key, ntor_key, - sizeof(curve25519_public_key_t)); - tor_addr_copy(&info->addr, addr); - info->port = port; - return info; -} - -/** Allocate and return a new extend_info that can be used to build a - * circuit to or through the node node. Use the primary address - * of the node (i.e. its IPv4 address) unless - * for_direct_connect is true, in which case the preferred - * address is used instead. May return NULL if there is not enough - * info about node to extend to it--for example, if the preferred - * routerinfo_t or microdesc_t is missing, or if for_direct_connect is - * true and none of the node's addresses is allowed by tor's firewall - * and IP version config. - **/ -extend_info_t * -extend_info_from_node(const node_t *node, int for_direct_connect) -{ - crypto_pk_t *rsa_pubkey = NULL; - extend_info_t *info = NULL; - tor_addr_port_t ap; - int valid_addr = 0; - - if (!node_has_preferred_descriptor(node, for_direct_connect)) { - return NULL; - } - - /* Choose a preferred address first, but fall back to an allowed address. */ - if (for_direct_connect) - fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap); - else { - node_get_prim_orport(node, &ap); - } - valid_addr = tor_addr_port_is_valid_ap(&ap, 0); - - if (valid_addr) - log_debug(LD_CIRC, "using %s for %s", - fmt_addrport(&ap.addr, ap.port), - node->ri ? node->ri->nickname : node->rs->nickname); - else - log_warn(LD_CIRC, "Could not choose valid address for %s", - node->ri ? node->ri->nickname : node->rs->nickname); - - /* Every node we connect or extend to must support ntor */ - if (!node_has_curve25519_onion_key(node)) { - log_fn(LOG_PROTOCOL_WARN, LD_CIRC, - "Attempted to create extend_info for a node that does not support " - "ntor: %s", node_describe(node)); - return NULL; - } - - const ed25519_public_key_t *ed_pubkey = NULL; - - /* Don't send the ed25519 pubkey unless the target node actually supports - * authenticating with it. */ - if (node_supports_ed25519_link_authentication(node, 0)) { - log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node)); - ed_pubkey = node_get_ed25519_id(node); - } else if (node_get_ed25519_id(node)) { - log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't " - "be able to authenticate it.", - node_describe(node)); - } - - /* Retrieve the curve25519 pubkey. */ - const curve25519_public_key_t *curve_pubkey = - node_get_curve25519_onion_key(node); - rsa_pubkey = node_get_rsa_onion_key(node); - - if (valid_addr && node->ri) { - info = extend_info_new(node->ri->nickname, - node->identity, - ed_pubkey, - rsa_pubkey, - curve_pubkey, - &ap.addr, - ap.port); - } else if (valid_addr && node->rs && node->md) { - info = extend_info_new(node->rs->nickname, - node->identity, - ed_pubkey, - rsa_pubkey, - curve_pubkey, - &ap.addr, - ap.port); - } - - crypto_pk_free(rsa_pubkey); - return info; -} - -/** Release storage held by an extend_info_t struct. */ -void -extend_info_free_(extend_info_t *info) -{ - if (!info) - return; - crypto_pk_free(info->onion_key); - tor_free(info); -} - -/** Allocate and return a new extend_info_t with the same contents as - * info. */ -extend_info_t * -extend_info_dup(extend_info_t *info) -{ - extend_info_t *newinfo; - tor_assert(info); - newinfo = tor_malloc(sizeof(extend_info_t)); - memcpy(newinfo, info, sizeof(extend_info_t)); - if (info->onion_key) - newinfo->onion_key = crypto_pk_dup_key(info->onion_key); - else - newinfo->onion_key = NULL; - return newinfo; -} - /** Return the node_t for the chosen exit router in state. * If there is no chosen exit, or if we don't know the node_t for * the chosen exit, return NULL. @@ -2634,43 +2495,6 @@ build_state_get_exit_nickname(cpath_build_state_t *state) return state->chosen_exit->nickname; } -/** Return true iff the given address can be used to extend to. */ -int -extend_info_addr_is_allowed(const tor_addr_t *addr) -{ - tor_assert(addr); - - /* Check if we have a private address and if we can extend to it. */ - if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) && - !get_options()->ExtendAllowPrivateAddresses) { - goto disallow; - } - /* Allowed! */ - return 1; - disallow: - return 0; -} - -/* Does ei have a valid TAP key? */ -int -extend_info_supports_tap(const extend_info_t* ei) -{ - tor_assert(ei); - /* Valid TAP keys are not NULL */ - return ei->onion_key != NULL; -} - -/* Does ei have a valid ntor key? */ -int -extend_info_supports_ntor(const extend_info_t* ei) -{ - tor_assert(ei); - /* Valid ntor keys have at least one non-zero byte */ - return !fast_mem_is_zero( - (const char*)ei->curve25519_onion_key.public_key, - CURVE25519_PUBKEY_LEN); -} - /* Is circuit purpose allowed to use the deprecated TAP encryption protocol? * The hidden service protocol still uses TAP for some connections, because * ntor onion keys aren't included in HS descriptors or INTRODUCE cells. */ @@ -2705,15 +2529,6 @@ circuit_has_usable_onion_key(const origin_circuit_t *circ) circuit_can_use_tap(circ)); } -/* Does ei have an onion key which it would prefer to use? - * Currently, we prefer ntor keys*/ -int -extend_info_has_preferred_onion_key(const extend_info_t* ei) -{ - tor_assert(ei); - return extend_info_supports_ntor(ei); -} - /** Find the circuits that are waiting to find out whether their guards are * usable, and if any are ready to become usable, mark them open and try * attaching streams as appropriate. */ diff --git a/src/core/or/circuitbuild.h b/src/core/or/circuitbuild.h index 565be09975..bbb78eada7 100644 --- a/src/core/or/circuitbuild.h +++ b/src/core/or/circuitbuild.h @@ -42,23 +42,8 @@ MOCK_DECL(int, circuit_all_predicted_ports_handled, (time_t now, int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *info); int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info); -extend_info_t *extend_info_new(const char *nickname, - const char *rsa_id_digest, - const struct ed25519_public_key_t *ed_id, - crypto_pk_t *onion_key, - const struct curve25519_public_key_t *ntor_key, - const tor_addr_t *addr, uint16_t port); -extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect); -extend_info_t *extend_info_dup(extend_info_t *info); -void extend_info_free_(extend_info_t *info); -#define extend_info_free(info) \ - FREE_AND_NULL(extend_info_t, extend_info_free_, (info)) -int extend_info_addr_is_allowed(const tor_addr_t *addr); -int extend_info_supports_tap(const extend_info_t* ei); -int extend_info_supports_ntor(const extend_info_t* ei); int circuit_can_use_tap(const origin_circuit_t *circ); int circuit_has_usable_onion_key(const origin_circuit_t *circ); -int extend_info_has_preferred_onion_key(const extend_info_t* ei); const uint8_t *build_state_get_exit_rsa_id(cpath_build_state_t *state); MOCK_DECL(const node_t *, build_state_get_exit_node,(cpath_build_state_t *state)); diff --git a/src/core/or/circuitlist.c b/src/core/or/circuitlist.c index a69b7cbbe5..f4d6cd3c12 100644 --- a/src/core/or/circuitlist.c +++ b/src/core/or/circuitlist.c @@ -64,6 +64,7 @@ #include "core/or/circuitstats.h" #include "core/or/circuitpadding.h" #include "core/or/crypt_path.h" +#include "core/or/extendinfo.h" #include "core/mainloop/connection.h" #include "app/config/config.h" #include "core/or/connection_edge.h" diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index f4cd4ced43..0704f8521e 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -37,6 +37,7 @@ #include "core/or/circuituse.h" #include "core/or/circuitpadding.h" #include "core/or/connection_edge.h" +#include "core/or/extendinfo.h" #include "core/or/policies.h" #include "feature/client/addressmap.h" #include "feature/client/bridges.h" diff --git a/src/core/or/crypt_path.c b/src/core/or/crypt_path.c index 8f41540848..e1bbd81251 100644 --- a/src/core/or/crypt_path.c +++ b/src/core/or/crypt_path.c @@ -30,6 +30,7 @@ #include "core/crypto/onion_crypto.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" +#include "core/or/extendinfo.h" #include "lib/crypt_ops/crypto_dh.h" #include "lib/crypt_ops/crypto_util.h" @@ -259,4 +260,3 @@ cpath_get_n_hops(crypt_path_t **head_ptr) } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c new file mode 100644 index 0000000000..74d4a54a33 --- /dev/null +++ b/src/core/or/extendinfo.c @@ -0,0 +1,209 @@ +/* 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 extendinfo.c + * @brief Functions for creating and using extend_info_t objects. + * + * An extend_info_t is the information we hold about a relay in order to + * extend a circuit to it. + **/ + +#include "core/or/or.h" +#include "core/or/extendinfo.h" + +#include "app/config/config.h" +#include "core/or/policies.h" +#include "feature/nodelist/describe.h" +#include "feature/nodelist/nodelist.h" + +#include "core/or/extend_info_st.h" +#include "feature/nodelist/node_st.h" +#include "feature/nodelist/routerinfo_st.h" +#include "feature/nodelist/routerstatus_st.h" + +/** Allocate a new extend_info object based on the various arguments. */ +extend_info_t * +extend_info_new(const char *nickname, + const char *rsa_id_digest, + const ed25519_public_key_t *ed_id, + crypto_pk_t *onion_key, + const curve25519_public_key_t *ntor_key, + const tor_addr_t *addr, uint16_t port) +{ + extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t)); + memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN); + if (ed_id && !ed25519_public_key_is_zero(ed_id)) + memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t)); + if (nickname) + strlcpy(info->nickname, nickname, sizeof(info->nickname)); + if (onion_key) + info->onion_key = crypto_pk_dup_key(onion_key); + if (ntor_key) + memcpy(&info->curve25519_onion_key, ntor_key, + sizeof(curve25519_public_key_t)); + tor_addr_copy(&info->addr, addr); + info->port = port; + return info; +} + +/** Allocate and return a new extend_info that can be used to build a + * circuit to or through the node node. Use the primary address + * of the node (i.e. its IPv4 address) unless + * for_direct_connect is true, in which case the preferred + * address is used instead. May return NULL if there is not enough + * info about node to extend to it--for example, if the preferred + * routerinfo_t or microdesc_t is missing, or if for_direct_connect is + * true and none of the node's addresses is allowed by tor's firewall + * and IP version config. + **/ +extend_info_t * +extend_info_from_node(const node_t *node, int for_direct_connect) +{ + crypto_pk_t *rsa_pubkey = NULL; + extend_info_t *info = NULL; + tor_addr_port_t ap; + int valid_addr = 0; + + if (!node_has_preferred_descriptor(node, for_direct_connect)) { + return NULL; + } + + /* Choose a preferred address first, but fall back to an allowed address. */ + if (for_direct_connect) + fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap); + else { + node_get_prim_orport(node, &ap); + } + valid_addr = tor_addr_port_is_valid_ap(&ap, 0); + + if (valid_addr) + log_debug(LD_CIRC, "using %s for %s", + fmt_addrport(&ap.addr, ap.port), + node->ri ? node->ri->nickname : node->rs->nickname); + else + log_warn(LD_CIRC, "Could not choose valid address for %s", + node->ri ? node->ri->nickname : node->rs->nickname); + + /* Every node we connect or extend to must support ntor */ + if (!node_has_curve25519_onion_key(node)) { + log_fn(LOG_PROTOCOL_WARN, LD_CIRC, + "Attempted to create extend_info for a node that does not support " + "ntor: %s", node_describe(node)); + return NULL; + } + + const ed25519_public_key_t *ed_pubkey = NULL; + + /* Don't send the ed25519 pubkey unless the target node actually supports + * authenticating with it. */ + if (node_supports_ed25519_link_authentication(node, 0)) { + log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node)); + ed_pubkey = node_get_ed25519_id(node); + } else if (node_get_ed25519_id(node)) { + log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't " + "be able to authenticate it.", + node_describe(node)); + } + + /* Retrieve the curve25519 pubkey. */ + const curve25519_public_key_t *curve_pubkey = + node_get_curve25519_onion_key(node); + rsa_pubkey = node_get_rsa_onion_key(node); + + if (valid_addr && node->ri) { + info = extend_info_new(node->ri->nickname, + node->identity, + ed_pubkey, + rsa_pubkey, + curve_pubkey, + &ap.addr, + ap.port); + } else if (valid_addr && node->rs && node->md) { + info = extend_info_new(node->rs->nickname, + node->identity, + ed_pubkey, + rsa_pubkey, + curve_pubkey, + &ap.addr, + ap.port); + } + + crypto_pk_free(rsa_pubkey); + return info; +} + +/** Release storage held by an extend_info_t struct. */ +void +extend_info_free_(extend_info_t *info) +{ + if (!info) + return; + crypto_pk_free(info->onion_key); + tor_free(info); +} + +/** Allocate and return a new extend_info_t with the same contents as + * info. */ +extend_info_t * +extend_info_dup(extend_info_t *info) +{ + extend_info_t *newinfo; + tor_assert(info); + newinfo = tor_malloc(sizeof(extend_info_t)); + memcpy(newinfo, info, sizeof(extend_info_t)); + if (info->onion_key) + newinfo->onion_key = crypto_pk_dup_key(info->onion_key); + else + newinfo->onion_key = NULL; + return newinfo; +} + +/* Does ei have a valid TAP key? */ +int +extend_info_supports_tap(const extend_info_t* ei) +{ + tor_assert(ei); + /* Valid TAP keys are not NULL */ + return ei->onion_key != NULL; +} + +/* Does ei have a valid ntor key? */ +int +extend_info_supports_ntor(const extend_info_t* ei) +{ + tor_assert(ei); + /* Valid ntor keys have at least one non-zero byte */ + return !fast_mem_is_zero( + (const char*)ei->curve25519_onion_key.public_key, + CURVE25519_PUBKEY_LEN); +} + +/* Does ei have an onion key which it would prefer to use? + * Currently, we prefer ntor keys*/ +int +extend_info_has_preferred_onion_key(const extend_info_t* ei) +{ + tor_assert(ei); + return extend_info_supports_ntor(ei); +} + +/** Return true iff the given address can be used to extend to. */ +int +extend_info_addr_is_allowed(const tor_addr_t *addr) +{ + tor_assert(addr); + + /* Check if we have a private address and if we can extend to it. */ + if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) && + !get_options()->ExtendAllowPrivateAddresses) { + goto disallow; + } + /* Allowed! */ + return 1; + disallow: + return 0; +} diff --git a/src/core/or/extendinfo.h b/src/core/or/extendinfo.h new file mode 100644 index 0000000000..1e542efe2a --- /dev/null +++ b/src/core/or/extendinfo.h @@ -0,0 +1,31 @@ +/* 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 extendinfo.h + * @brief Header for core/or/extendinfo.c + **/ + +#ifndef TOR_CORE_OR_EXTENDINFO_H +#define TOR_CORE_OR_EXTENDINFO_H + +extend_info_t *extend_info_new(const char *nickname, + const char *rsa_id_digest, + const struct ed25519_public_key_t *ed_id, + crypto_pk_t *onion_key, + const struct curve25519_public_key_t *ntor_key, + const tor_addr_t *addr, uint16_t port); +extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect); +extend_info_t *extend_info_dup(extend_info_t *info); +void extend_info_free_(extend_info_t *info); +#define extend_info_free(info) \ + FREE_AND_NULL(extend_info_t, extend_info_free_, (info)) +int extend_info_addr_is_allowed(const tor_addr_t *addr); +int extend_info_supports_tap(const extend_info_t* ei); +int extend_info_supports_ntor(const extend_info_t* ei); +int extend_info_has_preferred_onion_key(const extend_info_t* ei); + +#endif /* !defined(TOR_CORE_OR_EXTENDINFO_H) */ diff --git a/src/core/or/include.am b/src/core/or/include.am index 3626e76bed..af7c5a6f51 100644 --- a/src/core/or/include.am +++ b/src/core/or/include.am @@ -18,6 +18,7 @@ LIBTOR_APP_A_SOURCES += \ src/core/or/connection_edge.c \ src/core/or/connection_or.c \ src/core/or/dos.c \ + src/core/or/extendinfo.c \ src/core/or/onion.c \ src/core/or/ocirc_event.c \ src/core/or/or_periodic.c \ @@ -64,6 +65,7 @@ noinst_HEADERS += \ src/core/or/destroy_cell_queue_st.h \ src/core/or/dos.h \ src/core/or/edge_connection_st.h \ + src/core/or/extendinfo.h \ src/core/or/half_edge_st.h \ src/core/or/entry_connection_st.h \ src/core/or/entry_port_cfg_st.h \ diff --git a/src/core/or/relay.c b/src/core/or/relay.c index 75d2d479e7..6895591064 100644 --- a/src/core/or/relay.c +++ b/src/core/or/relay.c @@ -56,6 +56,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuituse.h" #include "core/or/circuitpadding.h" +#include "core/or/extendinfo.h" #include "lib/compress/compress.h" #include "app/config/config.h" #include "core/mainloop/connection.h" diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index a37f285d9e..a8926c0b79 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -21,6 +21,7 @@ #include "core/or/circuituse.h" #include "core/or/connection_edge.h" #include "core/or/circuitstats.h" +#include "core/or/extendinfo.h" #include "feature/client/addressmap.h" #include "feature/client/dnsserv.h" #include "feature/client/entrynodes.h" diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index 447f664f81..5e7a3ac9c8 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -16,6 +16,7 @@ #include "core/or/policies.h" #include "core/or/relay.h" #include "core/or/crypt_path.h" +#include "core/or/extendinfo.h" #include "feature/client/circpathbias.h" #include "feature/hs/hs_cell.h" #include "feature/hs/hs_circuit.h" diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index c3697d0c1d..9670ed44b3 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -16,6 +16,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuituse.h" #include "core/or/connection_edge.h" +#include "core/or/extendinfo.h" #include "core/or/reasons.h" #include "feature/client/circpathbias.h" #include "feature/dirclient/dirclient.h" diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index 4639cdb68a..706b42529f 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -16,6 +16,7 @@ #include "app/config/config.h" #include "core/or/circuitbuild.h" #include "core/or/policies.h" +#include "core/or/extendinfo.h" #include "feature/dirauth/shared_random_state.h" #include "feature/hs/hs_cache.h" #include "feature/hs/hs_circuitmap.h" diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index a42879a48f..249eb47b5d 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -16,6 +16,7 @@ #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" +#include "core/or/extendinfo.h" #include "core/or/relay.h" #include "feature/client/circpathbias.h" #include "feature/dirclient/dirclient.h" diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c index 470e639aa7..36e64d9b33 100644 --- a/src/feature/relay/circuitbuild_relay.c +++ b/src/feature/relay/circuitbuild_relay.c @@ -33,6 +33,7 @@ #include "core/or/channel.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" +#include "core/or/extendinfo.h" #include "core/or/onion.h" #include "core/or/relay.h" diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c index 101704e1c9..c663eb26b2 100644 --- a/src/feature/relay/selftest.c +++ b/src/feature/relay/selftest.c @@ -24,6 +24,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuituse.h" #include "core/or/crypt_path_st.h" +#include "core/or/extendinfo.h" #include "core/or/extend_info_st.h" #include "core/or/origin_circuit_st.h" #include "core/or/relay.h" diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index 09db7045fa..9c2286bbcf 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -15,6 +15,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuituse.h" #include "core/or/connection_edge.h" +#include "core/or/extendinfo.h" #include "core/or/relay.h" #include "feature/client/circpathbias.h" #include "feature/control/control_events.h" diff --git a/src/feature/rend/rendcommon.c b/src/feature/rend/rendcommon.c index 5d04755819..07cbeaa2f7 100644 --- a/src/feature/rend/rendcommon.c +++ b/src/feature/rend/rendcommon.c @@ -14,6 +14,7 @@ #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" +#include "core/or/extendinfo.h" #include "app/config/config.h" #include "feature/control/control_events.h" #include "lib/crypt_ops/crypto_rand.h" diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c index a88c2080fd..8154840f12 100644 --- a/src/feature/rend/rendservice.c +++ b/src/feature/rend/rendservice.c @@ -16,6 +16,7 @@ #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" +#include "core/or/extendinfo.h" #include "core/or/policies.h" #include "core/or/relay.h" #include "core/or/crypt_path.h" diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c index 3e3a59dc96..cc8c63d608 100644 --- a/src/test/test_circuitpadding.c +++ b/src/test/test_circuitpadding.c @@ -23,6 +23,7 @@ #include "core/or/circuitbuild.h" #include "core/or/circuitpadding.h" #include "core/or/circuitpadding_machines.h" +#include "core/or/extendinfo.h" #include "core/mainloop/netstatus.h" #include "core/crypto/relay_crypto.h" #include "core/or/protover.h" diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index ae5cc5ed84..3fef1b41c6 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -41,6 +41,7 @@ #include "feature/rend/rendcache.h" #include "core/or/circuitlist.h" #include "core/or/circuitbuild.h" +#include "core/or/extendinfo.h" #include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "feature/nodelist/networkstatus.h" diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 7949e90e9e..6cb588a0eb 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -8,6 +8,7 @@ #include "app/config/config.h" #include "core/or/circuitbuild.h" #include "core/or/policies.h" +#include "core/or/extendinfo.h" #include "feature/dirparse/policy_parse.h" #include "feature/hs/hs_common.h" #include "feature/hs/hs_descriptor.h" From 81d312f12c196a87f6fb0a4ba7c445afe95b6d4a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 30 Jun 2020 15:45:02 -0400 Subject: [PATCH 03/10] Add a function for comparing the orport on an extendinfo. --- src/core/or/channeltls.c | 8 ++++---- src/core/or/circuituse.c | 4 ++-- src/core/or/connection_edge.c | 5 +++-- src/core/or/extendinfo.c | 13 +++++++++++++ src/core/or/extendinfo.h | 2 ++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index f9937ce880..a51fbf1dd6 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -63,10 +63,10 @@ #include "trunnel/channelpadding_negotiation.h" #include "trunnel/netinfo.h" #include "core/or/channelpadding.h" +#include "core/or/extendinfo.h" #include "core/or/cell_st.h" #include "core/or/cell_queue_st.h" -#include "core/or/extend_info_st.h" #include "core/or/or_connection_st.h" #include "core/or/or_handshake_certs_st.h" #include "core/or/or_handshake_state_st.h" @@ -702,9 +702,9 @@ channel_tls_matches_extend_info_method(channel_t *chan, return 0; } - return (tor_addr_eq(&(extend_info->addr), - &(TO_CONN(tlschan->conn)->addr)) && - (extend_info->port == TO_CONN(tlschan->conn)->port)); + return extend_info_has_orport(extend_info, + &TO_CONN(tlschan->conn)->addr, + TO_CONN(tlschan->conn)->port); } /** diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index 0704f8521e..6ff308dae2 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -203,8 +203,8 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ, const int family = tor_addr_parse(&addr, conn->socks_request->address); if (family < 0 || - !tor_addr_eq(&build_state->chosen_exit->addr, &addr) || - build_state->chosen_exit->port != conn->socks_request->port) + !extend_info_has_orport(build_state->chosen_exit, &addr, + conn->socks_request->port)) return 0; } } diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index fc77db8334..2826a99249 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -70,6 +70,7 @@ #include "core/or/circuitpadding.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" +#include "core/or/extendinfo.h" #include "core/or/policies.h" #include "core/or/reasons.h" #include "core/or/relay.h" @@ -1444,8 +1445,8 @@ connection_ap_fail_onehop(const char *failed_digest, continue; } if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 || - !tor_addr_eq(&build_state->chosen_exit->addr, &addr) || - build_state->chosen_exit->port != entry_conn->socks_request->port) + !extend_info_has_orport(build_state->chosen_exit, &addr, + entry_conn->socks_request->port)) continue; } log_info(LD_APP, "Closing one-hop stream to '%s/%s' because the OR conn " diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c index 74d4a54a33..874a0a58f8 100644 --- a/src/core/or/extendinfo.c +++ b/src/core/or/extendinfo.c @@ -207,3 +207,16 @@ extend_info_addr_is_allowed(const tor_addr_t *addr) disallow: return 0; } + +/** + * Return true if @a addr : @a port is a listed ORPort in @a ei. + **/ +bool +extend_info_has_orport(const extend_info_t *ei, + const tor_addr_t *addr, uint16_t port) +{ + IF_BUG_ONCE(ei == NULL) + return false; + + return tor_addr_eq(&ei->addr, addr) && ei->port == port; +} diff --git a/src/core/or/extendinfo.h b/src/core/or/extendinfo.h index 1e542efe2a..6ebacccf1a 100644 --- a/src/core/or/extendinfo.h +++ b/src/core/or/extendinfo.h @@ -27,5 +27,7 @@ int extend_info_addr_is_allowed(const tor_addr_t *addr); int extend_info_supports_tap(const extend_info_t* ei); int extend_info_supports_ntor(const extend_info_t* ei); int extend_info_has_preferred_onion_key(const extend_info_t* ei); +bool extend_info_has_orport(const extend_info_t *ei, + const tor_addr_t *addr, uint16_t port); #endif /* !defined(TOR_CORE_OR_EXTENDINFO_H) */ From ad71303f5f07972ca7576a500e4ac6f6bffbd853 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 30 Jun 2020 16:04:20 -0400 Subject: [PATCH 04/10] Remove an untrue comment in extend_cell_t --- src/core/or/onion.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/or/onion.h b/src/core/or/onion.h index 256f0a3f31..600e67c3cd 100644 --- a/src/core/or/onion.h +++ b/src/core/or/onion.h @@ -48,8 +48,7 @@ typedef struct extend_cell_t { uint8_t cell_type; /** An IPv4 address and port for the node we're connecting to. */ tor_addr_port_t orport_ipv4; - /** An IPv6 address and port for the node we're connecting to. Not currently - * used. */ + /** An IPv6 address and port for the node we're connecting to. */ tor_addr_port_t orport_ipv6; /** Identity fingerprint of the node we're conecting to.*/ uint8_t node_id[DIGEST_LEN]; From 6a0b9e47462d7c0bcb4598343cc7d6e7689216d7 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 1 Jul 2020 14:20:17 -0400 Subject: [PATCH 05/10] Allow null ID argument to extend_info_new. --- src/core/or/extendinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c index 874a0a58f8..8f506d774c 100644 --- a/src/core/or/extendinfo.c +++ b/src/core/or/extendinfo.c @@ -35,7 +35,8 @@ extend_info_new(const char *nickname, const tor_addr_t *addr, uint16_t port) { extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t)); - memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN); + if (rsa_id_digest) + memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN); if (ed_id && !ed25519_public_key_is_zero(ed_id)) memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t)); if (nickname) From 1e97f968882f12edad20874ada99c2bd8542119d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 1 Jul 2020 14:42:55 -0400 Subject: [PATCH 06/10] Refactor channel_connect_for_circuit() to take an extend_info_t. --- src/core/or/circuitbuild.c | 15 +++++++-------- src/core/or/circuitbuild.h | 8 +------- src/feature/relay/circuitbuild_relay.c | 6 +----- src/test/test_circuitbuild.c | 10 ++-------- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index 1f9b5050ef..d1f097c25a 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -94,12 +94,15 @@ static const node_t *choose_good_middle_server(uint8_t purpose, * callbacks. */ MOCK_IMPL(channel_t *, -channel_connect_for_circuit,(const tor_addr_t *addr, uint16_t port, - const char *id_digest, - const struct ed25519_public_key_t *ed_id)) +channel_connect_for_circuit,(const extend_info_t *ei)) { channel_t *chan; + const tor_addr_t *addr = &ei->addr; + uint16_t port = ei->port; + const char *id_digest = ei->identity_digest; + const ed25519_public_key_t *ed_id = &ei->ed_identity; + chan = channel_connect(addr, port, id_digest, ed_id); if (chan) command_setup_channel(chan); @@ -581,11 +584,7 @@ circuit_handle_first_hop(origin_circuit_t *circ) circ->base_.n_hop = extend_info_dup(firsthop->extend_info); if (should_launch) { - n_chan = channel_connect_for_circuit( - &firsthop->extend_info->addr, - firsthop->extend_info->port, - firsthop->extend_info->identity_digest, - &firsthop->extend_info->ed_identity); + n_chan = channel_connect_for_circuit(firsthop->extend_info); if (!n_chan) { /* connect failed, forget the whole thing */ log_info(LD_CIRC,"connect to firsthop failed. Closing."); return -END_CIRC_REASON_CONNECTFAILED; diff --git a/src/core/or/circuitbuild.h b/src/core/or/circuitbuild.h index bbb78eada7..0cd1eb4f45 100644 --- a/src/core/or/circuitbuild.h +++ b/src/core/or/circuitbuild.h @@ -56,13 +56,7 @@ const node_t *choose_good_entry_server(uint8_t purpose, struct circuit_guard_state_t **guard_state_out); void circuit_upgrade_circuits_from_guard_wait(void); -struct ed25519_public_key_t; - -MOCK_DECL(channel_t *, -channel_connect_for_circuit,(const tor_addr_t *addr, - uint16_t port, - const char *id_digest, - const struct ed25519_public_key_t *ed_id)); +MOCK_DECL(channel_t *, channel_connect_for_circuit,(const extend_info_t *ei)); struct create_cell_t; MOCK_DECL(int, diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c index 36e64d9b33..881cbd51be 100644 --- a/src/feature/relay/circuitbuild_relay.c +++ b/src/feature/relay/circuitbuild_relay.c @@ -401,11 +401,7 @@ circuit_open_connection_for_extend(const struct extend_cell_t *ec, if (should_launch) { /* we should try to open a connection */ - channel_t *n_chan = channel_connect_for_circuit( - &circ->n_hop->addr, - circ->n_hop->port, - circ->n_hop->identity_digest, - &circ->n_hop->ed_identity); + channel_t *n_chan = channel_connect_for_circuit(circ->n_hop); if (!n_chan) { log_info(LD_CIRC,"Launching n_chan failed. Closing circuit."); circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED); diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c index e1fbd333d7..f7a27146b0 100644 --- a/src/test/test_circuitbuild.c +++ b/src/test/test_circuitbuild.c @@ -1001,15 +1001,9 @@ mock_circuit_mark_for_close_(circuit_t *circ, int reason, static int mock_channel_connect_calls = 0; static channel_t *mock_channel_connect_nchan = NULL; static channel_t * -mock_channel_connect_for_circuit(const tor_addr_t *addr, - uint16_t port, - const char *id_digest, - const struct ed25519_public_key_t *ed_id) +mock_channel_connect_for_circuit(const extend_info_t *ei) { - (void)addr; - (void)port; - (void)id_digest; - (void)ed_id; + (void)ei; mock_channel_connect_calls++; return mock_channel_connect_nchan; } From cca3164f8d22492c40276ebda670836f93dab536 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 1 Jul 2020 15:53:48 -0400 Subject: [PATCH 07/10] Add a convenience function to check for unspec address. --- src/lib/net/address.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib/net/address.h b/src/lib/net/address.h index 5ab654ef1d..6b18919f6d 100644 --- a/src/lib/net/address.h +++ b/src/lib/net/address.h @@ -95,6 +95,7 @@ static inline uint32_t tor_addr_to_ipv4n(const tor_addr_t *a); static inline uint32_t tor_addr_to_ipv4h(const tor_addr_t *a); static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a); static inline sa_family_t tor_addr_family(const tor_addr_t *a); +static inline bool tor_addr_is_unspec(const tor_addr_t *a); static inline const struct in_addr *tor_addr_to_in(const tor_addr_t *a); static inline int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u); @@ -188,6 +189,15 @@ tor_addr_family(const tor_addr_t *a) return a->family; } +/** + * Return true if the address @a is in the UNSPEC family. + **/ +static inline bool +tor_addr_is_unspec(const tor_addr_t *a) +{ + return a->family == AF_UNSPEC; +} + /** Return an in_addr* equivalent to a, or NULL if a is not * an IPv4 address. */ static inline const struct in_addr * From e93ad428e2507f676ce97450b919c2d849633669 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 30 Jun 2020 16:06:05 -0400 Subject: [PATCH 08/10] Allow multiple addresses in extend_info_t. In practice, there will be at most one ipv4 address and ipv6 address for now, but this code is designed to not care which address is which until forced to do so. This patch does not yet actually create extend_info_t objects with multiple addresses. Closes #34069. --- src/core/or/circuitbuild.c | 79 +++++++++++++++-------------- src/core/or/extend_info_st.h | 10 +++- src/core/or/extendinfo.c | 86 ++++++++++++++++++++++++++++++-- src/core/or/extendinfo.h | 7 +++ src/feature/client/bridges.c | 17 ++++++- src/feature/nodelist/describe.c | 10 +++- src/feature/nodelist/routerset.c | 19 ++++--- src/feature/relay/selftest.c | 5 +- src/feature/rend/rendclient.c | 10 +++- src/feature/rend/rendcommon.c | 9 +++- src/feature/rend/rendparse.c | 17 +++++-- src/feature/rend/rendservice.c | 16 ++++-- src/test/rend_test_helpers.c | 13 +++-- src/test/test.c | 21 +++++--- src/test/test_circuitbuild.c | 10 ++-- src/test/test_hs_client.c | 5 +- src/test/test_nodelist.c | 4 +- src/test/test_policy.c | 4 +- 18 files changed, 250 insertions(+), 92 deletions(-) diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index d1f097c25a..59ae58b98d 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -98,12 +98,13 @@ channel_connect_for_circuit,(const extend_info_t *ei)) { channel_t *chan; - const tor_addr_t *addr = &ei->addr; - uint16_t port = ei->port; + const tor_addr_port_t *orport = extend_info_pick_orport(ei); + if (!orport) + return NULL; const char *id_digest = ei->identity_digest; const ed25519_public_key_t *ed_id = &ei->ed_identity; - chan = channel_connect(addr, port, id_digest, ed_id); + chan = channel_connect(&orport->addr, orport->port, id_digest, ed_id); if (chan) command_setup_channel(chan); return chan; @@ -551,7 +552,7 @@ circuit_handle_first_hop(origin_circuit_t *circ) * - the address is internal, and * - we're not connecting to a configured bridge, and * - we're not configured to allow extends to private addresses. */ - if (tor_addr_is_internal(&firsthop->extend_info->addr, 0) && + if (extend_info_any_orport_addr_is_internal(firsthop->extend_info) && !extend_info_is_a_configured_bridge(firsthop->extend_info) && !options->ExtendAllowPrivateAddresses) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, @@ -560,19 +561,19 @@ circuit_handle_first_hop(origin_circuit_t *circ) } /* now see if we're already connected to the first OR in 'route' */ - log_debug(LD_CIRC,"Looking for firsthop '%s'", - fmt_addrport(&firsthop->extend_info->addr, - firsthop->extend_info->port)); + // TODO XXXX S55 -- remove this log + log_debug(LD_CIRC,"Looking for firsthop for %s", + extend_info_describe(firsthop->extend_info)); - /* We'll cleanup this code in #33220, when we add an IPv6 address to - * extend_info_t. */ - const bool addr_is_ipv4 = - (tor_addr_family(&firsthop->extend_info->addr) == AF_INET); + const tor_addr_port_t *orport4 = + extend_info_get_orport(firsthop->extend_info, AF_INET); + const tor_addr_port_t *orport6 = + extend_info_get_orport(firsthop->extend_info, AF_INET6); n_chan = channel_get_for_extend( firsthop->extend_info->identity_digest, &firsthop->extend_info->ed_identity, - addr_is_ipv4 ? &firsthop->extend_info->addr : NULL, - addr_is_ipv4 ? NULL : &firsthop->extend_info->addr, + orport4 ? &orport4->addr : NULL, + orport6 ? &orport6->addr : NULL, &msg, &should_launch); @@ -1075,42 +1076,40 @@ circuit_send_intermediate_onion_skin(origin_circuit_t *circ, crypt_path_t *hop) { int len; - int family = tor_addr_family(&hop->extend_info->addr); extend_cell_t ec; - memset(&ec, 0, sizeof(ec)); - - log_debug(LD_CIRC,"starting to send subsequent skin."); - /* Relays and bridges can send IPv6 extends. But for clients, it's an * obvious version distinguisher. */ - if (server_mode(get_options())) { - if (family != AF_INET && family != AF_INET6) { - log_warn(LD_BUG, "Server trying to extend to an invalid address " - "family."); - return - END_CIRC_REASON_INTERNAL; - } - } else { - if (family != AF_INET) { - log_warn(LD_BUG, "Client trying to extend to a non-IPv4 address."); - return - END_CIRC_REASON_INTERNAL; - } - } + const bool include_ipv6 = server_mode(get_options()); + memset(&ec, 0, sizeof(ec)); + tor_addr_make_unspec(&ec.orport_ipv4.addr); + tor_addr_make_unspec(&ec.orport_ipv6.addr); + + log_debug(LD_CIRC,"starting to send subsequent skin."); circuit_pick_extend_handshake(&ec.cell_type, &ec.create_cell.cell_type, &ec.create_cell.handshake_type, hop->extend_info); - /* At the moment, extend_info only has one ORPort address. We'll add a - * second address in #34069, to support dual-stack extend cells. */ - if (family == AF_INET) { - tor_addr_copy(&ec.orport_ipv4.addr, &hop->extend_info->addr); - ec.orport_ipv4.port = hop->extend_info->port; - tor_addr_make_unspec(&ec.orport_ipv6.addr); - } else { - tor_addr_copy(&ec.orport_ipv6.addr, &hop->extend_info->addr); - ec.orport_ipv6.port = hop->extend_info->port; - tor_addr_make_unspec(&ec.orport_ipv4.addr); + const tor_addr_port_t *orport4 = + extend_info_get_orport(hop->extend_info, AF_INET); + const tor_addr_port_t *orport6 = + extend_info_get_orport(hop->extend_info, AF_INET6); + int n_addrs_set = 0; + if (orport4) { + tor_addr_copy(&ec.orport_ipv4.addr, &orport4->addr); + ec.orport_ipv4.port = orport4->port; + ++n_addrs_set; + } + if (orport6 && include_ipv6) { + tor_addr_copy(&ec.orport_ipv6.addr, &orport6->addr); + ec.orport_ipv6.port = orport6->port; + ++n_addrs_set; + } + + if (n_addrs_set == 0) { + log_warn(LD_BUG, "No supported address family found in extend_info."); + return - END_CIRC_REASON_INTERNAL; } memcpy(ec.node_id, hop->extend_info->identity_digest, DIGEST_LEN); /* Set the ED25519 identity too -- it will only get included diff --git a/src/core/or/extend_info_st.h b/src/core/or/extend_info_st.h index 7f1187cb83..757c6a1771 100644 --- a/src/core/or/extend_info_st.h +++ b/src/core/or/extend_info_st.h @@ -15,6 +15,11 @@ #include "lib/crypt_ops/crypto_curve25519.h" #include "lib/crypt_ops/crypto_ed25519.h" +/** Largest number of addresses we handle in an extend_info. + * + * More are permitted in an EXTEND cell, but we won't handle them. */ +#define EXTEND_INFO_MAX_ADDRS 2 + /** Information on router used when extending a circuit. We don't need a * full routerinfo_t to extend: we only need addr:port:keyid to build an OR * connection, and onion_key to create the onionskin. Note that for one-hop @@ -26,8 +31,9 @@ struct extend_info_t { char identity_digest[DIGEST_LEN]; /** Ed25519 identity for this router, if any. */ ed25519_public_key_t ed_identity; - uint16_t port; /**< OR port. */ - tor_addr_t addr; /**< IP address. */ + /** IP/Port values for this hop's ORPort(s). Any unused values are set + * to a null address. */ + tor_addr_port_t orports[EXTEND_INFO_MAX_ADDRS]; /** TAP onion key for this hop. */ crypto_pk_t *onion_key; /** Ntor onion key for this hop. */ diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c index 8f506d774c..e4aec634a5 100644 --- a/src/core/or/extendinfo.c +++ b/src/core/or/extendinfo.c @@ -46,11 +46,35 @@ extend_info_new(const char *nickname, if (ntor_key) memcpy(&info->curve25519_onion_key, ntor_key, sizeof(curve25519_public_key_t)); - tor_addr_copy(&info->addr, addr); - info->port = port; + for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { + tor_addr_make_unspec(&info->orports[i].addr); + } + + if (addr) { + extend_info_add_orport(info, addr, port); + } return info; } +/** + * Add another address:port pair to a given extend_info_t, if there is + * room. Return 0 on success, -1 on failure. + **/ +int +extend_info_add_orport(extend_info_t *ei, + const tor_addr_t *addr, + uint16_t port) +{ + for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { + if (tor_addr_is_unspec(&ei->orports[i].addr)) { + tor_addr_copy(&ei->orports[i].addr, addr); + ei->orports[i].port = port; + return 0; + } + } + return -1; +} + /** Allocate and return a new extend_info that can be used to build a * circuit to or through the node node. Use the primary address * of the node (i.e. its IPv4 address) unless @@ -219,5 +243,61 @@ extend_info_has_orport(const extend_info_t *ei, IF_BUG_ONCE(ei == NULL) return false; - return tor_addr_eq(&ei->addr, addr) && ei->port == port; + for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { + const tor_addr_port_t *ei_ap = &ei->orports[i]; + if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port) + return true; + } + return false; +} + +/** + * If the extend_info @a ei has an orport of the chosen family, then return + * that orport. Otherwise, return NULL. + **/ +const tor_addr_port_t * +extend_info_get_orport(const extend_info_t *ei, int family) +{ + for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { + if (tor_addr_is_unspec(&ei->orports[i].addr)) + continue; + if (tor_addr_family(&ei->orports[i].addr) == family) + return &ei->orports[i]; + } + return NULL; +} + +/** + * Chose an addr_port_t within @a ei to connect to. + **/ +const tor_addr_port_t * +extend_info_pick_orport(const extend_info_t *ei) +{ + // XXXX S55 -- for now, we just pick the first. We'll work on + // XXXX more choices as we move forward. + IF_BUG_ONCE(!ei) { + return NULL; + } + + if (tor_addr_is_unspec(&ei->orports[0].addr)) { + return NULL; + } + return &ei->orports[0]; +} + +/** + * Return true if any orport address in @a ei is an internal address. + **/ +bool +extend_info_any_orport_addr_is_internal(const extend_info_t *ei) +{ + IF_BUG_ONCE(ei == NULL) + return false; + + for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { + if (! tor_addr_is_unspec(&ei->orports[i].addr) && + tor_addr_is_internal(&ei->orports[i].addr, 0)) + return true; + } + return false; } diff --git a/src/core/or/extendinfo.h b/src/core/or/extendinfo.h index 6ebacccf1a..0049dd0189 100644 --- a/src/core/or/extendinfo.h +++ b/src/core/or/extendinfo.h @@ -29,5 +29,12 @@ int extend_info_supports_ntor(const extend_info_t* ei); int extend_info_has_preferred_onion_key(const extend_info_t* ei); bool extend_info_has_orport(const extend_info_t *ei, const tor_addr_t *addr, uint16_t port); +int extend_info_add_orport(extend_info_t *ei, + const tor_addr_t *addr, + uint16_t port); +const tor_addr_port_t *extend_info_get_orport(const extend_info_t *ei, + int family); +const tor_addr_port_t *extend_info_pick_orport(const extend_info_t *ei); +bool extend_info_any_orport_addr_is_internal(const extend_info_t *ei); #endif /* !defined(TOR_CORE_OR_EXTENDINFO_H) */ diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c index 66b04f3bc2..3a3d1bb681 100644 --- a/src/feature/client/bridges.c +++ b/src/feature/client/bridges.c @@ -259,12 +259,25 @@ addr_is_a_configured_bridge(const tor_addr_t *addr, /** If we have a bridge configured whose digest matches * ei->identity_digest, or a bridge with no known digest whose address * matches ei->addr:ei->port, return 1. Else return 0. - * If ei->onion_key is NULL, check for address/port matches only. */ + * If ei->onion_key is NULL, check for address/port matches only. + * + * Note that if the extend_info_t contains multiple addresses, we return true + * only if _every_ address is a bridge. + */ int extend_info_is_a_configured_bridge(const extend_info_t *ei) { const char *digest = ei->onion_key ? ei->identity_digest : NULL; - return addr_is_a_configured_bridge(&ei->addr, ei->port, digest); + const tor_addr_port_t *ap1 = NULL, *ap2 = NULL; + if (! tor_addr_is_null(&ei->orports[0].addr)) + ap1 = &ei->orports[0]; + if (! tor_addr_is_null(&ei->orports[1].addr)) + ap2 = &ei->orports[1]; + IF_BUG_ONCE(ap1 == NULL) + return 0; + return addr_is_a_configured_bridge(&ap1->addr, ap1->port, digest) && + (ap2 == NULL || + addr_is_a_configured_bridge(&ap2->addr, ap2->port, digest)); } /** Wrapper around get_configured_bridge_by_addr_port_digest() to look diff --git a/src/feature/nodelist/describe.c b/src/feature/nodelist/describe.c index 00896d5a44..f118436499 100644 --- a/src/feature/nodelist/describe.c +++ b/src/feature/nodelist/describe.c @@ -12,6 +12,7 @@ #define DESCRIBE_PRIVATE #include "core/or/or.h" +#include "core/or/extendinfo.h" #include "feature/nodelist/describe.h" #include "core/or/extend_info_st.h" @@ -208,11 +209,16 @@ extend_info_describe(const extend_info_t *ei) if (!ei) return ""; + const tor_addr_port_t *ap4 = extend_info_get_orport(ei, AF_INET); + const tor_addr_port_t *ap6 = extend_info_get_orport(ei, AF_INET6); + uint32_t addr4 = ap4 ? tor_addr_to_ipv4h(&ap4->addr) : 0; + const tor_addr_t *addr6 = ap6 ? &ap6->addr : NULL; + return format_node_description(buf, ei->identity_digest, ei->nickname, - &ei->addr, - 0); + addr6, + addr4); } /** Set buf (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c index ebc08b7a51..cba7203d44 100644 --- a/src/feature/nodelist/routerset.c +++ b/src/feature/nodelist/routerset.c @@ -306,12 +306,19 @@ routerset_add_unknown_ccs(routerset_t **setp, int only_if_some_cc_set) int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei) { - return routerset_contains(set, - &ei->addr, - ei->port, - ei->nickname, - ei->identity_digest, - -1 /*country*/); + const tor_addr_port_t *ap1 = NULL, *ap2 = NULL; + if (! tor_addr_is_null(&ei->orports[0].addr)) + ap1 = &ei->orports[0]; + if (! tor_addr_is_null(&ei->orports[1].addr)) + ap2 = &ei->orports[1]; + return routerset_contains2(set, + ap1 ? &ap1->addr : NULL, + ap1 ? ap1->port : 0, + ap2 ? &ap2->addr : NULL, + ap2 ? ap2->port : 0, + ei->nickname, + ei->identity_digest, + -1 /*country*/); } /** Return true iff ri is in set. If country is -1, we diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c index c663eb26b2..77c04abdd7 100644 --- a/src/feature/relay/selftest.c +++ b/src/feature/relay/selftest.c @@ -256,14 +256,15 @@ router_do_orport_reachability_checks(const routerinfo_t *me, * be NULL. */ if (ei) { const char *family_name = fmt_af_family(family); + const tor_addr_port_t *ap = extend_info_get_orport(ei, family); log_info(LD_CIRC, "Testing %s of my %s ORPort: %s.", !orport_reachable ? "reachability" : "bandwidth", - family_name, fmt_addrport(&ei->addr, ei->port)); + family_name, fmt_addrport_ap(ap)); if (!orport_reachable) { /* This is only a 'reachability test' if we don't already think that * the port is reachable. If we _do_ think it's reachable, then * it counts as a 'bandwidth test'. */ - inform_testing_reachability(&ei->addr, ei->port, false); + inform_testing_reachability(&ap->addr, ap->port, false); } circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei, CIRCLAUNCH_NEED_CAPACITY| diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index 9c2286bbcf..e171562d17 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -235,9 +235,15 @@ rend_client_send_introduction(origin_circuit_t *introcirc, /* version 2 format */ extend_info_t *extend_info = rendcirc->build_state->chosen_exit; int klen; + const tor_addr_port_t *orport = + extend_info_get_orport(extend_info, AF_INET); + IF_BUG_ONCE(! orport) { + /* we should never put an IPv6 address here. */ + goto perm_err; + } /* nul pads */ - set_uint32(tmp+v3_shift+1, tor_addr_to_ipv4n(&extend_info->addr)); - set_uint16(tmp+v3_shift+5, htons(extend_info->port)); + set_uint32(tmp+v3_shift+1, tor_addr_to_ipv4n(&orport->addr)); + set_uint16(tmp+v3_shift+5, htons(orport->port)); memcpy(tmp+v3_shift+7, extend_info->identity_digest, DIGEST_LEN); klen = crypto_pk_asn1_encode(extend_info->onion_key, tmp+v3_shift+7+DIGEST_LEN+2, diff --git a/src/feature/rend/rendcommon.c b/src/feature/rend/rendcommon.c index 07cbeaa2f7..775d487805 100644 --- a/src/feature/rend/rendcommon.c +++ b/src/feature/rend/rendcommon.c @@ -234,7 +234,12 @@ rend_encode_v2_intro_points(char **encoded, rend_service_descriptor_t *desc) goto done; } /* Assemble everything for this introduction point. */ - address = tor_addr_to_str_dup(&info->addr); + const tor_addr_port_t *orport = extend_info_get_orport(info, AF_INET); + IF_BUG_ONCE(!orport) { + /* There must be an IPv4 address for v2 hs. */ + goto done; + } + address = tor_addr_to_str_dup(&orport->addr); res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written, "introduction-point %s\n" "ip-address %s\n" @@ -243,7 +248,7 @@ rend_encode_v2_intro_points(char **encoded, rend_service_descriptor_t *desc) "service-key\n%s", id_base32, address, - info->port, + orport->port, onion_key, service_key); tor_free(address); diff --git a/src/feature/rend/rendparse.c b/src/feature/rend/rendparse.c index 0979d767a7..c28add5ca9 100644 --- a/src/feature/rend/rendparse.c +++ b/src/feature/rend/rendparse.c @@ -10,6 +10,7 @@ **/ #include "core/or/or.h" +#include "core/or/extendinfo.h" #include "feature/dirparse/parsecommon.h" #include "feature/dirparse/sigcommon.h" #include "feature/rend/rendcommon.h" @@ -428,7 +429,8 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed, } /* Allocate new intro point and extend info. */ intro = tor_malloc_zero(sizeof(rend_intro_point_t)); - info = intro->extend_info = tor_malloc_zero(sizeof(extend_info_t)); + info = intro->extend_info = + extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0); /* Parse identifier. */ tok = find_by_keyword(tokens, R_IPO_IDENTIFIER); if (base32_decode(info->identity_digest, DIGEST_LEN, @@ -446,12 +448,13 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed, info->identity_digest, DIGEST_LEN); /* Parse IP address. */ tok = find_by_keyword(tokens, R_IPO_IP_ADDRESS); - if (tor_addr_parse(&info->addr, tok->args[0])<0) { + tor_addr_t addr; + if (tor_addr_parse(&addr, tok->args[0])<0) { log_warn(LD_REND, "Could not parse introduction point address."); rend_intro_point_free(intro); goto err; } - if (tor_addr_family(&info->addr) != AF_INET) { + if (tor_addr_family(&addr) != AF_INET) { log_warn(LD_REND, "Introduction point address was not ipv4."); rend_intro_point_free(intro); goto err; @@ -459,14 +462,18 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed, /* Parse onion port. */ tok = find_by_keyword(tokens, R_IPO_ONION_PORT); - info->port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535, + uint16_t port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535, &num_ok,NULL); - if (!info->port || !num_ok) { + if (!port || !num_ok) { log_warn(LD_REND, "Introduction point onion port %s is invalid", escaped(tok->args[0])); rend_intro_point_free(intro); goto err; } + + /* Add the address and port. */ + extend_info_add_orport(info, &addr, port); + /* Parse onion key. */ tok = find_by_keyword(tokens, R_IPO_ONION_KEY); if (!crypto_pk_public_exponent_ok(tok->key)) { diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c index 8154840f12..1c456cb6ee 100644 --- a/src/feature/rend/rendservice.c +++ b/src/feature/rend/rendservice.c @@ -1832,8 +1832,11 @@ rend_service_use_direct_connection(const or_options_t* options, /* We'll connect directly all reachable addresses, whether preferred or not. * The prefer_ipv6 argument to fascist_firewall_allows_address_addr is * ignored, because pref_only is 0. */ + const tor_addr_port_t *ap = extend_info_get_orport(ei, AF_INET); + if (!ap) + return 0; return (rend_service_allow_non_anonymous_connection(options) && - fascist_firewall_allows_address_addr(&ei->addr, ei->port, + fascist_firewall_allows_address_addr(&ap->addr, ap->port, FIREWALL_OR_CONNECTION, 0, 0)); } @@ -2262,7 +2265,8 @@ find_rp_for_intro(const rend_intro_cell_t *intro, /* Make sure the RP we are being asked to connect to is _not_ a private * address unless it's allowed. Let's avoid to build a circuit to our * second middle node and fail right after when extending to the RP. */ - if (!extend_info_addr_is_allowed(&rp->addr)) { + const tor_addr_port_t *orport = extend_info_get_orport(rp, AF_INET); + if (! orport || !extend_info_addr_is_allowed(&orport->addr)) { if (err_msg_out) { tor_asprintf(&err_msg, "Relay IP in INTRODUCE2 cell is private address."); @@ -2531,9 +2535,11 @@ rend_service_parse_intro_for_v2( goto err; } - extend_info = tor_malloc_zero(sizeof(extend_info_t)); - tor_addr_from_ipv4n(&extend_info->addr, get_uint32(buf + 1)); - extend_info->port = ntohs(get_uint16(buf + 5)); + extend_info = extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0); + tor_addr_t addr; + tor_addr_from_ipv4n(&addr, get_uint32(buf + 1)); + uint16_t port = ntohs(get_uint16(buf + 5)); + extend_info_add_orport(extend_info, &addr, port); memcpy(extend_info->identity_digest, buf + 7, DIGEST_LEN); extend_info->nickname[0] = '$'; base16_encode(extend_info->nickname + 1, sizeof(extend_info->nickname) - 1, diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c index 61bacb4d2e..8e40167aeb 100644 --- a/src/test/rend_test_helpers.c +++ b/src/test/rend_test_helpers.c @@ -2,6 +2,7 @@ /* See LICENSE for licensing information */ #include "core/or/or.h" +#include "core/or/extendinfo.h" #include "lib/crypt_ops/crypto_rand.h" #include "test/test.h" #include "feature/rend/rendcommon.h" @@ -58,7 +59,8 @@ create_descriptor(rend_service_descriptor_t **generated, char **service_id, for (i = 0; i < intro_points; i++) { rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t)); crypto_pk_t *okey = pk_generate(2 + i); - intro->extend_info = tor_malloc_zero(sizeof(extend_info_t)); + intro->extend_info = + extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0); intro->extend_info->onion_key = okey; crypto_pk_get_digest(intro->extend_info->onion_key, intro->extend_info->identity_digest); @@ -66,8 +68,12 @@ create_descriptor(rend_service_descriptor_t **generated, char **service_id, base16_encode(intro->extend_info->nickname + 1, sizeof(intro->extend_info->nickname) - 1, intro->extend_info->identity_digest, DIGEST_LEN); - tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536)); - intro->extend_info->port = 1 + crypto_rand_int(65535); + tor_addr_t addr; + uint16_t port; + /* Does not cover all IP addresses. */ + tor_addr_from_ipv4h(&addr, crypto_rand_int(65536) + 1); + port = 1 + crypto_rand_int(65535); + extend_info_add_orport(intro->extend_info, &addr, port); intro->intro_key = crypto_pk_dup_key(pk2); smartlist_add((*generated)->intro_nodes, intro); } @@ -91,4 +97,3 @@ mock_rend_data(const char *onion_address) DIGEST_LEN)); return rend_query; } - diff --git a/src/test/test.c b/src/test/test.c index 4b6082ce4f..2961669c46 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1,5 +1,5 @@ /* Copyright (c) 2001-2004, Roger Dingledine. - * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. +->a * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ @@ -44,6 +44,7 @@ #include "lib/compress/compress.h" #include "app/config/config.h" #include "core/or/connection_edge.h" +#include "core/or/extendinfo.h" #include "feature/rend/rendcommon.h" #include "feature/rend/rendcache.h" #include "feature/rend/rendparse.h" @@ -564,7 +565,8 @@ test_rend_fns(void *arg) for (i = 0; i < 3; i++) { rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t)); crypto_pk_t *okey = pk_generate(2 + i); - intro->extend_info = tor_malloc_zero(sizeof(extend_info_t)); + intro->extend_info = + extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0); intro->extend_info->onion_key = okey; crypto_pk_get_digest(intro->extend_info->onion_key, intro->extend_info->identity_digest); @@ -573,9 +575,12 @@ test_rend_fns(void *arg) base16_encode(intro->extend_info->nickname + 1, sizeof(intro->extend_info->nickname) - 1, intro->extend_info->identity_digest, DIGEST_LEN); + tor_addr_t addr; + uint16_t port; /* Does not cover all IP addresses. */ - tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536)); - intro->extend_info->port = 1 + crypto_rand_int(65535); + tor_addr_from_ipv4h(&addr, crypto_rand_int(65536) + 1); + port = 1 + crypto_rand_int(65535); + extend_info_add_orport(intro->extend_info, &addr, port); intro->intro_key = crypto_pk_dup_key(pk2); smartlist_add(generated->intro_nodes, intro); } @@ -613,8 +618,12 @@ test_rend_fns(void *arg) tt_mem_op(gen_info->identity_digest,OP_EQ, par_info->identity_digest, DIGEST_LEN); tt_str_op(gen_info->nickname,OP_EQ, par_info->nickname); - tt_assert(tor_addr_eq(&gen_info->addr, &par_info->addr)); - tt_int_op(gen_info->port,OP_EQ, par_info->port); + const tor_addr_port_t *a1, *a2; + a1 = extend_info_get_orport(gen_info, AF_INET); + a2 = extend_info_get_orport(par_info, AF_INET); + tt_assert(a1 && a2); + tt_assert(tor_addr_eq(&a1->addr, &a2->addr)); + tt_int_op(a2->port,OP_EQ, a2->port); } rend_service_descriptor_free(parsed); diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c index f7a27146b0..8f0e8b54e8 100644 --- a/src/test/test_circuitbuild.c +++ b/src/test/test_circuitbuild.c @@ -1677,14 +1677,14 @@ test_circuit_send_next_onion_skin(void *arg) extend_info_t ipv6_hop; memset(&ipv6_hop, 0, sizeof(ipv6_hop)); - tor_addr_make_null(&ipv6_hop.addr, AF_INET6); + tor_addr_parse(&ipv6_hop.orports[0].addr, "1::2"); extend_info_t *multi_ipv6_hop[DEFAULT_ROUTE_LEN] = {&ipv6_hop, &ipv6_hop, &ipv6_hop}; extend_info_t ipv4_hop; memset(&ipv4_hop, 0, sizeof(ipv4_hop)); - tor_addr_make_null(&ipv4_hop.addr, AF_INET); + tor_addr_from_ipv4h(&ipv4_hop.orports[0].addr, 0x20304050); extend_info_t *multi_ipv4_hop[DEFAULT_ROUTE_LEN] = {&ipv4_hop, &ipv4_hop, &ipv4_hop}; @@ -1737,7 +1737,7 @@ test_circuit_send_next_onion_skin(void *arg) /* Fail because the address family is invalid */ tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, -END_CIRC_REASON_INTERNAL); - expect_log_msg("Client trying to extend to a non-IPv4 address.\n"); + expect_log_msg("No supported address family found in extend_info.\n"); mock_clean_saved_logs(); /* Try an extend, but fail the server valid address check */ @@ -1751,7 +1751,7 @@ test_circuit_send_next_onion_skin(void *arg) mock_circuit_deliver_create_cell_expect_direct = false; tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, -END_CIRC_REASON_INTERNAL); - expect_log_msg("Server trying to extend to an invalid address family.\n"); + expect_log_msg("No supported address family found in extend_info.\n"); mock_clean_saved_logs(); /* Try an extend, but fail in the client code, with an IPv6 address */ @@ -1765,7 +1765,7 @@ test_circuit_send_next_onion_skin(void *arg) mock_circuit_deliver_create_cell_expect_direct = false; tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, -END_CIRC_REASON_INTERNAL); - expect_log_msg("Client trying to extend to a non-IPv4 address.\n"); + expect_log_msg("No supported address family found in extend_info.\n"); mock_clean_saved_logs(); /* Stop capturing bugs, but keep capturing logs */ diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index 3fef1b41c6..f965344ce0 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -530,7 +530,7 @@ test_client_pick_intro(void *arg) get_options_mutable()->ClientUseIPv6 = 1; intro_ei = hs_get_extend_info_from_lspecs(ip->link_specifiers, &ip->onion_key, 1); - tt_assert(tor_addr_family(&intro_ei->addr) == AF_INET6); + tt_assert(tor_addr_family(&intro_ei->orports[0].addr) == AF_INET6); } tt_assert(intro_ei); if (intro_ei) { @@ -538,7 +538,8 @@ test_client_pick_intro(void *arg) char ip_addr[TOR_ADDR_BUF_LEN]; /* We need to decorate in case it is an IPv6 else routerset_parse() * doesn't like it. */ - ptr = tor_addr_to_str(ip_addr, &intro_ei->addr, sizeof(ip_addr), 1); + ptr = tor_addr_to_str(ip_addr, &intro_ei->orports[0].addr, + sizeof(ip_addr), 1); tt_assert(ptr == ip_addr); ret = routerset_parse(get_options_mutable()->ExcludeNodes, ip_addr, ""); diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c index fbbbf0a99f..93d1ce453b 100644 --- a/src/test/test_nodelist.c +++ b/src/test/test_nodelist.c @@ -1182,11 +1182,11 @@ test_nodelist_extend_info_describe(void *arg) sizeof(mock_ei_ipv4.identity_digest)); strlcpy(mock_ei_ipv4.nickname, "TestOR7890123456789", sizeof(mock_ei_ipv4.nickname)); - tor_addr_parse(&mock_ei_ipv4.addr, "111.222.233.244"); + tor_addr_parse(&mock_ei_ipv4.orports[0].addr, "111.222.233.244"); /* Create and modify the other extend info. */ memcpy(&mock_ei_ipv6, &mock_ei_ipv4, sizeof(mock_ei_ipv6)); - tor_addr_parse(&mock_ei_ipv6.addr, + tor_addr_parse(&mock_ei_ipv6.orports[0].addr, "[1111:2222:3333:4444:5555:6666:7777:8888]"); /* We don't test the no-nickname and no-IP cases, because they're covered by diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 6cb588a0eb..388b5c74c9 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -2085,8 +2085,8 @@ test_policies_fascist_firewall_allows_address(void *arg) expect_single_log_msg("Specified link specifiers is null"); \ } else { \ expect_no_log_entry(); \ - tt_assert(tor_addr_eq(&(expect_ap).addr, &ei->addr)); \ - tt_int_op((expect_ap).port, OP_EQ, ei->port); \ + tt_assert(tor_addr_eq(&(expect_ap).addr, &ei->orports[0].addr)); \ + tt_int_op((expect_ap).port, OP_EQ, ei->orports[0].port); \ extend_info_free(ei); \ } \ teardown_capture_of_logs(); \ From 873d6d3724a4f83e010a8e25f7191bd4ddfa4703 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 1 Jul 2020 15:41:32 -0400 Subject: [PATCH 09/10] Clean up a redundant debug log in circuit_handle_first_hop(). We don't need to log that we're about to look for a channel for a given extend_info_t, since we're either going to log that we're launching one (at info), or that we're using an existing one (at debug). --- src/core/or/circuitbuild.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index 59ae58b98d..cef70e3e76 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -561,10 +561,6 @@ circuit_handle_first_hop(origin_circuit_t *circ) } /* now see if we're already connected to the first OR in 'route' */ - // TODO XXXX S55 -- remove this log - log_debug(LD_CIRC,"Looking for firsthop for %s", - extend_info_describe(firsthop->extend_info)); - const tor_addr_port_t *orport4 = extend_info_get_orport(firsthop->extend_info, AF_INET); const tor_addr_port_t *orport6 = @@ -603,7 +599,8 @@ circuit_handle_first_hop(origin_circuit_t *circ) tor_assert(!circ->base_.n_hop); circ->base_.n_chan = n_chan; circuit_chan_publish(circ, n_chan); - log_debug(LD_CIRC,"Conn open. Delivering first onion skin."); + log_debug(LD_CIRC,"Conn open for %s. Delivering first onion skin.", + safe_str_client(extend_info_describe(firsthop->extend_info))); if ((err_reason = circuit_send_next_onion_skin(circ)) < 0) { log_info(LD_CIRC,"circuit_send_next_onion_skin failed."); circ->base_.n_chan = NULL; From c5707d6cf0d3009655ce4681a228c8d2767a9063 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 2 Jul 2020 11:55:18 -0400 Subject: [PATCH 10/10] Add braces to IF_BUG_ONCE()s introduced in ticket34069. --- src/core/or/extendinfo.c | 6 ++++-- src/feature/client/bridges.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c index e4aec634a5..bcdb57d5a0 100644 --- a/src/core/or/extendinfo.c +++ b/src/core/or/extendinfo.c @@ -240,8 +240,9 @@ bool extend_info_has_orport(const extend_info_t *ei, const tor_addr_t *addr, uint16_t port) { - IF_BUG_ONCE(ei == NULL) + IF_BUG_ONCE(ei == NULL) { return false; + } for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { const tor_addr_port_t *ei_ap = &ei->orports[i]; @@ -291,8 +292,9 @@ extend_info_pick_orport(const extend_info_t *ei) bool extend_info_any_orport_addr_is_internal(const extend_info_t *ei) { - IF_BUG_ONCE(ei == NULL) + IF_BUG_ONCE(ei == NULL) { return false; + } for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) { if (! tor_addr_is_unspec(&ei->orports[i].addr) && diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c index 3a3d1bb681..caa4776493 100644 --- a/src/feature/client/bridges.c +++ b/src/feature/client/bridges.c @@ -273,8 +273,9 @@ extend_info_is_a_configured_bridge(const extend_info_t *ei) ap1 = &ei->orports[0]; if (! tor_addr_is_null(&ei->orports[1].addr)) ap2 = &ei->orports[1]; - IF_BUG_ONCE(ap1 == NULL) + IF_BUG_ONCE(ap1 == NULL) { return 0; + } return addr_is_a_configured_bridge(&ap1->addr, ap1->port, digest) && (ap2 == NULL || addr_is_a_configured_bridge(&ap2->addr, ap2->port, digest));