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