resolve_addr.c 28.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* Copyright (c) 2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file resolve_addr.c
 * \brief Implement resolving address functions
 **/

#define RESOLVE_ADDR_PRIVATE

#include "app/config/config.h"
#include "app/config/resolve_addr.h"

#include "core/mainloop/mainloop.h"

#include "feature/control/control_events.h"
17
#include "feature/dirauth/authmode.h"
18

19
#include "lib/encoding/confline.h"
20
21
22
#include "lib/net/gethostname.h"
#include "lib/net/resolve.h"

23
24
25
26
27
/** Maximum "Address" statement allowed in our configuration. */
#define MAX_CONFIG_ADDRESS 2

/** Ease our life. Arrays containing state per address family. These are to
 * add semantic to the code so we know what is accessed. */
28
29
30
31
#define IDX_NULL 0 /* Index to zeroed address object. */
#define IDX_IPV4 1 /* Index to AF_INET. */
#define IDX_IPV6 2 /* Index to AF_INET6. */
#define IDX_SIZE 3 /* How many indexes do we have. */
32

33
34
35
36
37
38
39
40
41
42
43
44
/** Function in our address function table return one of these code. */
typedef enum {
  /* The address has been found. */
  FN_RET_OK   = 0,
  /* The failure requirements were not met and thus it is recommended that the
   * caller stops the search. */
  FN_RET_BAIL = 1,
  /* The address was not found or failure is transient so the caller should go
   * to the next method. */
  FN_RET_NEXT = 2,
} fn_address_ret_t;

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
51
52
53
/** Last suggested addresses.
 *
 * These addresses come from a NETINFO cell from a trusted relay (currently
 * 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
59
60
61
62
/** True iff the address was found to be configured that is from the
 * configuration file either using Address or ORPort. */
static bool last_addrs_configured[] = { false, false, false };
CTASSERT(ARRAY_LENGTH(last_addrs_configured) == IDX_SIZE);

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
static inline int
af_to_idx(const int family)
{
  switch (family) {
  case AF_INET:
    return IDX_IPV4;
  case AF_INET6:
    return IDX_IPV6;
  default:
    /* It wouldn't be safe to just die here with an assert but we can heavily
     * scream with a bug. Return the index of the NULL address. */
    tor_assert_nonfatal_unreached();
    return IDX_NULL;
  }
}

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/** Return string representation of the given method. */
const char *
resolved_addr_method_to_str(const resolved_addr_method_t method)
{
  switch (method) {
  case RESOLVED_ADDR_NONE:
    return "NONE";
  case RESOLVED_ADDR_CONFIGURED:
    return "CONFIGURED";
  case RESOLVED_ADDR_CONFIGURED_ORPORT:
    return "CONFIGURED_ORPORT";
  case RESOLVED_ADDR_GETHOSTNAME:
    return "GETHOSTNAME";
  case RESOLVED_ADDR_INTERFACE:
    return "INTERFACE";
  case RESOLVED_ADDR_RESOLVED:
    return "RESOLVED";
  default:
    tor_assert_nonfatal_unreached();
    return "???";
  }
}

102
103
104
105
106
107
108
109
110
111
112
113
/** Return true if the last address of family was configured or not. An
 * address is considered configured if it was found in the Address or ORPort
 * statement.
 *
 * This applies to the address returned by the function
 * resolved_addr_get_last() which is the cache of discovered addresses. */
bool
resolved_addr_is_configured(int family)
{
  return last_addrs_configured[af_to_idx(family)];
}

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/** Copy the last suggested address of family into addr_out.
 *
 * If no last suggested address exists, the addr_out is a null address (use
 * tor_addr_is_null() to confirm). */
void
resolved_addr_get_suggested(int family, tor_addr_t *addr_out)
{
  tor_addr_copy(addr_out, &last_suggested_addrs[af_to_idx(family)]);
}

/** Set the last suggested address into our cache. This is called when we get
 * a new NETINFO cell from a trusted source. */
void
resolved_addr_set_suggested(const tor_addr_t *addr)
{
129
  if (BUG(tor_addr_family(addr) != AF_INET &&
130
131
132
          tor_addr_family(addr) != AF_INET6)) {
    return;
  }
133
134
135
136
137
138
139
140
141
142

  /* In case we don't have a configured address, log that we will be using the
   * one discovered from the dirauth. */
  const int idx = af_to_idx(tor_addr_family(addr));
  if (tor_addr_is_null(&last_resolved_addrs[idx]) &&
      !tor_addr_eq(&last_suggested_addrs[idx], addr)) {
    log_notice(LD_CONFIG, "External address seen and suggested by a "
                          "directory authority: %s", fmt_addr(addr));
  }
  tor_addr_copy(&last_suggested_addrs[idx], addr);
143
144
}

145
146
147
148
149
150
/** Copy the last resolved address of family into addr_out.
 *
 * If not last resolved address existed, the addr_out is a null address (use
 * tor_addr_is_null()). */
void
resolved_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
156
157
/** Reset the last resolved address of family.
 *
 * This makes it null address. */
158
void
159
resolved_addr_reset_last(int family)
160
{
161
  tor_addr_make_null(&last_resolved_addrs[af_to_idx(family)], family);
162
163
}

164
165
166
167
168
/** Errors returned by address_can_be_used() in order for the caller to know
 * why the address is denied or not. */
#define ERR_DEFAULT_DIRAUTH     -1 /* Using default authorities. */
#define ERR_ADDRESS_IS_INTERNAL -2 /* IP is internal. */

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/** @brief Return true iff the given IP address can be used as a valid
 *         external resolved address.
 *
 * Two tests are done in this function:
 *    1) If the address if NOT internal, it can be used.
 *    2) If the address is internal and we have custom directory authorities
 *       configured then it can they be used. Important for testing networks.
 *
 * @param addr The IP address to validate.
 * @param options Global configuration options.
 * @param warn_severity Log level that should be used on error.
 * @param explicit_ip Was the IP address explicitly given.
 *
 * @return Return 0 if it can be used. Return error code ERR_* found at the
 *         top of the file.
 */
static int
address_can_be_used(const tor_addr_t *addr, const or_options_t *options,
                    int warn_severity, const bool explicit_ip)
{
  tor_assert(addr);

  /* Public address, this is fine. */
  if (!tor_addr_is_internal(addr, 0)) {
    goto allow;
  }

  /* We have a private IP address. It is allowed only if we set custom
   * directory authorities. */
  if (using_default_dir_authorities(options)) {
    log_fn(warn_severity, LD_CONFIG,
           "Address '%s' is a private IP address. Tor relays that use "
           "the default DirAuthorities must have public IP addresses.",
           fmt_addr(addr));
    return ERR_DEFAULT_DIRAUTH;
  }

  if (!explicit_ip) {
    /* Even with custom directory authorities, only an explicit internal
     * address is accepted. */
    log_fn(warn_severity, LD_CONFIG,
           "Address %s was resolved and thus not explicitly "
           "set. Even if DirAuthorities are custom, this is "
           "not allowed.", fmt_addr(addr));
    return ERR_ADDRESS_IS_INTERNAL;
  }

 allow:
  return 0;
}

/** @brief Get IP address from the given config line and for a specific address
 *         family.
 *
 * This can fail is more than two Address statement are found for the same
 * address family. It also fails if no statement is found.
 *
 * @param options Global configuration options.
 * @param warn_severity Log level that should be used on error.
 * @param family IP address family. Only AF_INET and AF_INET6 are supported.
229
230
 * @param method_out OUT: Method denoting how the address was found.
 *                   This is described in the control-spec.txt as
231
232
233
234
235
236
237
238
239
 *                   actions for "STATUS_SERVER".
 * @param hostname_out OUT: String containing the hostname gotten from the
 *                     Address value if any.
 * @param addr_out OUT: Tor address of the address found in the cline or
 *                 resolved from the cline.
 *
 * @return Return 0 on success that is an address has been found or resolved
 *         successfully. Return error code ERR_* found at the top of the file.
 */
240
static fn_address_ret_t
241
get_address_from_config(const or_options_t *options, int warn_severity,
242
                        int family, resolved_addr_method_t *method_out,
243
244
                        char **hostname_out, tor_addr_t *addr_out)
{
245
  int ret;
246
  bool explicit_ip = false, resolve_failure = false;
247
248
249
250
251
252
253
  int num_valid_addr = 0;

  tor_assert(options);
  tor_assert(addr_out);
  tor_assert(method_out);
  tor_assert(hostname_out);

254
255
  /* Set them to NULL for safety reasons. */
  *hostname_out = NULL;
256
  *method_out = RESOLVED_ADDR_NONE;
257

258
259
260
261
  log_debug(LD_CONFIG, "Attempting to get address from configuration");

  if (!options->Address) {
    log_info(LD_CONFIG, "No Address option found in configuration.");
262
263
    /* No Address statement, inform caller to try next method. */
    return FN_RET_NEXT;
264
265
266
267
268
269
270
271
272
273
  }

  for (const config_line_t *cfg = options->Address; cfg != NULL;
       cfg = cfg->next) {
    int af;
    tor_addr_t addr;

    af = tor_addr_parse(&addr, cfg->value);
    if (af == family) {
      tor_addr_copy(addr_out, &addr);
274
      *method_out = RESOLVED_ADDR_CONFIGURED;
275
276
277
      explicit_ip = true;
      num_valid_addr++;
      continue;
278
279
280
281
    } else if (af != -1) {
      /* Parsable address but just not the one from the family we want. Skip
       * it so we don't attempt a resolve. */
      continue;
282
283
284
285
286
287
    }

    /* Not an IP address. Considering this value a hostname and attempting to
     * do a DNS lookup. */
    if (!tor_addr_lookup(cfg->value, family, &addr)) {
      tor_addr_copy(addr_out, &addr);
288
      *method_out = RESOLVED_ADDR_RESOLVED;
289
290
291
      if (*hostname_out) {
        tor_free(*hostname_out);
      }
292
293
294
295
296
      *hostname_out = tor_strdup(cfg->value);
      explicit_ip = false;
      num_valid_addr++;
      continue;
    } else {
297
      /* Hostname that can't be resolved, this is a fatal error. */
298
      resolve_failure = true;
299
300
      log_fn(warn_severity, LD_CONFIG,
             "Could not resolve local Address '%s'. Failing.", cfg->value);
301
      continue;
302
303
304
305
    }
  }

  if (!num_valid_addr) {
306
307
308
309
310
311
312
313
314
315
    if (resolve_failure) {
      /* We found no address but we got a resolution failure. This means we
       * can know if the hostname given was v4 or v6 so we can't continue. */
      return FN_RET_BAIL;
    }
    log_info(LD_CONFIG,
             "No Address option found for family %s in configuration.",
             fmt_af_family(family));
    /* No Address statement for family so move on to try next method. */
    return FN_RET_NEXT;
316
317
318
  }

  if (num_valid_addr >= MAX_CONFIG_ADDRESS) {
319
    /* Too many Address for same family. This is a fatal error. */
320
321
322
    log_fn(warn_severity, LD_CONFIG,
           "Found %d Address statement of address family %s. "
           "Only one is allowed.", num_valid_addr, fmt_af_family(family));
323
    tor_free(*hostname_out);
324
    return FN_RET_BAIL;
325
326
327
  }

  /* Great, we found an address. */
328
329
330
331
332
333
  ret = address_can_be_used(addr_out, options, warn_severity, explicit_ip);
  if (ret != 0) {
    /* One of the requirement of this interface is if an internal Address is
     * used, custom authorities must be defined else it is a fatal error.
     * Furthermore, if the Address was resolved to an internal interface, we
     * stop immediately. */
334
    tor_free(*hostname_out);
335
336
337
338
    return FN_RET_BAIL;
  }

  /* Address can be used. We are done. */
339
340
  log_info(LD_CONFIG, "Address found in configuration: %s",
           fmt_addr(addr_out));
341
  return FN_RET_OK;
342
343
344
345
346
347
348
349
}

/** @brief Get IP address from the local hostname by calling gethostbyname()
 *         and doing a DNS resolution on the hostname.
 *
 * @param options Global configuration options.
 * @param warn_severity Log level that should be used on error.
 * @param family IP address family. Only AF_INET and AF_INET6 are supported.
350
351
 * @param method_out OUT: Method denoting how the address was found.
 *                   This is described in the control-spec.txt as
352
353
354
355
356
357
358
 *                   actions for "STATUS_SERVER".
 * @param hostname_out OUT: String containing the local hostname.
 * @param addr_out OUT: Tor address resolved from the local hostname.
 *
 * @return Return 0 on success that is an address has been found and resolved
 *         successfully. Return error code ERR_* found at the top of the file.
 */
359
static fn_address_ret_t
360
get_address_from_hostname(const or_options_t *options, int warn_severity,
361
                          int family, resolved_addr_method_t *method_out,
362
363
364
365
366
367
368
369
                          char **hostname_out, tor_addr_t *addr_out)
{
  int ret;
  char hostname[256];

  tor_assert(addr_out);
  tor_assert(method_out);

370
371
  /* Set them to NULL for safety reasons. */
  *hostname_out = NULL;
372
  *method_out = RESOLVED_ADDR_NONE;
373

374
375
376
377
  log_debug(LD_CONFIG, "Attempting to get address from local hostname");

  if (tor_gethostname(hostname, sizeof(hostname)) < 0) {
    log_fn(warn_severity, LD_NET, "Error obtaining local hostname");
378
379
    /* Unable to obtain the local hostname is a fatal error. */
    return FN_RET_BAIL;
380
381
382
383
  }
  if (tor_addr_lookup(hostname, family, addr_out)) {
    log_fn(warn_severity, LD_NET,
           "Could not resolve local hostname '%s'. Failing.", hostname);
384
385
    /* Unable to resolve, inform caller to try next method. */
    return FN_RET_NEXT;
386
387
388
  }

  ret = address_can_be_used(addr_out, options, warn_severity, false);
389
390
391
392
393
394
  if (ret == ERR_DEFAULT_DIRAUTH) {
    /* Non custom authorities, inform caller to try next method. */
    return FN_RET_NEXT;
  } else if (ret == ERR_ADDRESS_IS_INTERNAL) {
    /* Internal address is a fatal error. */
    return FN_RET_BAIL;
395
396
397
  }

  /* addr_out contains the address of the local hostname. */
398
  *method_out = RESOLVED_ADDR_GETHOSTNAME;
399
400
  *hostname_out = tor_strdup(hostname);

401
  /* Found it! */
402
403
  log_info(LD_CONFIG, "Address found from local hostname: %s",
           fmt_addr(addr_out));
404
  return FN_RET_OK;
405
406
407
408
409
410
411
}

/** @brief Get IP address from a network interface.
 *
 * @param options Global configuration options.
 * @param warn_severity Log level that should be used on error.
 * @param family IP address family. Only AF_INET and AF_INET6 are supported.
412
413
414
 * @param method_out OUT: Always RESOLVED_ADDR_INTERFACE on success which
 *                   is detailed in the control-spec.txt as actions
 *                   for "STATUS_SERVER".
415
416
 * @param hostname_out OUT: String containing the local hostname. For this
 *                     function, it is always set to NULL.
417
418
419
420
421
 * @param addr_out OUT: Tor address found attached to the interface.
 *
 * @return Return 0 on success that is an address has been found. Return
 *         error code ERR_* found at the top of the file.
 */
422
static fn_address_ret_t
423
get_address_from_interface(const or_options_t *options, int warn_severity,
424
                           int family, resolved_addr_method_t *method_out,
425
                           char **hostname_out, tor_addr_t *addr_out)
426
427
428
429
{
  int ret;

  tor_assert(method_out);
430
  tor_assert(hostname_out);
431
432
  tor_assert(addr_out);

433
  /* Set them to NULL for safety reasons. */
434
  *method_out = RESOLVED_ADDR_NONE;
435
  *hostname_out = NULL;
436

437
438
439
440
441
  log_debug(LD_CONFIG, "Attempting to get address from network interface");

  if (get_interface_address6(warn_severity, family, addr_out) < 0) {
    log_fn(warn_severity, LD_CONFIG,
           "Could not get local interface IP address.");
442
443
    /* Unable to get IP from interface. Inform caller to try next method. */
    return FN_RET_NEXT;
444
445
446
447
  }

  ret = address_can_be_used(addr_out, options, warn_severity, false);
  if (ret < 0) {
448
449
    /* Unable to use address. Inform caller to try next method. */
    return FN_RET_NEXT;
450
451
  }

452
  *method_out = RESOLVED_ADDR_INTERFACE;
453

454
  /* Found it! */
455
  log_info(LD_CONFIG, "Address found from interface: %s", fmt_addr(addr_out));
456
  return FN_RET_OK;
457
458
}

459
460
461
462
463
/** @brief Get IP address from the ORPort (if any).
 *
 * @param options Global configuration options.
 * @param warn_severity Log level that should be used on error.
 * @param family IP address family. Only AF_INET and AF_INET6 are supported.
464
465
 * @param method_out OUT: Always RESOLVED_ADDR_CONFIGURED_ORPORT on success
 *                   which is detailed in the control-spec.txt as actions
466
467
468
469
470
471
472
473
474
 *                   for "STATUS_SERVER".
 * @param hostname_out OUT: String containing the ORPort hostname if any.
 * @param addr_out OUT: Tor address found if any.
 *
 * @return Return 0 on success that is an address has been found. Return
 *         error code ERR_* found at the top of the file.
 */
static fn_address_ret_t
get_address_from_orport(const or_options_t *options, int warn_severity,
475
                        int family, resolved_addr_method_t *method_out,
476
477
478
479
480
481
482
483
484
                        char **hostname_out, tor_addr_t *addr_out)
{
  int ret;
  const tor_addr_t *addr;

  tor_assert(method_out);
  tor_assert(hostname_out);
  tor_assert(addr_out);

485
486
487
488
  /* Set them to NULL for safety reasons. */
  *method_out = RESOLVED_ADDR_NONE;
  *hostname_out = NULL;

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  log_debug(LD_CONFIG, "Attempting to get address from ORPort");

  if (!options->ORPort_set) {
    log_info(LD_CONFIG, "No ORPort found in configuration.");
    /* No ORPort statement, inform caller to try next method. */
    return FN_RET_NEXT;
  }

  /* Get ORPort for requested family. */
  addr = get_orport_addr(family);
  if (!addr) {
    /* No address configured for the ORPort. Ignore. */
    return FN_RET_NEXT;
  }

  /* We found the ORPort address. Just make sure it can be used. */
  ret = address_can_be_used(addr, options, warn_severity, true);
  if (ret < 0) {
    /* Unable to use address. Inform caller to try next method. */
    return FN_RET_NEXT;
  }

  /* Found it! */
512
  *method_out = RESOLVED_ADDR_CONFIGURED_ORPORT;
513
514
515
516
517
518
519
  tor_addr_copy(addr_out, addr);

  log_fn(warn_severity, LD_CONFIG, "Address found from ORPort: %s",
         fmt_addr(addr_out));
  return FN_RET_OK;
}

520
/** @brief Set the last resolved address cache using the given address.
521
522
523
524
525
526
527
528
529
530
531
532
 *
 * A log notice is emitted if the given address has changed from before. Not
 * emitted on first resolve.
 *
 * Control port event "STATUS_SERVER" is emitted with the new information if
 * it has changed.
 *
 * Finally, tor is notified that the IP address has changed.
 *
 * @param addr IP address to update the cache with.
 * @param method_used By which method did we resolved it (for logging and
 *                    control port).
533
534
 * @param hostname_used Which hostname was used. If none were used, it is
 *                      NULL. (for logging and control port).
535
 */
536
void
537
538
resolved_addr_set_last(const tor_addr_t *addr,
                       const resolved_addr_method_t method_used,
539
                       const char *hostname_used)
540
541
{
  /** Have we done a first resolve. This is used to control logging. */
542
543
544
  static bool have_resolved_once[] = { false, false, false };
  CTASSERT(ARRAY_LENGTH(have_resolved_once) == IDX_SIZE);

545
546
547
548
549
550
551
  bool *done_one_resolve;
  bool have_hostname = false;
  tor_addr_t *last_resolved;

  tor_assert(addr);

  /* Do we have an hostname. */
552
  have_hostname = (hostname_used != NULL);
553

554
555
556
  int idx = af_to_idx(tor_addr_family(addr));
  if (idx == IDX_NULL) {
    /* Not suppose to happen and if it does, af_to_idx() screams loudly. */
557
558
559
    return;
  }

560
561
562
563
  /* Get values from cache. */
  done_one_resolve = &have_resolved_once[idx];
  last_resolved = &last_resolved_addrs[idx];

564
565
566
567
568
569
570
571
572
573
574
575
  /* Same address last resolved. Ignore. */
  if (tor_addr_eq(last_resolved, addr)) {
    return;
  }

  /* Don't log notice if this is the first resolve we do. */
  if (*done_one_resolve) {
    /* Leave this as a notice, regardless of the requested severity,
     * at least until dynamic IP address support becomes bulletproof. */
    log_notice(LD_NET,
               "Your IP address seems to have changed to %s "
               "(METHOD=%s%s%s). Updating.",
576
577
               fmt_addr(addr),
               resolved_addr_method_to_str(method_used),
578
579
580
581
582
583
584
585
               have_hostname ? " HOSTNAME=" : "",
               have_hostname ? hostname_used : "");
    ip_address_changed(0);
  }

  /* Notify control port. */
  control_event_server_status(LOG_NOTICE,
                              "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s%s%s",
586
587
                              fmt_addr(addr),
                              resolved_addr_method_to_str(method_used),
588
589
590
591
592
                              have_hostname ? " HOSTNAME=" : "",
                              have_hostname ? hostname_used : "");
  /* Copy address to cache. */
  tor_addr_copy(last_resolved, addr);
  *done_one_resolve = true;
593
594
595
596
597
598
599

  /* Flag true if the address was configured. Else, indicate it was not. */
  last_addrs_configured[idx] = false;
  if (method_used == RESOLVED_ADDR_CONFIGURED ||
      method_used == RESOLVED_ADDR_CONFIGURED_ORPORT) {
    last_addrs_configured[idx] = true;
  }
600
601
}

602
603
604
605
/** Ease our lives. Typedef to the address discovery function signature. */
typedef fn_address_ret_t
  (*fn_address_t)(
     const or_options_t *options, int warn_severity, int family,
606
607
     resolved_addr_method_t *method_out, char **hostname_out,
     tor_addr_t *addr_out);
608

609
610
/** Address discovery function table. The order matters as in the first one is
 * executed first and so on. */
611
static const fn_address_t fn_address_table[] =
612
613
614
{
  /* These functions are in order for our find address algorithm. */
  get_address_from_config,
615
  get_address_from_orport,
616
  get_address_from_interface,
617
  get_address_from_hostname,
618
619
};
/** Length of address table as in how many functions. */
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
static const size_t fn_address_table_len =
  ARRAY_LENGTH(fn_address_table);

/* Address discover function table for authorities (bridge or directory).
 *
 * They only discover their address from either the configuration file or the
 * ORPort. They do not query the interface nor do any DNS resolution for
 * security reasons. */
static const fn_address_t fn_address_table_auth[] =
{
  /* These functions are in order for our find address algorithm. */
  get_address_from_config,
  get_address_from_orport,
};
/** Length of address table as in how many functions. */
static const size_t fn_address_table_auth_len =
  ARRAY_LENGTH(fn_address_table_auth);
637

638
639
640
641
642
643
644
645
646
/** @brief Attempt to find our IP address that can be used as our external
 *         reachable address.
 *
 *  The following describe the algorithm to find an address. Each have
 *  specific conditions so read carefully.
 *
 *  On success, true is returned and depending on how the address was found,
 *  the out parameters can have different values.
 *
647
 *  On error, false is returned and out parameters are set to NULL.
648
649
650
651
 *
 *  1. Look at the configuration Address option.

 *     If Address is a public address, True is returned and addr_out is set
652
653
 *     with it, the method_out is set to RESOLVED_ADDR_CONFIGURED and
 *     hostname_out is set to NULL.
654
655
656
657
658
659
 *
 *     If Address is an internal address but NO custom authorities are used,
 *     an error is returned.
 *
 *     If Address is a hostname, that is it can't be converted to an address,
 *     it is resolved. On success, addr_out is set with the address,
660
661
 *     method_out is set to RESOLVED_ADDR_RESOLVED and hostname_out is set
 *     to the resolved hostname. On failure to resolve, an error is returned.
662
 *
Roger Dingledine's avatar
Roger Dingledine committed
663
 *     If no given Address, fallback to the network interface (see section 2).
664
 *
665
666
667
 *  2. Look at the network interface.
 *
 *     Attempt to find the first public usable address from the list of
Roger Dingledine's avatar
Roger Dingledine committed
668
 *     network interfaces returned by the OS.
669
670
671
 *
 *     On failure, we attempt to look at the local hostname (3).
 *
672
673
 *     On success, addr_out is set with it, method_out is set to
 *     RESOLVED_ADDR_INTERFACE and hostname_out is set to NULL.
674
675
 *
 *  3. Look at the local hostname.
676
677
 *
 *     If the local hostname resolves to a non internal address, addr_out is
678
679
 *     set with it, method_out is set to RESOLVED_ADDR_GETHOSTNAME and
 *     hostname_out is set to the resolved hostname.
680
681
682
683
684
685
 *
 *     If a local hostname can NOT be found, an error is returned.
 *
 *     If the local hostname resolves to an internal address, an error is
 *     returned.
 *
686
 *     If the local hostname can NOT be resolved, an error is returned.
687
688
689
690
691
 *
 * @param options Global configuration options.
 * @param family IP address family. Only AF_INET and AF_INET6 are supported.
 * @param warn_severity Logging level.
 * @param addr_out OUT: Set with the IP address found if any.
692
693
694
 * @param method_out OUT: (optional) Method denoting how the address wa
 *                   found. This is described in the control-spec.txt as
 *                   actions for "STATUS_SERVER".
695
 * @param hostname_out OUT: String containing the hostname if any was used.
696
 *                     Only be set for RESOLVED and GETHOSTNAME methods.
697
698
699
700
701
702
703
 *                     Else it is set to NULL.
 *
 * @return True if the address was found for the given family. False if not or
 *         on errors.
 */
bool
find_my_address(const or_options_t *options, int family, int warn_severity,
704
                tor_addr_t *addr_out, resolved_addr_method_t *method_out,
705
706
                char **hostname_out)
{
707
  resolved_addr_method_t method_used = RESOLVED_ADDR_NONE;
708
  char *hostname_used = NULL;
709
  tor_addr_t my_addr;
710
711
  const fn_address_t *table = fn_address_table;
  size_t table_len = fn_address_table_len;
712
713
714
715

  tor_assert(options);
  tor_assert(addr_out);

716
  /* Set them to NULL for safety reasons. */
717
  tor_addr_make_unspec(addr_out);
718
  if (method_out) *method_out = RESOLVED_ADDR_NONE;
719
720
  if (hostname_out) *hostname_out = NULL;

721
722
723
724
725
726
727
  /* If an IPv6 is requested, check if IPv6 address discovery is disabled and
   * if so we always return a failure. It is done here so we don't populate
   * the resolve cache or do any DNS resolution. */
  if (family == AF_INET6 && options->AddressDisableIPv6) {
    return false;
  }

728
729
730
731
732
733
  /* For authorities (bridge and directory), we use a different table. */
  if (authdir_mode(options)) {
    table = fn_address_table_auth;
    table_len = fn_address_table_auth_len;
  }

734
  /*
735
   * Step 1: Discover address by calling methods from the function table.
736
737
   */

738
  /* Go over the function table. They are in order. */
739
740
741
  for (size_t idx = 0; idx < table_len; idx++) {
    fn_address_ret_t ret = table[idx](options, warn_severity, family,
                                      &method_used, &hostname_used, &my_addr);
742
    if (ret == FN_RET_BAIL) {
743
      return false;
744
745
    } else if (ret == FN_RET_OK) {
      goto found;
746
    }
747
    tor_assert(ret == FN_RET_NEXT);
748
749
  }

750
751
752
  /* We've exhausted our attempts. Failure. */
  log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address.");
  return false;
753

754
 found:
755
756
757
  /*
   * Step 2: Update last resolved address cache and inform the control port.
   */
758
  resolved_addr_set_last(&my_addr, method_used, hostname_used);
759
760
761
762
763

  if (method_out) {
    *method_out = method_used;
  }
  if (hostname_out) {
764
    *hostname_out = hostname_used;
765
766
767
768
769
770
771
772
  } else {
    tor_free(hostname_used);
  }

  tor_addr_copy(addr_out, &my_addr);
  return true;
}

773
774
775
776
777
/** @brief: Return true iff the given addr is judged to be local to our
 * resolved address.
 *
 * This function is used to tell whether another address is 'remote' enough
 * that we can trust it when it tells us that we are reachable, or that we
778
 * have a certain address.
779
780
781
782
783
784
785
786
787
788
789
790
791
792
 *
 * The criterion to learn if the address is local are the following:
 *
 *    1. Internal address.
 *    2. If EnforceDistinctSubnets is set then it is never local.
 *    3. Network mask is compared. IPv4: /24 and IPv6 /48. This is different
 *       from the path selection that looks at /16 and /32 because we only
 *       want to learn here if the address is considered to come from the
 *       Internet basically.
 *
 * @param addr The address to test if local and also test against our resovled
 *             address.
 *
 * @return True iff address is considered local or else False.
793
 */
794
MOCK_IMPL(bool,
795
is_local_to_resolve_addr, (const tor_addr_t *addr))
796
{
797
  const int family = tor_addr_family(addr);
798
799
  const tor_addr_t *last_resolved_addr =
    &last_resolved_addrs[af_to_idx(family)];
800
801
802
803
804
805
806
807
808
809
810
811
812

  /* Internal address is always local. */
  if (tor_addr_is_internal(addr, 0)) {
    return true;
  }

  /* Address is not local if we don't enforce subnet distinction. */
  if (get_options()->EnforceDistinctSubnets == 0) {
    return false;
  }

  switch (family) {
  case AF_INET:
813
    /* It's possible that this next check will hit before the first time
814
815
     * find_my_address actually succeeds. For clients, it is likely that
     * find_my_address will never be called at all. In those cases,
816
     * last_resolved_addr_v4 will be 0, and so checking to see whether ip is
817
818
819
820
821
822
     * on the same /24 as last_resolved_addrs[AF_INET] will be the same as
     * checking whether it was on net 0, which is already done by
     * tor_addr_is_internal. */
    return tor_addr_compare_masked(addr, last_resolved_addr, 24,
                                   CMP_SEMANTIC) == 0;
  case AF_INET6:
823
824
825
826
    /* Look at /48 because it is typically the smallest network in the global
     * IPv6 routing tables, and it was previously the recommended per-customer
     * network block. (See [RFC 6177: IPv6 End Site Address Assignment].) */
    return tor_addr_compare_masked(addr, last_resolved_addr, 48,
827
828
829
830
831
                                   CMP_SEMANTIC) == 0;
    break;
  default:
    /* Unknown address type so not local. */
    return false;
832
833
  }
}
834
835
836
837
838
839
840
841
842
843

#ifdef TOR_UNIT_TESTS

void
resolve_addr_reset_suggested(int family)
{
  tor_addr_make_unspec(&last_suggested_addrs[af_to_idx(family)]);
}

#endif /* TOR_UNIT_TESTS */