Tor 0.4.9.8
Loading...
Searching...
No Matches
circpathbias.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 circpathbias.c
9 *
10 * \brief Code to track success/failure rates of circuits built through
11 * different tor nodes, in an attempt to detect attacks where
12 * an attacker deliberately causes circuits to fail until the client
13 * choses a path they like.
14 *
15 * This code is currently configured in a warning-only mode, though false
16 * positives appear to be rare in practice. There is also support for
17 * disabling really bad guards, but it's quite experimental and may have bad
18 * anonymity effects.
19 *
20 * The information here is associated with the entry_guard_t object for
21 * each guard, and stored persistently in the state file.
22 */
23
24#include "core/or/or.h"
25#include "core/or/channel.h"
26#include "feature/client/circpathbias.h"
28#include "core/or/circuitlist.h"
29#include "core/or/circuituse.h"
32#include "app/config/config.h"
36#include "core/or/relay.h"
37#include "core/or/relay_msg.h"
38#include "lib/math/fp.h"
39#include "lib/math/laplace.h"
40
45
49static void pathbias_measure_use_rate(entry_guard_t *guard);
50static void pathbias_measure_close_rate(entry_guard_t *guard);
51static void pathbias_scale_use_rates(entry_guard_t *guard);
52static void pathbias_scale_close_rates(entry_guard_t *guard);
53static int entry_guard_inc_circ_attempt_count(entry_guard_t *guard);
54
55/** Increment the number of times we successfully extended a circuit to
56 * <b>guard</b>, first checking if the failure rate is high enough that
57 * we should eliminate the guard. Return -1 if the guard looks no good;
58 * return 0 if the guard looks fine.
59 */
60static int
62{
64
66
68
69 if (pb->path_bias_disabled)
70 return -1;
71
73 pb->circ_attempts++;
74
75 log_info(LD_CIRC, "Got success count %f/%f for guard %s",
78 return 0;
79}
80
81/** The minimum number of circuit attempts before we start
82 * thinking about warning about path bias and dropping guards */
83static int
85{
86#define DFLT_PATH_BIAS_MIN_CIRC 150
87 if (options->PathBiasCircThreshold >= 5)
88 return options->PathBiasCircThreshold;
89 else
90 return networkstatus_get_param(NULL, "pb_mincircs",
91 DFLT_PATH_BIAS_MIN_CIRC,
92 5, INT32_MAX);
93}
94
95/** The circuit success rate below which we issue a notice */
96static double
98{
99#define DFLT_PATH_BIAS_NOTICE_PCT 70
100 if (options->PathBiasNoticeRate >= 0.0)
101 return options->PathBiasNoticeRate;
102 else
103 return networkstatus_get_param(NULL, "pb_noticepct",
104 DFLT_PATH_BIAS_NOTICE_PCT, 0, 100)/100.0;
105}
106
107/** The circuit success rate below which we issue a warn */
108static double
110{
111#define DFLT_PATH_BIAS_WARN_PCT 50
112 if (options->PathBiasWarnRate >= 0.0)
113 return options->PathBiasWarnRate;
114 else
115 return networkstatus_get_param(NULL, "pb_warnpct",
116 DFLT_PATH_BIAS_WARN_PCT, 0, 100)/100.0;
117}
118
119/* XXXX I'd like to have this be static again, but entrynodes.c needs it. */
120/**
121 * The extreme rate is the rate at which we would drop the guard,
122 * if pb_dropguard is also set. Otherwise we just warn.
123 */
124double
126{
127#define DFLT_PATH_BIAS_EXTREME_PCT 30
128 if (options->PathBiasExtremeRate >= 0.0)
129 return options->PathBiasExtremeRate;
130 else
131 return networkstatus_get_param(NULL, "pb_extremepct",
132 DFLT_PATH_BIAS_EXTREME_PCT, 0, 100)/100.0;
133}
134
135/* XXXX I'd like to have this be static again, but entrynodes.c needs it. */
136/**
137 * If 1, we actually disable use of guards that fall below
138 * the extreme_pct.
139 */
140int
142{
143#define DFLT_PATH_BIAS_DROP_GUARDS 0
144 if (options->PathBiasDropGuards >= 0)
145 return options->PathBiasDropGuards;
146 else
147 return networkstatus_get_param(NULL, "pb_dropguards",
148 DFLT_PATH_BIAS_DROP_GUARDS, 0, 1);
149}
150
151/**
152 * This is the number of circuits at which we scale our
153 * counts by mult_factor/scale_factor. Note, this count is
154 * not exact, as we only perform the scaling in the event
155 * of no integer truncation.
156 */
157static int
159{
160#define DFLT_PATH_BIAS_SCALE_THRESHOLD 300
161 if (options->PathBiasScaleThreshold >= 10)
162 return options->PathBiasScaleThreshold;
163 else
164 return networkstatus_get_param(NULL, "pb_scalecircs",
165 DFLT_PATH_BIAS_SCALE_THRESHOLD, 10,
166 INT32_MAX);
167}
168
169/**
170 * Compute the path bias scaling ratio from the consensus
171 * parameters pb_multfactor/pb_scalefactor.
172 *
173 * Returns a value in (0, 1.0] which we multiply our pathbias
174 * counts with to scale them down.
175 */
176static double
178{
179 (void) options;
180 /*
181 * The scale factor is the denominator for our scaling
182 * of circuit counts for our path bias window.
183 *
184 * Note that our use of doubles for the path bias state
185 * file means that powers of 2 work best here.
186 */
187 int denominator = networkstatus_get_param(NULL, "pb_scalefactor",
188 2, 2, INT32_MAX);
189 tor_assert(denominator > 0);
190
191 /**
192 * The mult factor is the numerator for our scaling
193 * of circuit counts for our path bias window. It
194 * allows us to scale by fractions.
195 */
196 return networkstatus_get_param(NULL, "pb_multfactor",
197 1, 1, denominator)/((double)denominator);
198}
199
200/** The minimum number of circuit usage attempts before we start
201 * thinking about warning about path use bias and dropping guards */
202static int
204{
205#define DFLT_PATH_BIAS_MIN_USE 20
206 if (options->PathBiasUseThreshold >= 3)
207 return options->PathBiasUseThreshold;
208 else
209 return networkstatus_get_param(NULL, "pb_minuse",
210 DFLT_PATH_BIAS_MIN_USE,
211 3, INT32_MAX);
212}
213
214/** The circuit use success rate below which we issue a notice */
215static double
217{
218#define DFLT_PATH_BIAS_NOTICE_USE_PCT 80
219 if (options->PathBiasNoticeUseRate >= 0.0)
220 return options->PathBiasNoticeUseRate;
221 else
222 return networkstatus_get_param(NULL, "pb_noticeusepct",
223 DFLT_PATH_BIAS_NOTICE_USE_PCT,
224 0, 100)/100.0;
225}
226
227/**
228 * The extreme use rate is the rate at which we would drop the guard,
229 * if pb_dropguard is also set. Otherwise we just warn.
230 */
231double
233{
234#define DFLT_PATH_BIAS_EXTREME_USE_PCT 60
235 if (options->PathBiasExtremeUseRate >= 0.0)
236 return options->PathBiasExtremeUseRate;
237 else
238 return networkstatus_get_param(NULL, "pb_extremeusepct",
239 DFLT_PATH_BIAS_EXTREME_USE_PCT,
240 0, 100)/100.0;
241}
242
243/**
244 * This is the number of circuits at which we scale our
245 * use counts by mult_factor/scale_factor. Note, this count is
246 * not exact, as we only perform the scaling in the event
247 * of no integer truncation.
248 */
249static int
251{
252#define DFLT_PATH_BIAS_SCALE_USE_THRESHOLD 100
253 if (options->PathBiasScaleUseThreshold >= 10)
254 return options->PathBiasScaleUseThreshold;
255 else
256 return networkstatus_get_param(NULL, "pb_scaleuse",
257 DFLT_PATH_BIAS_SCALE_USE_THRESHOLD,
258 10, INT32_MAX);
259}
260
261/**
262 * Convert a Guard's path state to string.
263 */
264const char *
266{
267 switch (state) {
269 return "new";
271 return "build attempted";
273 return "build succeeded";
275 return "use attempted";
277 return "use succeeded";
279 return "use failed";
281 return "already counted";
282 }
283
284 return "unknown";
285}
286
287/**
288 * This function decides if a circuit has progressed far enough to count
289 * as a circuit "attempt". As long as end-to-end tagging is possible,
290 * we assume the adversary will use it over hop-to-hop failure. Therefore,
291 * we only need to account bias for the last hop. This should make us
292 * much more resilient to ambient circuit failure, and also make that
293 * failure easier to measure (we only need to measure Exit failure rates).
294 */
295static int
297{
298#define N2N_TAGGING_IS_POSSIBLE
299#ifdef N2N_TAGGING_IS_POSSIBLE
300 /* cpath is a circular list. We want circs with more than one hop,
301 * and the second hop must be waiting for keys still (it's just
302 * about to get them). */
303 return circ->cpath &&
304 circ->cpath->next != circ->cpath &&
305 circ->cpath->next->state == CPATH_STATE_AWAITING_KEYS;
306#else /* !defined(N2N_TAGGING_IS_POSSIBLE) */
307 /* If tagging attacks are no longer possible, we probably want to
308 * count bias from the first hop. However, one could argue that
309 * timing-based tagging is still more useful than per-hop failure.
310 * In which case, we'd never want to use this.
311 */
312 return circ->cpath &&
313 circ->cpath->state == CPATH_STATE_AWAITING_KEYS;
314#endif /* defined(N2N_TAGGING_IS_POSSIBLE) */
315}
316
317/**
318 * Decide if the path bias code should count a circuit.
319 *
320 * @returns 1 if we should count it, 0 otherwise.
321 */
322static int
324{
325#define PATHBIAS_COUNT_INTERVAL (600)
326 static ratelim_t count_limit =
327 RATELIM_INIT(PATHBIAS_COUNT_INTERVAL);
328 char *rate_msg = NULL;
329
330 /* We can't do path bias accounting without entry guards.
331 * Testing and controller circuits also have no guards.
332 *
333 * We also don't count server-side rends, because their
334 * endpoint could be chosen maliciously.
335 * Similarly, we can't count client-side intro attempts,
336 * because clients can be manipulated into connecting to
337 * malicious intro points.
338 *
339 * Finally, avoid counting conflux circuits for now, because
340 * a malicious exit could cause us to reconnect and blame
341 * our guard...
342 *
343 * TODO-329-PURPOSE: This is not quite right, we could
344 * instead avoid sending usable probes on conflux circs,
345 * and count only linked circs as failures, but it is
346 * not 100% clear that would result in accurate counts. */
347 if (get_options()->UseEntryGuards == 0 ||
348 circ->base_.purpose == CIRCUIT_PURPOSE_TESTING ||
349 circ->base_.purpose == CIRCUIT_PURPOSE_CONTROLLER ||
351 circ->base_.purpose == CIRCUIT_PURPOSE_S_REND_JOINED ||
353 circ->base_.purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
354 (circ->base_.purpose >= CIRCUIT_PURPOSE_C_INTRODUCING &&
356
357 /* Check to see if the shouldcount result has changed due to a
358 * unexpected purpose change that would affect our results.
359 *
360 * The reason we check the path state too here is because for the
361 * cannibalized versions of these purposes, we count them as successful
362 * before their purpose change.
363 */
364 if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_COUNTED
366 log_info(LD_BUG,
367 "Circuit %d is now being ignored despite being counted "
368 "in the past. Purpose is %s, path state is %s",
369 circ->global_identifier,
372 }
373 circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
374 return 0;
375 }
376
377 /* Ignore circuits where the controller helped choose the path. When
378 * this happens, we can't be sure whether the path was chosen randomly
379 * or not. */
380 if (circ->any_hop_from_controller) {
381 /* (In this case, we _don't_ check to see if shouldcount is changing,
382 * since it's possible that an already-created circuit later gets extended
383 * by the controller. */
384 circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
385 return 0;
386 }
387
388 /* Completely ignore one hop circuits */
389 if (circ->build_state->onehop_tunnel ||
390 circ->build_state->desired_path_len == 1) {
391 /* Check for inconsistency */
392 if (circ->build_state->desired_path_len != 1 ||
393 !circ->build_state->onehop_tunnel) {
394 if ((rate_msg = rate_limit_log(&count_limit, approx_time()))) {
395 log_info(LD_BUG,
396 "One-hop circuit %d has length %d. Path state is %s. "
397 "Circuit is a %s currently %s.%s",
398 circ->global_identifier,
402 circuit_state_to_string(circ->base_.state),
403 rate_msg);
404 tor_free(rate_msg);
405 }
407 }
408
409 /* Check to see if the shouldcount result has changed due to a
410 * unexpected change that would affect our results */
411 if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_COUNTED) {
412 log_info(LD_BUG,
413 "One-hop circuit %d is now being ignored despite being counted "
414 "in the past. Purpose is %s, path state is %s",
415 circ->global_identifier,
418 }
419 circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
420 return 0;
421 }
422
423 /* Check to see if the shouldcount result has changed due to a
424 * unexpected purpose change that would affect our results */
425 if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_IGNORED) {
426 log_info(LD_CIRC,
427 "Circuit %d is not being counted by pathbias because it was "
428 "ignored in the past. Purpose is %s, path state is %s",
429 circ->global_identifier,
432 return 0;
433 }
434 circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_COUNTED;
435
436 return 1;
437}
438
439/**
440 * Check our circuit state to see if this is a successful circuit attempt.
441 * If so, record it in the current guard's path bias circ_attempt count.
442 *
443 * Also check for several potential error cases for bug #6475.
444 */
445int
447{
448#define CIRC_ATTEMPT_NOTICE_INTERVAL (600)
449 static ratelim_t circ_attempt_notice_limit =
450 RATELIM_INIT(CIRC_ATTEMPT_NOTICE_INTERVAL);
451 char *rate_msg = NULL;
452
453 if (!pathbias_should_count(circ)) {
454 return 0;
455 }
456
458 /* Help track down the real cause of bug #6475: */
459 if (circ->has_opened && circ->path_state != PATH_STATE_BUILD_ATTEMPTED) {
460 if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
461 approx_time()))) {
462 log_info(LD_BUG,
463 "Opened circuit %d is in strange path state %s. "
464 "Circuit is a %s currently %s.%s",
465 circ->global_identifier,
468 circuit_state_to_string(circ->base_.state),
469 rate_msg);
470 tor_free(rate_msg);
471 }
472 }
473
474 /* Don't re-count cannibalized circs.. */
475 if (!circ->has_opened) {
476 entry_guard_t *guard = NULL;
477
478 if (circ->cpath && circ->cpath->extend_info) {
481 } else if (circ->base_.n_chan) {
482 guard =
484 }
485
486 if (guard) {
487 if (circ->path_state == PATH_STATE_NEW_CIRC) {
489
490 if (entry_guard_inc_circ_attempt_count(guard) < 0) {
491 /* Bogus guard; we already warned. */
492 return -END_CIRC_REASON_TORPROTOCOL;
493 }
494 } else {
495 if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
496 approx_time()))) {
497 log_info(LD_BUG,
498 "Unopened circuit %d has strange path state %s. "
499 "Circuit is a %s currently %s.%s",
500 circ->global_identifier,
503 circuit_state_to_string(circ->base_.state),
504 rate_msg);
505 tor_free(rate_msg);
506 }
507 }
508 } else {
509 if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
510 approx_time()))) {
511 log_info(LD_CIRC,
512 "Unopened circuit has no known guard. "
513 "Circuit is a %s currently %s.%s",
515 circuit_state_to_string(circ->base_.state),
516 rate_msg);
517 tor_free(rate_msg);
518 }
519 }
520 }
521 }
522
523 return 0;
524}
525
526/**
527 * Check our circuit state to see if this is a successful circuit
528 * completion. If so, record it in the current guard's path bias
529 * success count.
530 *
531 * Also check for several potential error cases for bug #6475.
532 */
533void
535{
536#define SUCCESS_NOTICE_INTERVAL (600)
537 static ratelim_t success_notice_limit =
538 RATELIM_INIT(SUCCESS_NOTICE_INTERVAL);
539 char *rate_msg = NULL;
540 entry_guard_t *guard = NULL;
541
542 if (!pathbias_should_count(circ)) {
543 return;
544 }
545
546 /* Don't count cannibalized/reused circs for path bias
547 * "build" success, since they get counted under "use" success. */
548 if (!circ->has_opened) {
549 if (circ->cpath && circ->cpath->extend_info) {
552 }
553
554 if (guard) {
556
559 pb->circ_successes++;
561
562 log_info(LD_CIRC, "Got success count %f/%f for guard %s",
564 entry_guard_describe(guard));
565 } else {
566 if ((rate_msg = rate_limit_log(&success_notice_limit,
567 approx_time()))) {
568 log_info(LD_BUG,
569 "Succeeded circuit %d is in strange path state %s. "
570 "Circuit is a %s currently %s.%s",
571 circ->global_identifier,
574 circuit_state_to_string(circ->base_.state),
575 rate_msg);
576 tor_free(rate_msg);
577 }
578 }
579
580 if (pb->circ_attempts < pb->circ_successes) {
581 log_notice(LD_BUG, "Unexpectedly high successes counts (%f/%f) "
582 "for guard %s",
584 entry_guard_describe(guard));
585 }
586 /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
587 * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
588 * No need to log that case. */
589 } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
590 if ((rate_msg = rate_limit_log(&success_notice_limit,
591 approx_time()))) {
592 log_info(LD_CIRC,
593 "Completed circuit has no known guard. "
594 "Circuit is a %s currently %s.%s",
596 circuit_state_to_string(circ->base_.state),
597 rate_msg);
598 tor_free(rate_msg);
599 }
600 }
601 } else {
603 if ((rate_msg = rate_limit_log(&success_notice_limit,
604 approx_time()))) {
605 log_info(LD_BUG,
606 "Opened circuit %d is in strange path state %s. "
607 "Circuit is a %s currently %s.%s",
608 circ->global_identifier,
611 circuit_state_to_string(circ->base_.state),
612 rate_msg);
613 tor_free(rate_msg);
614 }
615 }
616 }
617}
618
619/**
620 * Record an attempt to use a circuit. Changes the circuit's
621 * path state and update its guard's usage counter.
622 *
623 * Used for path bias usage accounting.
624 */
625void
627{
628 if (!pathbias_should_count(circ)) {
629 return;
630 }
631
633 log_notice(LD_BUG,
634 "Used circuit %d is in strange path state %s. "
635 "Circuit is a %s currently %s.",
636 circ->global_identifier,
639 circuit_state_to_string(circ->base_.state));
640 } else if (circ->path_state < PATH_STATE_USE_ATTEMPTED) {
641 entry_guard_t *guard = entry_guard_get_by_id_digest(
643 if (guard) {
645
648 pb->use_attempts++;
650
651 log_debug(LD_CIRC,
652 "Marked circuit %d (%f/%f) as used for guard %s.",
653 circ->global_identifier,
655 entry_guard_describe(guard));
656 }
657
659 } else {
660 /* Harmless but educational log message */
661 log_info(LD_CIRC,
662 "Used circuit %d is already in path state %s. "
663 "Circuit is a %s currently %s.",
664 circ->global_identifier,
667 circuit_state_to_string(circ->base_.state));
668 }
669
670 return;
671}
672
673/**
674 * Check the circuit's path state is appropriate and mark it as
675 * successfully used. Used for path bias usage accounting.
676 *
677 * We don't actually increment the guard's counters until
678 * pathbias_check_close(), because the circuit can still transition
679 * back to PATH_STATE_USE_ATTEMPTED if a stream fails later (this
680 * is done so we can probe the circuit for liveness at close).
681 */
682void
684{
685 if (!pathbias_should_count(circ)) {
686 return;
687 }
688
690 log_notice(LD_BUG,
691 "Used circuit %d is in strange path state %s. "
692 "Circuit is a %s currently %s.",
693 circ->global_identifier,
696 circuit_state_to_string(circ->base_.state));
697
699 }
700
701 /* We don't do any accounting at the guard until actual circuit close */
703
704 return;
705}
706
707/**
708 * If a stream ever detaches from a circuit in a retriable way,
709 * we need to mark this circuit as still needing either another
710 * successful stream, or in need of a probe.
711 *
712 * An adversary could let the first stream request succeed (ie the
713 * resolve), but then tag and timeout the remainder (via cell
714 * dropping), forcing them on new circuits.
715 *
716 * Rolling back the state will cause us to probe such circuits, which
717 * should lead to probe failures in the event of such tagging due to
718 * either unrecognized cells coming in while we wait for the probe,
719 * or the cipher state getting out of sync in the case of dropped cells.
720 */
721void
723{
725 log_info(LD_CIRC,
726 "Rolling back pathbias use state to 'attempted' for detached "
727 "circuit %d", circ->global_identifier);
729 }
730}
731
732/**
733 * Actually count a circuit success towards a guard's usage counters
734 * if the path state is appropriate.
735 */
736static void
738{
739 entry_guard_t *guard;
740
741 if (!pathbias_should_count(circ)) {
742 return;
743 }
744
746 log_notice(LD_BUG,
747 "Successfully used circuit %d is in strange path state %s. "
748 "Circuit is a %s currently %s.",
749 circ->global_identifier,
752 circuit_state_to_string(circ->base_.state));
753 } else {
756 if (guard) {
758
759 pb->use_successes++;
761
762 if (pb->use_attempts < pb->use_successes) {
763 log_notice(LD_BUG, "Unexpectedly high use successes counts (%f/%f) "
764 "for guard %s",
766 entry_guard_describe(guard));
767 }
768
769 log_debug(LD_CIRC,
770 "Marked circuit %d (%f/%f) as used successfully for guard %s",
772 pb->use_attempts,
773 entry_guard_describe(guard));
774 }
775 }
776
777 return;
778}
779
780/**
781 * Send a probe down a circuit that the client attempted to use,
782 * but for which the stream timed out/failed. The probe is a
783 * RELAY_BEGIN cell with a 0.a.b.c destination address, which
784 * the exit will reject and reply back, echoing that address.
785 *
786 * The reason for such probes is because it is possible to bias
787 * a user's paths simply by causing timeouts, and these timeouts
788 * are not possible to differentiate from unresponsive servers.
789 *
790 * The probe is sent at the end of the circuit lifetime for two
791 * reasons: to prevent cryptographic taggers from being able to
792 * drop cells to cause timeouts, and to prevent easy recognition
793 * of probes before any real client traffic happens.
794 *
795 * Returns -1 if we couldn't probe, 0 otherwise.
796 */
797static int
799{
800 /* Based on connection_ap_handshake_send_begin() */
801 char payload[RELAY_PAYLOAD_SIZE_MAX];
802 int payload_len;
803 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
804 crypt_path_t *cpath_layer = NULL;
805 char *probe_nonce = NULL;
806
807 tor_assert(ocirc);
808
809 cpath_layer = ocirc->cpath->prev;
810
811 if (cpath_layer->state != CPATH_STATE_OPEN) {
812 /* This can happen for cannibalized circuits. Their
813 * last hop isn't yet open */
814 log_info(LD_CIRC,
815 "Got pathbias probe request for unopened circuit %d. "
816 "Opened %d, len %d", ocirc->global_identifier,
817 ocirc->has_opened, ocirc->build_state->desired_path_len);
818 return -1;
819 }
820
821 /* We already went down this road. */
823 ocirc->pathbias_probe_id) {
824 log_info(LD_CIRC,
825 "Got pathbias probe request for circuit %d with "
826 "outstanding probe", ocirc->global_identifier);
827 return -1;
828 }
829
830 /* Can't probe if the channel isn't open */
831 if (circ->n_chan == NULL ||
832 (!CHANNEL_IS_OPEN(circ->n_chan)
833 && !CHANNEL_IS_MAINT(circ->n_chan))) {
834 log_info(LD_CIRC,
835 "Skipping pathbias probe for circuit %d: Channel is not open.",
836 ocirc->global_identifier);
837 return -1;
838 }
839
841
842 /* Update timestamp for when circuit_expire_building() should kill us */
844
845 /* Generate a random address for the nonce */
846 crypto_rand((char*)&ocirc->pathbias_probe_nonce,
847 sizeof(ocirc->pathbias_probe_nonce));
848 ocirc->pathbias_probe_nonce &= 0x00ffffff;
849 probe_nonce = tor_dup_ip(ocirc->pathbias_probe_nonce);
850
851 if (!probe_nonce) {
852 log_err(LD_BUG, "Failed to generate nonce");
853 return -1;
854 }
855
856 tor_snprintf(payload,RELAY_PAYLOAD_SIZE_MAX, "%s:25", probe_nonce);
857 payload_len = (int)strlen(payload)+1;
858
859 // XXX: need this? Can we assume ipv4 will always be supported?
860 // If not, how do we tell?
861 //if (payload_len <= RELAY_PAYLOAD_SIZE - 4 && edge_conn->begincell_flags) {
862 // set_uint32(payload + payload_len, htonl(edge_conn->begincell_flags));
863 // payload_len += 4;
864 //}
865
866 /* Generate+Store stream id, make sure it's non-zero */
868
869 if (ocirc->pathbias_probe_id==0) {
870 log_warn(LD_CIRC,
871 "Ran out of stream IDs on circuit %u during "
872 "pathbias probe attempt.", ocirc->global_identifier);
873 tor_free(probe_nonce);
874 return -1;
875 }
876
877 log_info(LD_CIRC,
878 "Sending pathbias testing cell to %s:25 on stream %d for circ %d.",
879 probe_nonce, ocirc->pathbias_probe_id, ocirc->global_identifier);
880 tor_free(probe_nonce);
881
882 /* Send a test relay cell */
883 if (relay_send_command_from_edge(ocirc->pathbias_probe_id, circ,
884 RELAY_COMMAND_BEGIN, payload,
885 payload_len, cpath_layer) < 0) {
886 log_notice(LD_CIRC,
887 "Failed to send pathbias probe cell on circuit %d.",
888 ocirc->global_identifier);
889 return -1;
890 }
891
892 /* Mark it freshly dirty so it doesn't get expired in the meantime */
893 circ->timestamp_dirty = time(NULL);
894
895 return 0;
896}
897
898/**
899 * Check the response to a pathbias probe, to ensure the
900 * cell is recognized and the nonce and other probe
901 * characteristics are as expected.
902 *
903 * If the response is valid, return 0. Otherwise return < 0.
904 */
905int
907{
908 /* Based on connection_edge_process_relay_cell() */
909 int reason;
910 uint32_t ipv4_host;
911 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
912
913 tor_assert(msg);
914 tor_assert(ocirc);
916
917 reason = msg->length > 0 ? get_uint8(msg->body) : END_STREAM_REASON_MISC;
918
919 if (msg->command == RELAY_COMMAND_END &&
920 reason == END_STREAM_REASON_EXITPOLICY &&
921 ocirc->pathbias_probe_id == msg->stream_id) {
922
923 /* Check length+extract host: It is in network order after the reason code.
924 * See connection_edge_end(). */
925 if (msg->length < 9) { /* reason+ipv4+dns_ttl */
926 log_notice(LD_PROTOCOL,
927 "Short path bias probe response length field (%d).", msg->length);
928 return - END_CIRC_REASON_TORPROTOCOL;
929 }
930
931 ipv4_host = ntohl(get_uint32(msg->body + 1));
932
933 /* Check nonce */
934 if (ipv4_host == ocirc->pathbias_probe_nonce) {
936 circuit_read_valid_data(ocirc, msg->length);
937 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
938 log_info(LD_CIRC,
939 "Got valid path bias probe back for circ %d, stream %d.",
940 ocirc->global_identifier, ocirc->pathbias_probe_id);
941 return 0;
942 } else {
943 log_notice(LD_CIRC,
944 "Got strange probe value 0x%x vs 0x%x back for circ %d, "
945 "stream %d.", ipv4_host, ocirc->pathbias_probe_nonce,
946 ocirc->global_identifier, ocirc->pathbias_probe_id);
947 return -1;
948 }
949 }
950 log_info(LD_CIRC,
951 "Got another cell back back on pathbias probe circuit %d: "
952 "Command: %d, Reason: %d, Stream-id: %d",
953 ocirc->global_identifier, msg->command, reason, msg->stream_id);
954 return -1;
955}
956
957/**
958 * Check if a cell is counts as valid data for a circuit,
959 * and if so, count it as valid.
960 */
961void
963{
964 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
965
966 /* Check to see if this is a cell from a previous connection,
967 * or is a request to close the circuit. */
968 switch (msg->command) {
969 case RELAY_COMMAND_TRUNCATED:
970 /* Truncated cells can arrive on path bias circs. When they do,
971 * just process them. This closes the circ, but it was junk anyway.
972 * No reason to wait for the probe. */
973 circuit_read_valid_data(ocirc, msg->length);
974 if (msg->length > 0) {
976 }
977 break;
978
979 case RELAY_COMMAND_END:
981 msg->stream_id)) {
982 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
983 }
984 break;
985
986 case RELAY_COMMAND_DATA:
988 msg->stream_id)) {
989 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
990 }
991 break;
992
993 case RELAY_COMMAND_SENDME:
995 msg->stream_id)) {
996 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
997 }
998 break;
999
1000 case RELAY_COMMAND_CONNECTED:
1002 msg->stream_id)) {
1003 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
1004 }
1005 break;
1006
1007 case RELAY_COMMAND_RESOLVED:
1009 msg->stream_id)) {
1010 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
1011 }
1012 break;
1013 }
1014}
1015
1016/**
1017 * Check if a circuit was used and/or closed successfully.
1018 *
1019 * If we attempted to use the circuit to carry a stream but failed
1020 * for whatever reason, or if the circuit mysteriously died before
1021 * we could attach any streams, record these two cases.
1022 *
1023 * If we *have* successfully used the circuit, or it appears to
1024 * have been closed by us locally, count it as a success.
1025 *
1026 * Returns 0 if we're done making decisions with the circ,
1027 * or -1 if we want to probe it first.
1028 */
1029int
1031{
1032 circuit_t *circ = &ocirc->base_;
1033
1034 if (!pathbias_should_count(ocirc)) {
1035 return 0;
1036 }
1037
1038 switch (ocirc->path_state) {
1039 /* If the circuit was closed after building, but before use, we need
1040 * to ensure we were the ones who tried to close it (and not a remote
1041 * actor). */
1043 if (reason & END_CIRC_REASON_FLAG_REMOTE) {
1044 /* Remote circ close reasons on an unused circuit all could be bias */
1045 log_info(LD_CIRC,
1046 "Circuit %d remote-closed without successful use for reason %d. "
1047 "Circuit purpose %d currently %d,%s. Len %d.",
1048 ocirc->global_identifier,
1049 reason, circ->purpose, ocirc->has_opened,
1053 } else if ((reason & ~END_CIRC_REASON_FLAG_REMOTE)
1054 == END_CIRC_REASON_CHANNEL_CLOSED &&
1055 circ->n_chan &&
1057 != CHANNEL_CLOSE_REQUESTED) {
1058 /* If we didn't close the channel ourselves, it could be bias */
1059 /* XXX: Only count bias if the network is live?
1060 * What about clock jumps/suspends? */
1061 log_info(LD_CIRC,
1062 "Circuit %d's channel closed without successful use for reason "
1063 "%d, channel reason %d. Circuit purpose %d currently %d,%s. Len "
1064 "%d.", ocirc->global_identifier,
1065 reason, circ->n_chan->reason_for_closing,
1066 circ->purpose, ocirc->has_opened,
1070 } else {
1072 }
1073 break;
1074
1075 /* If we tried to use a circuit but failed, we should probe it to ensure
1076 * it has not been tampered with. */
1078 /* XXX: Only probe and/or count failure if the network is live?
1079 * What about clock jumps/suspends? */
1080 if (pathbias_send_usable_probe(circ) == 0)
1081 return -1;
1082 else
1084
1085 /* Any circuit where there were attempted streams but no successful
1086 * streams could be bias */
1087 log_info(LD_CIRC,
1088 "Circuit %d closed without successful use for reason %d. "
1089 "Circuit purpose %d currently %d,%s. Len %d.",
1090 ocirc->global_identifier,
1091 reason, circ->purpose, ocirc->has_opened,
1094 break;
1095
1099 break;
1100
1103 break;
1104
1108 default:
1109 // Other states are uninteresting. No stats to count.
1110 break;
1111 }
1112
1114
1115 return 0;
1116}
1117
1118/**
1119 * Count a successfully closed circuit.
1120 */
1121static void
1123{
1124 entry_guard_t *guard = NULL;
1125 if (!pathbias_should_count(circ)) {
1126 return;
1127 }
1128
1129 if (circ->cpath && circ->cpath->extend_info) {
1132 }
1133
1134 if (guard) {
1136
1137 /* In the long run: circuit_success ~= successful_circuit_close +
1138 * circ_failure + stream_failure */
1141 } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
1142 /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
1143 * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
1144 * No need to log that case. */
1145 log_info(LD_CIRC,
1146 "Successfully closed circuit has no known guard. "
1147 "Circuit is a %s currently %s",
1149 circuit_state_to_string(circ->base_.state));
1150 }
1151}
1152
1153/**
1154 * Count a circuit that fails after it is built, but before it can
1155 * carry any traffic.
1156 *
1157 * This is needed because there are ways to destroy a
1158 * circuit after it has successfully completed. Right now, this is
1159 * used for purely informational/debugging purposes.
1160 */
1161static void
1163{
1164 entry_guard_t *guard = NULL;
1165
1166 if (!pathbias_should_count(circ)) {
1167 return;
1168 }
1169
1170 if (circ->cpath && circ->cpath->extend_info) {
1173 }
1174
1175 if (guard) {
1177
1178 pb->collapsed_circuits++;
1180 } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
1181 /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
1182 * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
1183 * No need to log that case. */
1184 log_info(LD_CIRC,
1185 "Destroyed circuit has no known guard. "
1186 "Circuit is a %s currently %s",
1188 circuit_state_to_string(circ->base_.state));
1189 }
1190}
1191
1192/**
1193 * Count a known failed circuit (because we could not probe it).
1194 *
1195 * This counter is informational.
1196 */
1197static void
1199{
1200 entry_guard_t *guard = NULL;
1201 if (!pathbias_should_count(circ)) {
1202 return;
1203 }
1204
1205 if (circ->cpath && circ->cpath->extend_info) {
1208 }
1209
1210 if (guard) {
1212
1213 pb->unusable_circuits++;
1215 } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
1216 /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
1217 * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
1218 * No need to log that case. */
1219 /* XXX note cut-and-paste code in this function compared to nearby
1220 * functions. Would be nice to refactor. -RD */
1221 log_info(LD_CIRC,
1222 "Stream-failing circuit has no known guard. "
1223 "Circuit is a %s currently %s",
1225 circuit_state_to_string(circ->base_.state));
1226 }
1227}
1228
1229/**
1230 * Count timeouts for path bias log messages.
1231 *
1232 * These counts are purely informational.
1233 */
1234void
1236{
1237 entry_guard_t *guard = NULL;
1238
1239 if (!pathbias_should_count(circ)) {
1240 return;
1241 }
1242
1243 /* For hidden service circs, they can actually be used
1244 * successfully and then time out later (because
1245 * the other side declines to use them). */
1246 if (circ->path_state == PATH_STATE_USE_SUCCEEDED) {
1247 return;
1248 }
1249
1250 if (circ->cpath && circ->cpath->extend_info) {
1253 }
1254
1255 if (guard) {
1257
1258 pb->timeouts++;
1260 }
1261}
1262
1263/**
1264 * Helper function to count all of the currently opened circuits
1265 * for a guard that are in a given path state range. The state
1266 * range is inclusive on both ends.
1267 */
1268static int
1270 path_state_t from,
1271 path_state_t to)
1272{
1273 int open_circuits = 0;
1274
1275 /* Count currently open circuits. Give them the benefit of the doubt. */
1277 origin_circuit_t *ocirc = NULL;
1278 if (!CIRCUIT_IS_ORIGIN(circ) || /* didn't originate here */
1279 circ->marked_for_close) /* already counted */
1280 continue;
1281
1282 ocirc = TO_ORIGIN_CIRCUIT(circ);
1283
1284 if (!ocirc->cpath || !ocirc->cpath->extend_info)
1285 continue;
1286
1287 if (ocirc->path_state >= from &&
1288 ocirc->path_state <= to &&
1289 pathbias_should_count(ocirc) &&
1292 DIGEST_LEN)) {
1293 log_debug(LD_CIRC, "Found opened circuit %d in path_state %s",
1294 ocirc->global_identifier,
1296 open_circuits++;
1297 }
1298 }
1299 SMARTLIST_FOREACH_END(circ);
1300
1301 return open_circuits;
1302}
1303
1304/**
1305 * Return the number of circuits counted as successfully closed for
1306 * this guard.
1307 *
1308 * Also add in the currently open circuits to give them the benefit
1309 * of the doubt.
1310 */
1311double
1321
1322/**
1323 * Return the number of circuits counted as successfully used
1324 * this guard.
1325 *
1326 * Also add in the currently open circuits that we are attempting
1327 * to use to give them the benefit of the doubt.
1328 */
1329double
1339
1340/**
1341 * Check the path bias use rate against our consensus parameter limits.
1342 *
1343 * Emits a log message if the use success rates are too low.
1344 *
1345 * If pathbias_get_dropguards() is set, we also disable the use of
1346 * very failure prone guards.
1347 */
1348static void
1349pathbias_measure_use_rate(entry_guard_t *guard)
1350{
1351 const or_options_t *options = get_options();
1353
1354 if (pb->use_attempts > pathbias_get_min_use(options)) {
1355 /* Note: We rely on the < comparison here to allow us to set a 0
1356 * rate and disable the feature entirely. If refactoring, don't
1357 * change to <= */
1359 < pathbias_get_extreme_use_rate(options)) {
1360 /* Dropping is currently disabled by default. */
1361 if (pathbias_get_dropguards(options)) {
1362 if (!pb->path_bias_disabled) {
1363 log_warn(LD_CIRC,
1364 "Guard %s is failing to carry an extremely large "
1365 "amount of stream on its circuits. "
1366 "To avoid potential route manipulation attacks, Tor has "
1367 "disabled use of this guard. "
1368 "Use counts are %ld/%ld. Success counts are %ld/%ld. "
1369 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1370 "and %ld timed out. "
1371 "For reference, your timeout cutoff is %ld seconds.",
1372 entry_guard_describe(guard),
1380 tor_lround(pb->timeouts),
1382 pb->path_bias_disabled = 1;
1383 return;
1384 }
1385 } else if (!pb->path_bias_use_extreme) {
1386 pb->path_bias_use_extreme = 1;
1387 log_warn(LD_CIRC,
1388 "Guard %s is failing to carry an extremely large "
1389 "amount of streams on its circuits. "
1390 "This could indicate a route manipulation attack, network "
1391 "overload, bad local network connectivity, or a bug. "
1392 "Use counts are %ld/%ld. Success counts are %ld/%ld. "
1393 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1394 "and %ld timed out. "
1395 "For reference, your timeout cutoff is %ld seconds.",
1396 entry_guard_describe(guard),
1404 tor_lround(pb->timeouts),
1406 }
1407 } else if (pathbias_get_use_success_count(guard)/pb->use_attempts
1408 < pathbias_get_notice_use_rate(options)) {
1409 if (!pb->path_bias_use_noticed) {
1410 pb->path_bias_use_noticed = 1;
1411 log_notice(LD_CIRC,
1412 "Guard %s is failing to carry more streams on its "
1413 "circuits than usual. "
1414 "Most likely this means the Tor network is overloaded "
1415 "or your network connection is poor. "
1416 "Use counts are %ld/%ld. Success counts are %ld/%ld. "
1417 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1418 "and %ld timed out. "
1419 "For reference, your timeout cutoff is %ld seconds.",
1420 entry_guard_describe(guard),
1428 tor_lround(pb->timeouts),
1430 }
1431 }
1432 }
1433}
1434
1435/**
1436 * Check the path bias circuit close status rates against our consensus
1437 * parameter limits.
1438 *
1439 * Emits a log message if the use success rates are too low.
1440 *
1441 * If pathbias_get_dropguards() is set, we also disable the use of
1442 * very failure prone guards.
1443 *
1444 * XXX: This function shares similar log messages and checks to
1445 * pathbias_measure_use_rate(). It may be possible to combine them
1446 * eventually, especially if we can ever remove the need for 3
1447 * levels of closure warns (if the overall circuit failure rate
1448 * goes down with ntor). One way to do so would be to multiply
1449 * the build rate with the use rate to get an idea of the total
1450 * fraction of the total network paths the user is able to use.
1451 * See ticket #8159.
1452 */
1453static void
1454pathbias_measure_close_rate(entry_guard_t *guard)
1455{
1456 const or_options_t *options = get_options();
1458
1459 if (pb->circ_attempts > pathbias_get_min_circs(options)) {
1460 /* Note: We rely on the < comparison here to allow us to set a 0
1461 * rate and disable the feature entirely. If refactoring, don't
1462 * change to <= */
1464 < pathbias_get_extreme_rate(options)) {
1465 /* Dropping is currently disabled by default. */
1466 if (pathbias_get_dropguards(options)) {
1467 if (!pb->path_bias_disabled) {
1468 log_warn(LD_CIRC,
1469 "Guard %s is failing an extremely large "
1470 "amount of circuits. "
1471 "To avoid potential route manipulation attacks, Tor has "
1472 "disabled use of this guard. "
1473 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1474 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1475 "and %ld timed out. "
1476 "For reference, your timeout cutoff is %ld seconds.",
1477 entry_guard_describe(guard),
1485 tor_lround(pb->timeouts),
1487 pb->path_bias_disabled = 1;
1488 return;
1489 }
1490 } else if (!pb->path_bias_extreme) {
1491 pb->path_bias_extreme = 1;
1492 log_warn(LD_CIRC,
1493 "Guard %s is failing an extremely large "
1494 "amount of circuits. "
1495 "This could indicate a route manipulation attack, "
1496 "extreme network overload, or a bug. "
1497 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1498 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1499 "and %ld timed out. "
1500 "For reference, your timeout cutoff is %ld seconds.",
1501 entry_guard_describe(guard),
1509 tor_lround(pb->timeouts),
1511 }
1513 < pathbias_get_warn_rate(options)) {
1514 if (!pb->path_bias_warned) {
1515 pb->path_bias_warned = 1;
1516 log_warn(LD_CIRC,
1517 "Guard %s is failing a very large "
1518 "amount of circuits. "
1519 "Most likely this means the Tor network is "
1520 "overloaded, but it could also mean an attack against "
1521 "you or potentially the guard itself. "
1522 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1523 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1524 "and %ld timed out. "
1525 "For reference, your timeout cutoff is %ld seconds.",
1526 entry_guard_describe(guard),
1534 tor_lround(pb->timeouts),
1536 }
1538 < pathbias_get_notice_rate(options)) {
1539 if (!pb->path_bias_noticed) {
1540 pb->path_bias_noticed = 1;
1541 log_notice(LD_CIRC,
1542 "Guard %s is failing more circuits than "
1543 "usual. "
1544 "Most likely this means the Tor network is overloaded. "
1545 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1546 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1547 "and %ld timed out. "
1548 "For reference, your timeout cutoff is %ld seconds.",
1549 entry_guard_describe(guard),
1557 tor_lround(pb->timeouts),
1559 }
1560 }
1561 }
1562}
1563
1564/**
1565 * This function scales the path bias use rates if we have
1566 * more data than the scaling threshold. This allows us to
1567 * be more sensitive to recent measurements.
1568 *
1569 * XXX: The attempt count transfer stuff here might be done
1570 * better by keeping separate pending counters that get
1571 * transferred at circuit close. See ticket #8160.
1572 */
1573static void
1574pathbias_scale_close_rates(entry_guard_t *guard)
1575{
1576 const or_options_t *options = get_options();
1578
1579 /* If we get a ton of circuits, just scale everything down */
1580 if (pb->circ_attempts > pathbias_get_scale_threshold(options)) {
1581 double scale_ratio = pathbias_get_scale_ratio(options);
1582 int opened_attempts = pathbias_count_circs_in_states(guard,
1584 int opened_built = pathbias_count_circs_in_states(guard,
1587 /* Verify that the counts are sane before and after scaling */
1588 int counts_are_sane = (pb->circ_attempts >= pb->circ_successes);
1589
1590 pb->circ_attempts -= (opened_attempts+opened_built);
1591 pb->circ_successes -= opened_built;
1592
1593 pb->circ_attempts *= scale_ratio;
1594 pb->circ_successes *= scale_ratio;
1595 pb->timeouts *= scale_ratio;
1596 pb->successful_circuits_closed *= scale_ratio;
1597 pb->collapsed_circuits *= scale_ratio;
1598 pb->unusable_circuits *= scale_ratio;
1599
1600 pb->circ_attempts += (opened_attempts+opened_built);
1601 pb->circ_successes += opened_built;
1602
1604
1605 log_info(LD_CIRC,
1606 "Scaled pathbias counts to (%f,%f)/%f (%d/%d open) for guard "
1607 "%s",
1609 pb->circ_attempts, opened_built, opened_attempts,
1610 entry_guard_describe(guard));
1611
1612 /* Have the counts just become invalid by this scaling attempt? */
1613 if (counts_are_sane && pb->circ_attempts < pb->circ_successes) {
1614 log_notice(LD_BUG,
1615 "Scaling has mangled pathbias counts to %f/%f (%d/%d open) "
1616 "for guard %s",
1617 pb->circ_successes, pb->circ_attempts, opened_built,
1618 opened_attempts,
1619 entry_guard_describe(guard));
1620 }
1621 }
1622}
1623
1624/**
1625 * This function scales the path bias circuit close rates if we have
1626 * more data than the scaling threshold. This allows us to be more
1627 * sensitive to recent measurements.
1628 *
1629 * XXX: The attempt count transfer stuff here might be done
1630 * better by keeping separate pending counters that get
1631 * transferred at circuit close. See ticket #8160.
1632 */
1633void
1634pathbias_scale_use_rates(entry_guard_t *guard)
1635{
1636 const or_options_t *options = get_options();
1638
1639 /* If we get a ton of circuits, just scale everything down */
1641 double scale_ratio = pathbias_get_scale_ratio(options);
1642 int opened_attempts = pathbias_count_circs_in_states(guard,
1644 /* Verify that the counts are sane before and after scaling */
1645 int counts_are_sane = (pb->use_attempts >= pb->use_successes);
1646
1647 pb->use_attempts -= opened_attempts;
1648
1649 pb->use_attempts *= scale_ratio;
1650 pb->use_successes *= scale_ratio;
1651
1652 pb->use_attempts += opened_attempts;
1653
1654 log_info(LD_CIRC,
1655 "Scaled pathbias use counts to %f/%f (%d open) for guard %s",
1656 pb->use_successes, pb->use_attempts, opened_attempts,
1657 entry_guard_describe(guard));
1658
1659 /* Have the counts just become invalid by this scaling attempt? */
1660 if (counts_are_sane && pb->use_attempts < pb->use_successes) {
1661 log_notice(LD_BUG,
1662 "Scaling has mangled pathbias usage counts to %f/%f "
1663 "(%d open) for guard %s",
1665 opened_attempts, entry_guard_describe(guard));
1666 }
1667
1669 }
1670}
char * tor_dup_ip(uint32_t addr)
Definition address.c:2047
time_t approx_time(void)
Definition approx_time.c:32
static uint8_t get_uint8(const void *cp)
Definition bytes.h:23
static uint32_t get_uint32(const void *cp)
Definition bytes.h:54
Header file for channel.c.
int pathbias_count_build_attempt(origin_circuit_t *circ)
double pathbias_get_extreme_use_rate(const or_options_t *options)
void pathbias_count_use_attempt(origin_circuit_t *circ)
static void pathbias_count_use_success(origin_circuit_t *circ)
static int pathbias_get_min_circs(const or_options_t *options)
static int pathbias_should_count(origin_circuit_t *circ)
static int pathbias_get_min_use(const or_options_t *options)
int pathbias_check_close(origin_circuit_t *ocirc, int reason)
static double pathbias_get_warn_rate(const or_options_t *options)
void pathbias_count_valid_cells(circuit_t *circ, const relay_msg_t *msg)
static void pathbias_scale_use_rates(entry_guard_t *guard)
static void pathbias_count_collapse(origin_circuit_t *circ)
static double pathbias_get_notice_use_rate(const or_options_t *options)
static void pathbias_count_use_failed(origin_circuit_t *circ)
void pathbias_count_timeout(origin_circuit_t *circ)
static void pathbias_count_successful_close(origin_circuit_t *circ)
static int pathbias_is_new_circ_attempt(origin_circuit_t *circ)
double pathbias_get_extreme_rate(const or_options_t *options)
const char * pathbias_state_to_string(path_state_t state)
static int pathbias_send_usable_probe(circuit_t *circ)
void pathbias_mark_use_rollback(origin_circuit_t *circ)
double pathbias_get_use_success_count(entry_guard_t *guard)
static int pathbias_get_scale_use_threshold(const or_options_t *options)
static void pathbias_measure_use_rate(entry_guard_t *guard)
static double pathbias_get_notice_rate(const or_options_t *options)
static int entry_guard_inc_circ_attempt_count(entry_guard_t *guard)
static void pathbias_measure_close_rate(entry_guard_t *guard)
static int pathbias_count_circs_in_states(entry_guard_t *guard, path_state_t from, path_state_t to)
static double pathbias_get_scale_ratio(const or_options_t *options)
int pathbias_check_probe_response(circuit_t *circ, const relay_msg_t *msg)
static int pathbias_get_scale_threshold(const or_options_t *options)
int pathbias_get_dropguards(const or_options_t *options)
static void pathbias_scale_close_rates(entry_guard_t *guard)
void pathbias_mark_use_success(origin_circuit_t *circ)
void pathbias_count_build_success(origin_circuit_t *circ)
double pathbias_get_close_success_count(entry_guard_t *guard)
int circuit_truncated(origin_circuit_t *circ, int reason)
Header file for circuitbuild.c.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
const char * circuit_state_to_string(int state)
const char * circuit_purpose_to_string(uint8_t purpose)
smartlist_t * circuit_get_global_list(void)
Header file for circuitlist.c.
#define CIRCUIT_PURPOSE_S_CONNECT_REND
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
Definition circuitlist.h:93
#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING
#define CIRCUIT_PURPOSE_CONTROLLER
#define CIRCUIT_IS_ORIGIN(c)
#define CIRCUIT_PURPOSE_TESTING
#define CIRCUIT_PURPOSE_S_REND_JOINED
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED
Definition circuitlist.h:79
#define CIRCUIT_PURPOSE_C_INTRODUCING
Definition circuitlist.h:73
#define CIRCUIT_PURPOSE_CONFLUX_UNLINKED
double get_circuit_build_close_time_ms(void)
Header file for circuitstats.c.
void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
Header file for circuituse.c.
const or_options_t * get_options(void)
Definition config.c:948
Header file for config.c.
int connection_half_edge_is_valid_data(const smartlist_t *half_conns, streamid_t stream_id)
int connection_half_edge_is_valid_end(smartlist_t *half_conns, streamid_t stream_id)
int connection_half_edge_is_valid_connected(const smartlist_t *half_conns, streamid_t stream_id)
int connection_half_edge_is_valid_resolved(smartlist_t *half_conns, streamid_t stream_id)
int connection_half_edge_is_valid_sendme(const smartlist_t *half_conns, streamid_t stream_id)
streamid_t get_unique_stream_id_by_circ(origin_circuit_t *circ)
Header file for connection_edge.c.
Circuit-build-stse structure.
Path structures for origin circuits.
void crypto_rand(char *to, size_t n)
Common functions for using (pseudo-)random number generators.
#define fast_memeq(a, b, c)
Definition di_ops.h:35
#define DIGEST_LEN
void entry_guards_changed(void)
entry_guard_t * entry_guard_get_by_id_digest(const char *digest)
const char * entry_guard_get_rsa_id_digest(const entry_guard_t *guard)
Definition entrynodes.c:336
guard_pathbias_t * entry_guard_get_pathbias_state(entry_guard_t *guard)
Definition entrynodes.c:343
const char * entry_guard_describe(const entry_guard_t *guard)
Definition entrynodes.c:324
Header file for circuitbuild.c.
Extend-info structure.
long tor_lround(double d)
Definition fp.c:31
Header for fp.c.
Header for laplace.c.
#define LD_PROTOCOL
Definition log.h:72
#define LD_BUG
Definition log.h:86
#define LD_CIRC
Definition log.h:82
#define tor_free(p)
Definition malloc.h:56
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
Master header file for Tor-specific functionality.
#define END_CIRC_REASON_FLAG_REMOTE
Definition or.h:393
#define RELAY_PAYLOAD_SIZE_MAX
Definition or.h:576
Origin circuit structure.
path_state_t
@ PATH_STATE_ALREADY_COUNTED
@ PATH_STATE_USE_FAILED
@ PATH_STATE_BUILD_ATTEMPTED
@ PATH_STATE_BUILD_SUCCEEDED
@ PATH_STATE_USE_SUCCEEDED
@ PATH_STATE_NEW_CIRC
@ PATH_STATE_USE_ATTEMPTED
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition printf.c:27
char * rate_limit_log(ratelim_t *lim, time_t now)
Definition ratelim.c:42
Header file for relay.c.
Header file for relay_msg.c.
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
enum channel_t::@9 reason_for_closing
char identity_digest[DIGEST_LEN]
Definition channel.h:379
uint8_t state
Definition circuit_st.h:111
time_t timestamp_dirty
Definition circuit_st.h:198
uint8_t purpose
Definition circuit_st.h:112
struct timeval timestamp_began
Definition circuit_st.h:176
channel_t * n_chan
Definition circuit_st.h:70
struct crypt_path_t * prev
struct crypt_path_t * next
extend_info_t * extend_info
char identity_digest[DIGEST_LEN]
unsigned int path_bias_use_noticed
Definition entrynodes.h:44
unsigned int path_bias_use_extreme
Definition entrynodes.h:46
double use_successes
Definition entrynodes.h:62
unsigned int path_bias_warned
Definition entrynodes.h:38
unsigned int path_bias_extreme
Definition entrynodes.h:40
double circ_attempts
Definition entrynodes.h:49
double collapsed_circuits
Definition entrynodes.h:54
double circ_successes
Definition entrynodes.h:50
unsigned int path_bias_disabled
Definition entrynodes.h:42
double unusable_circuits
Definition entrynodes.h:57
double successful_circuits_closed
Definition entrynodes.h:52
double use_attempts
Definition entrynodes.h:61
unsigned int path_bias_noticed
Definition entrynodes.h:36
int PathBiasCircThreshold
unsigned int has_opened
path_state_bitfield_t path_state
unsigned int any_hop_from_controller
crypt_path_t * cpath
streamid_t pathbias_probe_id
cpath_build_state_t * build_state
smartlist_t * half_streams
void tor_gettimeofday(struct timeval *timeval)
#define tor_assert(expr)
Definition util_bug.h:103
#define tor_fragile_assert()
Definition util_bug.h:278