Line data Source code
1 : /* Copyright (c) 2020-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file resolve_addr.c
6 : * \brief Implement resolving address functions
7 : **/
8 :
9 : #define RESOLVE_ADDR_PRIVATE
10 :
11 : #include "app/config/config.h"
12 : #include "app/config/resolve_addr.h"
13 :
14 : #include "core/mainloop/mainloop.h"
15 :
16 : #include "feature/control/control_events.h"
17 : #include "feature/dirauth/authmode.h"
18 :
19 : #include "lib/encoding/confline.h"
20 : #include "lib/net/gethostname.h"
21 : #include "lib/net/resolve.h"
22 :
23 : /** Maximum "Address" statement allowed in our configuration. */
24 : #define MAX_CONFIG_ADDRESS 2
25 :
26 : /** Ease our life. Arrays containing state per address family. These are to
27 : * add semantic to the code so we know what is accessed. */
28 : #define IDX_NULL 0 /* Index to zeroed address object. */
29 : #define IDX_IPV4 1 /* Index to AF_INET. */
30 : #define IDX_IPV6 2 /* Index to AF_INET6. */
31 : #define IDX_SIZE 3 /* How many indexes do we have. */
32 :
33 : /** Function in our address function table return one of these code. */
34 : typedef enum {
35 : /* The address has been found. */
36 : FN_RET_OK = 0,
37 : /* The failure requirements were not met and thus it is recommended that the
38 : * caller stops the search. */
39 : FN_RET_BAIL = 1,
40 : /* The address was not found or failure is transient so the caller should go
41 : * to the next method. */
42 : FN_RET_NEXT = 2,
43 : } fn_address_ret_t;
44 :
45 : /** Last resolved addresses. */
46 : static tor_addr_t last_resolved_addrs[] =
47 : { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL };
48 : CTASSERT(ARRAY_LENGTH(last_resolved_addrs) == IDX_SIZE);
49 :
50 : /** Last suggested addresses.
51 : *
52 : * These addresses come from a NETINFO cell from a trusted relay (currently
53 : * only authorities). We only use those in last resort. */
54 : static tor_addr_t last_suggested_addrs[] =
55 : { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL };
56 : CTASSERT(ARRAY_LENGTH(last_suggested_addrs) == IDX_SIZE);
57 :
58 : /** True iff the address was found to be configured that is from the
59 : * configuration file either using Address or ORPort. */
60 : static bool last_addrs_configured[] = { false, false, false };
61 : CTASSERT(ARRAY_LENGTH(last_addrs_configured) == IDX_SIZE);
62 :
63 : static inline int
64 162 : af_to_idx(const int family)
65 : {
66 162 : switch (family) {
67 : case AF_INET:
68 : return IDX_IPV4;
69 29 : case AF_INET6:
70 29 : return IDX_IPV6;
71 0 : default:
72 : /* It wouldn't be safe to just die here with an assert but we can heavily
73 : * scream with a bug. Return the index of the NULL address. */
74 0 : tor_assert_nonfatal_unreached();
75 0 : return IDX_NULL;
76 : }
77 : }
78 :
79 : /** Return string representation of the given method. */
80 : const char *
81 55 : resolved_addr_method_to_str(const resolved_addr_method_t method)
82 : {
83 55 : switch (method) {
84 : case RESOLVED_ADDR_NONE:
85 : return "NONE";
86 33 : case RESOLVED_ADDR_CONFIGURED:
87 33 : return "CONFIGURED";
88 4 : case RESOLVED_ADDR_CONFIGURED_ORPORT:
89 4 : return "CONFIGURED_ORPORT";
90 4 : case RESOLVED_ADDR_GETHOSTNAME:
91 4 : return "GETHOSTNAME";
92 8 : case RESOLVED_ADDR_INTERFACE:
93 8 : return "INTERFACE";
94 6 : case RESOLVED_ADDR_RESOLVED:
95 6 : return "RESOLVED";
96 0 : default:
97 0 : tor_assert_nonfatal_unreached();
98 0 : return "???";
99 : }
100 : }
101 :
102 : /** Return true if the last address of family was configured or not. An
103 : * address is considered configured if it was found in the Address or ORPort
104 : * statement.
105 : *
106 : * This applies to the address returned by the function
107 : * resolved_addr_get_last() which is the cache of discovered addresses. */
108 : bool
109 0 : resolved_addr_is_configured(int family)
110 : {
111 0 : return last_addrs_configured[af_to_idx(family)];
112 : }
113 :
114 : /** Copy the last suggested address of family into addr_out.
115 : *
116 : * If no last suggested address exists, the addr_out is a null address (use
117 : * tor_addr_is_null() to confirm). */
118 : void
119 12 : resolved_addr_get_suggested(int family, tor_addr_t *addr_out)
120 : {
121 12 : tor_addr_copy(addr_out, &last_suggested_addrs[af_to_idx(family)]);
122 12 : }
123 :
124 : /** Set the last suggested address into our cache. This is called when we get
125 : * a new NETINFO cell from a trusted source. */
126 : void
127 4 : resolved_addr_set_suggested(const tor_addr_t *addr)
128 : {
129 4 : if (BUG(tor_addr_family(addr) != AF_INET &&
130 : tor_addr_family(addr) != AF_INET6)) {
131 0 : return;
132 : }
133 :
134 : /* In case we don't have a configured address, log that we will be using the
135 : * one discovered from the dirauth. */
136 4 : const int idx = af_to_idx(tor_addr_family(addr));
137 8 : if (tor_addr_is_null(&last_resolved_addrs[idx]) &&
138 4 : !tor_addr_eq(&last_suggested_addrs[idx], addr)) {
139 4 : log_notice(LD_CONFIG, "External address seen and suggested by a "
140 : "directory authority: %s", fmt_addr(addr));
141 : }
142 4 : tor_addr_copy(&last_suggested_addrs[idx], addr);
143 : }
144 :
145 : /** Copy the last resolved address of family into addr_out.
146 : *
147 : * If not last resolved address existed, the addr_out is a null address (use
148 : * tor_addr_is_null()). */
149 : void
150 8 : resolved_addr_get_last(int family, tor_addr_t *addr_out)
151 : {
152 8 : tor_addr_copy(addr_out, &last_resolved_addrs[af_to_idx(family)]);
153 8 : }
154 :
155 : /** Reset the last resolved address of family.
156 : *
157 : * This makes it null address. */
158 : void
159 2 : resolved_addr_reset_last(int family)
160 : {
161 2 : tor_addr_make_null(&last_resolved_addrs[af_to_idx(family)], family);
162 2 : }
163 :
164 : /** Errors returned by address_can_be_used() in order for the caller to know
165 : * why the address is denied or not. */
166 : #define ERR_DEFAULT_DIRAUTH -1 /* Using default authorities. */
167 : #define ERR_ADDRESS_IS_INTERNAL -2 /* IP is internal. */
168 :
169 : /** @brief Return true iff the given IP address can be used as a valid
170 : * external resolved address.
171 : *
172 : * Two tests are done in this function:
173 : * 1) If the address if NOT internal, it can be used.
174 : * 2) If the address is internal and we have custom directory authorities
175 : * configured then it can they be used. Important for testing networks.
176 : *
177 : * @param addr The IP address to validate.
178 : * @param options Global configuration options.
179 : * @param warn_severity Log level that should be used on error.
180 : * @param explicit_ip Was the IP address explicitly given.
181 : *
182 : * @return Return 0 if it can be used. Return error code ERR_* found at the
183 : * top of the file.
184 : */
185 : static int
186 101 : address_can_be_used(const tor_addr_t *addr, const or_options_t *options,
187 : int warn_severity, const bool explicit_ip)
188 : {
189 101 : tor_assert(addr);
190 :
191 : /* Public address, this is fine. */
192 101 : if (!tor_addr_is_internal(addr, 0)) {
193 91 : goto allow;
194 : }
195 :
196 : /* We allow internal addresses to be used if the PublishServerDescriptor is
197 : * unset and AssumeReachable (or for IPv6) is set.
198 : *
199 : * This is to cover the case where a relay/bridge might be run behind a
200 : * firewall on a local network to users can reach the network through it
201 : * using Tor Browser for instance. */
202 10 : if (options->PublishServerDescriptor_ == NO_DIRINFO &&
203 2 : (options->AssumeReachable ||
204 1 : (tor_addr_family(addr) == AF_INET6 && options->AssumeReachableIPv6))) {
205 2 : goto allow;
206 : }
207 :
208 : /* We have a private IP address. This is also allowed if we set custom
209 : * directory authorities. */
210 8 : if (using_default_dir_authorities(options)) {
211 6 : log_fn(warn_severity, LD_CONFIG,
212 : "Address '%s' is a private IP address. Tor relays that use "
213 : "the default DirAuthorities must have public IP addresses.",
214 : fmt_addr(addr));
215 6 : return ERR_DEFAULT_DIRAUTH;
216 : }
217 :
218 2 : if (!explicit_ip) {
219 : /* Even with custom directory authorities, only an explicit internal
220 : * address is accepted. */
221 0 : log_fn(warn_severity, LD_CONFIG,
222 : "Address %s was resolved and thus not explicitly "
223 : "set. Even if DirAuthorities are custom, this is "
224 : "not allowed.", fmt_addr(addr));
225 0 : return ERR_ADDRESS_IS_INTERNAL;
226 : }
227 :
228 2 : allow:
229 : return 0;
230 : }
231 :
232 : /** @brief Get IP address from the given config line and for a specific address
233 : * family.
234 : *
235 : * This can fail is more than two Address statement are found for the same
236 : * address family. It also fails if no statement is found.
237 : *
238 : * @param options Global configuration options.
239 : * @param warn_severity Log level that should be used on error.
240 : * @param family IP address family. Only AF_INET and AF_INET6 are supported.
241 : * @param method_out OUT: Method denoting how the address was found.
242 : * This is described in the control-spec.txt as
243 : * actions for "STATUS_SERVER".
244 : * @param hostname_out OUT: String containing the hostname gotten from the
245 : * Address value if any.
246 : * @param addr_out OUT: Tor address of the address found in the cline or
247 : * resolved from the cline.
248 : *
249 : * @return Return 0 on success that is an address has been found or resolved
250 : * successfully. Return error code ERR_* found at the top of the file.
251 : */
252 : static fn_address_ret_t
253 106 : get_address_from_config(const or_options_t *options, int warn_severity,
254 : int family, resolved_addr_method_t *method_out,
255 : char **hostname_out, tor_addr_t *addr_out)
256 : {
257 106 : int ret;
258 106 : bool explicit_ip = false, resolve_failure = false;
259 106 : int num_valid_addr = 0;
260 :
261 106 : tor_assert(options);
262 106 : tor_assert(addr_out);
263 106 : tor_assert(method_out);
264 106 : tor_assert(hostname_out);
265 :
266 : /* Set them to NULL for safety reasons. */
267 106 : *hostname_out = NULL;
268 106 : *method_out = RESOLVED_ADDR_NONE;
269 :
270 106 : log_debug(LD_CONFIG, "Attempting to get address from configuration");
271 :
272 106 : if (!options->Address) {
273 14 : log_info(LD_CONFIG, "No Address option found in configuration.");
274 : /* No Address statement, inform caller to try next method. */
275 14 : return FN_RET_NEXT;
276 : }
277 :
278 194 : for (const config_line_t *cfg = options->Address; cfg != NULL;
279 102 : cfg = cfg->next) {
280 102 : int af;
281 102 : tor_addr_t addr;
282 :
283 102 : af = tor_addr_parse(&addr, cfg->value);
284 102 : if (af == family) {
285 87 : tor_addr_copy(addr_out, &addr);
286 87 : *method_out = RESOLVED_ADDR_CONFIGURED;
287 87 : explicit_ip = true;
288 87 : num_valid_addr++;
289 87 : continue;
290 15 : } else if (af != -1) {
291 : /* Parsable address but just not the one from the family we want. Skip
292 : * it so we don't attempt a resolve. */
293 4 : continue;
294 : }
295 :
296 : /* Not an IP address. Considering this value a hostname and attempting to
297 : * do a DNS lookup. */
298 11 : if (!tor_addr_lookup(cfg->value, family, &addr)) {
299 6 : tor_addr_copy(addr_out, &addr);
300 6 : *method_out = RESOLVED_ADDR_RESOLVED;
301 6 : if (*hostname_out) {
302 0 : tor_free(*hostname_out);
303 : }
304 6 : *hostname_out = tor_strdup(cfg->value);
305 6 : explicit_ip = false;
306 6 : num_valid_addr++;
307 6 : continue;
308 : } else {
309 : /* Hostname that can't be resolved, this is a fatal error. */
310 5 : resolve_failure = true;
311 5 : log_fn(warn_severity, LD_CONFIG,
312 : "Could not resolve local Address '%s'. Failing.", cfg->value);
313 5 : continue;
314 : }
315 : }
316 :
317 92 : if (!num_valid_addr) {
318 1 : if (resolve_failure) {
319 : /* We found no address but we got a resolution failure. This means we
320 : * can know if the hostname given was v4 or v6 so we can't continue. */
321 : return FN_RET_BAIL;
322 : }
323 0 : log_info(LD_CONFIG,
324 : "No Address option found for family %s in configuration.",
325 : fmt_af_family(family));
326 : /* No Address statement for family so move on to try next method. */
327 0 : return FN_RET_NEXT;
328 : }
329 :
330 91 : if (num_valid_addr >= MAX_CONFIG_ADDRESS) {
331 : /* Too many Address for same family. This is a fatal error. */
332 2 : log_fn(warn_severity, LD_CONFIG,
333 : "Found %d Address statement of address family %s. "
334 : "Only one is allowed.", num_valid_addr, fmt_af_family(family));
335 2 : tor_free(*hostname_out);
336 2 : return FN_RET_BAIL;
337 : }
338 :
339 : /* Great, we found an address. */
340 89 : ret = address_can_be_used(addr_out, options, warn_severity, explicit_ip);
341 89 : if (ret != 0) {
342 : /* One of the requirement of this interface is if an internal Address is
343 : * used, custom authorities must be defined else it is a fatal error.
344 : * Furthermore, if the Address was resolved to an internal interface, we
345 : * stop immediately. */
346 2 : if (ret == ERR_ADDRESS_IS_INTERNAL) {
347 0 : static bool logged_once = false;
348 0 : if (!logged_once) {
349 0 : log_warn(LD_CONFIG, "Address set with an internal address. Tor will "
350 : "not work unless custom directory authorities "
351 : "are defined (AlternateDirAuthority). It is also "
352 : "possible to use an internal address if "
353 : "PublishServerDescriptor is set to 0 and "
354 : "AssumeReachable(IPv6) to 1.");
355 0 : logged_once = true;
356 : }
357 : }
358 2 : tor_free(*hostname_out);
359 2 : return FN_RET_BAIL;
360 : }
361 :
362 : /* Address can be used. We are done. */
363 87 : log_info(LD_CONFIG, "Address found in configuration: %s",
364 : fmt_addr(addr_out));
365 87 : return FN_RET_OK;
366 : }
367 :
368 : /** @brief Get IP address from the local hostname by calling gethostbyname()
369 : * and doing a DNS resolution on the hostname.
370 : *
371 : * @param options Global configuration options.
372 : * @param warn_severity Log level that should be used on error.
373 : * @param family IP address family. Only AF_INET and AF_INET6 are supported.
374 : * @param method_out OUT: Method denoting how the address was found.
375 : * This is described in the control-spec.txt as
376 : * actions for "STATUS_SERVER".
377 : * @param hostname_out OUT: String containing the local hostname.
378 : * @param addr_out OUT: Tor address resolved from the local hostname.
379 : *
380 : * @return Return 0 on success that is an address has been found and resolved
381 : * successfully. Return error code ERR_* found at the top of the file.
382 : */
383 : static fn_address_ret_t
384 8 : get_address_from_hostname(const or_options_t *options, int warn_severity,
385 : int family, resolved_addr_method_t *method_out,
386 : char **hostname_out, tor_addr_t *addr_out)
387 : {
388 8 : int ret;
389 8 : char hostname[256];
390 :
391 8 : tor_assert(addr_out);
392 8 : tor_assert(method_out);
393 :
394 : /* Set them to NULL for safety reasons. */
395 8 : *hostname_out = NULL;
396 8 : *method_out = RESOLVED_ADDR_NONE;
397 :
398 8 : log_debug(LD_CONFIG, "Attempting to get address from local hostname");
399 :
400 8 : if (tor_gethostname(hostname, sizeof(hostname)) < 0) {
401 2 : log_fn(warn_severity, LD_NET, "Error obtaining local hostname");
402 : /* Unable to obtain the local hostname is a fatal error. */
403 2 : return FN_RET_BAIL;
404 : }
405 6 : if (tor_addr_lookup(hostname, family, addr_out)) {
406 2 : log_fn(warn_severity, LD_NET,
407 : "Could not resolve local hostname '%s'. Failing.", hostname);
408 : /* Unable to resolve, inform caller to try next method. */
409 2 : return FN_RET_NEXT;
410 : }
411 :
412 4 : ret = address_can_be_used(addr_out, options, warn_severity, false);
413 4 : if (ret == ERR_DEFAULT_DIRAUTH) {
414 : /* Non custom authorities, inform caller to try next method. */
415 : return FN_RET_NEXT;
416 2 : } else if (ret == ERR_ADDRESS_IS_INTERNAL) {
417 : /* Internal address is a fatal error. */
418 : return FN_RET_BAIL;
419 : }
420 :
421 : /* addr_out contains the address of the local hostname. */
422 2 : *method_out = RESOLVED_ADDR_GETHOSTNAME;
423 2 : *hostname_out = tor_strdup(hostname);
424 :
425 : /* Found it! */
426 2 : log_info(LD_CONFIG, "Address found from local hostname: %s",
427 : fmt_addr(addr_out));
428 2 : return FN_RET_OK;
429 : }
430 :
431 : /** @brief Get IP address from a network interface.
432 : *
433 : * @param options Global configuration options.
434 : * @param warn_severity Log level that should be used on error.
435 : * @param family IP address family. Only AF_INET and AF_INET6 are supported.
436 : * @param method_out OUT: Always RESOLVED_ADDR_INTERFACE on success which
437 : * is detailed in the control-spec.txt as actions
438 : * for "STATUS_SERVER".
439 : * @param hostname_out OUT: String containing the local hostname. For this
440 : * function, it is always set to NULL.
441 : * @param addr_out OUT: Tor address found attached to the interface.
442 : *
443 : * @return Return 0 on success that is an address has been found. Return
444 : * error code ERR_* found at the top of the file.
445 : */
446 : static fn_address_ret_t
447 12 : get_address_from_interface(const or_options_t *options, int warn_severity,
448 : int family, resolved_addr_method_t *method_out,
449 : char **hostname_out, tor_addr_t *addr_out)
450 : {
451 12 : int ret;
452 :
453 12 : tor_assert(method_out);
454 12 : tor_assert(hostname_out);
455 12 : tor_assert(addr_out);
456 :
457 : /* Set them to NULL for safety reasons. */
458 12 : *method_out = RESOLVED_ADDR_NONE;
459 12 : *hostname_out = NULL;
460 :
461 12 : log_debug(LD_CONFIG, "Attempting to get address from network interface");
462 :
463 12 : if (get_interface_address6(warn_severity, family, addr_out) < 0) {
464 8 : log_fn(warn_severity, LD_CONFIG,
465 : "Could not get local interface IP address.");
466 : /* Unable to get IP from interface. Inform caller to try next method. */
467 8 : return FN_RET_NEXT;
468 : }
469 :
470 4 : ret = address_can_be_used(addr_out, options, warn_severity, false);
471 4 : if (ret < 0) {
472 : /* Unable to use address. Inform caller to try next method. */
473 : return FN_RET_NEXT;
474 : }
475 :
476 4 : *method_out = RESOLVED_ADDR_INTERFACE;
477 :
478 : /* Found it! */
479 4 : log_info(LD_CONFIG, "Address found from interface: %s", fmt_addr(addr_out));
480 4 : return FN_RET_OK;
481 : }
482 :
483 : /** @brief Get IP address from the ORPort (if any).
484 : *
485 : * @param options Global configuration options.
486 : * @param warn_severity Log level that should be used on error.
487 : * @param family IP address family. Only AF_INET and AF_INET6 are supported.
488 : * @param method_out OUT: Always RESOLVED_ADDR_CONFIGURED_ORPORT on success
489 : * which is detailed in the control-spec.txt as actions
490 : * for "STATUS_SERVER".
491 : * @param hostname_out OUT: String containing the ORPort hostname if any.
492 : * @param addr_out OUT: Tor address found if any.
493 : *
494 : * @return Return 0 on success that is an address has been found. Return
495 : * error code ERR_* found at the top of the file.
496 : */
497 : static fn_address_ret_t
498 14 : get_address_from_orport(const or_options_t *options, int warn_severity,
499 : int family, resolved_addr_method_t *method_out,
500 : char **hostname_out, tor_addr_t *addr_out)
501 : {
502 14 : int ret;
503 14 : const tor_addr_t *addr;
504 :
505 14 : tor_assert(method_out);
506 14 : tor_assert(hostname_out);
507 14 : tor_assert(addr_out);
508 :
509 : /* Set them to NULL for safety reasons. */
510 14 : *method_out = RESOLVED_ADDR_NONE;
511 14 : *hostname_out = NULL;
512 :
513 14 : log_debug(LD_CONFIG, "Attempting to get address from ORPort");
514 :
515 14 : if (!options->ORPort_set) {
516 10 : log_info(LD_CONFIG, "No ORPort found in configuration.");
517 : /* No ORPort statement, inform caller to try next method. */
518 10 : return FN_RET_NEXT;
519 : }
520 :
521 : /* Get ORPort for requested family. */
522 4 : addr = get_orport_addr(family);
523 4 : if (!addr) {
524 : /* No address configured for the ORPort. Ignore. */
525 : return FN_RET_NEXT;
526 : }
527 :
528 : /* We found the ORPort address. Just make sure it can be used. */
529 4 : ret = address_can_be_used(addr, options, warn_severity, true);
530 4 : if (ret < 0) {
531 : /* Unable to use address. Inform caller to try next method. */
532 : return FN_RET_NEXT;
533 : }
534 :
535 : /* Found it! */
536 2 : *method_out = RESOLVED_ADDR_CONFIGURED_ORPORT;
537 2 : tor_addr_copy(addr_out, addr);
538 :
539 2 : log_fn(warn_severity, LD_CONFIG, "Address found from ORPort: %s",
540 : fmt_addr(addr_out));
541 2 : return FN_RET_OK;
542 : }
543 :
544 : /** @brief Set the last resolved address cache using the given address.
545 : *
546 : * A log notice is emitted if the given address has changed from before. Not
547 : * emitted on first resolve.
548 : *
549 : * Control port event "STATUS_SERVER" is emitted with the new information if
550 : * it has changed.
551 : *
552 : * Finally, tor is notified that the IP address has changed.
553 : *
554 : * @param addr IP address to update the cache with.
555 : * @param method_used By which method did we resolved it (for logging and
556 : * control port).
557 : * @param hostname_used Which hostname was used. If none were used, it is
558 : * NULL. (for logging and control port).
559 : */
560 : void
561 97 : resolved_addr_set_last(const tor_addr_t *addr,
562 : const resolved_addr_method_t method_used,
563 : const char *hostname_used)
564 : {
565 : /** Have we done a first resolve. This is used to control logging. */
566 97 : static bool have_resolved_once[] = { false, false, false };
567 97 : CTASSERT(ARRAY_LENGTH(have_resolved_once) == IDX_SIZE);
568 :
569 97 : bool *done_one_resolve;
570 97 : bool have_hostname = false;
571 97 : tor_addr_t *last_resolved;
572 :
573 97 : tor_assert(addr);
574 :
575 : /* Do we have an hostname. */
576 97 : have_hostname = (hostname_used != NULL);
577 :
578 97 : int idx = af_to_idx(tor_addr_family(addr));
579 97 : if (idx == IDX_NULL) {
580 : /* Not suppose to happen and if it does, af_to_idx() screams loudly. */
581 : return;
582 : }
583 :
584 : /* Get values from cache. */
585 97 : done_one_resolve = &have_resolved_once[idx];
586 97 : last_resolved = &last_resolved_addrs[idx];
587 :
588 : /* Same address last resolved. Ignore. */
589 97 : if (tor_addr_eq(last_resolved, addr)) {
590 : return;
591 : }
592 :
593 : /* Don't log notice if this is the first resolve we do. */
594 37 : if (*done_one_resolve) {
595 : /* Leave this as a notice, regardless of the requested severity,
596 : * at least until dynamic IP address support becomes bulletproof. */
597 44 : log_notice(LD_NET,
598 : "Your IP address seems to have changed to %s "
599 : "(METHOD=%s%s%s). Updating.",
600 : fmt_addr(addr),
601 : resolved_addr_method_to_str(method_used),
602 : have_hostname ? " HOSTNAME=" : "",
603 : have_hostname ? hostname_used : "");
604 18 : ip_address_changed(0);
605 : }
606 :
607 : /* Notify control port. */
608 101 : control_event_server_status(LOG_NOTICE,
609 : "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s%s%s",
610 : fmt_addr(addr),
611 : resolved_addr_method_to_str(method_used),
612 : have_hostname ? " HOSTNAME=" : "",
613 : have_hostname ? hostname_used : "");
614 : /* Copy address to cache. */
615 37 : tor_addr_copy(last_resolved, addr);
616 37 : *done_one_resolve = true;
617 :
618 : /* Flag true if the address was configured. Else, indicate it was not. */
619 37 : last_addrs_configured[idx] = false;
620 37 : if (method_used == RESOLVED_ADDR_CONFIGURED ||
621 : method_used == RESOLVED_ADDR_CONFIGURED_ORPORT) {
622 28 : last_addrs_configured[idx] = true;
623 : }
624 : }
625 :
626 : /** Ease our lives. Typedef to the address discovery function signature. */
627 : typedef fn_address_ret_t
628 : (*fn_address_t)(
629 : const or_options_t *options, int warn_severity, int family,
630 : resolved_addr_method_t *method_out, char **hostname_out,
631 : tor_addr_t *addr_out);
632 :
633 : /** Address discovery function table. The order matters as in the first one is
634 : * executed first and so on. */
635 : static const fn_address_t fn_address_table[] =
636 : {
637 : /* These functions are in order for our find address algorithm. */
638 : get_address_from_config,
639 : get_address_from_orport,
640 : get_address_from_interface,
641 : get_address_from_hostname,
642 : };
643 : /** Length of address table as in how many functions. */
644 : static const size_t fn_address_table_len =
645 : ARRAY_LENGTH(fn_address_table);
646 :
647 : /* Address discover function table for authorities (bridge or directory).
648 : *
649 : * They only discover their address from either the configuration file or the
650 : * ORPort. They do not query the interface nor do any DNS resolution for
651 : * security reasons. */
652 : static const fn_address_t fn_address_table_auth[] =
653 : {
654 : /* These functions are in order for our find address algorithm. */
655 : get_address_from_config,
656 : get_address_from_orport,
657 : };
658 : /** Length of address table as in how many functions. */
659 : static const size_t fn_address_table_auth_len =
660 : ARRAY_LENGTH(fn_address_table_auth);
661 :
662 : /** @brief Attempt to find our IP address that can be used as our external
663 : * reachable address.
664 : *
665 : * The following describe the algorithm to find an address. Each have
666 : * specific conditions so read carefully.
667 : *
668 : * On success, true is returned and depending on how the address was found,
669 : * the out parameters can have different values.
670 : *
671 : * On error, false is returned and out parameters are set to NULL.
672 : *
673 : * 1. Look at the configuration Address option.
674 :
675 : * If Address is a public address, True is returned and addr_out is set
676 : * with it, the method_out is set to RESOLVED_ADDR_CONFIGURED and
677 : * hostname_out is set to NULL.
678 : *
679 : * If Address is an internal address but NO custom authorities are used,
680 : * an error is returned.
681 : *
682 : * If Address is a hostname, that is it can't be converted to an address,
683 : * it is resolved. On success, addr_out is set with the address,
684 : * method_out is set to RESOLVED_ADDR_RESOLVED and hostname_out is set
685 : * to the resolved hostname. On failure to resolve, an error is returned.
686 : *
687 : * If no given Address, fallback to the network interface (see section 2).
688 : *
689 : * 2. Look at the network interface.
690 : *
691 : * Attempt to find the first public usable address from the list of
692 : * network interfaces returned by the OS.
693 : *
694 : * On failure, we attempt to look at the local hostname (3).
695 : *
696 : * On success, addr_out is set with it, method_out is set to
697 : * RESOLVED_ADDR_INTERFACE and hostname_out is set to NULL.
698 : *
699 : * 3. Look at the local hostname.
700 : *
701 : * If the local hostname resolves to a non internal address, addr_out is
702 : * set with it, method_out is set to RESOLVED_ADDR_GETHOSTNAME and
703 : * hostname_out is set to the resolved hostname.
704 : *
705 : * If a local hostname can NOT be found, an error is returned.
706 : *
707 : * If the local hostname resolves to an internal address, an error is
708 : * returned.
709 : *
710 : * If the local hostname can NOT be resolved, an error is returned.
711 : *
712 : * @param options Global configuration options.
713 : * @param family IP address family. Only AF_INET and AF_INET6 are supported.
714 : * @param warn_severity Logging level.
715 : * @param addr_out OUT: Set with the IP address found if any.
716 : * @param method_out OUT: (optional) Method denoting how the address wa
717 : * found. This is described in the control-spec.txt as
718 : * actions for "STATUS_SERVER".
719 : * @param hostname_out OUT: String containing the hostname if any was used.
720 : * Only be set for RESOLVED and GETHOSTNAME methods.
721 : * Else it is set to NULL.
722 : *
723 : * @return True if the address was found for the given family. False if not or
724 : * on errors.
725 : */
726 : bool
727 107 : find_my_address(const or_options_t *options, int family, int warn_severity,
728 : tor_addr_t *addr_out, resolved_addr_method_t *method_out,
729 : char **hostname_out)
730 : {
731 107 : resolved_addr_method_t method_used = RESOLVED_ADDR_NONE;
732 107 : char *hostname_used = NULL;
733 107 : tor_addr_t my_addr;
734 107 : const fn_address_t *table = fn_address_table;
735 107 : size_t table_len = fn_address_table_len;
736 :
737 107 : tor_assert(options);
738 107 : tor_assert(addr_out);
739 :
740 : /* Set them to NULL for safety reasons. */
741 107 : tor_addr_make_unspec(addr_out);
742 107 : if (method_out) *method_out = RESOLVED_ADDR_NONE;
743 107 : if (hostname_out) *hostname_out = NULL;
744 :
745 : /* If an IPv6 is requested, check if IPv6 address discovery is disabled and
746 : * if so we always return a failure. It is done here so we don't populate
747 : * the resolve cache or do any DNS resolution. */
748 107 : if (family == AF_INET6 && options->AddressDisableIPv6) {
749 : return false;
750 : }
751 :
752 : /* For authorities (bridge and directory), we use a different table. */
753 106 : if (authdir_mode(options)) {
754 71 : table = fn_address_table_auth;
755 71 : table_len = fn_address_table_auth_len;
756 : }
757 :
758 : /*
759 : * Step 1: Discover address by calling methods from the function table.
760 : */
761 :
762 : /* Go over the function table. They are in order. */
763 144 : for (size_t idx = 0; idx < table_len; idx++) {
764 140 : fn_address_ret_t ret = table[idx](options, warn_severity, family,
765 : &method_used, &hostname_used, &my_addr);
766 140 : if (ret == FN_RET_BAIL) {
767 : return false;
768 133 : } else if (ret == FN_RET_OK) {
769 95 : goto found;
770 : }
771 38 : tor_assert(ret == FN_RET_NEXT);
772 : }
773 :
774 : /* We've exhausted our attempts. Failure. */
775 4 : log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address.");
776 4 : return false;
777 :
778 95 : found:
779 : /*
780 : * Step 2: Update last resolved address cache and inform the control port.
781 : */
782 95 : resolved_addr_set_last(&my_addr, method_used, hostname_used);
783 :
784 95 : if (method_out) {
785 25 : *method_out = method_used;
786 : }
787 95 : if (hostname_out) {
788 25 : *hostname_out = hostname_used;
789 : } else {
790 70 : tor_free(hostname_used);
791 : }
792 :
793 95 : tor_addr_copy(addr_out, &my_addr);
794 95 : return true;
795 : }
796 :
797 : /** @brief: Return true iff the given addr is judged to be local to our
798 : * resolved address.
799 : *
800 : * This function is used to tell whether another address is 'remote' enough
801 : * that we can trust it when it tells us that we are reachable, or that we
802 : * have a certain address.
803 : *
804 : * The criterion to learn if the address is local are the following:
805 : *
806 : * 1. Internal address.
807 : * 2. If EnforceDistinctSubnets is set then it is never local.
808 : * 3. Network mask is compared. IPv4: /24 and IPv6 /48. This is different
809 : * from the path selection that looks at /16 and /32 because we only
810 : * want to learn here if the address is considered to come from the
811 : * Internet basically.
812 : *
813 : * @param addr The address to test if local and also test against our resovled
814 : * address.
815 : *
816 : * @return True iff address is considered local or else False.
817 : */
818 35 : MOCK_IMPL(bool,
819 : is_local_to_resolve_addr, (const tor_addr_t *addr))
820 : {
821 35 : const int family = tor_addr_family(addr);
822 70 : const tor_addr_t *last_resolved_addr =
823 35 : &last_resolved_addrs[af_to_idx(family)];
824 :
825 : /* Internal address is always local. */
826 35 : if (tor_addr_is_internal(addr, 0)) {
827 : return true;
828 : }
829 :
830 : /* Address is not local if we don't enforce subnet distinction. */
831 5 : if (get_options()->EnforceDistinctSubnets == 0) {
832 : return false;
833 : }
834 :
835 5 : switch (family) {
836 5 : case AF_INET:
837 : /* It's possible that this next check will hit before the first time
838 : * find_my_address actually succeeds. For clients, it is likely that
839 : * find_my_address will never be called at all. In those cases,
840 : * last_resolved_addr_v4 will be 0, and so checking to see whether ip is
841 : * on the same /24 as last_resolved_addrs[AF_INET] will be the same as
842 : * checking whether it was on net 0, which is already done by
843 : * tor_addr_is_internal. */
844 5 : return tor_addr_compare_masked(addr, last_resolved_addr, 24,
845 5 : CMP_SEMANTIC) == 0;
846 0 : case AF_INET6:
847 : /* Look at /48 because it is typically the smallest network in the global
848 : * IPv6 routing tables, and it was previously the recommended per-customer
849 : * network block. (See [RFC 6177: IPv6 End Site Address Assignment].) */
850 0 : return tor_addr_compare_masked(addr, last_resolved_addr, 48,
851 0 : CMP_SEMANTIC) == 0;
852 : break;
853 : default:
854 : /* Unknown address type so not local. */
855 : return false;
856 : }
857 : }
858 :
859 : #ifdef TOR_UNIT_TESTS
860 :
861 : void
862 4 : resolve_addr_reset_suggested(int family)
863 : {
864 4 : tor_addr_make_unspec(&last_suggested_addrs[af_to_idx(family)]);
865 4 : }
866 :
867 : #endif /* defined(TOR_UNIT_TESTS) */
|