From 789beca7831253737ea91bd3ab516a581051fa4d Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 6 Jul 2020 08:45:12 -0400 Subject: [PATCH 1/9] channel: Refactor NETINFO process function In order to process a NETINFO cell, the OR connection needs to go through a series of validation else we don't process the cell. Move those into its own function in and improve documentation. This is an attempt at reducing technical debt of the rather large and complicated channel_tls_process_netinfo_cell() function. Related to #40022 Signed-off-by: David Goulet --- src/core/or/channeltls.c | 51 ++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index a51fbf1dd6..9b2ac7d167 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -1688,6 +1688,41 @@ time_abs(time_t val) return (val < 0) ? -val : val; } +/** Return true iff the channel can process a NETINFO cell. For this to return + * true, these channel conditions apply: + * + * 1. Link protocol is version 2 or higher (tor-spec.txt, NETINFO cells + * section). + * + * 2. Underlying OR connection of the channel is either in v2 or v3 + * handshaking state. + */ +static bool +can_process_netinfo_cell(const channel_tls_t *chan) +{ + /* NETINFO cells can only be negotiated on link protocol 2 or higher. */ + if (chan->conn->link_proto < 2) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a NETINFO cell on %s connection; dropping.", + chan->conn->link_proto == 0 ? "non-versioned" : "a v1"); + return false; + } + + /* Can't process a NETINFO cell if the connection is not handshaking. */ + if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V2 && + chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a NETINFO cell on non-handshaking connection; dropping."); + return false; + } + + /* Make sure we do have handshake state. */ + tor_assert(chan->conn->handshake_state); + tor_assert(chan->conn->handshake_state->received_versions); + + return true; +} + /** * Process a 'netinfo' cell * @@ -1713,20 +1748,12 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) tor_assert(chan); tor_assert(chan->conn); - if (chan->conn->link_proto < 2) { - log_fn(LOG_PROTOCOL_WARN, LD_OR, - "Received a NETINFO cell on %s connection; dropping.", - chan->conn->link_proto == 0 ? "non-versioned" : "a v1"); + /* Make sure we can process a NETINFO cell. Link protocol and state + * validation is done to make sure of it. */ + if (!can_process_netinfo_cell(chan)) { return; } - if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V2 && - chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) { - log_fn(LOG_PROTOCOL_WARN, LD_OR, - "Received a NETINFO cell on non-handshaking connection; dropping."); - return; - } - tor_assert(chan->conn->handshake_state && - chan->conn->handshake_state->received_versions); + started_here = connection_or_nonopen_was_started_here(chan->conn); identity_digest = chan->conn->identity_digest; From 78bc52c47c8d7c3747ea3335b571fd98a15a47b1 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 6 Jul 2020 09:06:22 -0400 Subject: [PATCH 2/9] channel: Continue refactor NETINFO process function In the spirit of reducing technical debt. Move code that marks a channel as a client into its own function and document it properly. No behavior change, only code movement. Related to #40022 Signed-off-by: David Goulet --- src/core/or/channeltls.c | 73 +++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 9b2ac7d167..fc93ea8d56 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -1723,6 +1723,50 @@ can_process_netinfo_cell(const channel_tls_t *chan) return true; } +/** Mark the given channel endpoint as a client (which means either a tor + * client or a tor bridge). + * + * This MUST be done on an _unauthenticated_ channel. It is a mistake to mark + * an authenticated channel as a client. + * + * The following is done on the channel: + * + * 1. Marked as a client. + * 2. Type of circuit ID type is set. + * 3. The underlying OR connection is initialized with the address of the + * endpoint. + */ +static void +mark_channel_tls_endpoint_as_client(channel_tls_t *chan) +{ + /* Ending up here for an authenticated link is a mistake. */ + if (BUG(chan->conn->handshake_state->authenticated)) { + return; + } + + tor_assert(tor_digest_is_zero( + (const char*)(chan->conn->handshake_state-> + authenticated_rsa_peer_id))); + tor_assert(fast_mem_is_zero( + (const char*)(chan->conn->handshake_state-> + authenticated_ed25519_peer_id.pubkey), 32)); + /* If the client never authenticated, it's a tor client or bridge + * relay, and we must not use it for EXTEND requests (nor could we, as + * there are no authenticated peer IDs) */ + channel_mark_client(TLS_CHAN_TO_BASE(chan)); + channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL, + chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS); + + connection_or_init_conn_from_address(chan->conn, + &(chan->conn->base_.addr), + chan->conn->base_.port, + /* zero, checked above */ + (const char*)(chan->conn->handshake_state-> + authenticated_rsa_peer_id), + NULL, /* Ed25519 ID: Also checked as zero */ + 0); +} + /** * Process a 'netinfo' cell * @@ -1768,30 +1812,13 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) return; } } else { - /* we're the server. If the client never authenticated, we have - some housekeeping to do.*/ + /* We're the server. If the client never authenticated, we have some + * housekeeping to do. + * + * It's a tor client or bridge relay, and we must not use it for EXTEND + * requests (nor could we, as there are no authenticated peer IDs) */ if (!(chan->conn->handshake_state->authenticated)) { - tor_assert(tor_digest_is_zero( - (const char*)(chan->conn->handshake_state-> - authenticated_rsa_peer_id))); - tor_assert(fast_mem_is_zero( - (const char*)(chan->conn->handshake_state-> - authenticated_ed25519_peer_id.pubkey), 32)); - /* If the client never authenticated, it's a tor client or bridge - * relay, and we must not use it for EXTEND requests (nor could we, as - * there are no authenticated peer IDs) */ - channel_mark_client(TLS_CHAN_TO_BASE(chan)); - channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL, - chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS); - - connection_or_init_conn_from_address(chan->conn, - &(chan->conn->base_.addr), - chan->conn->base_.port, - /* zero, checked above */ - (const char*)(chan->conn->handshake_state-> - authenticated_rsa_peer_id), - NULL, /* Ed25519 ID: Also checked as zero */ - 0); + mark_channel_tls_endpoint_as_client(chan); } } } From f57ce632fe3d391e62d288c0b8acd0001bf670df Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 6 Jul 2020 09:40:03 -0400 Subject: [PATCH 3/9] addr: Rename and make resolved_addr_set_last() function public Rename the static function update_resolved_cache() to resolved_addr_set_last() and make it public. We are about to use it in order to record any suggested address from a NETINFO cell. Related to #40022 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 10 +++++----- src/app/config/resolve_addr.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 808c5ddf0b..2a11ba3c00 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -370,7 +370,7 @@ get_address_from_interface(const or_options_t *options, int warn_severity, return FN_RET_OK; } -/** @brief Update the last resolved address cache using the given address. +/** @brief Set the last resolved address cache using the given address. * * A log notice is emitted if the given address has changed from before. Not * emitted on first resolve. @@ -386,9 +386,9 @@ get_address_from_interface(const or_options_t *options, int warn_severity, * @param hostname_used Which hostname was used. If none were used, it is * NULL. (for logging and control port). */ -static void -update_resolved_cache(const tor_addr_t *addr, const char *method_used, - const char *hostname_used) +void +resolved_addr_set_last(const tor_addr_t *addr, const char *method_used, + const char *hostname_used) { /** Have we done a first resolve. This is used to control logging. */ static bool have_resolved_once[IDX_SIZE] = { false, false, false }; @@ -561,7 +561,7 @@ find_my_address(const or_options_t *options, int family, int warn_severity, /* * Step 2: Update last resolved address cache and inform the control port. */ - update_resolved_cache(&my_addr, method_used, hostname_used); + resolved_addr_set_last(&my_addr, method_used, hostname_used); if (method_out) { *method_out = method_used; diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 54f55ba36c..055d59a8f1 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -17,6 +17,8 @@ bool find_my_address(const or_options_t *options, int family, void resolved_addr_get_last(int family, tor_addr_t *addr_out); void resolved_addr_reset_last(int family); +void resolved_addr_set_last(const tor_addr_t *addr, const char *method_used, + const char *hostname_used); MOCK_DECL(bool, is_local_to_resolve_addr, (const tor_addr_t *addr)); From 192d367b411019760f92f58adde7592476341d6b Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 6 Jul 2020 09:42:10 -0400 Subject: [PATCH 4/9] addr: New function relay_address_new_suggestion() This behaves like router_new_address_suggestion() but differs in couple of ways: 1. It takes a tor_addr_t instead of an address string and supports both AF_INET and AF_INET6. 2. It does _not_ use the last_guessed_ip local cache and instead only relies on the last resolved address cache in resolve_addr.c It is not used at this commit. This function is made to process a suggested address found in a NETINFO cell exactly like router_new_address_suggestion() does with the address a directory suggests us. Related to #40022 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 29 ++++++++++++++++ src/app/config/resolve_addr.h | 3 ++ src/feature/nodelist/dirlist.c | 28 +++++++++++++++ src/feature/nodelist/dirlist.h | 5 +++ src/feature/relay/relay_find_addr.c | 54 +++++++++++++++++++++++++++++ src/feature/relay/relay_find_addr.h | 3 ++ 6 files changed, 122 insertions(+) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 2a11ba3c00..75b5eb75b1 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -44,6 +44,12 @@ typedef enum { /** Last resolved addresses. */ static tor_addr_t last_resolved_addrs[IDX_SIZE]; +/** Last suggested addresses. + * + * These addresses come from a NETINFO cell from a trusted relay (currently + * only authorities). We only use those in last resort. */ +static tor_addr_t last_suggested_addrs[IDX_SIZE]; + static inline int af_to_idx(const int family) { @@ -60,6 +66,29 @@ af_to_idx(const int family) } } +/** Copy the last suggested address of family into addr_out. + * + * If no last suggested address exists, the addr_out is a null address (use + * tor_addr_is_null() to confirm). */ +void +resolved_addr_get_suggested(int family, tor_addr_t *addr_out) +{ + tor_addr_copy(addr_out, &last_suggested_addrs[af_to_idx(family)]); +} + +/** Set the last suggested address into our cache. This is called when we get + * a new NETINFO cell from a trusted source. */ +void +resolved_addr_set_suggested(const tor_addr_t *addr) +{ + if (BUG(tor_addr_family(addr) != AF_INET || + tor_addr_family(addr) != AF_INET6)) { + return; + } + tor_addr_copy(&last_suggested_addrs[af_to_idx(tor_addr_family(addr))], + addr); +} + /** Copy the last resolved address of family into addr_out. * * If not last resolved address existed, the addr_out is a null address (use diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 055d59a8f1..7ba70541a5 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -20,6 +20,9 @@ void resolved_addr_reset_last(int family); void resolved_addr_set_last(const tor_addr_t *addr, const char *method_used, const char *hostname_used); +void resolved_addr_get_suggested(int family, tor_addr_t *addr_out); +void resolved_addr_set_suggested(const tor_addr_t *addr); + MOCK_DECL(bool, is_local_to_resolve_addr, (const tor_addr_t *addr)); #ifdef RESOLVE_ADDR_PRIVATE diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c index bd647ab530..c1864faedf 100644 --- a/src/feature/nodelist/dirlist.c +++ b/src/feature/nodelist/dirlist.c @@ -250,6 +250,34 @@ router_digest_is_trusted_dir_type(const char *digest, dirinfo_type_t type) return 0; } +/** Return true iff the given address matches a trusted directory that matches + * at least one bit of type. + * + * If type is NO_DIRINFO or ALL_DIRINFO, any authority is matched. */ +bool +router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type) +{ + int family = tor_addr_family(addr); + + if (!trusted_dir_servers) { + return false; + } + + SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, dir_server_t *, ent) { + /* Ignore entries that don't match the given type. */ + if (type != NO_DIRINFO && (type & ent->type) == 0) { + continue; + } + /* Match IPv4 or IPv6 address. */ + if ((family == AF_INET && tor_addr_eq_ipv4h(addr, ent->addr)) || + (family == AF_INET6 && tor_addr_eq(addr, &ent->ipv6_addr))) { + return true; + } + } SMARTLIST_FOREACH_END(ent); + + return false; +} + /** Create a directory server at address:port, with OR identity * key digest which has DIGEST_LEN bytes. If address is NULL, * add ourself. If is_authority, this is a directory authority. Return diff --git a/src/feature/nodelist/dirlist.h b/src/feature/nodelist/dirlist.h index 9201e76a9c..c9310ff357 100644 --- a/src/feature/nodelist/dirlist.h +++ b/src/feature/nodelist/dirlist.h @@ -25,6 +25,11 @@ int router_digest_is_fallback_dir(const char *digest); MOCK_DECL(dir_server_t *, trusteddirserver_get_by_v3_auth_digest, (const char *d)); +bool router_addr_is_trusted_dir_type(const tor_addr_t *addr, + dirinfo_type_t type); +#define router_addr_is_trusted_dir(d) \ + router_addr_is_trusted_dir_type((d), NO_DIRINFO) + int router_digest_is_trusted_dir_type(const char *digest, dirinfo_type_t type); #define router_digest_is_trusted_dir(d) \ diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index a51457ddbb..699eb7e380 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -15,6 +15,7 @@ #include "feature/control/control_events.h" #include "feature/dircommon/dir_connection_st.h" +#include "feature/nodelist/dirlist.h" #include "feature/relay/relay_find_addr.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" @@ -37,6 +38,59 @@ router_guess_address_from_dir_headers(uint32_t *guess) return -1; } +/** Consider the address suggestion suggested_addr as a possible one to use as + * our address. + * + * This is called when a valid NETINFO cell is recevied containing a candidate + * for our address. + * + * The suggested address is ignored if it does NOT come from a trusted source. + * At the moment, we only look a trusted directory authorities. + * + * The suggested address is ignored if it is internal or it is the same as the + * given peer_addr which is the address from the endpoint that sent the + * NETINFO cell. + * + * The suggested address is set in our suggested address cache if everything + * passes. */ +void +relay_address_new_suggestion(const tor_addr_t *suggested_addr, + const tor_addr_t *peer_addr) +{ + const or_options_t *options = get_options(); + + tor_assert(suggested_addr); + tor_assert(peer_addr); + + /* This should never be called on a non Tor relay. */ + if (BUG(!server_mode(options))) { + return; + } + + /* Is the peer a trusted source? Ignore anything coming from non trusted + * source. In this case, we only look at trusted authorities. */ + if (!router_addr_is_trusted_dir(peer_addr)) { + return; + } + + /* Ignore a suggestion that is an internal address or the same as the one + * the peer address. */ + if (tor_addr_is_internal(suggested_addr, 0)) { + /* Do not believe anyone who says our address is internal. */ + return; + } + if (tor_addr_eq(suggested_addr, peer_addr)) { + /* Do not believe anyone who says our address is their address. */ + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "A relay endpoint %s is telling us that their address is ours.", + fmt_addr(peer_addr)); + return; + } + + /* Save the suggestion in our cache. */ + resolved_addr_set_suggested(suggested_addr); +} + /** A directory server d_conn told us our IP address is * suggestion. * If this address is different from the one we think we are now, and diff --git a/src/feature/relay/relay_find_addr.h b/src/feature/relay/relay_find_addr.h index ac51a977e6..d856e706ea 100644 --- a/src/feature/relay/relay_find_addr.h +++ b/src/feature/relay/relay_find_addr.h @@ -15,6 +15,9 @@ MOCK_DECL(int, router_pick_published_address, void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn); +void relay_address_new_suggestion(const tor_addr_t *suggested_addr, + const tor_addr_t *peer_addr); + #ifdef RELAY_FIND_ADDR_PRIVATE #endif /* RELAY_FIND_ADDR_PRIVATE */ From f5ce8a2bed833befcee895d4966d5731ad2fdf75 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 6 Jul 2020 09:50:48 -0400 Subject: [PATCH 5/9] channel: Consider NETINFO other address as ours Attempt to learn our address from the NETINFO cell. At this commit, the address won't be used in the descriptor if selected. Next commit will make it happen. Related to #40022 Signed-off-by: David Goulet --- src/core/or/channeltls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index fc93ea8d56..9198a8bfbc 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -72,6 +72,7 @@ #include "core/or/or_handshake_state_st.h" #include "feature/nodelist/routerinfo_st.h" #include "core/or/var_cell_st.h" +#include "src/feature/relay/relay_find_addr.h" #include "lib/tls/tortls.h" #include "lib/tls/x509.h" @@ -1929,8 +1930,11 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) "NETINFO cell", "OR"); } - /* XXX maybe act on my_apparent_addr, if the source is sufficiently - * trustworthy. */ + /* Consider our apparent address as a possible suggestion for our address if + * we were unable to resolve it previously. The endpoint address is passed + * in order to make sure to never consider an address that is the same as + * our endpoint. */ + relay_address_new_suggestion(&my_apparent_addr, &chan->conn->real_addr); if (! chan->conn->handshake_state->sent_netinfo) { /* If we were prepared to authenticate, but we never got an AUTH_CHALLENGE From 15be1ff8ad568629f809b4feac79a8dcbfac9444 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 6 Jul 2020 10:02:45 -0400 Subject: [PATCH 6/9] changes: Add a changes file for #40022 Signed-off-by: David Goulet --- changes/ticket40022 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/ticket40022 diff --git a/changes/ticket40022 b/changes/ticket40022 new file mode 100644 index 0000000000..aa7bb256e6 --- /dev/null +++ b/changes/ticket40022 @@ -0,0 +1,4 @@ + o Minor feature (relay): + - If a relay is unable to discover its address, attempt to learn it from the + NETINFO cell. Closes ticket 40022. + From 9b2cadb492ee07ebb086b934b01ff8a5159fcc77 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 8 Jul 2020 07:46:12 -0400 Subject: [PATCH 7/9] addr: Validate identity key when getting a suggestion We do look at the address but with this we also look if the identity digest of the relay suggesting us an address is a trusted source. Related to #40022 Signed-off-by: David Goulet --- src/core/or/channeltls.c | 3 ++- src/feature/relay/relay_find_addr.c | 9 ++++++--- src/feature/relay/relay_find_addr.h | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 9198a8bfbc..4db3730972 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -1934,7 +1934,8 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) * we were unable to resolve it previously. The endpoint address is passed * in order to make sure to never consider an address that is the same as * our endpoint. */ - relay_address_new_suggestion(&my_apparent_addr, &chan->conn->real_addr); + relay_address_new_suggestion(&my_apparent_addr, &chan->conn->real_addr, + identity_digest); if (! chan->conn->handshake_state->sent_netinfo) { /* If we were prepared to authenticate, but we never got an AUTH_CHALLENGE diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index 699eb7e380..28b5985bb8 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -55,12 +55,14 @@ router_guess_address_from_dir_headers(uint32_t *guess) * passes. */ void relay_address_new_suggestion(const tor_addr_t *suggested_addr, - const tor_addr_t *peer_addr) + const tor_addr_t *peer_addr, + const char *identity_digest) { const or_options_t *options = get_options(); tor_assert(suggested_addr); tor_assert(peer_addr); + tor_assert(identity_digest); /* This should never be called on a non Tor relay. */ if (BUG(!server_mode(options))) { @@ -68,8 +70,9 @@ relay_address_new_suggestion(const tor_addr_t *suggested_addr, } /* Is the peer a trusted source? Ignore anything coming from non trusted - * source. In this case, we only look at trusted authorities. */ - if (!router_addr_is_trusted_dir(peer_addr)) { + * source. In this case, we only look at trusted directory authorities. */ + if (!router_addr_is_trusted_dir(peer_addr) || + !router_digest_is_trusted_dir(identity_digest)) { return; } diff --git a/src/feature/relay/relay_find_addr.h b/src/feature/relay/relay_find_addr.h index d856e706ea..6f298e6c79 100644 --- a/src/feature/relay/relay_find_addr.h +++ b/src/feature/relay/relay_find_addr.h @@ -16,7 +16,8 @@ void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn); void relay_address_new_suggestion(const tor_addr_t *suggested_addr, - const tor_addr_t *peer_addr); + const tor_addr_t *peer_addr, + const char *identity_digest); #ifdef RELAY_FIND_ADDR_PRIVATE From 46e34842619be7467e3cd062a2c7fbcd112b9cff Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 8 Jul 2020 07:50:50 -0400 Subject: [PATCH 8/9] addr: Initialize resolved address cache to NULL address Related to #40022 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 75b5eb75b1..9e7c23c881 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -42,13 +42,15 @@ typedef enum { } fn_address_ret_t; /** Last resolved addresses. */ -static tor_addr_t last_resolved_addrs[IDX_SIZE]; +static tor_addr_t last_resolved_addrs[IDX_SIZE] = + { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL }; /** Last suggested addresses. * * These addresses come from a NETINFO cell from a trusted relay (currently * only authorities). We only use those in last resort. */ -static tor_addr_t last_suggested_addrs[IDX_SIZE]; +static tor_addr_t last_suggested_addrs[IDX_SIZE] = + { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL }; static inline int af_to_idx(const int family) From 7bc54ccba9b9a9ac2ee9f5c1ecccd1d13afbcdda Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 9 Jul 2020 13:33:52 -0400 Subject: [PATCH 9/9] addr: Static assert resolved address cache size This will make sure that we always properly initialize the cache by the exact size all the time. Related to #40022 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 9e7c23c881..fb5cb2ed6c 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -42,15 +42,17 @@ typedef enum { } fn_address_ret_t; /** Last resolved addresses. */ -static tor_addr_t last_resolved_addrs[IDX_SIZE] = +static tor_addr_t last_resolved_addrs[] = { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL }; +CTASSERT(ARRAY_LENGTH(last_resolved_addrs) == IDX_SIZE); /** Last suggested addresses. * * These addresses come from a NETINFO cell from a trusted relay (currently * only authorities). We only use those in last resort. */ -static tor_addr_t last_suggested_addrs[IDX_SIZE] = +static tor_addr_t last_suggested_addrs[] = { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL }; +CTASSERT(ARRAY_LENGTH(last_suggested_addrs) == IDX_SIZE); static inline int af_to_idx(const int family) @@ -422,7 +424,9 @@ resolved_addr_set_last(const tor_addr_t *addr, const char *method_used, const char *hostname_used) { /** Have we done a first resolve. This is used to control logging. */ - static bool have_resolved_once[IDX_SIZE] = { false, false, false }; + static bool have_resolved_once[] = { false, false, false }; + CTASSERT(ARRAY_LENGTH(have_resolved_once) == IDX_SIZE); + bool *done_one_resolve; bool have_hostname = false; tor_addr_t *last_resolved;