Tor  0.4.6.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 #include "core/or/circuitlist.h"
16 #include "core/or/circuituse.h"
17 #include "core/or/extendinfo.h"
18 
26 #include "feature/relay/router.h"
28 
29 /** Consider the address suggestion suggested_addr as a possible one to use as
30  * our address.
31  *
32  * This is called when a valid NETINFO cell is received containing a candidate
33  * for our address or when a directory sends us back the X-Your-Address-Is
34  * header.
35  *
36  * The suggested address is ignored if it does NOT come from a trusted source.
37  * At the moment, we only look a trusted directory authorities.
38  *
39  * The suggested address is ignored if it is internal or it is the same as the
40  * given peer_addr which is the address from the endpoint that sent the
41  * NETINFO cell.
42  *
43  * The identity_digest is NULL if this is an address suggested by a directory
44  * since this is a plaintext connection.
45  *
46  * The suggested address is set in our suggested address cache if everything
47  * passes. */
48 void
50  const tor_addr_t *peer_addr,
51  const char *identity_digest)
52 {
53  const or_options_t *options = get_options();
54 
55  tor_assert(suggested_addr);
56  tor_assert(peer_addr);
57 
58  /* Non server should just ignore this suggestion. Clients don't need to
59  * learn their address let alone cache it. */
60  if (!server_mode(options)) {
61  return;
62  }
63 
64  /* Is the peer a trusted source? Ignore anything coming from non trusted
65  * source. In this case, we only look at trusted directory authorities. */
66  if (!router_addr_is_trusted_dir(peer_addr) ||
67  (identity_digest && !router_digest_is_trusted_dir(identity_digest))) {
68  return;
69  }
70 
71  /* Ignore a suggestion that is an internal address or the same as the one
72  * the peer address. */
73  if (tor_addr_is_internal(suggested_addr, 0)) {
74  /* Do not believe anyone who says our address is internal. */
75  return;
76  }
77  if (tor_addr_eq(suggested_addr, peer_addr)) {
78  /* Do not believe anyone who says our address is their address. */
79  log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
80  "A relay endpoint %s is telling us that their address is ours.",
81  fmt_addr(peer_addr));
82  return;
83  }
84 
85  /* Save the suggestion in our cache. */
86  resolved_addr_set_suggested(suggested_addr);
87 }
88 
89 /** Find our address to be published in our descriptor. Three places are
90  * looked at:
91  *
92  * 1. Resolved cache. Populated by find_my_address() during the relay
93  * periodic event that attempts to learn if our address has changed.
94  *
95  * 2. If flags is set with RELAY_FIND_ADDR_CACHE_ONLY, only the resolved
96  * and suggested cache are looked at. No address discovery will be done.
97  *
98  * 3. Finally, if all fails, use the suggested address cache which is
99  * populated by the NETINFO cell content or HTTP header from a
100  * directory.
101  *
102  * Return true on success and addr_out contains the address to use for the
103  * given family. On failure to find the address, false is returned and
104  * addr_out is set to an AF_UNSPEC address. */
105 MOCK_IMPL(bool,
106 relay_find_addr_to_publish, (const or_options_t *options, int family,
107  int flags, tor_addr_t *addr_out))
108 {
109  tor_assert(options);
110  tor_assert(addr_out);
111 
112  tor_addr_make_unspec(addr_out);
113 
114  /* If an IPv6 is requested, check if IPv6 address discovery is disabled on
115  * this instance. If so, we return a failure. It is done here so we don't
116  * query the suggested cache that might be populated with an IPv6. */
117  if (family == AF_INET6 && options->AddressDisableIPv6) {
118  return false;
119  }
120 
121  /* First, check our resolved address cache. It should contain the address
122  * we've discovered from the periodic relay event. */
123  resolved_addr_get_last(family, addr_out);
124  if (!tor_addr_is_null(addr_out)) {
125  goto found;
126  }
127 
128  /* Second, attempt to find our address. The following can do a DNS resolve
129  * thus only do it when the no cache only flag is flipped. */
130  if (!(flags & RELAY_FIND_ADDR_CACHE_ONLY)) {
131  if (find_my_address(options, family, LOG_INFO, addr_out, NULL, NULL)) {
132  goto found;
133  }
134  }
135 
136  /* Third, consider address from our suggestion cache. */
137  resolved_addr_get_suggested(family, addr_out);
138  if (!tor_addr_is_null(addr_out)) {
139  goto found;
140  }
141 
142  /* No publishable address was found. */
143  return false;
144 
145  found:
146  return true;
147 }
148 
149 /** Return true iff this relay has an address set for the given family.
150  *
151  * This only checks the caches so it will not trigger a full discovery of the
152  * address. */
153 bool
155 {
156  tor_addr_t addr;
157  return relay_find_addr_to_publish(get_options(), family,
158  RELAY_FIND_ADDR_CACHE_ONLY, &addr);
159 }
160 
161 /** How often should we launch a circuit to an authority to be sure of getting
162  * a guess for our IP? */
163 #define DUMMY_DOWNLOAD_INTERVAL (20*60)
164 
165 void
166 relay_addr_learn_from_dirauth(void)
167 {
168  static time_t last_dummy_circuit = 0;
169  const or_options_t *options = get_options();
170  time_t now = time(NULL);
171  bool have_addr;
172  tor_addr_t addr_out;
173 
174  /* This dummy circuit only matter for relays. */
175  if (BUG(!server_mode(options))) {
176  return;
177  }
178 
179  /* Lookup the address cache to learn if we have a good usable address. We
180  * still force relays to have an IPv4 so that alone is enough to learn if we
181  * need a lookup. In case we don't have one, we might want to attempt a
182  * dummy circuit to learn our address as a suggestion from an authority. */
183  have_addr = relay_find_addr_to_publish(options, AF_INET,
184  RELAY_FIND_ADDR_CACHE_ONLY,
185  &addr_out);
186 
187  /* If we're a relay or bridge for which we were unable to discover our
188  * public address, we rely on learning our address from a directory
189  * authority from the NETINFO cell. */
190  if (!have_addr && last_dummy_circuit + DUMMY_DOWNLOAD_INTERVAL < now) {
191  last_dummy_circuit = now;
192 
194  if (BUG(!rs)) {
195  /* We should really always have trusted directories configured at this
196  * stage. They are loaded early either from default list or the one
197  * given in the configuration file. */
198  return;
199  }
200  const node_t *node = node_get_by_id(rs->identity_digest);
201  if (BUG(!node)) {
202  /* If there is a routerstatus_t, there is a node_t thus this should
203  * never fail. */
204  return;
205  }
206  extend_info_t *ei = extend_info_from_node(node, 1);
207  if (BUG(!ei)) {
208  return;
209  }
210 
211  log_debug(LD_GENERAL, "Attempting dummy testing circuit to an authority "
212  "in order to learn our address.");
213 
214  /* Launch a one-hop testing circuit to a trusted authority so we can learn
215  * our address through the NETINFO cell. */
219  extend_info_free(ei);
220  }
221 }
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:283
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:154
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.
circuituse.h
Header file for circuituse.c.
LD_GENERAL
#define LD_GENERAL
Definition: log.h:62
node_get_by_id
const node_t * node_get_by_id(const char *identity_digest)
Definition: nodelist.c:223
routerstatus_t
Definition: routerstatus_st.h:19
DUMMY_DOWNLOAD_INTERVAL
#define DUMMY_DOWNLOAD_INTERVAL
Definition: relay_find_addr.c:163
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:107
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.
circuitlist.h
Header file for circuitlist.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
node_t
Definition: node_st.h:34
CIRCLAUNCH_ONEHOP_TUNNEL
#define CIRCLAUNCH_ONEHOP_TUNNEL
Definition: circuituse.h:39
extend_info_from_node
extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect)
Definition: extendinfo.c:92
nodelist.h
Header file for nodelist.c.
router_pick_trusteddirserver
const routerstatus_t * router_pick_trusteddirserver(dirinfo_type_t type, int flags)
Definition: node_select.c:1040
node_select.h
Header file for node_select.c.
extendinfo.h
Header for core/or/extendinfo.c.
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:932
CIRCLAUNCH_IS_INTERNAL
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
resolve_addr.h
Header file for resolve_addr.c.
routerstatus_st.h
Routerstatus (consensus entry) structure.
resolved_addr_set_suggested
void resolved_addr_set_suggested(const tor_addr_t *addr)
Definition: resolve_addr.c:127
V3_DIRINFO
@ V3_DIRINFO
Definition: or.h:908
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:104
CIRCUIT_PURPOSE_TESTING
#define CIRCUIT_PURPOSE_TESTING
Definition: circuitlist.h:120
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:49
config.h
Header file for config.c.
or_options_t
Definition: or_options_st.h:64
resolved_addr_get_last
void resolved_addr_get_last(int family, tor_addr_t *addr_out)
Definition: resolve_addr.c:142
routerstatus_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: routerstatus_st.h:27
circuit_launch_by_extend_info
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
Definition: circuituse.c:2121
tor_addr_eq
#define tor_addr_eq(a, b)
Definition: address.h:280
extend_info_t
Definition: extend_info_st.h:27
or.h
Master header file for Tor-specific functionality.
LD_PROTOCOL
#define LD_PROTOCOL
Definition: log.h:72