Tor 0.4.9.0-alpha-dev
resolve_addr.c
Go to the documentation of this file.
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"
13
15
18
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. */
34typedef 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,
44
45/** Last resolved addresses. */
47 { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL };
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. */
55 { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL };
57
58/** True iff the address was found to be configured that is from the
59 * configuration file either using Address or ORPort. */
60static bool last_addrs_configured[] = { false, false, false };
62
63static inline int
64af_to_idx(const int family)
65{
66 switch (family) {
67 case AF_INET:
68 return IDX_IPV4;
69 case AF_INET6:
70 return IDX_IPV6;
71 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. */
75 return IDX_NULL;
76 }
77}
78
79/** Return string representation of the given method. */
80const char *
82{
83 switch (method) {
84 case RESOLVED_ADDR_NONE:
85 return "NONE";
86 case RESOLVED_ADDR_CONFIGURED:
87 return "CONFIGURED";
88 case RESOLVED_ADDR_CONFIGURED_ORPORT:
89 return "CONFIGURED_ORPORT";
90 case RESOLVED_ADDR_GETHOSTNAME:
91 return "GETHOSTNAME";
92 case RESOLVED_ADDR_INTERFACE:
93 return "INTERFACE";
94 case RESOLVED_ADDR_RESOLVED:
95 return "RESOLVED";
96 default:
98 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. */
108bool
110{
111 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). */
118void
120{
121 tor_addr_copy(addr_out, &last_suggested_addrs[af_to_idx(family)]);
122}
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. */
126void
128{
129 if (BUG(tor_addr_family(addr) != AF_INET &&
130 tor_addr_family(addr) != AF_INET6)) {
131 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 const int idx = af_to_idx(tor_addr_family(addr));
138 !tor_addr_eq(&last_suggested_addrs[idx], addr)) {
139 log_notice(LD_CONFIG, "External address seen and suggested by a "
140 "directory authority: %s", fmt_addr(addr));
141 }
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()). */
149void
150resolved_addr_get_last(int family, tor_addr_t *addr_out)
151{
152 tor_addr_copy(addr_out, &last_resolved_addrs[af_to_idx(family)]);
153}
154
155/** Reset the last resolved address of family.
156 *
157 * This makes it null address. */
158void
160{
161 tor_addr_make_null(&last_resolved_addrs[af_to_idx(family)], family);
162}
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 */
185static int
186address_can_be_used(const tor_addr_t *addr, const or_options_t *options,
187 int warn_severity, const bool explicit_ip)
188{
189 tor_assert(addr);
190
191 /* Public address, this is fine. */
192 if (!tor_addr_is_internal(addr, 0)) {
193 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 if (options->PublishServerDescriptor_ == NO_DIRINFO &&
203 (options->AssumeReachable ||
204 (tor_addr_family(addr) == AF_INET6 && options->AssumeReachableIPv6))) {
205 goto allow;
206 }
207
208 /* We have a private IP address. This is also allowed if we set custom
209 * directory authorities. */
210 if (using_default_dir_authorities(options)) {
211 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 return ERR_DEFAULT_DIRAUTH;
216 }
217
218 if (!explicit_ip) {
219 /* Even with custom directory authorities, only an explicit internal
220 * address is accepted. */
221 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 return ERR_ADDRESS_IS_INTERNAL;
226 }
227
228 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 */
252static fn_address_ret_t
253get_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 int ret;
258 bool explicit_ip = false, resolve_failure = false;
259 int num_valid_addr = 0;
260
261 tor_assert(options);
262 tor_assert(addr_out);
263 tor_assert(method_out);
264 tor_assert(hostname_out);
265
266 /* Set them to NULL for safety reasons. */
267 *hostname_out = NULL;
268 *method_out = RESOLVED_ADDR_NONE;
269
270 log_debug(LD_CONFIG, "Attempting to get address from configuration");
271
272 if (!options->Address) {
273 log_info(LD_CONFIG, "No Address option found in configuration.");
274 /* No Address statement, inform caller to try next method. */
275 return FN_RET_NEXT;
276 }
277
278 for (const config_line_t *cfg = options->Address; cfg != NULL;
279 cfg = cfg->next) {
280 int af;
281 tor_addr_t addr;
282
283 af = tor_addr_parse(&addr, cfg->value);
284 if (af == family) {
285 tor_addr_copy(addr_out, &addr);
286 *method_out = RESOLVED_ADDR_CONFIGURED;
287 explicit_ip = true;
288 num_valid_addr++;
289 continue;
290 } 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 continue;
294 }
295
296 /* Not an IP address. Considering this value a hostname and attempting to
297 * do a DNS lookup. */
298 if (!tor_addr_lookup(cfg->value, family, &addr)) {
299 tor_addr_copy(addr_out, &addr);
300 *method_out = RESOLVED_ADDR_RESOLVED;
301 if (*hostname_out) {
302 tor_free(*hostname_out);
303 }
304 *hostname_out = tor_strdup(cfg->value);
305 explicit_ip = false;
306 num_valid_addr++;
307 continue;
308 } else {
309 /* Hostname that can't be resolved, this is a fatal error. */
310 resolve_failure = true;
311 log_fn(warn_severity, LD_CONFIG,
312 "Could not resolve local Address '%s'. Failing.", cfg->value);
313 continue;
314 }
315 }
316
317 if (!num_valid_addr) {
318 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 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 return FN_RET_NEXT;
328 }
329
330 if (num_valid_addr >= MAX_CONFIG_ADDRESS) {
331 /* Too many Address for same family. This is a fatal error. */
332 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 tor_free(*hostname_out);
336 return FN_RET_BAIL;
337 }
338
339 /* Great, we found an address. */
340 ret = address_can_be_used(addr_out, options, warn_severity, explicit_ip);
341 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 if (ret == ERR_ADDRESS_IS_INTERNAL) {
347 static bool logged_once = false;
348 if (!logged_once) {
349 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 logged_once = true;
356 }
357 }
358 tor_free(*hostname_out);
359 return FN_RET_BAIL;
360 }
361
362 /* Address can be used. We are done. */
363 log_info(LD_CONFIG, "Address found in configuration: %s",
364 fmt_addr(addr_out));
365 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 */
383static fn_address_ret_t
384get_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 int ret;
389 char hostname[256];
390
391 tor_assert(addr_out);
392 tor_assert(method_out);
393
394 /* Set them to NULL for safety reasons. */
395 *hostname_out = NULL;
396 *method_out = RESOLVED_ADDR_NONE;
397
398 log_debug(LD_CONFIG, "Attempting to get address from local hostname");
399
400 if (tor_gethostname(hostname, sizeof(hostname)) < 0) {
401 log_fn(warn_severity, LD_NET, "Error obtaining local hostname");
402 /* Unable to obtain the local hostname is a fatal error. */
403 return FN_RET_BAIL;
404 }
405 if (tor_addr_lookup(hostname, family, addr_out)) {
406 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 return FN_RET_NEXT;
410 }
411
412 ret = address_can_be_used(addr_out, options, warn_severity, false);
413 if (ret == ERR_DEFAULT_DIRAUTH) {
414 /* Non custom authorities, inform caller to try next method. */
415 return FN_RET_NEXT;
416 } 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 *method_out = RESOLVED_ADDR_GETHOSTNAME;
423 *hostname_out = tor_strdup(hostname);
424
425 /* Found it! */
426 log_info(LD_CONFIG, "Address found from local hostname: %s",
427 fmt_addr(addr_out));
428 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 */
446static fn_address_ret_t
447get_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 int ret;
452
453 tor_assert(method_out);
454 tor_assert(hostname_out);
455 tor_assert(addr_out);
456
457 /* Set them to NULL for safety reasons. */
458 *method_out = RESOLVED_ADDR_NONE;
459 *hostname_out = NULL;
460
461 log_debug(LD_CONFIG, "Attempting to get address from network interface");
462
463 if (get_interface_address6(warn_severity, family, addr_out) < 0) {
464 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 return FN_RET_NEXT;
468 }
469
470 ret = address_can_be_used(addr_out, options, warn_severity, false);
471 if (ret < 0) {
472 /* Unable to use address. Inform caller to try next method. */
473 return FN_RET_NEXT;
474 }
475
476 *method_out = RESOLVED_ADDR_INTERFACE;
477
478 /* Found it! */
479 log_info(LD_CONFIG, "Address found from interface: %s", fmt_addr(addr_out));
480 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 */
497static fn_address_ret_t
498get_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 int ret;
503 const tor_addr_t *addr;
504
505 tor_assert(method_out);
506 tor_assert(hostname_out);
507 tor_assert(addr_out);
508
509 /* Set them to NULL for safety reasons. */
510 *method_out = RESOLVED_ADDR_NONE;
511 *hostname_out = NULL;
512
513 log_debug(LD_CONFIG, "Attempting to get address from ORPort");
514
515 if (!options->ORPort_set) {
516 log_info(LD_CONFIG, "No ORPort found in configuration.");
517 /* No ORPort statement, inform caller to try next method. */
518 return FN_RET_NEXT;
519 }
520
521 /* Get ORPort for requested family. */
522 addr = get_orport_addr(family);
523 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 ret = address_can_be_used(addr, options, warn_severity, true);
530 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 *method_out = RESOLVED_ADDR_CONFIGURED_ORPORT;
537 tor_addr_copy(addr_out, addr);
538
539 log_fn(warn_severity, LD_CONFIG, "Address found from ORPort: %s",
540 fmt_addr(addr_out));
541 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 */
560void
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 static bool have_resolved_once[] = { false, false, false };
567 CTASSERT(ARRAY_LENGTH(have_resolved_once) == IDX_SIZE);
568
569 bool *done_one_resolve;
570 bool have_hostname = false;
571 tor_addr_t *last_resolved;
572
573 tor_assert(addr);
574
575 /* Do we have an hostname. */
576 have_hostname = (hostname_used != NULL);
577
578 int idx = af_to_idx(tor_addr_family(addr));
579 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 done_one_resolve = &have_resolved_once[idx];
586 last_resolved = &last_resolved_addrs[idx];
587
588 /* Same address last resolved. Ignore. */
589 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 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 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 : "");
605 }
606
607 /* Notify control port. */
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 tor_addr_copy(last_resolved, addr);
616 *done_one_resolve = true;
617
618 /* Flag true if the address was configured. Else, indicate it was not. */
619 last_addrs_configured[idx] = false;
620 if (method_used == RESOLVED_ADDR_CONFIGURED ||
621 method_used == RESOLVED_ADDR_CONFIGURED_ORPORT) {
622 last_addrs_configured[idx] = true;
623 }
624}
625
626/** Ease our lives. Typedef to the address discovery function signature. */
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. */
636{
637 /* These functions are in order for our find address algorithm. */
642};
643/** Length of address table as in how many functions. */
644static const size_t fn_address_table_len =
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. */
652static const fn_address_t fn_address_table_auth[] =
653{
654 /* These functions are in order for our find address algorithm. */
657};
658/** Length of address table as in how many functions. */
659static 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 */
726bool
727find_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 resolved_addr_method_t method_used = RESOLVED_ADDR_NONE;
732 char *hostname_used = NULL;
733 tor_addr_t my_addr;
734 const fn_address_t *table = fn_address_table;
735 size_t table_len = fn_address_table_len;
736
737 tor_assert(options);
738 tor_assert(addr_out);
739
740 /* Set them to NULL for safety reasons. */
741 tor_addr_make_unspec(addr_out);
742 if (method_out) *method_out = RESOLVED_ADDR_NONE;
743 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 if (family == AF_INET6 && options->AddressDisableIPv6) {
749 return false;
750 }
751
752 /* For authorities (bridge and directory), we use a different table. */
753 if (authdir_mode(options)) {
754 table = fn_address_table_auth;
755 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 for (size_t idx = 0; idx < table_len; idx++) {
764 fn_address_ret_t ret = table[idx](options, warn_severity, family,
765 &method_used, &hostname_used, &my_addr);
766 if (ret == FN_RET_BAIL) {
767 return false;
768 } else if (ret == FN_RET_OK) {
769 goto found;
770 }
771 tor_assert(ret == FN_RET_NEXT);
772 }
773
774 /* We've exhausted our attempts. Failure. */
775 log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address.");
776 return false;
777
778 found:
779 /*
780 * Step 2: Update last resolved address cache and inform the control port.
781 */
782 resolved_addr_set_last(&my_addr, method_used, hostname_used);
783
784 if (method_out) {
785 *method_out = method_used;
786 }
787 if (hostname_out) {
788 *hostname_out = hostname_used;
789 } else {
790 tor_free(hostname_used);
791 }
792
793 tor_addr_copy(addr_out, &my_addr);
794 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 resolved
814 * address.
815 *
816 * @return True iff address is considered local or else False.
817 */
818MOCK_IMPL(bool,
820{
821 const int family = tor_addr_family(addr);
822 const tor_addr_t *last_resolved_addr =
823 &last_resolved_addrs[af_to_idx(family)];
824
825 /* Internal address is always local. */
826 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 if (get_options()->EnforceDistinctSubnets == 0) {
832 return false;
833 }
834
835 switch (family) {
836 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 return tor_addr_compare_masked(addr, last_resolved_addr, 24,
845 CMP_SEMANTIC) == 0;
846 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 return tor_addr_compare_masked(addr, last_resolved_addr, 48,
851 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
861void
862resolve_addr_reset_suggested(int family)
863{
864 tor_addr_make_unspec(&last_suggested_addrs[af_to_idx(family)]);
865}
866
867#endif /* defined(TOR_UNIT_TESTS) */
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
Definition: address.c:933
void tor_addr_make_unspec(tor_addr_t *a)
Definition: address.c:225
int tor_addr_parse(tor_addr_t *addr, const char *src)
Definition: address.c:1349
void tor_addr_make_null(tor_addr_t *a, sa_family_t family)
Definition: address.c:235
int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, maskbits_t mbits, tor_addr_comparison_t how)
Definition: address.c:1005
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr)
Definition: address.c:1723
const char * fmt_af_family(sa_family_t family)
Definition: address.c:1246
static sa_family_t tor_addr_family(const tor_addr_t *a)
Definition: address.h:187
#define fmt_addr(a)
Definition: address.h:239
#define tor_addr_eq(a, b)
Definition: address.h:280
int authdir_mode(const or_options_t *options)
Definition: authmode.c:25
Header file for directory authority mode.
#define ARRAY_LENGTH(x)
const or_options_t * get_options(void)
Definition: config.c:944
Header file for config.c.
Header for confline.c.
int control_event_server_status(int severity, const char *format,...)
Header file for control_events.c.
CTASSERT(NUMBER_SECOND_GUARDS< 20)
int tor_gethostname(char *name, size_t namelen)
Definition: gethostname.c:27
Header for gethostname.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_NET
Definition: log.h:66
#define LOG_NOTICE
Definition: log.h:50
#define LD_CONFIG
Definition: log.h:68
void ip_address_changed(int on_client_conn)
Definition: mainloop.c:2318
Header file for mainloop.c.
#define tor_free(p)
Definition: malloc.h:56
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
Definition: resolve.c:190
Header for resolve.c.
static fn_address_ret_t get_address_from_hostname(const or_options_t *options, int warn_severity, int family, resolved_addr_method_t *method_out, char **hostname_out, tor_addr_t *addr_out)
Get IP address from the local hostname by calling gethostbyname() and doing a DNS resolution on the h...
Definition: resolve_addr.c:384
static const fn_address_t fn_address_table[]
Definition: resolve_addr.c:635
static fn_address_ret_t get_address_from_config(const or_options_t *options, int warn_severity, int family, resolved_addr_method_t *method_out, char **hostname_out, tor_addr_t *addr_out)
Get IP address from the given config line and for a specific address family.
Definition: resolve_addr.c:253
bool is_local_to_resolve_addr(const tor_addr_t *addr)
: Return true iff the given addr is judged to be local to our resolved address.
Definition: resolve_addr.c:819
void resolved_addr_set_suggested(const tor_addr_t *addr)
Definition: resolve_addr.c:127
static tor_addr_t last_resolved_addrs[]
Definition: resolve_addr.c:46
fn_address_ret_t(* fn_address_t)(const or_options_t *options, int warn_severity, int family, resolved_addr_method_t *method_out, char **hostname_out, tor_addr_t *addr_out)
Definition: resolve_addr.c:628
#define ERR_DEFAULT_DIRAUTH
Definition: resolve_addr.c:166
void resolved_addr_reset_last(int family)
Definition: resolve_addr.c:159
static fn_address_ret_t get_address_from_interface(const or_options_t *options, int warn_severity, int family, resolved_addr_method_t *method_out, char **hostname_out, tor_addr_t *addr_out)
Get IP address from a network interface.
Definition: resolve_addr.c:447
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:727
static const size_t fn_address_table_auth_len
Definition: resolve_addr.c:659
static const size_t fn_address_table_len
Definition: resolve_addr.c:644
static int address_can_be_used(const tor_addr_t *addr, const or_options_t *options, int warn_severity, const bool explicit_ip)
Return true iff the given IP address can be used as a valid external resolved address.
Definition: resolve_addr.c:186
#define MAX_CONFIG_ADDRESS
Definition: resolve_addr.c:24
void resolved_addr_get_suggested(int family, tor_addr_t *addr_out)
Definition: resolve_addr.c:119
#define IDX_NULL
Definition: resolve_addr.c:28
bool resolved_addr_is_configured(int family)
Definition: resolve_addr.c:109
static tor_addr_t last_suggested_addrs[]
Definition: resolve_addr.c:54
static fn_address_ret_t get_address_from_orport(const or_options_t *options, int warn_severity, int family, resolved_addr_method_t *method_out, char **hostname_out, tor_addr_t *addr_out)
Get IP address from the ORPort (if any).
Definition: resolve_addr.c:498
static bool last_addrs_configured[]
Definition: resolve_addr.c:60
void resolved_addr_set_last(const tor_addr_t *addr, const resolved_addr_method_t method_used, const char *hostname_used)
Set the last resolved address cache using the given address.
Definition: resolve_addr.c:561
fn_address_ret_t
Definition: resolve_addr.c:34
void resolved_addr_get_last(int family, tor_addr_t *addr_out)
Definition: resolve_addr.c:150
const char * resolved_addr_method_to_str(const resolved_addr_method_t method)
Definition: resolve_addr.c:81
Header file for resolve_addr.c.
resolved_addr_method_t
Definition: resolve_addr.h:19
dirinfo_type_t PublishServerDescriptor_
int AddressDisableIPv6
struct config_line_t * Address
int AssumeReachableIPv6
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:177
#define tor_assert(expr)
Definition: util_bug.h:103