Coverage Report

Created: 2025-08-29 06:15

/src/tor/src/feature/client/circpathbias.c
Line
Count
Source (jump to first uncovered line)
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"
27
#include "core/or/circuitbuild.h"
28
#include "core/or/circuitlist.h"
29
#include "core/or/circuituse.h"
30
#include "core/or/circuitstats.h"
31
#include "core/or/connection_edge.h"
32
#include "app/config/config.h"
33
#include "lib/crypt_ops/crypto_rand.h"
34
#include "feature/client/entrynodes.h"
35
#include "feature/nodelist/networkstatus.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
41
#include "core/or/cpath_build_state_st.h"
42
#include "core/or/crypt_path_st.h"
43
#include "core/or/extend_info_st.h"
44
#include "core/or/origin_circuit_st.h"
45
46
static void pathbias_count_successful_close(origin_circuit_t *circ);
47
static void pathbias_count_collapse(origin_circuit_t *circ);
48
static void pathbias_count_use_failed(origin_circuit_t *circ);
49
static void pathbias_measure_use_rate(entry_guard_t *guard);
50
static void pathbias_measure_close_rate(entry_guard_t *guard);
51
static void pathbias_scale_use_rates(entry_guard_t *guard);
52
static void pathbias_scale_close_rates(entry_guard_t *guard);
53
static 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
 */
60
static int
61
entry_guard_inc_circ_attempt_count(entry_guard_t *guard)
62
0
{
63
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
64
65
0
  entry_guards_changed();
66
67
0
  pathbias_measure_close_rate(guard);
68
69
0
  if (pb->path_bias_disabled)
70
0
    return -1;
71
72
0
  pathbias_scale_close_rates(guard);
73
0
  pb->circ_attempts++;
74
75
0
  log_info(LD_CIRC, "Got success count %f/%f for guard %s",
76
0
           pb->circ_successes, pb->circ_attempts,
77
0
           entry_guard_describe(guard));
78
0
  return 0;
79
0
}
80
81
/** The minimum number of circuit attempts before we start
82
  * thinking about warning about path bias and dropping guards */
83
static int
84
pathbias_get_min_circs(const or_options_t *options)
85
0
{
86
0
#define DFLT_PATH_BIAS_MIN_CIRC 150
87
0
  if (options->PathBiasCircThreshold >= 5)
88
0
    return options->PathBiasCircThreshold;
89
0
  else
90
0
    return networkstatus_get_param(NULL, "pb_mincircs",
91
0
                                   DFLT_PATH_BIAS_MIN_CIRC,
92
0
                                   5, INT32_MAX);
93
0
}
94
95
/** The circuit success rate below which we issue a notice */
96
static double
97
pathbias_get_notice_rate(const or_options_t *options)
98
0
{
99
0
#define DFLT_PATH_BIAS_NOTICE_PCT 70
100
0
  if (options->PathBiasNoticeRate >= 0.0)
101
0
    return options->PathBiasNoticeRate;
102
0
  else
103
0
    return networkstatus_get_param(NULL, "pb_noticepct",
104
0
                                   DFLT_PATH_BIAS_NOTICE_PCT, 0, 100)/100.0;
105
0
}
106
107
/** The circuit success rate below which we issue a warn */
108
static double
109
pathbias_get_warn_rate(const or_options_t *options)
110
0
{
111
0
#define DFLT_PATH_BIAS_WARN_PCT 50
112
0
  if (options->PathBiasWarnRate >= 0.0)
113
0
    return options->PathBiasWarnRate;
114
0
  else
115
0
    return networkstatus_get_param(NULL, "pb_warnpct",
116
0
                                   DFLT_PATH_BIAS_WARN_PCT, 0, 100)/100.0;
117
0
}
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
 */
124
double
125
pathbias_get_extreme_rate(const or_options_t *options)
126
0
{
127
0
#define DFLT_PATH_BIAS_EXTREME_PCT 30
128
0
  if (options->PathBiasExtremeRate >= 0.0)
129
0
    return options->PathBiasExtremeRate;
130
0
  else
131
0
    return networkstatus_get_param(NULL, "pb_extremepct",
132
0
                                   DFLT_PATH_BIAS_EXTREME_PCT, 0, 100)/100.0;
133
0
}
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
 */
140
int
141
pathbias_get_dropguards(const or_options_t *options)
142
0
{
143
0
#define DFLT_PATH_BIAS_DROP_GUARDS 0
144
0
  if (options->PathBiasDropGuards >= 0)
145
0
    return options->PathBiasDropGuards;
146
0
  else
147
0
    return networkstatus_get_param(NULL, "pb_dropguards",
148
0
                                   DFLT_PATH_BIAS_DROP_GUARDS, 0, 1);
149
0
}
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
 */
157
static int
158
pathbias_get_scale_threshold(const or_options_t *options)
159
0
{
160
0
#define DFLT_PATH_BIAS_SCALE_THRESHOLD 300
161
0
  if (options->PathBiasScaleThreshold >= 10)
162
0
    return options->PathBiasScaleThreshold;
163
0
  else
164
0
    return networkstatus_get_param(NULL, "pb_scalecircs",
165
0
                                   DFLT_PATH_BIAS_SCALE_THRESHOLD, 10,
166
0
                                   INT32_MAX);
167
0
}
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
 */
176
static double
177
pathbias_get_scale_ratio(const or_options_t *options)
178
0
{
179
0
  (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
0
  int denominator = networkstatus_get_param(NULL, "pb_scalefactor",
188
0
                              2, 2, INT32_MAX);
189
0
  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
0
  return networkstatus_get_param(NULL, "pb_multfactor",
197
0
                              1, 1, denominator)/((double)denominator);
198
0
}
199
200
/** The minimum number of circuit usage attempts before we start
201
  * thinking about warning about path use bias and dropping guards */
202
static int
203
pathbias_get_min_use(const or_options_t *options)
204
0
{
205
0
#define DFLT_PATH_BIAS_MIN_USE 20
206
0
  if (options->PathBiasUseThreshold >= 3)
207
0
    return options->PathBiasUseThreshold;
208
0
  else
209
0
    return networkstatus_get_param(NULL, "pb_minuse",
210
0
                                   DFLT_PATH_BIAS_MIN_USE,
211
0
                                   3, INT32_MAX);
212
0
}
213
214
/** The circuit use success rate below which we issue a notice */
215
static double
216
pathbias_get_notice_use_rate(const or_options_t *options)
217
0
{
218
0
#define DFLT_PATH_BIAS_NOTICE_USE_PCT 80
219
0
  if (options->PathBiasNoticeUseRate >= 0.0)
220
0
    return options->PathBiasNoticeUseRate;
221
0
  else
222
0
    return networkstatus_get_param(NULL, "pb_noticeusepct",
223
0
                                   DFLT_PATH_BIAS_NOTICE_USE_PCT,
224
0
                                   0, 100)/100.0;
225
0
}
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
 */
231
double
232
pathbias_get_extreme_use_rate(const or_options_t *options)
233
0
{
234
0
#define DFLT_PATH_BIAS_EXTREME_USE_PCT 60
235
0
  if (options->PathBiasExtremeUseRate >= 0.0)
236
0
    return options->PathBiasExtremeUseRate;
237
0
  else
238
0
    return networkstatus_get_param(NULL, "pb_extremeusepct",
239
0
                                   DFLT_PATH_BIAS_EXTREME_USE_PCT,
240
0
                                   0, 100)/100.0;
241
0
}
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
 */
249
static int
250
pathbias_get_scale_use_threshold(const or_options_t *options)
251
0
{
252
0
#define DFLT_PATH_BIAS_SCALE_USE_THRESHOLD 100
253
0
  if (options->PathBiasScaleUseThreshold >= 10)
254
0
    return options->PathBiasScaleUseThreshold;
255
0
  else
256
0
    return networkstatus_get_param(NULL, "pb_scaleuse",
257
0
                                   DFLT_PATH_BIAS_SCALE_USE_THRESHOLD,
258
0
                                   10, INT32_MAX);
259
0
}
260
261
/**
262
 * Convert a Guard's path state to string.
263
 */
264
const char *
265
pathbias_state_to_string(path_state_t state)
266
0
{
267
0
  switch (state) {
268
0
    case PATH_STATE_NEW_CIRC:
269
0
      return "new";
270
0
    case PATH_STATE_BUILD_ATTEMPTED:
271
0
      return "build attempted";
272
0
    case PATH_STATE_BUILD_SUCCEEDED:
273
0
      return "build succeeded";
274
0
    case PATH_STATE_USE_ATTEMPTED:
275
0
      return "use attempted";
276
0
    case PATH_STATE_USE_SUCCEEDED:
277
0
      return "use succeeded";
278
0
    case PATH_STATE_USE_FAILED:
279
0
      return "use failed";
280
0
    case PATH_STATE_ALREADY_COUNTED:
281
0
      return "already counted";
282
0
  }
283
284
0
  return "unknown";
285
0
}
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
 */
295
static int
296
pathbias_is_new_circ_attempt(origin_circuit_t *circ)
297
0
{
298
0
#define N2N_TAGGING_IS_POSSIBLE
299
0
#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
0
  return circ->cpath &&
304
0
         circ->cpath->next != circ->cpath &&
305
0
         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
0
}
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
 */
322
static int
323
pathbias_should_count(origin_circuit_t *circ)
324
0
{
325
0
#define PATHBIAS_COUNT_INTERVAL (600)
326
0
  static ratelim_t count_limit =
327
0
    RATELIM_INIT(PATHBIAS_COUNT_INTERVAL);
328
0
  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
0
  if (get_options()->UseEntryGuards == 0 ||
348
0
          circ->base_.purpose == CIRCUIT_PURPOSE_TESTING ||
349
0
          circ->base_.purpose == CIRCUIT_PURPOSE_CONTROLLER ||
350
0
          circ->base_.purpose == CIRCUIT_PURPOSE_S_CONNECT_REND ||
351
0
          circ->base_.purpose == CIRCUIT_PURPOSE_S_REND_JOINED ||
352
0
          circ->base_.purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED ||
353
0
          circ->base_.purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
354
0
          (circ->base_.purpose >= CIRCUIT_PURPOSE_C_INTRODUCING &&
355
0
           circ->base_.purpose <= CIRCUIT_PURPOSE_C_INTRODUCE_ACKED)) {
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
0
    if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_COUNTED
365
0
            && circ->path_state != PATH_STATE_ALREADY_COUNTED) {
366
0
      log_info(LD_BUG,
367
0
               "Circuit %d is now being ignored despite being counted "
368
0
               "in the past. Purpose is %s, path state is %s",
369
0
               circ->global_identifier,
370
0
               circuit_purpose_to_string(circ->base_.purpose),
371
0
               pathbias_state_to_string(circ->path_state));
372
0
    }
373
0
    circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
374
0
    return 0;
375
0
  }
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
0
  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
0
    circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
385
0
    return 0;
386
0
  }
387
388
  /* Completely ignore one hop circuits */
389
0
  if (circ->build_state->onehop_tunnel ||
390
0
      circ->build_state->desired_path_len == 1) {
391
    /* Check for inconsistency */
392
0
    if (circ->build_state->desired_path_len != 1 ||
393
0
        !circ->build_state->onehop_tunnel) {
394
0
      if ((rate_msg = rate_limit_log(&count_limit, approx_time()))) {
395
0
        log_info(LD_BUG,
396
0
               "One-hop circuit %d has length %d. Path state is %s. "
397
0
               "Circuit is a %s currently %s.%s",
398
0
               circ->global_identifier,
399
0
               circ->build_state->desired_path_len,
400
0
               pathbias_state_to_string(circ->path_state),
401
0
               circuit_purpose_to_string(circ->base_.purpose),
402
0
               circuit_state_to_string(circ->base_.state),
403
0
               rate_msg);
404
0
        tor_free(rate_msg);
405
0
      }
406
0
      tor_fragile_assert();
407
0
    }
408
409
    /* Check to see if the shouldcount result has changed due to a
410
     * unexpected change that would affect our results */
411
0
    if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_COUNTED) {
412
0
      log_info(LD_BUG,
413
0
               "One-hop circuit %d is now being ignored despite being counted "
414
0
               "in the past. Purpose is %s, path state is %s",
415
0
               circ->global_identifier,
416
0
               circuit_purpose_to_string(circ->base_.purpose),
417
0
               pathbias_state_to_string(circ->path_state));
418
0
    }
419
0
    circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
420
0
    return 0;
421
0
  }
422
423
  /* Check to see if the shouldcount result has changed due to a
424
   * unexpected purpose change that would affect our results */
425
0
  if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_IGNORED) {
426
0
    log_info(LD_CIRC,
427
0
            "Circuit %d is not being counted by pathbias because it was "
428
0
            "ignored in the past. Purpose is %s, path state is %s",
429
0
            circ->global_identifier,
430
0
            circuit_purpose_to_string(circ->base_.purpose),
431
0
            pathbias_state_to_string(circ->path_state));
432
0
    return 0;
433
0
  }
434
0
  circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_COUNTED;
435
436
0
  return 1;
437
0
}
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
 */
445
int
446
pathbias_count_build_attempt(origin_circuit_t *circ)
447
0
{
448
0
#define CIRC_ATTEMPT_NOTICE_INTERVAL (600)
449
0
  static ratelim_t circ_attempt_notice_limit =
450
0
    RATELIM_INIT(CIRC_ATTEMPT_NOTICE_INTERVAL);
451
0
  char *rate_msg = NULL;
452
453
0
  if (!pathbias_should_count(circ)) {
454
0
    return 0;
455
0
  }
456
457
0
  if (pathbias_is_new_circ_attempt(circ)) {
458
    /* Help track down the real cause of bug #6475: */
459
0
    if (circ->has_opened && circ->path_state != PATH_STATE_BUILD_ATTEMPTED) {
460
0
      if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
461
0
                                     approx_time()))) {
462
0
        log_info(LD_BUG,
463
0
                "Opened circuit %d is in strange path state %s. "
464
0
                "Circuit is a %s currently %s.%s",
465
0
                circ->global_identifier,
466
0
                pathbias_state_to_string(circ->path_state),
467
0
                circuit_purpose_to_string(circ->base_.purpose),
468
0
                circuit_state_to_string(circ->base_.state),
469
0
                rate_msg);
470
0
        tor_free(rate_msg);
471
0
      }
472
0
    }
473
474
    /* Don't re-count cannibalized circs.. */
475
0
    if (!circ->has_opened) {
476
0
      entry_guard_t *guard = NULL;
477
478
0
      if (circ->cpath && circ->cpath->extend_info) {
479
0
        guard = entry_guard_get_by_id_digest(
480
0
                  circ->cpath->extend_info->identity_digest);
481
0
      } else if (circ->base_.n_chan) {
482
0
        guard =
483
0
          entry_guard_get_by_id_digest(circ->base_.n_chan->identity_digest);
484
0
      }
485
486
0
      if (guard) {
487
0
        if (circ->path_state == PATH_STATE_NEW_CIRC) {
488
0
          circ->path_state = PATH_STATE_BUILD_ATTEMPTED;
489
490
0
          if (entry_guard_inc_circ_attempt_count(guard) < 0) {
491
            /* Bogus guard; we already warned. */
492
0
            return -END_CIRC_REASON_TORPROTOCOL;
493
0
          }
494
0
        } else {
495
0
          if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
496
0
                  approx_time()))) {
497
0
            log_info(LD_BUG,
498
0
                   "Unopened circuit %d has strange path state %s. "
499
0
                   "Circuit is a %s currently %s.%s",
500
0
                   circ->global_identifier,
501
0
                   pathbias_state_to_string(circ->path_state),
502
0
                   circuit_purpose_to_string(circ->base_.purpose),
503
0
                   circuit_state_to_string(circ->base_.state),
504
0
                   rate_msg);
505
0
            tor_free(rate_msg);
506
0
          }
507
0
        }
508
0
      } else {
509
0
        if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
510
0
                approx_time()))) {
511
0
          log_info(LD_CIRC,
512
0
              "Unopened circuit has no known guard. "
513
0
              "Circuit is a %s currently %s.%s",
514
0
              circuit_purpose_to_string(circ->base_.purpose),
515
0
              circuit_state_to_string(circ->base_.state),
516
0
              rate_msg);
517
0
          tor_free(rate_msg);
518
0
        }
519
0
      }
520
0
    }
521
0
  }
522
523
0
  return 0;
524
0
}
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
 */
533
void
534
pathbias_count_build_success(origin_circuit_t *circ)
535
0
{
536
0
#define SUCCESS_NOTICE_INTERVAL (600)
537
0
  static ratelim_t success_notice_limit =
538
0
    RATELIM_INIT(SUCCESS_NOTICE_INTERVAL);
539
0
  char *rate_msg = NULL;
540
0
  entry_guard_t *guard = NULL;
541
542
0
  if (!pathbias_should_count(circ)) {
543
0
    return;
544
0
  }
545
546
  /* Don't count cannibalized/reused circs for path bias
547
   * "build" success, since they get counted under "use" success. */
548
0
  if (!circ->has_opened) {
549
0
    if (circ->cpath && circ->cpath->extend_info) {
550
0
      guard = entry_guard_get_by_id_digest(
551
0
                circ->cpath->extend_info->identity_digest);
552
0
    }
553
554
0
    if (guard) {
555
0
      guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
556
557
0
      if (circ->path_state == PATH_STATE_BUILD_ATTEMPTED) {
558
0
        circ->path_state = PATH_STATE_BUILD_SUCCEEDED;
559
0
        pb->circ_successes++;
560
0
        entry_guards_changed();
561
562
0
        log_info(LD_CIRC, "Got success count %f/%f for guard %s",
563
0
                 pb->circ_successes, pb->circ_attempts,
564
0
                 entry_guard_describe(guard));
565
0
      } else {
566
0
        if ((rate_msg = rate_limit_log(&success_notice_limit,
567
0
                approx_time()))) {
568
0
          log_info(LD_BUG,
569
0
              "Succeeded circuit %d is in strange path state %s. "
570
0
              "Circuit is a %s currently %s.%s",
571
0
              circ->global_identifier,
572
0
              pathbias_state_to_string(circ->path_state),
573
0
              circuit_purpose_to_string(circ->base_.purpose),
574
0
              circuit_state_to_string(circ->base_.state),
575
0
              rate_msg);
576
0
          tor_free(rate_msg);
577
0
        }
578
0
      }
579
580
0
      if (pb->circ_attempts < pb->circ_successes) {
581
0
        log_notice(LD_BUG, "Unexpectedly high successes counts (%f/%f) "
582
0
                 "for guard %s",
583
0
                 pb->circ_successes, pb->circ_attempts,
584
0
                 entry_guard_describe(guard));
585
0
      }
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
0
    } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
590
0
      if ((rate_msg = rate_limit_log(&success_notice_limit,
591
0
              approx_time()))) {
592
0
        log_info(LD_CIRC,
593
0
            "Completed circuit has no known guard. "
594
0
            "Circuit is a %s currently %s.%s",
595
0
            circuit_purpose_to_string(circ->base_.purpose),
596
0
            circuit_state_to_string(circ->base_.state),
597
0
            rate_msg);
598
0
        tor_free(rate_msg);
599
0
      }
600
0
    }
601
0
  } else {
602
0
    if (circ->path_state < PATH_STATE_BUILD_SUCCEEDED) {
603
0
      if ((rate_msg = rate_limit_log(&success_notice_limit,
604
0
              approx_time()))) {
605
0
        log_info(LD_BUG,
606
0
            "Opened circuit %d is in strange path state %s. "
607
0
            "Circuit is a %s currently %s.%s",
608
0
            circ->global_identifier,
609
0
            pathbias_state_to_string(circ->path_state),
610
0
            circuit_purpose_to_string(circ->base_.purpose),
611
0
            circuit_state_to_string(circ->base_.state),
612
0
            rate_msg);
613
0
        tor_free(rate_msg);
614
0
      }
615
0
    }
616
0
  }
617
0
}
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
 */
625
void
626
pathbias_count_use_attempt(origin_circuit_t *circ)
627
0
{
628
0
  if (!pathbias_should_count(circ)) {
629
0
    return;
630
0
  }
631
632
0
  if (circ->path_state < PATH_STATE_BUILD_SUCCEEDED) {
633
0
    log_notice(LD_BUG,
634
0
        "Used circuit %d is in strange path state %s. "
635
0
        "Circuit is a %s currently %s.",
636
0
        circ->global_identifier,
637
0
        pathbias_state_to_string(circ->path_state),
638
0
        circuit_purpose_to_string(circ->base_.purpose),
639
0
        circuit_state_to_string(circ->base_.state));
640
0
  } else if (circ->path_state < PATH_STATE_USE_ATTEMPTED) {
641
0
    entry_guard_t *guard = entry_guard_get_by_id_digest(
642
0
                circ->cpath->extend_info->identity_digest);
643
0
    if (guard) {
644
0
      guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
645
646
0
      pathbias_measure_use_rate(guard);
647
0
      pathbias_scale_use_rates(guard);
648
0
      pb->use_attempts++;
649
0
      entry_guards_changed();
650
651
0
      log_debug(LD_CIRC,
652
0
               "Marked circuit %d (%f/%f) as used for guard %s.",
653
0
               circ->global_identifier,
654
0
               pb->use_successes, pb->use_attempts,
655
0
               entry_guard_describe(guard));
656
0
    }
657
658
0
    circ->path_state = PATH_STATE_USE_ATTEMPTED;
659
0
  } else {
660
    /* Harmless but educational log message */
661
0
    log_info(LD_CIRC,
662
0
        "Used circuit %d is already in path state %s. "
663
0
        "Circuit is a %s currently %s.",
664
0
        circ->global_identifier,
665
0
        pathbias_state_to_string(circ->path_state),
666
0
        circuit_purpose_to_string(circ->base_.purpose),
667
0
        circuit_state_to_string(circ->base_.state));
668
0
  }
669
670
0
  return;
671
0
}
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
 */
682
void
683
pathbias_mark_use_success(origin_circuit_t *circ)
684
0
{
685
0
  if (!pathbias_should_count(circ)) {
686
0
    return;
687
0
  }
688
689
0
  if (circ->path_state < PATH_STATE_USE_ATTEMPTED) {
690
0
    log_notice(LD_BUG,
691
0
        "Used circuit %d is in strange path state %s. "
692
0
        "Circuit is a %s currently %s.",
693
0
        circ->global_identifier,
694
0
        pathbias_state_to_string(circ->path_state),
695
0
        circuit_purpose_to_string(circ->base_.purpose),
696
0
        circuit_state_to_string(circ->base_.state));
697
698
0
    pathbias_count_use_attempt(circ);
699
0
  }
700
701
  /* We don't do any accounting at the guard until actual circuit close */
702
0
  circ->path_state = PATH_STATE_USE_SUCCEEDED;
703
704
0
  return;
705
0
}
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
 */
721
void
722
pathbias_mark_use_rollback(origin_circuit_t *circ)
723
0
{
724
0
  if (circ->path_state == PATH_STATE_USE_SUCCEEDED) {
725
0
    log_info(LD_CIRC,
726
0
             "Rolling back pathbias use state to 'attempted' for detached "
727
0
             "circuit %d", circ->global_identifier);
728
0
    circ->path_state = PATH_STATE_USE_ATTEMPTED;
729
0
  }
730
0
}
731
732
/**
733
 * Actually count a circuit success towards a guard's usage counters
734
 * if the path state is appropriate.
735
 */
736
static void
737
pathbias_count_use_success(origin_circuit_t *circ)
738
0
{
739
0
  entry_guard_t *guard;
740
741
0
  if (!pathbias_should_count(circ)) {
742
0
    return;
743
0
  }
744
745
0
  if (circ->path_state != PATH_STATE_USE_SUCCEEDED) {
746
0
    log_notice(LD_BUG,
747
0
        "Successfully used circuit %d is in strange path state %s. "
748
0
        "Circuit is a %s currently %s.",
749
0
        circ->global_identifier,
750
0
        pathbias_state_to_string(circ->path_state),
751
0
        circuit_purpose_to_string(circ->base_.purpose),
752
0
        circuit_state_to_string(circ->base_.state));
753
0
  } else {
754
0
    guard = entry_guard_get_by_id_digest(
755
0
                circ->cpath->extend_info->identity_digest);
756
0
    if (guard) {
757
0
      guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
758
759
0
      pb->use_successes++;
760
0
      entry_guards_changed();
761
762
0
      if (pb->use_attempts < pb->use_successes) {
763
0
        log_notice(LD_BUG, "Unexpectedly high use successes counts (%f/%f) "
764
0
                 "for guard %s",
765
0
                 pb->use_successes, pb->use_attempts,
766
0
                 entry_guard_describe(guard));
767
0
      }
768
769
0
      log_debug(LD_CIRC,
770
0
                "Marked circuit %d (%f/%f) as used successfully for guard %s",
771
0
                circ->global_identifier, pb->use_successes,
772
0
                pb->use_attempts,
773
0
                entry_guard_describe(guard));
774
0
    }
775
0
  }
776
777
0
  return;
778
0
}
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
 */
797
static int
798
pathbias_send_usable_probe(circuit_t *circ)
799
0
{
800
  /* Based on connection_ap_handshake_send_begin() */
801
0
  char payload[RELAY_PAYLOAD_SIZE_MAX];
802
0
  int payload_len;
803
0
  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
804
0
  crypt_path_t *cpath_layer = NULL;
805
0
  char *probe_nonce = NULL;
806
807
0
  tor_assert(ocirc);
808
809
0
  cpath_layer = ocirc->cpath->prev;
810
811
0
  if (cpath_layer->state != CPATH_STATE_OPEN) {
812
    /* This can happen for cannibalized circuits. Their
813
     * last hop isn't yet open */
814
0
    log_info(LD_CIRC,
815
0
             "Got pathbias probe request for unopened circuit %d. "
816
0
             "Opened %d, len %d", ocirc->global_identifier,
817
0
             ocirc->has_opened, ocirc->build_state->desired_path_len);
818
0
    return -1;
819
0
  }
820
821
  /* We already went down this road. */
822
0
  if (circ->purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING &&
823
0
      ocirc->pathbias_probe_id) {
824
0
    log_info(LD_CIRC,
825
0
             "Got pathbias probe request for circuit %d with "
826
0
             "outstanding probe", ocirc->global_identifier);
827
0
    return -1;
828
0
  }
829
830
  /* Can't probe if the channel isn't open */
831
0
  if (circ->n_chan == NULL ||
832
0
      (!CHANNEL_IS_OPEN(circ->n_chan)
833
0
       && !CHANNEL_IS_MAINT(circ->n_chan))) {
834
0
    log_info(LD_CIRC,
835
0
             "Skipping pathbias probe for circuit %d: Channel is not open.",
836
0
             ocirc->global_identifier);
837
0
    return -1;
838
0
  }
839
840
0
  circuit_change_purpose(circ, CIRCUIT_PURPOSE_PATH_BIAS_TESTING);
841
842
  /* Update timestamp for when circuit_expire_building() should kill us */
843
0
  tor_gettimeofday(&circ->timestamp_began);
844
845
  /* Generate a random address for the nonce */
846
0
  crypto_rand((char*)&ocirc->pathbias_probe_nonce,
847
0
              sizeof(ocirc->pathbias_probe_nonce));
848
0
  ocirc->pathbias_probe_nonce &= 0x00ffffff;
849
0
  probe_nonce = tor_dup_ip(ocirc->pathbias_probe_nonce);
850
851
0
  if (!probe_nonce) {
852
0
    log_err(LD_BUG, "Failed to generate nonce");
853
0
    return -1;
854
0
  }
855
856
0
  tor_snprintf(payload,RELAY_PAYLOAD_SIZE_MAX, "%s:25", probe_nonce);
857
0
  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 */
867
0
  ocirc->pathbias_probe_id = get_unique_stream_id_by_circ(ocirc);
868
869
0
  if (ocirc->pathbias_probe_id==0) {
870
0
    log_warn(LD_CIRC,
871
0
             "Ran out of stream IDs on circuit %u during "
872
0
             "pathbias probe attempt.", ocirc->global_identifier);
873
0
    tor_free(probe_nonce);
874
0
    return -1;
875
0
  }
876
877
0
  log_info(LD_CIRC,
878
0
           "Sending pathbias testing cell to %s:25 on stream %d for circ %d.",
879
0
           probe_nonce, ocirc->pathbias_probe_id, ocirc->global_identifier);
880
0
  tor_free(probe_nonce);
881
882
  /* Send a test relay cell */
883
0
  if (relay_send_command_from_edge(ocirc->pathbias_probe_id, circ,
884
0
                               RELAY_COMMAND_BEGIN, payload,
885
0
                               payload_len, cpath_layer) < 0) {
886
0
    log_notice(LD_CIRC,
887
0
               "Failed to send pathbias probe cell on circuit %d.",
888
0
               ocirc->global_identifier);
889
0
    return -1;
890
0
  }
891
892
  /* Mark it freshly dirty so it doesn't get expired in the meantime */
893
0
  circ->timestamp_dirty = time(NULL);
894
895
0
  return 0;
896
0
}
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
 */
905
int
906
pathbias_check_probe_response(circuit_t *circ, const relay_msg_t *msg)
907
0
{
908
  /* Based on connection_edge_process_relay_cell() */
909
0
  int reason;
910
0
  uint32_t ipv4_host;
911
0
  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
912
913
0
  tor_assert(msg);
914
0
  tor_assert(ocirc);
915
0
  tor_assert(circ->purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING);
916
917
0
  reason = msg->length > 0 ? get_uint8(msg->body) : END_STREAM_REASON_MISC;
918
919
0
  if (msg->command == RELAY_COMMAND_END &&
920
0
      reason == END_STREAM_REASON_EXITPOLICY &&
921
0
      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
0
    if (msg->length < 9) { /* reason+ipv4+dns_ttl */
926
0
      log_notice(LD_PROTOCOL,
927
0
             "Short path bias probe response length field (%d).", msg->length);
928
0
      return - END_CIRC_REASON_TORPROTOCOL;
929
0
    }
930
931
0
    ipv4_host = ntohl(get_uint32(msg->body + 1));
932
933
    /* Check nonce */
934
0
    if (ipv4_host == ocirc->pathbias_probe_nonce) {
935
0
      pathbias_mark_use_success(ocirc);
936
0
      circuit_read_valid_data(ocirc, msg->length);
937
0
      circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
938
0
      log_info(LD_CIRC,
939
0
               "Got valid path bias probe back for circ %d, stream %d.",
940
0
               ocirc->global_identifier, ocirc->pathbias_probe_id);
941
0
      return 0;
942
0
    } else {
943
0
      log_notice(LD_CIRC,
944
0
               "Got strange probe value 0x%x vs 0x%x back for circ %d, "
945
0
               "stream %d.", ipv4_host, ocirc->pathbias_probe_nonce,
946
0
               ocirc->global_identifier, ocirc->pathbias_probe_id);
947
0
      return -1;
948
0
    }
949
0
  }
950
0
  log_info(LD_CIRC,
951
0
             "Got another cell back back on pathbias probe circuit %d: "
952
0
             "Command: %d, Reason: %d, Stream-id: %d",
953
0
             ocirc->global_identifier, msg->command, reason, msg->stream_id);
954
0
  return -1;
955
0
}
956
957
/**
958
 * Check if a cell is counts as valid data for a circuit,
959
 * and if so, count it as valid.
960
 */
961
void
962
pathbias_count_valid_cells(circuit_t *circ, const relay_msg_t *msg)
963
0
{
964
0
  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
0
  switch (msg->command) {
969
0
    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
0
      circuit_read_valid_data(ocirc, msg->length);
974
0
      circuit_truncated(TO_ORIGIN_CIRCUIT(circ), get_uint8(msg->body));
975
976
0
      break;
977
978
0
    case RELAY_COMMAND_END:
979
0
      if (connection_half_edge_is_valid_end(ocirc->half_streams,
980
0
                                            msg->stream_id)) {
981
0
        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
982
0
      }
983
0
      break;
984
985
0
    case RELAY_COMMAND_DATA:
986
0
      if (connection_half_edge_is_valid_data(ocirc->half_streams,
987
0
                                             msg->stream_id)) {
988
0
        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
989
0
      }
990
0
      break;
991
992
0
    case RELAY_COMMAND_SENDME:
993
0
      if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
994
0
                                               msg->stream_id)) {
995
0
        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
996
0
      }
997
0
      break;
998
999
0
    case RELAY_COMMAND_CONNECTED:
1000
0
      if (connection_half_edge_is_valid_connected(ocirc->half_streams,
1001
0
                                                  msg->stream_id)) {
1002
0
        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
1003
0
      }
1004
0
      break;
1005
1006
0
    case RELAY_COMMAND_RESOLVED:
1007
0
      if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
1008
0
                                                 msg->stream_id)) {
1009
0
        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
1010
0
      }
1011
0
      break;
1012
0
  }
1013
0
}
1014
1015
/**
1016
 * Check if a circuit was used and/or closed successfully.
1017
 *
1018
 * If we attempted to use the circuit to carry a stream but failed
1019
 * for whatever reason, or if the circuit mysteriously died before
1020
 * we could attach any streams, record these two cases.
1021
 *
1022
 * If we *have* successfully used the circuit, or it appears to
1023
 * have been closed by us locally, count it as a success.
1024
 *
1025
 * Returns 0 if we're done making decisions with the circ,
1026
 * or -1 if we want to probe it first.
1027
 */
1028
int
1029
pathbias_check_close(origin_circuit_t *ocirc, int reason)
1030
0
{
1031
0
  circuit_t *circ = &ocirc->base_;
1032
1033
0
  if (!pathbias_should_count(ocirc)) {
1034
0
    return 0;
1035
0
  }
1036
1037
0
  switch (ocirc->path_state) {
1038
    /* If the circuit was closed after building, but before use, we need
1039
     * to ensure we were the ones who tried to close it (and not a remote
1040
     * actor). */
1041
0
    case PATH_STATE_BUILD_SUCCEEDED:
1042
0
      if (reason & END_CIRC_REASON_FLAG_REMOTE) {
1043
        /* Remote circ close reasons on an unused circuit all could be bias */
1044
0
        log_info(LD_CIRC,
1045
0
            "Circuit %d remote-closed without successful use for reason %d. "
1046
0
            "Circuit purpose %d currently %d,%s. Len %d.",
1047
0
            ocirc->global_identifier,
1048
0
            reason, circ->purpose, ocirc->has_opened,
1049
0
            circuit_state_to_string(circ->state),
1050
0
            ocirc->build_state->desired_path_len);
1051
0
        pathbias_count_collapse(ocirc);
1052
0
      } else if ((reason & ~END_CIRC_REASON_FLAG_REMOTE)
1053
0
                  == END_CIRC_REASON_CHANNEL_CLOSED &&
1054
0
                 circ->n_chan &&
1055
0
                 circ->n_chan->reason_for_closing
1056
0
                  != CHANNEL_CLOSE_REQUESTED) {
1057
        /* If we didn't close the channel ourselves, it could be bias */
1058
        /* XXX: Only count bias if the network is live?
1059
         * What about clock jumps/suspends? */
1060
0
        log_info(LD_CIRC,
1061
0
            "Circuit %d's channel closed without successful use for reason "
1062
0
            "%d, channel reason %d. Circuit purpose %d currently %d,%s. Len "
1063
0
            "%d.", ocirc->global_identifier,
1064
0
            reason, circ->n_chan->reason_for_closing,
1065
0
            circ->purpose, ocirc->has_opened,
1066
0
            circuit_state_to_string(circ->state),
1067
0
            ocirc->build_state->desired_path_len);
1068
0
        pathbias_count_collapse(ocirc);
1069
0
      } else {
1070
0
        pathbias_count_successful_close(ocirc);
1071
0
      }
1072
0
      break;
1073
1074
    /* If we tried to use a circuit but failed, we should probe it to ensure
1075
     * it has not been tampered with. */
1076
0
    case PATH_STATE_USE_ATTEMPTED:
1077
      /* XXX: Only probe and/or count failure if the network is live?
1078
       * What about clock jumps/suspends? */
1079
0
      if (pathbias_send_usable_probe(circ) == 0)
1080
0
        return -1;
1081
0
      else
1082
0
        pathbias_count_use_failed(ocirc);
1083
1084
      /* Any circuit where there were attempted streams but no successful
1085
       * streams could be bias */
1086
0
      log_info(LD_CIRC,
1087
0
            "Circuit %d closed without successful use for reason %d. "
1088
0
            "Circuit purpose %d currently %d,%s. Len %d.",
1089
0
            ocirc->global_identifier,
1090
0
            reason, circ->purpose, ocirc->has_opened,
1091
0
            circuit_state_to_string(circ->state),
1092
0
            ocirc->build_state->desired_path_len);
1093
0
      break;
1094
1095
0
    case PATH_STATE_USE_SUCCEEDED:
1096
0
      pathbias_count_successful_close(ocirc);
1097
0
      pathbias_count_use_success(ocirc);
1098
0
      break;
1099
1100
0
    case PATH_STATE_USE_FAILED:
1101
0
      pathbias_count_use_failed(ocirc);
1102
0
      break;
1103
1104
0
    case PATH_STATE_NEW_CIRC:
1105
0
    case PATH_STATE_BUILD_ATTEMPTED:
1106
0
    case PATH_STATE_ALREADY_COUNTED:
1107
0
    default:
1108
      // Other states are uninteresting. No stats to count.
1109
0
      break;
1110
0
  }
1111
1112
0
  ocirc->path_state = PATH_STATE_ALREADY_COUNTED;
1113
1114
0
  return 0;
1115
0
}
1116
1117
/**
1118
 * Count a successfully closed circuit.
1119
 */
1120
static void
1121
pathbias_count_successful_close(origin_circuit_t *circ)
1122
0
{
1123
0
  entry_guard_t *guard = NULL;
1124
0
  if (!pathbias_should_count(circ)) {
1125
0
    return;
1126
0
  }
1127
1128
0
  if (circ->cpath && circ->cpath->extend_info) {
1129
0
    guard = entry_guard_get_by_id_digest(
1130
0
              circ->cpath->extend_info->identity_digest);
1131
0
  }
1132
1133
0
  if (guard) {
1134
0
    guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1135
1136
    /* In the long run: circuit_success ~= successful_circuit_close +
1137
     *                                     circ_failure + stream_failure */
1138
0
    pb->successful_circuits_closed++;
1139
0
    entry_guards_changed();
1140
0
  } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
1141
   /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
1142
    * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
1143
    * No need to log that case. */
1144
0
    log_info(LD_CIRC,
1145
0
        "Successfully closed circuit has no known guard. "
1146
0
        "Circuit is a %s currently %s",
1147
0
        circuit_purpose_to_string(circ->base_.purpose),
1148
0
        circuit_state_to_string(circ->base_.state));
1149
0
  }
1150
0
}
1151
1152
/**
1153
 * Count a circuit that fails after it is built, but before it can
1154
 * carry any traffic.
1155
 *
1156
 * This is needed because there are ways to destroy a
1157
 * circuit after it has successfully completed. Right now, this is
1158
 * used for purely informational/debugging purposes.
1159
 */
1160
static void
1161
pathbias_count_collapse(origin_circuit_t *circ)
1162
0
{
1163
0
  entry_guard_t *guard = NULL;
1164
1165
0
  if (!pathbias_should_count(circ)) {
1166
0
    return;
1167
0
  }
1168
1169
0
  if (circ->cpath && circ->cpath->extend_info) {
1170
0
    guard = entry_guard_get_by_id_digest(
1171
0
              circ->cpath->extend_info->identity_digest);
1172
0
  }
1173
1174
0
  if (guard) {
1175
0
    guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1176
1177
0
    pb->collapsed_circuits++;
1178
0
    entry_guards_changed();
1179
0
  } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
1180
   /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
1181
    * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
1182
    * No need to log that case. */
1183
0
    log_info(LD_CIRC,
1184
0
        "Destroyed circuit has no known guard. "
1185
0
        "Circuit is a %s currently %s",
1186
0
        circuit_purpose_to_string(circ->base_.purpose),
1187
0
        circuit_state_to_string(circ->base_.state));
1188
0
  }
1189
0
}
1190
1191
/**
1192
 * Count a known failed circuit (because we could not probe it).
1193
 *
1194
 * This counter is informational.
1195
 */
1196
static void
1197
pathbias_count_use_failed(origin_circuit_t *circ)
1198
0
{
1199
0
  entry_guard_t *guard = NULL;
1200
0
  if (!pathbias_should_count(circ)) {
1201
0
    return;
1202
0
  }
1203
1204
0
  if (circ->cpath && circ->cpath->extend_info) {
1205
0
    guard = entry_guard_get_by_id_digest(
1206
0
              circ->cpath->extend_info->identity_digest);
1207
0
  }
1208
1209
0
  if (guard) {
1210
0
    guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1211
1212
0
    pb->unusable_circuits++;
1213
0
    entry_guards_changed();
1214
0
  } else if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
1215
   /* In rare cases, CIRCUIT_PURPOSE_TESTING can get converted to
1216
    * CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT and have no guards here.
1217
    * No need to log that case. */
1218
    /* XXX note cut-and-paste code in this function compared to nearby
1219
     * functions. Would be nice to refactor. -RD */
1220
0
    log_info(LD_CIRC,
1221
0
        "Stream-failing circuit has no known guard. "
1222
0
        "Circuit is a %s currently %s",
1223
0
        circuit_purpose_to_string(circ->base_.purpose),
1224
0
        circuit_state_to_string(circ->base_.state));
1225
0
  }
1226
0
}
1227
1228
/**
1229
 * Count timeouts for path bias log messages.
1230
 *
1231
 * These counts are purely informational.
1232
 */
1233
void
1234
pathbias_count_timeout(origin_circuit_t *circ)
1235
0
{
1236
0
  entry_guard_t *guard = NULL;
1237
1238
0
  if (!pathbias_should_count(circ)) {
1239
0
    return;
1240
0
  }
1241
1242
  /* For hidden service circs, they can actually be used
1243
   * successfully and then time out later (because
1244
   * the other side declines to use them). */
1245
0
  if (circ->path_state == PATH_STATE_USE_SUCCEEDED) {
1246
0
    return;
1247
0
  }
1248
1249
0
  if (circ->cpath && circ->cpath->extend_info) {
1250
0
    guard = entry_guard_get_by_id_digest(
1251
0
              circ->cpath->extend_info->identity_digest);
1252
0
  }
1253
1254
0
  if (guard) {
1255
0
    guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1256
1257
0
    pb->timeouts++;
1258
0
    entry_guards_changed();
1259
0
  }
1260
0
}
1261
1262
/**
1263
 * Helper function to count all of the currently opened circuits
1264
 * for a guard that are in a given path state range. The state
1265
 * range is inclusive on both ends.
1266
 */
1267
static int
1268
pathbias_count_circs_in_states(entry_guard_t *guard,
1269
                              path_state_t from,
1270
                              path_state_t to)
1271
0
{
1272
0
  int open_circuits = 0;
1273
1274
  /* Count currently open circuits. Give them the benefit of the doubt. */
1275
0
  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
1276
0
    origin_circuit_t *ocirc = NULL;
1277
0
    if (!CIRCUIT_IS_ORIGIN(circ) || /* didn't originate here */
1278
0
        circ->marked_for_close) /* already counted */
1279
0
      continue;
1280
1281
0
    ocirc = TO_ORIGIN_CIRCUIT(circ);
1282
1283
0
    if (!ocirc->cpath || !ocirc->cpath->extend_info)
1284
0
      continue;
1285
1286
0
    if (ocirc->path_state >= from &&
1287
0
        ocirc->path_state <= to &&
1288
0
        pathbias_should_count(ocirc) &&
1289
0
        fast_memeq(entry_guard_get_rsa_id_digest(guard),
1290
0
                   ocirc->cpath->extend_info->identity_digest,
1291
0
                   DIGEST_LEN)) {
1292
0
      log_debug(LD_CIRC, "Found opened circuit %d in path_state %s",
1293
0
                ocirc->global_identifier,
1294
0
                pathbias_state_to_string(ocirc->path_state));
1295
0
      open_circuits++;
1296
0
    }
1297
0
  }
1298
0
  SMARTLIST_FOREACH_END(circ);
1299
1300
0
  return open_circuits;
1301
0
}
1302
1303
/**
1304
 * Return the number of circuits counted as successfully closed for
1305
 * this guard.
1306
 *
1307
 * Also add in the currently open circuits to give them the benefit
1308
 * of the doubt.
1309
 */
1310
double
1311
pathbias_get_close_success_count(entry_guard_t *guard)
1312
0
{
1313
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1314
1315
0
  return pb->successful_circuits_closed +
1316
0
         pathbias_count_circs_in_states(guard,
1317
0
                       PATH_STATE_BUILD_SUCCEEDED,
1318
0
                       PATH_STATE_USE_SUCCEEDED);
1319
0
}
1320
1321
/**
1322
 * Return the number of circuits counted as successfully used
1323
 * this guard.
1324
 *
1325
 * Also add in the currently open circuits that we are attempting
1326
 * to use to give them the benefit of the doubt.
1327
 */
1328
double
1329
pathbias_get_use_success_count(entry_guard_t *guard)
1330
0
{
1331
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1332
1333
0
  return pb->use_successes +
1334
0
         pathbias_count_circs_in_states(guard,
1335
0
                       PATH_STATE_USE_ATTEMPTED,
1336
0
                       PATH_STATE_USE_SUCCEEDED);
1337
0
}
1338
1339
/**
1340
 * Check the path bias use rate against our consensus parameter limits.
1341
 *
1342
 * Emits a log message if the use success rates are too low.
1343
 *
1344
 * If pathbias_get_dropguards() is set, we also disable the use of
1345
 * very failure prone guards.
1346
 */
1347
static void
1348
pathbias_measure_use_rate(entry_guard_t *guard)
1349
0
{
1350
0
  const or_options_t *options = get_options();
1351
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1352
1353
0
  if (pb->use_attempts > pathbias_get_min_use(options)) {
1354
    /* Note: We rely on the < comparison here to allow us to set a 0
1355
     * rate and disable the feature entirely. If refactoring, don't
1356
     * change to <= */
1357
0
    if (pathbias_get_use_success_count(guard)/pb->use_attempts
1358
0
        < pathbias_get_extreme_use_rate(options)) {
1359
      /* Dropping is currently disabled by default. */
1360
0
      if (pathbias_get_dropguards(options)) {
1361
0
        if (!pb->path_bias_disabled) {
1362
0
          log_warn(LD_CIRC,
1363
0
                 "Guard %s is failing to carry an extremely large "
1364
0
                 "amount of stream on its circuits. "
1365
0
                 "To avoid potential route manipulation attacks, Tor has "
1366
0
                 "disabled use of this guard. "
1367
0
                 "Use counts are %ld/%ld. Success counts are %ld/%ld. "
1368
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1369
0
                 "and %ld timed out. "
1370
0
                 "For reference, your timeout cutoff is %ld seconds.",
1371
0
                 entry_guard_describe(guard),
1372
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1373
0
                 tor_lround(pb->use_attempts),
1374
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1375
0
                 tor_lround(pb->circ_attempts),
1376
0
                 tor_lround(pb->circ_successes),
1377
0
                 tor_lround(pb->unusable_circuits),
1378
0
                 tor_lround(pb->collapsed_circuits),
1379
0
                 tor_lround(pb->timeouts),
1380
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1381
0
          pb->path_bias_disabled = 1;
1382
0
          return;
1383
0
        }
1384
0
      } else if (!pb->path_bias_use_extreme) {
1385
0
        pb->path_bias_use_extreme = 1;
1386
0
        log_warn(LD_CIRC,
1387
0
                 "Guard %s is failing to carry an extremely large "
1388
0
                 "amount of streams on its circuits. "
1389
0
                 "This could indicate a route manipulation attack, network "
1390
0
                 "overload, bad local network connectivity, or a bug. "
1391
0
                 "Use counts are %ld/%ld. Success counts are %ld/%ld. "
1392
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1393
0
                 "and %ld timed out. "
1394
0
                 "For reference, your timeout cutoff is %ld seconds.",
1395
0
                 entry_guard_describe(guard),
1396
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1397
0
                 tor_lround(pb->use_attempts),
1398
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1399
0
                 tor_lround(pb->circ_attempts),
1400
0
                 tor_lround(pb->circ_successes),
1401
0
                 tor_lround(pb->unusable_circuits),
1402
0
                 tor_lround(pb->collapsed_circuits),
1403
0
                 tor_lround(pb->timeouts),
1404
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1405
0
      }
1406
0
    } else if (pathbias_get_use_success_count(guard)/pb->use_attempts
1407
0
               < pathbias_get_notice_use_rate(options)) {
1408
0
      if (!pb->path_bias_use_noticed) {
1409
0
        pb->path_bias_use_noticed = 1;
1410
0
        log_notice(LD_CIRC,
1411
0
                 "Guard %s is failing to carry more streams on its "
1412
0
                 "circuits than usual. "
1413
0
                 "Most likely this means the Tor network is overloaded "
1414
0
                 "or your network connection is poor. "
1415
0
                 "Use counts are %ld/%ld. Success counts are %ld/%ld. "
1416
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1417
0
                 "and %ld timed out. "
1418
0
                 "For reference, your timeout cutoff is %ld seconds.",
1419
0
                 entry_guard_describe(guard),
1420
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1421
0
                 tor_lround(pb->use_attempts),
1422
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1423
0
                 tor_lround(pb->circ_attempts),
1424
0
                 tor_lround(pb->circ_successes),
1425
0
                 tor_lround(pb->unusable_circuits),
1426
0
                 tor_lround(pb->collapsed_circuits),
1427
0
                 tor_lround(pb->timeouts),
1428
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1429
0
      }
1430
0
    }
1431
0
  }
1432
0
}
1433
1434
/**
1435
 * Check the path bias circuit close status rates against our consensus
1436
 * parameter limits.
1437
 *
1438
 * Emits a log message if the use success rates are too low.
1439
 *
1440
 * If pathbias_get_dropguards() is set, we also disable the use of
1441
 * very failure prone guards.
1442
 *
1443
 * XXX: This function shares similar log messages and checks to
1444
 * pathbias_measure_use_rate(). It may be possible to combine them
1445
 * eventually, especially if we can ever remove the need for 3
1446
 * levels of closure warns (if the overall circuit failure rate
1447
 * goes down with ntor). One way to do so would be to multiply
1448
 * the build rate with the use rate to get an idea of the total
1449
 * fraction of the total network paths the user is able to use.
1450
 * See ticket #8159.
1451
 */
1452
static void
1453
pathbias_measure_close_rate(entry_guard_t *guard)
1454
0
{
1455
0
  const or_options_t *options = get_options();
1456
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1457
1458
0
  if (pb->circ_attempts > pathbias_get_min_circs(options)) {
1459
    /* Note: We rely on the < comparison here to allow us to set a 0
1460
     * rate and disable the feature entirely. If refactoring, don't
1461
     * change to <= */
1462
0
    if (pathbias_get_close_success_count(guard)/pb->circ_attempts
1463
0
        < pathbias_get_extreme_rate(options)) {
1464
      /* Dropping is currently disabled by default. */
1465
0
      if (pathbias_get_dropguards(options)) {
1466
0
        if (!pb->path_bias_disabled) {
1467
0
          log_warn(LD_CIRC,
1468
0
                 "Guard %s is failing an extremely large "
1469
0
                 "amount of circuits. "
1470
0
                 "To avoid potential route manipulation attacks, Tor has "
1471
0
                 "disabled use of this guard. "
1472
0
                 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1473
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1474
0
                 "and %ld timed out. "
1475
0
                 "For reference, your timeout cutoff is %ld seconds.",
1476
0
                 entry_guard_describe(guard),
1477
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1478
0
                 tor_lround(pb->circ_attempts),
1479
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1480
0
                 tor_lround(pb->use_attempts),
1481
0
                 tor_lround(pb->circ_successes),
1482
0
                 tor_lround(pb->unusable_circuits),
1483
0
                 tor_lround(pb->collapsed_circuits),
1484
0
                 tor_lround(pb->timeouts),
1485
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1486
0
          pb->path_bias_disabled = 1;
1487
0
          return;
1488
0
        }
1489
0
      } else if (!pb->path_bias_extreme) {
1490
0
        pb->path_bias_extreme = 1;
1491
0
        log_warn(LD_CIRC,
1492
0
                 "Guard %s is failing an extremely large "
1493
0
                 "amount of circuits. "
1494
0
                 "This could indicate a route manipulation attack, "
1495
0
                 "extreme network overload, or a bug. "
1496
0
                 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1497
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1498
0
                 "and %ld timed out. "
1499
0
                 "For reference, your timeout cutoff is %ld seconds.",
1500
0
                 entry_guard_describe(guard),
1501
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1502
0
                 tor_lround(pb->circ_attempts),
1503
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1504
0
                 tor_lround(pb->use_attempts),
1505
0
                 tor_lround(pb->circ_successes),
1506
0
                 tor_lround(pb->unusable_circuits),
1507
0
                 tor_lround(pb->collapsed_circuits),
1508
0
                 tor_lround(pb->timeouts),
1509
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1510
0
      }
1511
0
    } else if (pathbias_get_close_success_count(guard)/pb->circ_attempts
1512
0
                < pathbias_get_warn_rate(options)) {
1513
0
      if (!pb->path_bias_warned) {
1514
0
        pb->path_bias_warned = 1;
1515
0
        log_warn(LD_CIRC,
1516
0
                 "Guard %s is failing a very large "
1517
0
                 "amount of circuits. "
1518
0
                 "Most likely this means the Tor network is "
1519
0
                 "overloaded, but it could also mean an attack against "
1520
0
                 "you or potentially the guard itself. "
1521
0
                 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1522
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1523
0
                 "and %ld timed out. "
1524
0
                 "For reference, your timeout cutoff is %ld seconds.",
1525
0
                 entry_guard_describe(guard),
1526
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1527
0
                 tor_lround(pb->circ_attempts),
1528
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1529
0
                 tor_lround(pb->use_attempts),
1530
0
                 tor_lround(pb->circ_successes),
1531
0
                 tor_lround(pb->unusable_circuits),
1532
0
                 tor_lround(pb->collapsed_circuits),
1533
0
                 tor_lround(pb->timeouts),
1534
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1535
0
      }
1536
0
    } else if (pathbias_get_close_success_count(guard)/pb->circ_attempts
1537
0
               < pathbias_get_notice_rate(options)) {
1538
0
      if (!pb->path_bias_noticed) {
1539
0
        pb->path_bias_noticed = 1;
1540
0
        log_notice(LD_CIRC,
1541
0
                 "Guard %s is failing more circuits than "
1542
0
                 "usual. "
1543
0
                 "Most likely this means the Tor network is overloaded. "
1544
0
                 "Success counts are %ld/%ld. Use counts are %ld/%ld. "
1545
0
                 "%ld circuits completed, %ld were unusable, %ld collapsed, "
1546
0
                 "and %ld timed out. "
1547
0
                 "For reference, your timeout cutoff is %ld seconds.",
1548
0
                 entry_guard_describe(guard),
1549
0
                 tor_lround(pathbias_get_close_success_count(guard)),
1550
0
                 tor_lround(pb->circ_attempts),
1551
0
                 tor_lround(pathbias_get_use_success_count(guard)),
1552
0
                 tor_lround(pb->use_attempts),
1553
0
                 tor_lround(pb->circ_successes),
1554
0
                 tor_lround(pb->unusable_circuits),
1555
0
                 tor_lround(pb->collapsed_circuits),
1556
0
                 tor_lround(pb->timeouts),
1557
0
                 tor_lround(get_circuit_build_close_time_ms()/1000));
1558
0
      }
1559
0
    }
1560
0
  }
1561
0
}
1562
1563
/**
1564
 * This function scales the path bias use rates if we have
1565
 * more data than the scaling threshold. This allows us to
1566
 * be more sensitive to recent measurements.
1567
 *
1568
 * XXX: The attempt count transfer stuff here might be done
1569
 * better by keeping separate pending counters that get
1570
 * transferred at circuit close. See ticket #8160.
1571
 */
1572
static void
1573
pathbias_scale_close_rates(entry_guard_t *guard)
1574
0
{
1575
0
  const or_options_t *options = get_options();
1576
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1577
1578
  /* If we get a ton of circuits, just scale everything down */
1579
0
  if (pb->circ_attempts > pathbias_get_scale_threshold(options)) {
1580
0
    double scale_ratio = pathbias_get_scale_ratio(options);
1581
0
    int opened_attempts = pathbias_count_circs_in_states(guard,
1582
0
            PATH_STATE_BUILD_ATTEMPTED, PATH_STATE_BUILD_ATTEMPTED);
1583
0
    int opened_built = pathbias_count_circs_in_states(guard,
1584
0
                        PATH_STATE_BUILD_SUCCEEDED,
1585
0
                        PATH_STATE_USE_FAILED);
1586
    /* Verify that the counts are sane before and after scaling */
1587
0
    int counts_are_sane = (pb->circ_attempts >= pb->circ_successes);
1588
1589
0
    pb->circ_attempts -= (opened_attempts+opened_built);
1590
0
    pb->circ_successes -= opened_built;
1591
1592
0
    pb->circ_attempts *= scale_ratio;
1593
0
    pb->circ_successes *= scale_ratio;
1594
0
    pb->timeouts *= scale_ratio;
1595
0
    pb->successful_circuits_closed *= scale_ratio;
1596
0
    pb->collapsed_circuits *= scale_ratio;
1597
0
    pb->unusable_circuits *= scale_ratio;
1598
1599
0
    pb->circ_attempts += (opened_attempts+opened_built);
1600
0
    pb->circ_successes += opened_built;
1601
1602
0
    entry_guards_changed();
1603
1604
0
    log_info(LD_CIRC,
1605
0
             "Scaled pathbias counts to (%f,%f)/%f (%d/%d open) for guard "
1606
0
             "%s",
1607
0
             pb->circ_successes, pb->successful_circuits_closed,
1608
0
             pb->circ_attempts, opened_built, opened_attempts,
1609
0
             entry_guard_describe(guard));
1610
1611
    /* Have the counts just become invalid by this scaling attempt? */
1612
0
    if (counts_are_sane && pb->circ_attempts < pb->circ_successes) {
1613
0
      log_notice(LD_BUG,
1614
0
               "Scaling has mangled pathbias counts to %f/%f (%d/%d open) "
1615
0
               "for guard %s",
1616
0
               pb->circ_successes, pb->circ_attempts, opened_built,
1617
0
               opened_attempts,
1618
0
               entry_guard_describe(guard));
1619
0
    }
1620
0
  }
1621
0
}
1622
1623
/**
1624
 * This function scales the path bias circuit close rates if we have
1625
 * more data than the scaling threshold. This allows us to be more
1626
 * sensitive to recent measurements.
1627
 *
1628
 * XXX: The attempt count transfer stuff here might be done
1629
 * better by keeping separate pending counters that get
1630
 * transferred at circuit close. See ticket #8160.
1631
 */
1632
void
1633
pathbias_scale_use_rates(entry_guard_t *guard)
1634
0
{
1635
0
  const or_options_t *options = get_options();
1636
0
  guard_pathbias_t *pb = entry_guard_get_pathbias_state(guard);
1637
1638
  /* If we get a ton of circuits, just scale everything down */
1639
0
  if (pb->use_attempts > pathbias_get_scale_use_threshold(options)) {
1640
0
    double scale_ratio = pathbias_get_scale_ratio(options);
1641
0
    int opened_attempts = pathbias_count_circs_in_states(guard,
1642
0
            PATH_STATE_USE_ATTEMPTED, PATH_STATE_USE_SUCCEEDED);
1643
    /* Verify that the counts are sane before and after scaling */
1644
0
    int counts_are_sane = (pb->use_attempts >= pb->use_successes);
1645
1646
0
    pb->use_attempts -= opened_attempts;
1647
1648
0
    pb->use_attempts *= scale_ratio;
1649
0
    pb->use_successes *= scale_ratio;
1650
1651
0
    pb->use_attempts += opened_attempts;
1652
1653
0
    log_info(LD_CIRC,
1654
0
           "Scaled pathbias use counts to %f/%f (%d open) for guard %s",
1655
0
           pb->use_successes, pb->use_attempts, opened_attempts,
1656
0
           entry_guard_describe(guard));
1657
1658
    /* Have the counts just become invalid by this scaling attempt? */
1659
0
    if (counts_are_sane && pb->use_attempts < pb->use_successes) {
1660
0
      log_notice(LD_BUG,
1661
0
               "Scaling has mangled pathbias usage counts to %f/%f "
1662
0
               "(%d open) for guard %s",
1663
0
               pb->circ_successes, pb->circ_attempts,
1664
0
               opened_attempts, entry_guard_describe(guard));
1665
0
    }
1666
1667
0
    entry_guards_changed();
1668
0
  }
1669
0
}