nodelist.c 47.6 KB
Newer Older
1
2
3
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4
 * Copyright (c) 2007-2013, The Tor Project, Inc. */
5
6
7
/* See LICENSE for licensing information */

#include "or.h"
8
#include "address.h"
9
#include "config.h"
10
#include "control.h"
11
#include "dirserv.h"
12
#include "geoip.h"
13
#include "main.h"
14
15
#include "microdesc.h"
#include "networkstatus.h"
16
#include "nodelist.h"
17
#include "policies.h"
18
#include "rendservice.h"
19
#include "router.h"
20
#include "routerlist.h"
21
#include "routerset.h"
22
23
24

#include <string.h>

25
static void nodelist_drop_node(node_t *node, int remove_from_ht);
26
static void node_free(node_t *node);
27
static void update_router_have_minimum_dir_info(void);
28
29
static double get_frac_paths_needed_for_circs(const or_options_t *options,
                                              const networkstatus_t *ns);
30
31
32
33
34
35
36
37
38
39

/** A nodelist_t holds a node_t object for every router we're "willing to use
 * for something".  Specifically, it should hold a node_t for every node that
 * is currently in the routerlist, or currently in the consensus we're using.
 */
typedef struct nodelist_t {
  /* A list of all the nodes. */
  smartlist_t *nodes;
  /* Hash table to map from node ID digest to node. */
  HT_HEAD(nodelist_map, node_t) nodes_by_id;
40

41
42
43
44
45
} nodelist_t;

static INLINE unsigned int
node_id_hash(const node_t *node)
{
46
  return (unsigned) siphash24g(node->identity, DIGEST_LEN);
47
48
49
50
51
}

static INLINE unsigned int
node_id_eq(const node_t *node1, const node_t *node2)
{
52
  return tor_memeq(node1->identity, node2->identity, DIGEST_LEN);
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
}

HT_PROTOTYPE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq);
HT_GENERATE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq,
            0.6, malloc, realloc, free);

/** The global nodelist. */
static nodelist_t *the_nodelist=NULL;

/** Create an empty nodelist if we haven't done so already. */
static void
init_nodelist(void)
{
  if (PREDICT_UNLIKELY(the_nodelist == NULL)) {
    the_nodelist = tor_malloc_zero(sizeof(nodelist_t));
    HT_INIT(nodelist_map, &the_nodelist->nodes_by_id);
69
    the_nodelist->nodes = smartlist_new();
70
71
72
  }
}

73
/** As node_get_by_id, but returns a non-const pointer */
74
node_t *
75
node_get_mutable_by_id(const char *identity_digest)
76
77
78
79
80
81
82
83
84
85
{
  node_t search, *node;
  if (PREDICT_UNLIKELY(the_nodelist == NULL))
    return NULL;

  memcpy(&search.identity, identity_digest, DIGEST_LEN);
  node = HT_FIND(nodelist_map, &the_nodelist->nodes_by_id, &search);
  return node;
}

86
87
88
89
90
91
92
93
/** Return the node_t whose identity is <b>identity_digest</b>, or NULL
 * if no such node exists. */
const node_t *
node_get_by_id(const char *identity_digest)
{
  return node_get_mutable_by_id(identity_digest);
}

94
95
96
97
98
99
100
101
102
103
104
/** Internal: return the node_t whose identity_digest is
 * <b>identity_digest</b>.  If none exists, create a new one, add it to the
 * nodelist, and return it.
 *
 * Requires that the nodelist be initialized.
 */
static node_t *
node_get_or_create(const char *identity_digest)
{
  node_t *node;

105
  if ((node = node_get_mutable_by_id(identity_digest)))
106
107
108
109
110
111
112
113
114
    return node;

  node = tor_malloc_zero(sizeof(node_t));
  memcpy(node->identity, identity_digest, DIGEST_LEN);
  HT_INSERT(nodelist_map, &the_nodelist->nodes_by_id, node);

  smartlist_add(the_nodelist->nodes, node);
  node->nodelist_idx = smartlist_len(the_nodelist->nodes) - 1;

115
116
  node->country = -1;

117
118
119
  return node;
}

120
121
122
/** Called when a node's address changes. */
static void
node_addrs_changed(node_t *node)
123
{
124
125
  node->last_reachable = node->last_reachable6 = 0;
  node->country = -1;
126
127
}

128
129
130
131
/** Add <b>ri</b> to an appropriate node in the nodelist.  If we replace an
 * old routerinfo, and <b>ri_old_out</b> is not NULL, set *<b>ri_old_out</b>
 * to the previous routerinfo.
 */
132
node_t *
133
nodelist_set_routerinfo(routerinfo_t *ri, routerinfo_t **ri_old_out)
134
{
135
136
137
138
  node_t *node;
  const char *id_digest;
  int had_router = 0;
  tor_assert(ri);
139

140
141
142
143
144
145
146
147
148
149
150
  init_nodelist();
  id_digest = ri->cache_info.identity_digest;
  node = node_get_or_create(id_digest);

  if (node->ri) {
    if (!routers_have_same_or_addrs(node->ri, ri)) {
      node_addrs_changed(node);
    }
    had_router = 1;
    if (ri_old_out)
      *ri_old_out = node->ri;
151
  } else {
152
153
    if (ri_old_out)
      *ri_old_out = NULL;
154
  }
155
  node->ri = ri;
156
157
158
159

  if (node->country == -1)
    node_set_country(node);

160
  if (authdir_mode(get_options()) && !had_router) {
161
162
163
164
165
    const char *discard=NULL;
    uint32_t status = dirserv_router_get_status(ri, &discard);
    dirserv_set_node_flags_from_authoritative_status(node, status);
  }

166
167
168
169
170
171
172
173
174
175
176
177
178
  return node;
}

/** Set the appropriate node_t to use <b>md</b> as its microdescriptor.
 *
 * Called when a new microdesc has arrived and the usable consensus flavor
 * is "microdesc".
 **/
node_t *
nodelist_add_microdesc(microdesc_t *md)
{
  networkstatus_t *ns =
    networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC);
179
  const routerstatus_t *rs;
180
181
182
183
184
185
186
187
188
189
  node_t *node;
  if (ns == NULL)
    return NULL;
  init_nodelist();

  /* Microdescriptors don't carry an identity digest, so we need to figure
   * it out by looking up the routerstatus. */
  rs = router_get_consensus_status_by_descriptor_digest(ns, md->digest);
  if (rs == NULL)
    return NULL;
190
  node = node_get_mutable_by_id(rs->identity_digest);
191
192
  if (node) {
    if (node->md)
193
      node->md->held_by_nodes--;
194
    node->md = md;
195
    md->held_by_nodes++;
196
  }
197
198
199
  return node;
}

Linus Nordberg's avatar
Linus Nordberg committed
200
/** Tell the nodelist that the current usable consensus is <b>ns</b>.
201
202
203
204
205
206
207
 * This makes the nodelist change all of the routerstatus entries for
 * the nodes, drop nodes that no longer have enough info to get used,
 * and grab microdescriptors into nodes as appropriate.
 */
void
nodelist_set_consensus(networkstatus_t *ns)
{
208
  const or_options_t *options = get_options();
209
  int authdir = authdir_mode_v3(options);
210
  int client = !server_mode(options);
211

212
  init_nodelist();
213
214
  if (ns->flavor == FLAV_MICRODESC)
    (void) get_microdesc_cache(); /* Make sure it exists first. */
215
216
217
218
219
220
221
222
223

  SMARTLIST_FOREACH(the_nodelist->nodes, node_t *, node,
                    node->rs = NULL);

  SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
    node_t *node = node_get_or_create(rs->identity_digest);
    node->rs = rs;
    if (ns->flavor == FLAV_MICRODESC) {
      if (node->md == NULL ||
224
          tor_memneq(node->md->digest,rs->descriptor_digest,DIGEST256_LEN)) {
225
        if (node->md)
226
          node->md->held_by_nodes--;
227
228
        node->md = microdesc_cache_lookup_by_digest256(NULL,
                                                       rs->descriptor_digest);
229
        if (node->md)
230
          node->md->held_by_nodes++;
231
232
      }
    }
233
234
235
236
237
238

    node_set_country(node);

    /* If we're not an authdir, believe others. */
    if (!authdir) {
      node->is_valid = rs->is_valid;
239
      node->is_running = rs->is_flagged_running;
240
241
242
243
244
245
246
      node->is_fast = rs->is_fast;
      node->is_stable = rs->is_stable;
      node->is_possible_guard = rs->is_possible_guard;
      node->is_exit = rs->is_exit;
      node->is_bad_directory = rs->is_bad_directory;
      node->is_bad_exit = rs->is_bad_exit;
      node->is_hs_dir = rs->is_hs_dir;
247
248
249
250
251
      node->ipv6_preferred = 0;
      if (client && options->ClientPreferIPv6ORPort == 1 &&
          (tor_addr_is_null(&rs->ipv6_addr) == 0 ||
           (node->md && tor_addr_is_null(&node->md->ipv6_addr) == 0)))
        node->ipv6_preferred = 1;
252
253
    }

254
  } SMARTLIST_FOREACH_END(rs);
255

256
  nodelist_purge();
257
258
259
260
261
262
263
264
265
266
267
268
269

  if (! authdir) {
    SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
      /* We have no routerstatus for this router. Clear flags so we can skip
       * it, maybe.*/
      if (!node->rs) {
        tor_assert(node->ri); /* if it had only an md, or nothing, purge
                               * would have removed it. */
        if (node->ri->purpose == ROUTER_PURPOSE_GENERAL) {
          /* Clear all flags. */
          node->is_valid = node->is_running = node->is_hs_dir =
            node->is_fast = node->is_stable =
            node->is_possible_guard = node->is_exit =
270
271
            node->is_bad_exit = node->is_bad_directory =
            node->ipv6_preferred = 0;
272
273
274
275
        }
      }
    } SMARTLIST_FOREACH_END(node);
  }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
}

/** Helper: return true iff a node has a usable amount of information*/
static INLINE int
node_is_usable(const node_t *node)
{
  return (node->rs) || (node->ri);
}

/** Tell the nodelist that <b>md</b> is no longer a microdescriptor for the
 * node with <b>identity_digest</b>. */
void
nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md)
{
290
  node_t *node = node_get_mutable_by_id(identity_digest);
291
  if (node && node->md == md) {
292
    node->md = NULL;
293
    md->held_by_nodes--;
294
  }
295
296
297
298
299
300
}

/** Tell the nodelist that <b>ri</b> is no longer in the routerlist. */
void
nodelist_remove_routerinfo(routerinfo_t *ri)
{
301
  node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
302
303
304
  if (node && node->ri == ri) {
    node->ri = NULL;
    if (! node_is_usable(node)) {
305
      nodelist_drop_node(node, 1);
306
307
308
309
310
311
312
313
      node_free(node);
    }
  }
}

/** Remove <b>node</b> from the nodelist.  (Asserts that it was there to begin
 * with.) */
static void
314
nodelist_drop_node(node_t *node, int remove_from_ht)
315
316
317
{
  node_t *tmp;
  int idx;
318
319
320
321
  if (remove_from_ht) {
    tmp = HT_REMOVE(nodelist_map, &the_nodelist->nodes_by_id, node);
    tor_assert(tmp == node);
  }
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

  idx = node->nodelist_idx;
  tor_assert(idx >= 0);

  tor_assert(node == smartlist_get(the_nodelist->nodes, idx));
  smartlist_del(the_nodelist->nodes, idx);
  if (idx < smartlist_len(the_nodelist->nodes)) {
    tmp = smartlist_get(the_nodelist->nodes, idx);
    tmp->nodelist_idx = idx;
  }
  node->nodelist_idx = -1;
}

/** Release storage held by <b>node</b>  */
static void
node_free(node_t *node)
{
  if (!node)
    return;
341
  if (node->md)
342
    node->md->held_by_nodes--;
343
344
345
346
347
348
349
350
351
352
353
354
355
  tor_assert(node->nodelist_idx == -1);
  tor_free(node);
}

/** Remove all entries from the nodelist that don't have enough info to be
 * usable for anything. */
void
nodelist_purge(void)
{
  node_t **iter;
  if (PREDICT_UNLIKELY(the_nodelist == NULL))
    return;

356
  /* Remove the non-usable nodes. */
357
358
359
  for (iter = HT_START(nodelist_map, &the_nodelist->nodes_by_id); iter; ) {
    node_t *node = *iter;

360
361
    if (node->md && !node->rs) {
      /* An md is only useful if there is an rs. */
362
      node->md->held_by_nodes--;
363
364
365
      node->md = NULL;
    }

366
367
368
369
    if (node_is_usable(node)) {
      iter = HT_NEXT(nodelist_map, &the_nodelist->nodes_by_id, iter);
    } else {
      iter = HT_NEXT_RMV(nodelist_map, &the_nodelist->nodes_by_id, iter);
370
      nodelist_drop_node(node, 0);
371
372
373
      node_free(node);
    }
  }
374
  nodelist_assert_ok();
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
}

/** Release all storage held by the nodelist. */
void
nodelist_free_all(void)
{
  if (PREDICT_UNLIKELY(the_nodelist == NULL))
    return;

  HT_CLEAR(nodelist_map, &the_nodelist->nodes_by_id);
  SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
    node->nodelist_idx = -1;
    node_free(node);
  } SMARTLIST_FOREACH_END(node);

  smartlist_free(the_nodelist->nodes);

  tor_free(the_nodelist);
}

/** Check that the nodelist is internally consistent, and consistent with
 * the directory info it's derived from.
 */
void
nodelist_assert_ok(void)
{
  routerlist_t *rl = router_get_routerlist();
  networkstatus_t *ns = networkstatus_get_latest_consensus();
403
  digestmap_t *dm;
404
405
406
407

  if (!the_nodelist)
    return;

408
409
  dm = digestmap_new();

410
411
412
  /* every routerinfo in rl->routers should be in the nodelist. */
  if (rl) {
    SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
413
      const node_t *node = node_get_by_id(ri->cache_info.identity_digest);
414
      tor_assert(node && node->ri == ri);
415
      tor_assert(fast_memeq(ri->cache_info.identity_digest,
416
417
                             node->identity, DIGEST_LEN));
      tor_assert(! digestmap_get(dm, node->identity));
418
      digestmap_set(dm, node->identity, (void*)node);
419
420
421
422
423
424
    } SMARTLIST_FOREACH_END(ri);
  }

  /* every routerstatus in ns should be in the nodelist */
  if (ns) {
    SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
425
      const node_t *node = node_get_by_id(rs->identity_digest);
426
      tor_assert(node && node->rs == rs);
427
      tor_assert(fast_memeq(rs->identity_digest, node->identity, DIGEST_LEN));
428
      digestmap_set(dm, node->identity, (void*)node);
429
      if (ns->flavor == FLAV_MICRODESC) {
430
431
        /* If it's a microdesc consensus, every entry that has a
         * microdescriptor should be in the nodelist.
432
433
434
435
         */
        microdesc_t *md =
          microdesc_cache_lookup_by_digest256(NULL, rs->descriptor_digest);
        tor_assert(md == node->md);
436
        if (md)
437
          tor_assert(md->held_by_nodes >= 1);
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
      }
    } SMARTLIST_FOREACH_END(rs);
  }

  /* The nodelist should have no other entries, and its entries should be
   * well-formed. */
  SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
    tor_assert(digestmap_get(dm, node->identity) != NULL);
    tor_assert(node_sl_idx == node->nodelist_idx);
  } SMARTLIST_FOREACH_END(node);

  tor_assert((long)smartlist_len(the_nodelist->nodes) ==
             (long)HT_SIZE(&the_nodelist->nodes_by_id));

  digestmap_free(dm, NULL);
}

455
456
457
458
459
460
461
462
463
464
/** Return a list of a node_t * for every node we know about.  The caller
 * MUST NOT modify the list. (You can set and clear flags in the nodes if
 * you must, but you must not add or remove nodes.) */
smartlist_t *
nodelist_get_list(void)
{
  init_nodelist();
  return the_nodelist->nodes;
}

Nick Mathewson's avatar
Nick Mathewson committed
465
466
467
468
/** Given a hex-encoded nickname of the format DIGEST, $DIGEST, $DIGEST=name,
 * or $DIGEST~name, return the node with the matching identity digest and
 * nickname (if any).  Return NULL if no such node exists, or if <b>hex_id</b>
 * is not well-formed. */
469
const node_t *
Nick Mathewson's avatar
Nick Mathewson committed
470
node_get_by_hex_id(const char *hex_id)
471
472
473
474
475
{
  char digest_buf[DIGEST_LEN];
  char nn_buf[MAX_NICKNAME_LEN+1];
  char nn_char='\0';

Nick Mathewson's avatar
Nick Mathewson committed
476
  if (hex_digest_nickname_decode(hex_id, digest_buf, &nn_char, nn_buf)==0) {
477
478
479
480
481
482
483
484
485
486
    const node_t *node = node_get_by_id(digest_buf);
    if (!node)
      return NULL;
    if (nn_char) {
      const char *real_name = node_get_nickname(node);
      if (!real_name || strcasecmp(real_name, nn_buf))
        return NULL;
      if (nn_char == '=') {
        const char *named_id =
          networkstatus_get_router_digest_by_nickname(nn_buf);
487
        if (!named_id || tor_memneq(named_id, digest_buf, DIGEST_LEN))
488
489
490
491
492
493
          return NULL;
      }
    }
    return node;
  }

Nick Mathewson's avatar
Nick Mathewson committed
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  return NULL;
}

/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
 * the corresponding node_t, or NULL if none exists.  Warn the user if
 * <b>warn_if_unnamed</b> is set, and they have specified a router by
 * nickname, but the Named flag isn't set for that router. */
const node_t *
node_get_by_nickname(const char *nickname, int warn_if_unnamed)
{
  const node_t *node;
  if (!the_nodelist)
    return NULL;

  /* Handle these cases: DIGEST, $DIGEST, $DIGEST=name, $DIGEST~name. */
  if ((node = node_get_by_hex_id(nickname)) != NULL)
      return node;

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  if (!strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME))
    return NULL;

  /* Okay, so if we get here, the nickname is just a nickname.  Is there
   * a binding for it in the consensus? */
  {
    const char *named_id =
      networkstatus_get_router_digest_by_nickname(nickname);
    if (named_id)
      return node_get_by_id(named_id);
  }

  /* Is it marked as owned-by-someone-else? */
  if (networkstatus_nickname_is_unnamed(nickname)) {
    log_info(LD_GENERAL, "The name %s is listed as Unnamed: there is some "
             "router that holds it, but not one listed in the current "
             "consensus.", escaped(nickname));
    return NULL;
  }

  /* Okay, so the name is not canonical for anybody. */
  {
534
    smartlist_t *matches = smartlist_new();
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
    const node_t *choice = NULL;

    SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
      if (!strcasecmp(node_get_nickname(node), nickname))
        smartlist_add(matches, node);
    } SMARTLIST_FOREACH_END(node);

    if (smartlist_len(matches)>1 && warn_if_unnamed) {
      int any_unwarned = 0;
      SMARTLIST_FOREACH_BEGIN(matches, node_t *, node) {
        if (!node->name_lookup_warned) {
          node->name_lookup_warned = 1;
          any_unwarned = 1;
        }
      } SMARTLIST_FOREACH_END(node);

      if (any_unwarned) {
        log_warn(LD_CONFIG, "There are multiple matches for the name %s, "
                 "but none is listed as Named in the directory consensus. "
                 "Choosing one arbitrarily.", nickname);
      }
    } else if (smartlist_len(matches)>1 && warn_if_unnamed) {
      char fp[HEX_DIGEST_LEN+1];
      node_t *node = smartlist_get(matches, 0);
      if (node->name_lookup_warned) {
        base16_encode(fp, sizeof(fp), node->identity, DIGEST_LEN);
        log_warn(LD_CONFIG,
                 "You specified a server \"%s\" by name, but the directory "
                 "authorities do not have any key registered for this "
                 "nickname -- so it could be used by any server, not just "
                 "the one you meant. "
                 "To make sure you get the same server in the future, refer "
                 "to it by key, as \"$%s\".", nickname, fp);
        node->name_lookup_warned = 1;
      }
    }

    if (smartlist_len(matches))
      choice = smartlist_get(matches, 0);

    smartlist_free(matches);
    return choice;
  }
}

/** Return the nickname of <b>node</b>, or NULL if we can't find one. */
const char *
node_get_nickname(const node_t *node)
{
584
  tor_assert(node);
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  if (node->rs)
    return node->rs->nickname;
  else if (node->ri)
    return node->ri->nickname;
  else
    return NULL;
}

/** Return true iff the nickname of <b>node</b> is canonical, based on the
 * latest consensus. */
int
node_is_named(const node_t *node)
{
  const char *named_id;
  const char *nickname = node_get_nickname(node);
  if (!nickname)
    return 0;
  named_id = networkstatus_get_router_digest_by_nickname(nickname);
  if (!named_id)
    return 0;
605
  return tor_memeq(named_id, node->identity, DIGEST_LEN);
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
}

/** Return true iff <b>node</b> appears to be a directory authority or
 * directory cache */
int
node_is_dir(const node_t *node)
{
  if (node->rs)
    return node->rs->dir_port != 0;
  else if (node->ri)
    return node->ri->dir_port != 0;
  else
    return 0;
}

/** Return true iff <b>node</b> has either kind of usable descriptor -- that
Roger Dingledine's avatar
Roger Dingledine committed
622
 * is, a routerdescriptor or a microdescriptor. */
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
int
node_has_descriptor(const node_t *node)
{
  return (node->ri ||
          (node->rs && node->md));
}

/** Return the router_purpose of <b>node</b>. */
int
node_get_purpose(const node_t *node)
{
  if (node->ri)
    return node->ri->purpose;
  else
    return ROUTER_PURPOSE_GENERAL;
}

/** Compute the verbose ("extended") nickname of <b>node</b> and store it
 * into the MAX_VERBOSE_NICKNAME_LEN+1 character buffer at
642
 * <b>verbose_name_out</b> */
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
void
node_get_verbose_nickname(const node_t *node,
                          char *verbose_name_out)
{
  const char *nickname = node_get_nickname(node);
  int is_named = node_is_named(node);
  verbose_name_out[0] = '$';
  base16_encode(verbose_name_out+1, HEX_DIGEST_LEN+1, node->identity,
                DIGEST_LEN);
  if (!nickname)
    return;
  verbose_name_out[1+HEX_DIGEST_LEN] = is_named ? '=' : '~';
  strlcpy(verbose_name_out+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1);
}

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
/** Compute the verbose ("extended") nickname of node with
 * given <b>id_digest</b> and store it into the MAX_VERBOSE_NICKNAME_LEN+1
 * character buffer at <b>verbose_name_out</b>
 *
 * If node_get_by_id() returns NULL, base 16 encoding of
 * <b>id_digest</b> is returned instead. */
void
node_get_verbose_nickname_by_id(const char *id_digest,
                                char *verbose_name_out)
{
  const node_t *node = node_get_by_id(id_digest);
  if (!node) {
    verbose_name_out[0] = '$';
    base16_encode(verbose_name_out+1, HEX_DIGEST_LEN+1, id_digest, DIGEST_LEN);
  } else {
    node_get_verbose_nickname(node, verbose_name_out);
  }
}

677
678
679
680
681
/** Return true iff it seems that <b>node</b> allows circuits to exit
 * through it directlry from the client. */
int
node_allows_single_hop_exits(const node_t *node)
{
682
683
684
685
  if (node && node->ri)
    return node->ri->allow_single_hop_exits;
  else
    return 0;
686
687
}

688
689
/** Return true iff it seems that <b>node</b> has an exit policy that doesn't
 * actually permit anything to exit, or we don't know its exit policy */
690
691
692
int
node_exit_policy_rejects_all(const node_t *node)
{
693
694
695
  if (node->rejects_all)
    return 1;

696
697
698
699
700
701
702
  if (node->ri)
    return node->ri->policy_is_reject_star;
  else if (node->md)
    return node->md->exit_policy == NULL ||
      short_policy_is_reject_star(node->md->exit_policy);
  else
    return 1;
703
704
}

705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
/** Return true iff the exit policy for <b>node</b> is such that we can treat
 * rejecting an address of type <b>family</b> unexpectedly as a sign of that
 * node's failure. */
int
node_exit_policy_is_exact(const node_t *node, sa_family_t family)
{
  if (family == AF_UNSPEC) {
    return 1; /* Rejecting an address but not telling us what address
               * is a bad sign. */
  } else if (family == AF_INET) {
    return node->ri != NULL;
  } else if (family == AF_INET6) {
    return 0;
  }
  tor_fragile_assert();
  return 1;
}

723
724
725
726
727
728
729
730
731
732
733
/** Return list of tor_addr_port_t with all OR ports (in the sense IP
 * addr + TCP port) for <b>node</b>.  Caller must free all elements
 * using tor_free() and free the list using smartlist_free().
 *
 * XXX this is potentially a memory fragmentation hog -- if on
 * critical path consider the option of having the caller allocate the
 * memory
 */
smartlist_t *
node_get_all_orports(const node_t *node)
{
734
  smartlist_t *sl = smartlist_new();
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758

  if (node->ri != NULL) {
    if (node->ri->addr != 0) {
      tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t));
      tor_addr_from_ipv4h(&ap->addr, node->ri->addr);
      ap->port = node->ri->or_port;
      smartlist_add(sl, ap);
    }
    if (!tor_addr_is_null(&node->ri->ipv6_addr)) {
      tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t));
      tor_addr_copy(&ap->addr, &node->ri->ipv6_addr);
      ap->port = node->ri->or_port;
      smartlist_add(sl, ap);
    }
  } else if (node->rs != NULL) {
      tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t));
      tor_addr_from_ipv4h(&ap->addr, node->rs->addr);
      ap->port = node->rs->or_port;
      smartlist_add(sl, ap);
  }

  return sl;
}

759
760
761
762
763
764
765
766
767
768
/** Wrapper around node_get_prim_orport for backward
    compatibility.  */
void
node_get_addr(const node_t *node, tor_addr_t *addr_out)
{
  tor_addr_port_t ap;
  node_get_prim_orport(node, &ap);
  tor_addr_copy(addr_out, &ap.addr);
}

769
770
771
/** Return the host-order IPv4 address for <b>node</b>, or 0 if it doesn't
 * seem to have one.  */
uint32_t
772
node_get_prim_addr_ipv4h(const node_t *node)
773
774
775
776
777
778
779
780
781
{
  if (node->ri) {
    return node->ri->addr;
  } else if (node->rs) {
    return node->rs->addr;
  }
  return 0;
}

782
783
/** Copy a string representation of an IP address for <b>node</b> into
 * the <b>len</b>-byte buffer at <b>buf</b>.  */
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
void
node_get_address_string(const node_t *node, char *buf, size_t len)
{
  if (node->ri) {
    strlcpy(buf, node->ri->address, len);
  } else if (node->rs) {
    tor_addr_t addr;
    tor_addr_from_ipv4h(&addr, node->rs->addr);
    tor_addr_to_str(buf, &addr, len, 0);
  } else {
    buf[0] = '\0';
  }
}

/** Return <b>node</b>'s declared uptime, or -1 if it doesn't seem to have
 * one. */
long
node_get_declared_uptime(const node_t *node)
{
803
804
805
806
  if (node->ri)
    return node->ri->uptime;
  else
    return -1;
807
808
}

809
/** Return <b>node</b>'s platform string, or NULL if we don't know it. */
810
811
812
const char *
node_get_platform(const node_t *node)
{
813
814
815
816
817
818
819
  /* If we wanted, we could record the version in the routerstatus_t, since
   * the consensus lists it.  We don't, though, so this function just won't
   * work with microdescriptors. */
  if (node->ri)
    return node->ri->platform;
  else
    return NULL;
820
821
}

822
/** Return <b>node</b>'s time of publication, or 0 if we don't have one. */
823
824
825
time_t
node_get_published_on(const node_t *node)
{
826
827
828
829
  if (node->ri)
    return node->ri->cache_info.published_on;
  else
    return 0;
830
831
832
833
834
835
836
837
838
}

/** Return true iff <b>node</b> is one representing this router. */
int
node_is_me(const node_t *node)
{
  return router_digest_is_me(node->identity);
}

839
840
841
842
843
844
845
846
847
848
849
850
/** Return <b>node</b> declared family (as a list of names), or NULL if
 * the node didn't declare a family. */
const smartlist_t *
node_get_declared_family(const node_t *node)
{
  if (node->ri && node->ri->declared_family)
    return node->ri->declared_family;
  else if (node->md && node->md->family)
    return node->md->family;
  else
    return NULL;
}
Sebastian Hahn's avatar
Sebastian Hahn committed
851

852
853
854
855
/** Return 1 if we prefer the IPv6 address and OR TCP port of
 * <b>node</b>, else 0.
 *
 *  We prefer the IPv6 address if the router has an IPv6 address and
856
 *  i) the node_t says that it prefers IPv6
857
 *  or
858
 *  ii) the router has no IPv4 address. */
859
860
861
int
node_ipv6_preferred(const node_t *node)
{
862
  tor_addr_port_t ipv4_addr;
863
  node_assert_ok(node);
864
865
866
867
868
869
870
871
872

  if (node->ipv6_preferred || node_get_prim_orport(node, &ipv4_addr)) {
    if (node->ri)
      return !tor_addr_is_null(&node->ri->ipv6_addr);
    if (node->md)
      return !tor_addr_is_null(&node->md->ipv6_addr);
    if (node->rs)
      return !tor_addr_is_null(&node->rs->ipv6_addr);
  }
873
874
875
876
  return 0;
}

/** Copy the primary (IPv4) OR port (IP address and TCP port) for
877
878
879
 * <b>node</b> into *<b>ap_out</b>. Return 0 if a valid address and
 * port was copied, else return non-zero.*/
int
880
881
882
883
884
885
node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out)
{
  node_assert_ok(node);
  tor_assert(ap_out);

  if (node->ri) {
886
887
    if (node->ri->addr == 0 || node->ri->or_port == 0)
      return -1;
888
889
    tor_addr_from_ipv4h(&ap_out->addr, node->ri->addr);
    ap_out->port = node->ri->or_port;
890
891
892
893
894
    return 0;
  }
  if (node->rs) {
    if (node->rs->addr == 0 || node->rs->or_port == 0)
      return -1;
895
896
    tor_addr_from_ipv4h(&ap_out->addr, node->rs->addr);
    ap_out->port = node->rs->or_port;
897
    return 0;
898
  }
899
  return -1;
900
901
902
903
904
905
906
}

/** Copy the preferred OR port (IP address and TCP port) for
 * <b>node</b> into *<b>ap_out</b>.  */
void
node_get_pref_orport(const node_t *node, tor_addr_port_t *ap_out)
{
907
  const or_options_t *options = get_options();
908
909
  tor_assert(ap_out);

910
  /* Cheap implementation of config option ClientUseIPv6 -- simply
911
912
913
914
915
916
917
918
919
     don't prefer IPv6 when ClientUseIPv6 is not set and we're not a
     client running with bridges. See #4455 for more on this subject.

     Note that this filter is too strict since we're hindering not
     only clients! Erring on the safe side shouldn't be a problem
     though. XXX move this check to where outgoing connections are
     made? -LN */
  if ((options->ClientUseIPv6 || options->UseBridges) &&
      node_ipv6_preferred(node)) {
920
    node_get_pref_ipv6_orport(node, ap_out);
921
  } else {
922
    node_get_prim_orport(node, ap_out);
923
  }
924
925
926
927
928
929
930
931
932
933
}

/** Copy the preferred IPv6 OR port (IP address and TCP port) for
 * <b>node</b> into *<b>ap_out</b>. */
void
node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out)
{
  node_assert_ok(node);
  tor_assert(ap_out);

934
935
936
937
938
  /* We prefer the microdesc over a potential routerstatus here. They
     are not being synchronised atm so there might be a chance that
     they differ at some point, f.ex. when flipping
     UseMicrodescriptors? -LN */

939
940
941
  if (node->ri) {
    tor_addr_copy(&ap_out->addr, &node->ri->ipv6_addr);
    ap_out->port = node->ri->ipv6_orport;
942
943
944
  } else if (node->md) {
    tor_addr_copy(&ap_out->addr, &node->md->ipv6_addr);
    ap_out->port = node->md->ipv6_orport;
945
946
947
948
949
  } else if (node->rs) {
    tor_addr_copy(&ap_out->addr, &node->rs->ipv6_addr);
    ap_out->port = node->rs->ipv6_orport;
  }
}
Nick Mathewson's avatar
Nick Mathewson committed
950

951
952
953
954
955
956
957
958
959
960
961
962
/** Return true iff <b>node</b> has a curve25519 onion key. */
int
node_has_curve25519_onion_key(const node_t *node)
{
  if (node->ri)
    return node->ri->onion_curve25519_pkey != NULL;
  else if (node->md)
    return node->md->onion_curve25519_pkey != NULL;
  else
    return 0;
}

963
964
965
966
967
/** Refresh the country code of <b>ri</b>.  This function MUST be called on
 * each router when the GeoIP database is reloaded, and on all new routers. */
void
node_set_country(node_t *node)
{
968
969
970
  tor_addr_t addr = TOR_ADDR_NULL;

  /* XXXXipv6 */
971
  if (node->rs)
972
    tor_addr_from_ipv4h(&addr, node->rs->addr);
973
  else if (node->ri)
974
975
976
    tor_addr_from_ipv4h(&addr, node->ri->addr);

  node->country = geoip_get_country_by_addr(&addr);
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
}

/** Set the country code of all routers in the routerlist. */
void
nodelist_refresh_countries(void)
{
  smartlist_t *nodes = nodelist_get_list();
  SMARTLIST_FOREACH(nodes, node_t *, node,
                    node_set_country(node));
}

/** Return true iff router1 and router2 have similar enough network addresses
 * that we should treat them as being in the same family */
static INLINE int
addrs_in_same_network_family(const tor_addr_t *a1,
                             const tor_addr_t *a2)
{
  return 0 == tor_addr_compare_masked(a1, a2, 16, CMP_SEMANTIC);
}

/** Return true if <b>node</b>'s nickname matches <b>nickname</b>
 * (case-insensitive), or if <b>node's</b> identity key digest
 * matches a hexadecimal value stored in <b>nickname</b>.  Return
 * false otherwise. */