Tor 0.4.9.0-alpha-dev
node_select.c
Go to the documentation of this file.
1/* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * \file node_select.c
9 * \brief Code to choose nodes randomly based on restrictions and
10 * weighted probabilities.
11 **/
12
13#define NODE_SELECT_PRIVATE
14#include "core/or/or.h"
15
16#include "app/config/config.h"
18#include "core/or/policies.h"
19#include "core/or/reasons.h"
36#include "lib/math/fp.h"
37
43
44static int compute_weighted_bandwidths(const smartlist_t *sl,
46 double **bandwidths_out,
47 double *total_bandwidth_out);
49 const smartlist_t *sourcelist, dirinfo_type_t auth,
50 int flags, int *n_busy_out);
52 smartlist_t *sourcelist,
53 dirinfo_type_t type, int flags);
54
55/** Try to find a running dirserver that supports operations of <b>type</b>.
56 *
57 * If there are no running dirservers in our routerlist and the
58 * <b>PDS_RETRY_IF_NO_SERVERS</b> flag is set, set all the fallback ones
59 * (including authorities) as running again, and pick one.
60 *
61 * If the <b>PDS_IGNORE_FASCISTFIREWALL</b> flag is set, then include
62 * dirservers that we can't reach.
63 *
64 * If the <b>PDS_ALLOW_SELF</b> flag is not set, then don't include ourself
65 * (if we're a dirserver).
66 *
67 * Don't pick a fallback directory mirror if any non-fallback is viable;
68 * (the fallback directory mirrors include the authorities)
69 * try to avoid using servers that have returned 503 recently.
70 */
71const routerstatus_t *
73{
74 int busy = 0;
75 const routerstatus_t *choice;
76
77 choice = router_pick_directory_server_impl(type, flags, &busy);
78 if (choice || !(flags & PDS_RETRY_IF_NO_SERVERS))
79 return choice;
80
81 if (busy) {
82 /* If the reason that we got no server is that servers are "busy",
83 * we must be excluding good servers because we already have serverdesc
84 * fetches with them. Do not mark down servers up because of this. */
87 return NULL;
88 }
89
90 log_info(LD_DIR,
91 "No reachable router entries for dirservers. "
92 "Trying them all again.");
93 /* mark all fallback directory mirrors as up again */
95 /* try again */
96 choice = router_pick_directory_server_impl(type, flags, NULL);
97 return choice;
98}
99
100/** Try to find a running fallback directory. Flags are as for
101 * router_pick_directory_server.
102 */
103const routerstatus_t *
105 dirinfo_type_t type, int flags)
106{
107 const routerstatus_t *choice;
108 int busy = 0;
109
110 if (smartlist_len(sourcelist) == 1) {
111 /* If there's only one choice, then we should disable the logic that
112 * would otherwise prevent us from choosing ourself. */
113 flags |= PDS_ALLOW_SELF;
114 }
115
116 choice = router_pick_trusteddirserver_impl(sourcelist, type, flags, &busy);
117 if (choice || !(flags & PDS_RETRY_IF_NO_SERVERS))
118 return choice;
119 if (busy) {
120 /* If the reason that we got no server is that servers are "busy",
121 * we must be excluding good servers because we already have serverdesc
122 * fetches with them. Do not mark down servers up because of this. */
125 return NULL;
126 }
127
128 log_info(LD_DIR,
129 "No dirservers are reachable. Trying them all again.");
130 mark_all_dirservers_up(sourcelist);
131 return router_pick_trusteddirserver_impl(sourcelist, type, flags, NULL);
132}
133
134/* Common retry code for router_pick_directory_server_impl and
135 * router_pick_trusteddirserver_impl. Retry with the non-preferred IP version.
136 * Must be called before RETRY_WITHOUT_EXCLUDE().
137 *
138 * If we got no result, and we are applying IP preferences, and we are a
139 * client that could use an alternate IP version, try again with the
140 * opposite preferences. */
141#define RETRY_ALTERNATE_IP_VERSION(retry_label) \
142 STMT_BEGIN \
143 if (result == NULL && try_ip_pref && options->ClientUseIPv4 \
144 && reachable_addr_use_ipv6(options) && !server_mode(options) \
145 && !n_busy) { \
146 n_excluded = 0; \
147 n_busy = 0; \
148 try_ip_pref = 0; \
149 goto retry_label; \
150 } \
151 STMT_END
152
153/* Common retry code for router_pick_directory_server_impl and
154 * router_pick_trusteddirserver_impl. Retry without excluding nodes, but with
155 * the preferred IP version. Must be called after RETRY_ALTERNATE_IP_VERSION().
156 *
157 * If we got no result, and we are excluding nodes, and StrictNodes is
158 * not set, try again without excluding nodes. */
159#define RETRY_WITHOUT_EXCLUDE(retry_label) \
160 STMT_BEGIN \
161 if (result == NULL && try_excluding && !options->StrictNodes \
162 && n_excluded && !n_busy) { \
163 try_excluding = 0; \
164 n_excluded = 0; \
165 n_busy = 0; \
166 try_ip_pref = 1; \
167 goto retry_label; \
168 } \
169 STMT_END
170
171/* Common code used in the loop within router_pick_directory_server_impl and
172 * router_pick_trusteddirserver_impl.
173 *
174 * Check if the given <b>identity</b> supports extrainfo. If not, skip further
175 * checks.
176 */
177#define SKIP_MISSING_TRUSTED_EXTRAINFO(type, identity) \
178 STMT_BEGIN \
179 int is_trusted_extrainfo = router_digest_is_trusted_dir_type( \
180 (identity), EXTRAINFO_DIRINFO); \
181 if (((type) & EXTRAINFO_DIRINFO) && \
182 !router_supports_extrainfo((identity), is_trusted_extrainfo)) \
183 continue; \
184 STMT_END
185
186#ifndef LOG_FALSE_POSITIVES_DURING_BOOTSTRAP
187#define LOG_FALSE_POSITIVES_DURING_BOOTSTRAP 0
188#endif
189
190/* Log a message if rs is not found or not a preferred address */
191static void
192router_picked_poor_directory_log(const routerstatus_t *rs)
193{
194 const networkstatus_t *usable_consensus;
195 usable_consensus = networkstatus_get_reasonably_live_consensus(time(NULL),
197
198#if !LOG_FALSE_POSITIVES_DURING_BOOTSTRAP
199 /* Don't log early in the bootstrap process, it's normal to pick from a
200 * small pool of nodes. Of course, this won't help if we're trying to
201 * diagnose bootstrap issues. */
202 if (!smartlist_len(nodelist_get_list()) || !usable_consensus
204 return;
205 }
206#endif /* !LOG_FALSE_POSITIVES_DURING_BOOTSTRAP */
207
208 /* We couldn't find a node, or the one we have doesn't fit our preferences.
209 * Sometimes this is normal, sometimes it can be a reachability issue. */
210 if (!rs) {
211 /* This happens a lot, so it's at debug level */
212 log_debug(LD_DIR, "Wanted to make an outgoing directory connection, but "
213 "we couldn't find a directory that fit our criteria. "
214 "Perhaps we will succeed next time with less strict criteria.");
215 } else if (!reachable_addr_allows_rs(rs, FIREWALL_OR_CONNECTION, 1)
216 && !reachable_addr_allows_rs(rs, FIREWALL_DIR_CONNECTION, 1)
217 ) {
218 /* This is rare, and might be interesting to users trying to diagnose
219 * connection issues on dual-stack machines. */
220 char *ipv4_str = tor_addr_to_str_dup(&rs->ipv4_addr);
221 log_info(LD_DIR, "Selected a directory %s with non-preferred OR and Dir "
222 "addresses for launching an outgoing connection: "
223 "IPv4 %s OR %d Dir %d IPv6 %s OR %d Dir %d",
225 ipv4_str, rs->ipv4_orport,
227 rs->ipv6_orport, rs->ipv4_dirport);
228 tor_free(ipv4_str);
229 }
230}
231
232#undef LOG_FALSE_POSITIVES_DURING_BOOTSTRAP
233
234/* Check if we already have a directory fetch from ap, for serverdesc
235 * (including extrainfo) or microdesc documents.
236 * If so, return 1, if not, return 0.
237 * Also returns 0 if addr is NULL, tor_addr_is_null(addr), or dir_port is 0.
238 */
239STATIC int
240router_is_already_dir_fetching(const tor_addr_port_t *ap, int serverdesc,
241 int microdesc)
242{
243 if (!ap || tor_addr_is_null(&ap->addr) || !ap->port) {
244 return 0;
245 }
246
247 /* XX/teor - we're not checking tunnel connections here, see #17848
248 */
249 if (serverdesc && (
251 CONN_TYPE_DIR, &ap->addr, ap->port, DIR_PURPOSE_FETCH_SERVERDESC)
253 CONN_TYPE_DIR, &ap->addr, ap->port, DIR_PURPOSE_FETCH_EXTRAINFO))) {
254 return 1;
255 }
256
257 if (microdesc && (
259 CONN_TYPE_DIR, &ap->addr, ap->port, DIR_PURPOSE_FETCH_MICRODESC))) {
260 return 1;
261 }
262
263 return 0;
264}
265
266/* Check if we already have a directory fetch from the ipv4 or ipv6
267 * router, for serverdesc (including extrainfo) or microdesc documents.
268 * If so, return 1, if not, return 0.
269 */
270static int
271router_is_already_dir_fetching_(const tor_addr_t *ipv4_addr,
272 const tor_addr_t *ipv6_addr,
273 uint16_t dir_port,
274 int serverdesc,
275 int microdesc)
276{
277 tor_addr_port_t ipv4_dir_ap, ipv6_dir_ap;
278
279 /* Assume IPv6 DirPort is the same as IPv4 DirPort */
280 tor_addr_copy(&ipv4_dir_ap.addr, ipv4_addr);
281 ipv4_dir_ap.port = dir_port;
282 tor_addr_copy(&ipv6_dir_ap.addr, ipv6_addr);
283 ipv6_dir_ap.port = dir_port;
284
285 return (router_is_already_dir_fetching(&ipv4_dir_ap, serverdesc, microdesc)
286 || router_is_already_dir_fetching(&ipv6_dir_ap, serverdesc, microdesc));
287}
288
289/** Pick a random running valid directory server/mirror from our
290 * routerlist. Arguments are as for router_pick_directory_server(), except:
291 *
292 * If <b>n_busy_out</b> is provided, set *<b>n_busy_out</b> to the number of
293 * directories that we excluded for no other reason than
294 * PDS_NO_EXISTING_SERVERDESC_FETCH or PDS_NO_EXISTING_MICRODESC_FETCH.
295 */
298 int *n_busy_out)
299{
300 const or_options_t *options = get_options();
301 const node_t *result;
302 smartlist_t *direct, *tunnel;
303 smartlist_t *trusted_direct, *trusted_tunnel;
304 smartlist_t *overloaded_direct, *overloaded_tunnel;
305 time_t now = time(NULL);
307 const int requireother = ! (flags & PDS_ALLOW_SELF);
308 const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
309 const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
310 const int no_microdesc_fetching = (flags & PDS_NO_EXISTING_MICRODESC_FETCH);
311 int try_excluding = 1, n_excluded = 0, n_busy = 0;
312 int try_ip_pref = 1;
313
314 if (!consensus)
315 return NULL;
316
317 retry_search:
318
319 direct = smartlist_new();
320 tunnel = smartlist_new();
321 trusted_direct = smartlist_new();
322 trusted_tunnel = smartlist_new();
323 overloaded_direct = smartlist_new();
324 overloaded_tunnel = smartlist_new();
325
326 const int skip_or_fw = router_or_conn_should_skip_reachable_address_check(
327 options,
328 try_ip_pref);
329 const int skip_dir_fw = router_dir_conn_should_skip_reachable_address_check(
330 options,
331 try_ip_pref);
332 const int must_have_or = dirclient_must_use_begindir(options);
333
334 /* Find all the running dirservers we know about. */
336 int is_trusted;
337 int is_overloaded;
338 const routerstatus_t *status = node->rs;
339 const country_t country = node->country;
340 if (!status)
341 continue;
342
343 if (!node->is_running || !node_is_dir(node) || !node->is_valid)
344 continue;
345 if (requireother && router_digest_is_me(node->identity))
346 continue;
347
348 SKIP_MISSING_TRUSTED_EXTRAINFO(type, node->identity);
349
350 if (try_excluding &&
352 country)) {
353 ++n_excluded;
354 continue;
355 }
356
357 if (router_is_already_dir_fetching_(&status->ipv4_addr,
358 &status->ipv6_addr,
359 status->ipv4_dirport,
360 no_serverdesc_fetching,
361 no_microdesc_fetching)) {
362 ++n_busy;
363 continue;
364 }
365
366 is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
367 is_trusted = router_digest_is_trusted_dir(node->identity);
368
369 /* Clients use IPv6 addresses if the server has one and the client
370 * prefers IPv6.
371 * Add the router if its preferred address and port are reachable.
372 * If we don't get any routers, we'll try again with the non-preferred
373 * address for each router (if any). (To ensure correct load-balancing
374 * we try routers that only have one address both times.)
375 */
376 if (!fascistfirewall || skip_or_fw ||
377 reachable_addr_allows_node(node, FIREWALL_OR_CONNECTION,
378 try_ip_pref))
379 smartlist_add(is_trusted ? trusted_tunnel :
380 is_overloaded ? overloaded_tunnel : tunnel, (void*)node);
381 else if (!must_have_or && (skip_dir_fw ||
382 reachable_addr_allows_node(node, FIREWALL_DIR_CONNECTION,
383 try_ip_pref)))
384 smartlist_add(is_trusted ? trusted_direct :
385 is_overloaded ? overloaded_direct : direct, (void*)node);
386 } SMARTLIST_FOREACH_END(node);
387
388 if (smartlist_len(tunnel)) {
389 result = node_sl_choose_by_bandwidth(tunnel, WEIGHT_FOR_DIR);
390 } else if (smartlist_len(overloaded_tunnel)) {
391 result = node_sl_choose_by_bandwidth(overloaded_tunnel,
392 WEIGHT_FOR_DIR);
393 } else if (smartlist_len(trusted_tunnel)) {
394 /* FFFF We don't distinguish between trusteds and overloaded trusteds
395 * yet. Maybe one day we should. */
396 /* FFFF We also don't load balance over authorities yet. I think this
397 * is a feature, but it could easily be a bug. -RD */
398 result = smartlist_choose(trusted_tunnel);
399 } else if (smartlist_len(direct)) {
400 result = node_sl_choose_by_bandwidth(direct, WEIGHT_FOR_DIR);
401 } else if (smartlist_len(overloaded_direct)) {
402 result = node_sl_choose_by_bandwidth(overloaded_direct,
403 WEIGHT_FOR_DIR);
404 } else {
405 result = smartlist_choose(trusted_direct);
406 }
407 smartlist_free(direct);
408 smartlist_free(tunnel);
409 smartlist_free(trusted_direct);
410 smartlist_free(trusted_tunnel);
411 smartlist_free(overloaded_direct);
412 smartlist_free(overloaded_tunnel);
413
414 RETRY_ALTERNATE_IP_VERSION(retry_search);
415
416 RETRY_WITHOUT_EXCLUDE(retry_search);
417
418 if (n_busy_out)
419 *n_busy_out = n_busy;
420
421 router_picked_poor_directory_log(result ? result->rs : NULL);
422
423 return result ? result->rs : NULL;
424}
425
426/** Given an array of double/uint64_t unions that are currently being used as
427 * doubles, convert them to uint64_t, and try to scale them linearly so as to
428 * much of the range of uint64_t. If <b>total_out</b> is provided, set it to
429 * the sum of all elements in the array _before_ scaling. */
430STATIC void
431scale_array_elements_to_u64(uint64_t *entries_out, const double *entries_in,
432 int n_entries,
433 uint64_t *total_out)
434{
435 double total = 0.0;
436 double scale_factor = 0.0;
437 int i;
438
439 for (i = 0; i < n_entries; ++i)
440 total += entries_in[i];
441
442 if (total > 0.0) {
443 scale_factor = ((double)INT64_MAX) / total;
444 scale_factor /= 4.0; /* make sure we're very far away from overflowing */
445 }
446
447 for (i = 0; i < n_entries; ++i)
448 entries_out[i] = tor_llround(entries_in[i] * scale_factor);
449
450 if (total_out)
451 *total_out = (uint64_t) total;
452}
453
454/** Pick a random element of <b>n_entries</b>-element array <b>entries</b>,
455 * choosing each element with a probability proportional to its (uint64_t)
456 * value, and return the index of that element. If all elements are 0, choose
457 * an index at random. Return -1 on error.
458 */
459STATIC int
460choose_array_element_by_weight(const uint64_t *entries, int n_entries)
461{
462 int i;
463 uint64_t rand_val;
464 uint64_t total = 0;
465
466 for (i = 0; i < n_entries; ++i)
467 total += entries[i];
468
469 if (n_entries < 1)
470 return -1;
471
472 if (total == 0)
473 return crypto_rand_int(n_entries);
474
475 tor_assert(total < INT64_MAX);
476
477 rand_val = crypto_rand_uint64(total);
478
480 entries, n_entries, total, rand_val);
481}
482
483/** Return bw*1000, unless bw*1000 would overflow, in which case return
484 * INT32_MAX. */
485static inline int32_t
486kb_to_bytes(uint32_t bw)
487{
488 return (bw > (INT32_MAX/1000)) ? INT32_MAX : bw*1000;
489}
490
491/** Helper function:
492 * choose a random element of smartlist <b>sl</b> of nodes, weighted by
493 * the advertised bandwidth of each element using the consensus
494 * bandwidth weights.
495 *
496 * If <b>rule</b>==WEIGHT_FOR_EXIT. we're picking an exit node: consider all
497 * nodes' bandwidth equally regardless of their Exit status, since there may
498 * be some in the list because they exit to obscure ports. If
499 * <b>rule</b>==NO_WEIGHTING, we're picking a non-exit node: weight
500 * exit-node's bandwidth less depending on the smallness of the fraction of
501 * Exit-to-total bandwidth. If <b>rule</b>==WEIGHT_FOR_GUARD, we're picking a
502 * guard node: consider all guard's bandwidth equally. Otherwise, weight
503 * guards proportionally less.
504 */
505static const node_t *
508{
509 double *bandwidths_dbl=NULL;
510 uint64_t *bandwidths_u64=NULL;
511
512 if (compute_weighted_bandwidths(sl, rule, &bandwidths_dbl, NULL) < 0)
513 return NULL;
514
515 bandwidths_u64 = tor_calloc(smartlist_len(sl), sizeof(uint64_t));
516 scale_array_elements_to_u64(bandwidths_u64, bandwidths_dbl,
517 smartlist_len(sl), NULL);
518
519 {
520 int idx = choose_array_element_by_weight(bandwidths_u64,
521 smartlist_len(sl));
522 tor_free(bandwidths_dbl);
523 tor_free(bandwidths_u64);
524 return idx < 0 ? NULL : smartlist_get(sl, idx);
525 }
526}
527
528/** When weighting bridges, enforce these values as lower and upper
529 * bound for believable bandwidth, because there is no way for us
530 * to verify a bridge's bandwidth currently. */
531#define BRIDGE_MIN_BELIEVABLE_BANDWIDTH 20000 /* 20 kB/sec */
532#define BRIDGE_MAX_BELIEVABLE_BANDWIDTH 100000 /* 100 kB/sec */
533
534/** Return the smaller of the router's configured BandwidthRate
535 * and its advertised capacity, making sure to stay within the
536 * interval between bridge-min-believe-bw and
537 * bridge-max-believe-bw. */
538static uint32_t
540{
541 uint32_t result = router->bandwidthcapacity;
542 if (result > router->bandwidthrate)
543 result = router->bandwidthrate;
544 if (result > BRIDGE_MAX_BELIEVABLE_BANDWIDTH)
545 result = BRIDGE_MAX_BELIEVABLE_BANDWIDTH;
546 else if (result < BRIDGE_MIN_BELIEVABLE_BANDWIDTH)
548 return result;
549}
550
551/**
552 * We have found an instance of bug 32868: log our best guess about where the
553 * routerstatus was found.
554 **/
555static void
557{
558 static ratelim_t buggy_rs_ratelim = RATELIM_INIT(1200);
559 char *m;
560 if ((m = rate_limit_log(&buggy_rs_ratelim, approx_time()))) {
561 log_warn(LD_BUG,
562 "Found a routerstatus %p with has_guardfraction=%u "
563 " and guardfraction_percentage=%u, but is_possible_guard=%u.%s",
564 rs,
568 m);
569 tor_free(m);
570 networkstatus_t *ns;
571 int in_ns_count = 0;
573 int pos = smartlist_pos(ns->routerstatus_list, rs);
574 if (pos >= 0) {
575 ++in_ns_count;
576 log_warn(LD_BUG, "Found the routerstatus at position %d of the "
577 "NS consensus.", pos);
578 }
579 }
580 if ((ns = networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC))) {
581 int pos = smartlist_pos(ns->routerstatus_list, rs);
582 if (pos >= 0) {
583 ++in_ns_count;
584 log_warn(LD_BUG, "Found the routerstatus at position %d of the "
585 "MD consensus.", pos);
586 }
587 }
588 if (in_ns_count == 0) {
589 log_warn(LD_BUG, "Could not find the routerstatus in any "
590 "latest consensus.");
591 }
593 }
594}
595
596/** Given a list of routers and a weighting rule as in
597 * smartlist_choose_node_by_bandwidth_weights, compute weighted bandwidth
598 * values for each node and store them in a freshly allocated
599 * *<b>bandwidths_out</b> of the same length as <b>sl</b>, and holding results
600 * as doubles. If <b>total_bandwidth_out</b> is non-NULL, set it to the total
601 * of all the bandwidths.
602 * Return 0 on success, -1 on failure. */
603static int
606 double **bandwidths_out,
607 double *total_bandwidth_out)
608{
609 int64_t weight_scale;
610 double Wg = -1, Wm = -1, We = -1, Wd = -1;
611 double Wgb = -1, Wmb = -1, Web = -1, Wdb = -1;
612 guardfraction_bandwidth_t guardfraction_bw;
613 double *bandwidths = NULL;
614 double total_bandwidth = 0.0;
615
616 tor_assert(sl);
617 tor_assert(bandwidths_out);
618
619 /* Can't choose exit and guard at same time */
620 tor_assert(rule == NO_WEIGHTING ||
621 rule == WEIGHT_FOR_EXIT ||
622 rule == WEIGHT_FOR_GUARD ||
623 rule == WEIGHT_FOR_MID ||
624 rule == WEIGHT_FOR_DIR);
625
626 *bandwidths_out = NULL;
627
628 if (total_bandwidth_out) {
629 *total_bandwidth_out = 0.0;
630 }
631
632 if (smartlist_len(sl) == 0) {
633 log_info(LD_CIRC,
634 "Empty routerlist passed in to consensus weight node "
635 "selection for rule %s",
637 return -1;
638 }
639
640 weight_scale = networkstatus_get_weight_scale_param(NULL);
641 tor_assert(weight_scale >= 1);
642
643 if (rule == WEIGHT_FOR_GUARD) {
644 Wg = networkstatus_get_bw_weight(NULL, "Wgg", -1);
645 Wm = networkstatus_get_bw_weight(NULL, "Wgm", -1); /* Bridges */
646 We = 0;
647 Wd = networkstatus_get_bw_weight(NULL, "Wgd", -1);
648
649 Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
650 Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
651 Web = networkstatus_get_bw_weight(NULL, "Web", -1);
652 Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
653 } else if (rule == WEIGHT_FOR_MID) {
654 Wg = networkstatus_get_bw_weight(NULL, "Wmg", -1);
655 Wm = networkstatus_get_bw_weight(NULL, "Wmm", -1);
656 We = networkstatus_get_bw_weight(NULL, "Wme", -1);
657 Wd = networkstatus_get_bw_weight(NULL, "Wmd", -1);
658
659 Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
660 Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
661 Web = networkstatus_get_bw_weight(NULL, "Web", -1);
662 Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
663 } else if (rule == WEIGHT_FOR_EXIT) {
664 // Guards CAN be exits if they have weird exit policies
665 // They are d then I guess...
666 We = networkstatus_get_bw_weight(NULL, "Wee", -1);
667 Wm = networkstatus_get_bw_weight(NULL, "Wem", -1); /* Odd exit policies */
668 Wd = networkstatus_get_bw_weight(NULL, "Wed", -1);
669 Wg = networkstatus_get_bw_weight(NULL, "Weg", -1); /* Odd exit policies */
670
671 Wgb = networkstatus_get_bw_weight(NULL, "Wgb", -1);
672 Wmb = networkstatus_get_bw_weight(NULL, "Wmb", -1);
673 Web = networkstatus_get_bw_weight(NULL, "Web", -1);
674 Wdb = networkstatus_get_bw_weight(NULL, "Wdb", -1);
675 } else if (rule == WEIGHT_FOR_DIR) {
676 We = networkstatus_get_bw_weight(NULL, "Wbe", -1);
677 Wm = networkstatus_get_bw_weight(NULL, "Wbm", -1);
678 Wd = networkstatus_get_bw_weight(NULL, "Wbd", -1);
679 Wg = networkstatus_get_bw_weight(NULL, "Wbg", -1);
680
681 Wgb = Wmb = Web = Wdb = weight_scale;
682 } else if (rule == NO_WEIGHTING) {
683 Wg = Wm = We = Wd = weight_scale;
684 Wgb = Wmb = Web = Wdb = weight_scale;
685 }
686
687 if (Wg < 0 || Wm < 0 || We < 0 || Wd < 0 || Wgb < 0 || Wmb < 0 || Wdb < 0
688 || Web < 0) {
689 log_debug(LD_CIRC,
690 "Got negative bandwidth weights. Defaulting to naive selection"
691 " algorithm.");
692 Wg = Wm = We = Wd = weight_scale;
693 Wgb = Wmb = Web = Wdb = weight_scale;
694 }
695
696 Wg /= weight_scale;
697 Wm /= weight_scale;
698 We /= weight_scale;
699 Wd /= weight_scale;
700
701 Wgb /= weight_scale;
702 Wmb /= weight_scale;
703 Web /= weight_scale;
704 Wdb /= weight_scale;
705
706 bandwidths = tor_calloc(smartlist_len(sl), sizeof(double));
707
708 // Cycle through smartlist and total the bandwidth.
709 static int warned_missing_bw = 0;
710 SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
711 int is_exit = 0, is_guard = 0, is_dir = 0, this_bw = 0;
712 double weight = 1;
713 double weight_without_guard_flag = 0; /* Used for guardfraction */
714 double final_weight = 0;
715 is_exit = node->is_exit && ! node->is_bad_exit;
716 is_guard = node->is_possible_guard;
717 is_dir = node_is_dir(node);
718 if (node->rs) {
719 if (!node->rs->has_bandwidth) {
720 /* This should never happen, unless all the authorities downgrade
721 * to 0.2.0 or rogue routerstatuses get inserted into our consensus. */
722 if (! warned_missing_bw) {
723 log_warn(LD_BUG,
724 "Consensus is missing some bandwidths. Using a naive "
725 "router selection algorithm");
726 warned_missing_bw = 1;
727 }
728 this_bw = 30000; /* Chosen arbitrarily */
729 } else {
730 this_bw = kb_to_bytes(node->rs->bandwidth_kb);
731 }
732 } else if (node->ri) {
733 /* bridge or other descriptor not in our consensus */
734 this_bw = bridge_get_advertised_bandwidth_bounded(node->ri);
735 } else {
736 /* We can't use this one. */
737 continue;
738 }
739
740 if (is_guard && is_exit) {
741 weight = (is_dir ? Wdb*Wd : Wd);
742 weight_without_guard_flag = (is_dir ? Web*We : We);
743 } else if (is_guard) {
744 weight = (is_dir ? Wgb*Wg : Wg);
745 weight_without_guard_flag = (is_dir ? Wmb*Wm : Wm);
746 } else if (is_exit) {
747 weight = (is_dir ? Web*We : We);
748 } else { // middle
749 weight = (is_dir ? Wmb*Wm : Wm);
750 }
751 /* These should be impossible; but overflows here would be bad, so let's
752 * make sure. */
753 if (this_bw < 0)
754 this_bw = 0;
755 if (weight < 0.0)
756 weight = 0.0;
757 if (weight_without_guard_flag < 0.0)
758 weight_without_guard_flag = 0.0;
759
760 /* If guardfraction information is available in the consensus, we
761 * want to calculate this router's bandwidth according to its
762 * guardfraction. Quoting from proposal236:
763 *
764 * Let Wpf denote the weight from the 'bandwidth-weights' line a
765 * client would apply to N for position p if it had the guard
766 * flag, Wpn the weight if it did not have the guard flag, and B the
767 * measured bandwidth of N in the consensus. Then instead of choosing
768 * N for position p proportionally to Wpf*B or Wpn*B, clients should
769 * choose N proportionally to F*Wpf*B + (1-F)*Wpn*B.
770 */
771 if (node->rs && node->rs->has_guardfraction && rule != WEIGHT_FOR_GUARD) {
772 /* We should only have guardfraction set if the node has the Guard
773 flag. */
774 if (! node->rs->is_possible_guard) {
775 log_buggy_rs_source(node->rs);
776 }
777
778 guard_get_guardfraction_bandwidth(&guardfraction_bw,
779 this_bw,
780 node->rs->guardfraction_percentage);
781
782 /* Calculate final_weight = F*Wpf*B + (1-F)*Wpn*B */
783 final_weight =
784 guardfraction_bw.guard_bw * weight +
785 guardfraction_bw.non_guard_bw * weight_without_guard_flag;
786
787 log_debug(LD_GENERAL, "%s: Guardfraction weight %f instead of %f (%s)",
788 node->rs->nickname, final_weight, weight*this_bw,
790 } else { /* no guardfraction information. calculate the weight normally. */
791 final_weight = weight*this_bw;
792 }
793
794 bandwidths[node_sl_idx] = final_weight;
795 total_bandwidth += final_weight;
796 } SMARTLIST_FOREACH_END(node);
797
798 log_debug(LD_CIRC, "Generated weighted bandwidths for rule %s based "
799 "on weights "
800 "Wg=%f Wm=%f We=%f Wd=%f with total bw %f",
802 Wg, Wm, We, Wd, total_bandwidth);
803
804 *bandwidths_out = bandwidths;
805
806 if (total_bandwidth_out) {
807 *total_bandwidth_out = total_bandwidth;
808 }
809
810 return 0;
811}
812
813/** For all nodes in <b>sl</b>, return the fraction of those nodes, weighted
814 * by their weighted bandwidths with rule <b>rule</b>, for which we have
815 * descriptors.
816 *
817 * If <b>for_direct_connect</b> is true, we intend to connect to the node
818 * directly, as the first hop of a circuit; otherwise, we intend to connect
819 * to it indirectly, or use it as if we were connecting to it indirectly. */
820double
823 int for_direct_conn)
824{
825 double *bandwidths = NULL;
826 double total, present;
827
828 if (smartlist_len(sl) == 0)
829 return 0.0;
830
831 if (compute_weighted_bandwidths(sl, rule, &bandwidths, &total) < 0 ||
832 total <= 0.0) {
833 int n_with_descs = 0;
834 SMARTLIST_FOREACH(sl, const node_t *, node, {
835 if (node_has_preferred_descriptor(node, for_direct_conn))
836 n_with_descs++;
837 });
838 tor_free(bandwidths);
839 return ((double)n_with_descs) / smartlist_len(sl);
840 }
841
842 present = 0.0;
843 SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
844 if (node_has_preferred_descriptor(node, for_direct_conn))
845 present += bandwidths[node_sl_idx];
846 } SMARTLIST_FOREACH_END(node);
847
848 tor_free(bandwidths);
849
850 return present / total;
851}
852
853/** Choose a random element of status list <b>sl</b>, weighted by
854 * the advertised bandwidth of each node */
855const node_t *
858{ /*XXXX MOVE */
860}
861
862/** Given a <b>router</b>, add every node_t in its family (including the
863 * node itself!) to <b>sl</b>.
864 *
865 * Note the type mismatch: This function takes a routerinfo, but adds nodes
866 * to the smartlist!
867 */
868static void
870{
871 /* XXXX MOVE ? */
872 node_t fake_node;
873 const node_t *node = node_get_by_id(router->cache_info.identity_digest);
874 if (node == NULL) {
875 memset(&fake_node, 0, sizeof(fake_node));
876 fake_node.ri = (routerinfo_t *)router;
877 memcpy(fake_node.identity, router->cache_info.identity_digest, DIGEST_LEN);
878 node = &fake_node;
879 }
881}
882
883/**
884 * Remove every node_t that appears in <b>excluded</b> from <b>sl</b>.
885 *
886 * Behaves like smartlist_subtract, but uses nodelist_idx values to deliver
887 * linear performance when smartlist_subtract would be quadratic.
888 **/
889static void
891{
892 const smartlist_t *nodelist = nodelist_get_list();
893 const int nodelist_len = smartlist_len(nodelist);
894 bitarray_t *excluded_idx = bitarray_init_zero(nodelist_len);
895
896 /* We haven't used nodelist_idx in this way previously, so I'm going to be
897 * paranoid in this code, and check that nodelist_idx is correct for every
898 * node before we use it. If we fail, we fall back to smartlist_subtract().
899 */
900
901 /* Set the excluded_idx bit corresponding to every excluded node...
902 */
903 SMARTLIST_FOREACH_BEGIN(excluded, const node_t *, node) {
904 const int idx = node->nodelist_idx;
905 if (BUG(idx < 0) || BUG(idx >= nodelist_len) ||
906 BUG(node != smartlist_get(nodelist, idx))) {
907 goto internal_error;
908 }
909 bitarray_set(excluded_idx, idx);
910 } SMARTLIST_FOREACH_END(node);
911
912 /* Then remove them from sl.
913 */
914 SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
915 const int idx = node->nodelist_idx;
916 if (BUG(idx < 0) || BUG(idx >= nodelist_len) ||
917 BUG(node != smartlist_get(nodelist, idx))) {
918 goto internal_error;
919 }
920 if (bitarray_is_set(excluded_idx, idx)) {
921 SMARTLIST_DEL_CURRENT(sl, node);
922 }
923 } SMARTLIST_FOREACH_END(node);
924
925 bitarray_free(excluded_idx);
926 return;
927
928 internal_error:
929 log_warn(LD_BUG, "Internal error prevented us from using the fast method "
930 "for subtracting nodelists. Falling back to the quadratic way.");
931 smartlist_subtract(sl, excluded);
932 bitarray_free(excluded_idx);
933}
934
935/* Node selection helper for router_choose_random_node().
936 *
937 * Populates a node list based on <b>flags</b>, ignoring nodes in
938 * <b>excludednodes</b> and <b>excludedset</b>. Chooses the node based on
939 * <b>rule</b>. */
940static const node_t *
941router_choose_random_node_helper(smartlist_t *excludednodes,
942 routerset_t *excludedset,
943 router_crn_flags_t flags,
945{
947 const node_t *choice = NULL;
948
950 log_debug(LD_CIRC,
951 "We found %d running nodes.",
952 smartlist_len(sl));
953
954 nodelist_subtract(sl, excludednodes);
955
956 if (excludedset) {
957 routerset_subtract_nodes(sl,excludedset);
958 log_debug(LD_CIRC,
959 "We removed excludedset, leaving %d nodes.",
960 smartlist_len(sl));
961 }
962
963 // Always weight by bandwidth
964 choice = node_sl_choose_by_bandwidth(sl, rule);
965
966 smartlist_free(sl);
967
968 return choice;
969}
970
971/** Return a random running node from the nodelist. Never pick a node that is
972 * in <b>excludedsmartlist</b>, or which matches <b>excludedset</b>, even if
973 * they are the only nodes available.
974 *
975 * <b>flags</b> is a set of CRN_* flags, see
976 * router_add_running_nodes_to_smartlist() for details.
977 */
978const node_t *
980 routerset_t *excludedset,
981 router_crn_flags_t flags)
982{
983 /* A limited set of flags, used for fallback node selection.
984 */
985 const bool need_uptime = (flags & CRN_NEED_UPTIME) != 0;
986 const bool need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
987 const bool need_guard = (flags & CRN_NEED_GUARD) != 0;
988 const bool pref_addr = (flags & CRN_PREF_ADDR) != 0;
989
990 smartlist_t *excludednodes=smartlist_new();
991 const node_t *choice = NULL;
992 const routerinfo_t *r;
994
995 rule = (need_guard ? WEIGHT_FOR_GUARD : WEIGHT_FOR_MID);
996
997 /* If the node_t is not found we won't be to exclude ourself but we
998 * won't be able to pick ourself in router_choose_random_node() so
999 * this is fine to at least try with our routerinfo_t object. */
1000 if ((r = router_get_my_routerinfo()))
1001 routerlist_add_node_and_family(excludednodes, r);
1002
1003 if (excludedsmartlist) {
1004 smartlist_add_all(excludednodes, excludedsmartlist);
1005 }
1006
1007 choice = router_choose_random_node_helper(excludednodes,
1008 excludedset,
1009 flags,
1010 rule);
1011
1012 if (!choice && (need_uptime || need_capacity || need_guard || pref_addr)) {
1013 /* try once more, with fewer restrictions. */
1014 log_info(LD_CIRC,
1015 "We couldn't find any live%s%s%s%s routers; falling back "
1016 "to list of all routers.",
1017 need_capacity?", fast":"",
1018 need_uptime?", stable":"",
1019 need_guard?", guard":"",
1020 pref_addr?", preferred address":"");
1021 flags &= ~ (CRN_NEED_UPTIME|CRN_NEED_CAPACITY|CRN_NEED_GUARD|
1022 CRN_PREF_ADDR);
1023 choice = router_choose_random_node_helper(excludednodes,
1024 excludedset,
1025 flags,
1026 rule);
1027 }
1028 smartlist_free(excludednodes);
1029 if (!choice) {
1030 log_warn(LD_CIRC,
1031 "No available nodes when trying to choose node. Failing.");
1032 }
1033 return choice;
1034}
1035
1036/** Try to find a running directory authority. Flags are as for
1037 * router_pick_directory_server.
1038 */
1039const routerstatus_t *
1041{
1044 type, flags);
1045}
1046
1047/** Try to find a running fallback directory. Flags are as for
1048 * router_pick_directory_server.
1049 */
1050const routerstatus_t *
1052{
1054 router_get_fallback_dir_servers_mutable(),
1055 type, flags);
1056}
1057
1058/** Pick a random element from a list of dir_server_t, weighting by their
1059 * <b>weight</b> field. */
1060static const dir_server_t *
1061dirserver_choose_by_weight(const smartlist_t *servers, double authority_weight)
1062{
1063 int n = smartlist_len(servers);
1064 int i;
1065 double *weights_dbl;
1066 uint64_t *weights_u64;
1067 const dir_server_t *ds;
1068
1069 weights_dbl = tor_calloc(n, sizeof(double));
1070 weights_u64 = tor_calloc(n, sizeof(uint64_t));
1071 for (i = 0; i < n; ++i) {
1072 ds = smartlist_get(servers, i);
1073 weights_dbl[i] = ds->weight;
1074 if (ds->is_authority)
1075 weights_dbl[i] *= authority_weight;
1076 }
1077
1078 scale_array_elements_to_u64(weights_u64, weights_dbl, n, NULL);
1079 i = choose_array_element_by_weight(weights_u64, n);
1080 tor_free(weights_dbl);
1081 tor_free(weights_u64);
1082 return (i < 0) ? NULL : smartlist_get(servers, i);
1083}
1084
1085/** Choose randomly from among the dir_server_ts in sourcelist that
1086 * are up. Flags are as for router_pick_directory_server_impl().
1087 */
1088static const routerstatus_t *
1090 dirinfo_type_t type, int flags,
1091 int *n_busy_out)
1092{
1093 const or_options_t *options = get_options();
1094 smartlist_t *direct, *tunnel;
1095 smartlist_t *overloaded_direct, *overloaded_tunnel;
1097 const routerstatus_t *result = NULL;
1098 time_t now = time(NULL);
1099 const int requireother = ! (flags & PDS_ALLOW_SELF);
1100 const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
1101 const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
1102 const int no_microdesc_fetching =(flags & PDS_NO_EXISTING_MICRODESC_FETCH);
1103 const double auth_weight =
1104 (sourcelist == router_get_fallback_dir_servers()) ?
1105 options->DirAuthorityFallbackRate : 1.0;
1106 smartlist_t *pick_from;
1107 int n_busy = 0;
1108 int try_excluding = 1, n_excluded = 0;
1109 int try_ip_pref = 1;
1110
1111 if (!sourcelist)
1112 return NULL;
1113
1114 retry_search:
1115
1116 direct = smartlist_new();
1117 tunnel = smartlist_new();
1118 overloaded_direct = smartlist_new();
1119 overloaded_tunnel = smartlist_new();
1120
1121 const int skip_or_fw = router_or_conn_should_skip_reachable_address_check(
1122 options,
1123 try_ip_pref);
1124 const int skip_dir_fw = router_dir_conn_should_skip_reachable_address_check(
1125 options,
1126 try_ip_pref);
1127 const int must_have_or = dirclient_must_use_begindir(options);
1128
1129 SMARTLIST_FOREACH_BEGIN(sourcelist, const dir_server_t *, d)
1130 {
1131 int is_overloaded =
1132 d->fake_status.last_dir_503_at + DIR_503_TIMEOUT > now;
1133 if (!d->is_running) continue;
1134 if ((type & d->type) == 0)
1135 continue;
1136
1137 SKIP_MISSING_TRUSTED_EXTRAINFO(type, d->digest);
1138
1139 if (requireother && me && router_digest_is_me(d->digest))
1140 continue;
1141 if (try_excluding &&
1143 &d->fake_status, -1)) {
1144 ++n_excluded;
1145 continue;
1146 }
1147
1148 if (router_is_already_dir_fetching_(&d->ipv4_addr,
1149 &d->ipv6_addr,
1150 d->ipv4_dirport,
1151 no_serverdesc_fetching,
1152 no_microdesc_fetching)) {
1153 ++n_busy;
1154 continue;
1155 }
1156
1157 /* Clients use IPv6 addresses if the server has one and the client
1158 * prefers IPv6.
1159 * Add the router if its preferred address and port are reachable.
1160 * If we don't get any routers, we'll try again with the non-preferred
1161 * address for each router (if any). (To ensure correct load-balancing
1162 * we try routers that only have one address both times.)
1163 */
1164 if (!fascistfirewall || skip_or_fw ||
1165 reachable_addr_allows_dir_server(d, FIREWALL_OR_CONNECTION,
1166 try_ip_pref))
1167 smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, (void*)d);
1168 else if (!must_have_or && (skip_dir_fw ||
1169 reachable_addr_allows_dir_server(d, FIREWALL_DIR_CONNECTION,
1170 try_ip_pref)))
1171 smartlist_add(is_overloaded ? overloaded_direct : direct, (void*)d);
1172 }
1173 SMARTLIST_FOREACH_END(d);
1174
1175 if (smartlist_len(tunnel)) {
1176 pick_from = tunnel;
1177 } else if (smartlist_len(overloaded_tunnel)) {
1178 pick_from = overloaded_tunnel;
1179 } else if (smartlist_len(direct)) {
1180 pick_from = direct;
1181 } else {
1182 pick_from = overloaded_direct;
1183 }
1184
1185 {
1186 const dir_server_t *selection =
1187 dirserver_choose_by_weight(pick_from, auth_weight);
1188
1189 if (selection)
1190 result = &selection->fake_status;
1191 }
1192
1193 smartlist_free(direct);
1194 smartlist_free(tunnel);
1195 smartlist_free(overloaded_direct);
1196 smartlist_free(overloaded_tunnel);
1197
1198 RETRY_ALTERNATE_IP_VERSION(retry_search);
1199
1200 RETRY_WITHOUT_EXCLUDE(retry_search);
1201
1202 router_picked_poor_directory_log(result);
1203
1204 if (n_busy_out)
1205 *n_busy_out = n_busy;
1206 return result;
1207}
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
Definition: address.c:933
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:780
char * tor_addr_to_str_dup(const tor_addr_t *addr)
Definition: address.c:1164
#define fmt_addr(a)
Definition: address.h:239
time_t approx_time(void)
Definition: approx_time.c:32
Implements a variable-sized (but non-resizeable) bit-array.
unsigned int bitarray_t
Definition: bitarray.h:30
static bitarray_t * bitarray_init_zero(unsigned int n_bits)
Definition: bitarray.h:33
static void bitarray_set(bitarray_t *b, int bit)
Definition: bitarray.h:68
static unsigned int bitarray_is_set(bitarray_t *b, int bit)
Definition: bitarray.h:81
const or_options_t * get_options(void)
Definition: config.c:944
Header file for config.c.
connection_t * connection_get_by_type_addr_port_purpose(int type, const tor_addr_t *addr, uint16_t port, int purpose)
Definition: connection.c:4899
Header file for connection.c.
#define CONN_TYPE_DIR
Definition: connection.h:55
int16_t country_t
Definition: country.h:17
void * smartlist_choose(const smartlist_t *sl)
Definition: crypto_rand.c:594
Common functions for using (pseudo-)random number generators.
uint64_t crypto_rand_uint64(uint64_t max)
int crypto_rand_int(unsigned int max)
const char * routerstatus_describe(const routerstatus_t *rs)
Definition: describe.c:203
Header file for describe.c.
int select_array_member_cumulative_timei(const uint64_t *entries, int n_entries, uint64_t total, uint64_t rand_val)
Definition: di_ops.c:259
#define DIGEST_LEN
Definition: digest_sizes.h:20
Trusted/fallback directory server structure.
Header file for dirclient.c.
Header for feature/dirclient/dirclient_modes.c.
Header file for directory.c.
#define DIR_PURPOSE_FETCH_EXTRAINFO
Definition: directory.h:39
#define DIR_PURPOSE_FETCH_MICRODESC
Definition: directory.h:65
#define DIR_PURPOSE_FETCH_SERVERDESC
Definition: directory.h:36
void mark_all_dirservers_up(smartlist_t *server_list)
Definition: dirlist.c:232
void router_reset_status_download_failures(void)
Definition: dirlist.c:151
smartlist_t * router_get_trusted_dir_servers_mutable(void)
Definition: dirlist.c:119
Header file for dirlist.c.
Header file for circuitbuild.c.
bool is_dir(file_status_t file_type)
Definition: files.c:261
int64_t tor_llround(double d)
Definition: fp.c:46
Header for fp.c.
#define LD_BUG
Definition: log.h:86
#define LD_GENERAL
Definition: log.h:62
#define LD_DIR
Definition: log.h:88
#define LD_CIRC
Definition: log.h:82
#define tor_free(p)
Definition: malloc.h:56
int usable_consensus_flavor(void)
Definition: microdesc.c:1086
Header file for microdesc.c.
networkstatus_t * networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
networkstatus_t * networkstatus_get_reasonably_live_consensus(time_t now, int flavor)
networkstatus_t * networkstatus_get_latest_consensus(void)
int32_t networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight_name, int32_t default_val)
int networkstatus_get_weight_scale_param(networkstatus_t *ns)
Header file for networkstatus.c.
Networkstatus consensus/vote structure.
STATIC const routerstatus_t * router_pick_directory_server_impl(dirinfo_type_t type, int flags, int *n_busy_out)
Definition: node_select.c:297
static void nodelist_subtract(smartlist_t *sl, const smartlist_t *excluded)
Definition: node_select.c:890
static uint32_t bridge_get_advertised_bandwidth_bounded(routerinfo_t *router)
Definition: node_select.c:539
const routerstatus_t * router_pick_directory_server(dirinfo_type_t type, int flags)
Definition: node_select.c:72
static const dir_server_t * dirserver_choose_by_weight(const smartlist_t *servers, double authority_weight)
Definition: node_select.c:1061
const routerstatus_t * router_pick_fallback_dirserver(dirinfo_type_t type, int flags)
Definition: node_select.c:1051
static int compute_weighted_bandwidths(const smartlist_t *sl, bandwidth_weight_rule_t rule, double **bandwidths_out, double *total_bandwidth_out)
Definition: node_select.c:604
const routerstatus_t * router_pick_trusteddirserver(dirinfo_type_t type, int flags)
Definition: node_select.c:1040
static int32_t kb_to_bytes(uint32_t bw)
Definition: node_select.c:486
const node_t * router_choose_random_node(smartlist_t *excludedsmartlist, routerset_t *excludedset, router_crn_flags_t flags)
Definition: node_select.c:979
double frac_nodes_with_descriptors(const smartlist_t *sl, bandwidth_weight_rule_t rule, int for_direct_conn)
Definition: node_select.c:821
static const routerstatus_t * router_pick_dirserver_generic(smartlist_t *sourcelist, dirinfo_type_t type, int flags)
Definition: node_select.c:104
static const node_t * smartlist_choose_node_by_bandwidth_weights(const smartlist_t *sl, bandwidth_weight_rule_t rule)
Definition: node_select.c:506
STATIC int choose_array_element_by_weight(const uint64_t *entries, int n_entries)
Definition: node_select.c:460
static const routerstatus_t * router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, dirinfo_type_t auth, int flags, int *n_busy_out)
Definition: node_select.c:1089
STATIC void scale_array_elements_to_u64(uint64_t *entries_out, const double *entries_in, int n_entries, uint64_t *total_out)
Definition: node_select.c:431
#define BRIDGE_MIN_BELIEVABLE_BANDWIDTH
Definition: node_select.c:531
const node_t * node_sl_choose_by_bandwidth(const smartlist_t *sl, bandwidth_weight_rule_t rule)
Definition: node_select.c:856
static void log_buggy_rs_source(const routerstatus_t *rs)
Definition: node_select.c:556
static void routerlist_add_node_and_family(smartlist_t *sl, const routerinfo_t *router)
Definition: node_select.c:869
Header file for node_select.c.
#define PDS_NO_EXISTING_SERVERDESC_FETCH
Definition: node_select.h:69
router_crn_flags_t
Definition: node_select.h:16
#define PDS_ALLOW_SELF
Definition: node_select.h:52
#define PDS_NO_EXISTING_MICRODESC_FETCH
Definition: node_select.h:75
#define PDS_IGNORE_FASCISTFIREWALL
Definition: node_select.h:62
#define PDS_RETRY_IF_NO_SERVERS
Definition: node_select.h:56
bandwidth_weight_rule_t
Definition: node_select.h:43
Node information structure.
const node_t * node_get_by_id(const char *identity_digest)
Definition: nodelist.c:226
void nodelist_add_node_and_family(smartlist_t *sl, const node_t *node)
Definition: nodelist.c:2251
const smartlist_t * nodelist_get_list(void)
Definition: nodelist.c:1047
int node_has_preferred_descriptor(const node_t *node, int for_direct_connect)
Definition: nodelist.c:1509
int node_is_dir(const node_t *node)
Definition: nodelist.c:1473
int router_have_minimum_dir_info(void)
Definition: nodelist.c:2436
Header file for nodelist.c.
Master header file for Tor-specific functionality.
dirinfo_type_t
Definition: or.h:787
int reachable_addr_allows_rs(const routerstatus_t *rs, firewall_connection_t fw_connection, int pref_only)
Definition: policies.c:647
int reachable_addr_allows_node(const node_t *node, firewall_connection_t fw_connection, int pref_only)
Definition: policies.c:693
int reachable_addr_allows_dir_server(const dir_server_t *ds, firewall_connection_t fw_connection, int pref_only)
Definition: policies.c:731
Header file for policies.c.
char * rate_limit_log(ratelim_t *lim, time_t now)
Definition: ratelim.c:42
const char * bandwidth_weight_rule_to_string(bandwidth_weight_rule_t rule)
Definition: reasons.c:439
Header file for reasons.c.
int router_digest_is_me(const char *digest)
Definition: router.c:1744
const routerinfo_t * router_get_my_routerinfo(void)
Definition: router.c:1806
Header file for router.c.
Router descriptor structure.
void router_add_running_nodes_to_smartlist(smartlist_t *sl, int flags)
Definition: routerlist.c:618
Header file for routerlist.c.
#define DIR_503_TIMEOUT
Definition: routerlist.h:49
Header file for routermode.c.
int routerset_contains_routerstatus(const routerset_t *set, const routerstatus_t *rs, country_t country)
Definition: routerset.c:339
void routerset_subtract_nodes(smartlist_t *lst, const routerset_t *routerset)
Definition: routerset.c:413
Header file for routerset.c.
Routerstatus (consensus entry) structure.
int smartlist_pos(const smartlist_t *sl, const void *element)
Definition: smartlist.c:119
void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2)
Definition: smartlist.c:264
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define SMARTLIST_DEL_CURRENT(sl, var)
routerstatus_t fake_status
Definition: dir_server_st.h:57
unsigned int is_authority
Definition: dir_server_st.h:40
smartlist_t * routerstatus_list
Definition: node_st.h:34
char identity[DIGEST_LEN]
Definition: node_st.h:46
struct routerset_t * ExcludeNodes
double DirAuthorityFallbackRate
uint32_t bandwidthrate
Definition: routerinfo_st.h:54
uint32_t bandwidthcapacity
Definition: routerinfo_st.h:58
uint16_t ipv6_orport
tor_addr_t ipv6_addr
unsigned int has_guardfraction
uint16_t ipv4_dirport
unsigned int is_possible_guard
uint32_t guardfraction_percentage
uint16_t ipv4_orport
char identity_digest[DIGEST_LEN]
#define STATIC
Definition: testsupport.h:32
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:177
#define tor_assert(expr)
Definition: util_bug.h:103