Tor  0.4.5.0-alpha-dev
relay_find_addr.c
Go to the documentation of this file.
1 /* Copyright (c) 2001-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
4 /**
5  * \file relay_find_addr.c
6  * \brief Implement mechanism for a relay to find its address.
7  **/
8 
9 #include "core/or/or.h"
10 
11 #include "app/config/config.h"
13 
14 #include "core/mainloop/mainloop.h"
15 
20 #include "feature/relay/router.h"
22 
23 /** Consider the address suggestion suggested_addr as a possible one to use as
24  * our address.
25  *
26  * This is called when a valid NETINFO cell is received containing a candidate
27  * for our address or when a directory sends us back the X-Your-Address-Is
28  * header.
29  *
30  * The suggested address is ignored if it does NOT come from a trusted source.
31  * At the moment, we only look a trusted directory authorities.
32  *
33  * The suggested address is ignored if it is internal or it is the same as the
34  * given peer_addr which is the address from the endpoint that sent the
35  * NETINFO cell.
36  *
37  * The identity_digest is NULL if this is an address suggested by a directory
38  * since this is a plaintext connection.
39  *
40  * The suggested address is set in our suggested address cache if everything
41  * passes. */
42 void
44  const tor_addr_t *peer_addr,
45  const char *identity_digest)
46 {
47  const or_options_t *options = get_options();
48 
49  tor_assert(suggested_addr);
50  tor_assert(peer_addr);
51 
52  /* Non server should just ignore this suggestion. Clients don't need to
53  * learn their address let alone cache it. */
54  if (!server_mode(options)) {
55  return;
56  }
57 
58  /* Is the peer a trusted source? Ignore anything coming from non trusted
59  * source. In this case, we only look at trusted directory authorities. */
60  if (!router_addr_is_trusted_dir(peer_addr) ||
61  (identity_digest && !router_digest_is_trusted_dir(identity_digest))) {
62  return;
63  }
64 
65  /* Ignore a suggestion that is an internal address or the same as the one
66  * the peer address. */
67  if (tor_addr_is_internal(suggested_addr, 0)) {
68  /* Do not believe anyone who says our address is internal. */
69  return;
70  }
71  if (tor_addr_eq(suggested_addr, peer_addr)) {
72  /* Do not believe anyone who says our address is their address. */
73  log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
74  "A relay endpoint %s is telling us that their address is ours.",
75  fmt_addr(peer_addr));
76  return;
77  }
78 
79  /* Save the suggestion in our cache. */
80  resolved_addr_set_suggested(suggested_addr);
81 }
82 
83 /** Find our address to be published in our descriptor. Three places are
84  * looked at:
85  *
86  * 1. Resolved cache. Populated by find_my_address() during the relay
87  * periodic event that attempts to learn if our address has changed.
88  *
89  * 2. If flags is set with RELAY_FIND_ADDR_CACHE_ONLY, only the resolved
90  * and suggested cache are looked at. No address discovery will be done.
91  *
92  * 3. Finally, if all fails, use the suggested address cache which is
93  * populated by the NETINFO cell content or HTTP header from a
94  * directory.
95  *
96  * Return true on success and addr_out contains the address to use for the
97  * given family. On failure to find the address, false is returned and
98  * addr_out is set to an AF_UNSPEC address. */
99 MOCK_IMPL(bool,
100 relay_find_addr_to_publish, (const or_options_t *options, int family,
101  int flags, tor_addr_t *addr_out))
102 {
103  tor_assert(options);
104  tor_assert(addr_out);
105 
106  tor_addr_make_unspec(addr_out);
107 
108  /* If an IPv6 is requested, check if IPv6 address discovery is disabled on
109  * this instance. If so, we return a failure. It is done here so we don't
110  * query the suggested cache that might be populated with an IPv6. */
111  if (family == AF_INET6 && options->AddressDisableIPv6) {
112  return false;
113  }
114 
115  /* First, check our resolved address cache. It should contain the address
116  * we've discovered from the periodic relay event. */
117  resolved_addr_get_last(family, addr_out);
118  if (!tor_addr_is_null(addr_out)) {
119  goto found;
120  }
121 
122  /* Second, attempt to find our address. The following can do a DNS resolve
123  * thus only do it when the no cache only flag is flipped. */
124  if (!(flags & RELAY_FIND_ADDR_CACHE_ONLY)) {
125  if (find_my_address(options, family, LOG_INFO, addr_out, NULL, NULL)) {
126  goto found;
127  }
128  }
129 
130  /* Third, consider address from our suggestion cache. */
131  resolved_addr_get_suggested(family, addr_out);
132  if (!tor_addr_is_null(addr_out)) {
133  goto found;
134  }
135 
136  /* No publishable address was found. */
137  return false;
138 
139  found:
140  return true;
141 }
142 
143 /** Return true iff this relay has an address set for the given family.
144  *
145  * This only checks the caches so it will not trigger a full discovery of the
146  * address. */
147 bool
149 {
150  tor_addr_t addr;
151  return relay_find_addr_to_publish(get_options(), family,
152  RELAY_FIND_ADDR_CACHE_ONLY, &addr);
153 }
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:287
routermode.h
Header file for routermode.c.
tor_addr_t
Definition: address.h:69
relay_has_address_set
bool relay_has_address_set(int family)
Definition: relay_find_addr.c:148
MOCK_IMPL
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
relay_find_addr.h
Header file for relay_find_addr.c.
router.h
Header file for router.c.
relay_find_addr_to_publish
bool relay_find_addr_to_publish(const or_options_t *options, int family, int flags, tor_addr_t *addr_out)
Definition: relay_find_addr.c:101
find_my_address
bool find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, resolved_addr_method_t *method_out, char **hostname_out)
Attempt to find our IP address that can be used as our external reachable address.
Definition: resolve_addr.c:695
tor_addr_make_unspec
void tor_addr_make_unspec(tor_addr_t *a)
Definition: address.c:225
dirlist.h
Header file for dirlist.c.
mainloop.h
Header file for mainloop.c.
resolved_addr_get_suggested
void resolved_addr_get_suggested(int family, tor_addr_t *addr_out)
Definition: resolve_addr.c:119
LOG_INFO
#define LOG_INFO
Definition: log.h:45
fmt_addr
#define fmt_addr(a)
Definition: address.h:239
control_events.h
Header file for control_events.c.
get_options
const or_options_t * get_options(void)
Definition: config.c:928
resolve_addr.h
Header file for resolve_addr.c.
resolved_addr_set_suggested
void resolved_addr_set_suggested(const tor_addr_t *addr)
Definition: resolve_addr.c:127
server_mode
int server_mode(const or_options_t *options)
Definition: routermode.c:34
tor_addr_is_null
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
or_options_t::AddressDisableIPv6
int AddressDisableIPv6
Definition: or_options_st.h:86
dir_connection_st.h
Client/server directory connection structure.
relay_address_new_suggestion
void relay_address_new_suggestion(const tor_addr_t *suggested_addr, const tor_addr_t *peer_addr, const char *identity_digest)
Definition: relay_find_addr.c:43
config.h
Header file for config.c.
or_options_t
Definition: or_options_st.h:45
resolved_addr_get_last
void resolved_addr_get_last(int family, tor_addr_t *addr_out)
Definition: resolve_addr.c:142
tor_addr_eq
#define tor_addr_eq(a, b)
Definition: address.h:280
or.h
Master header file for Tor-specific functionality.
LD_PROTOCOL
#define LD_PROTOCOL
Definition: log.h:72