aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/directory.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/src/or/directory.c b/src/or/directory.c
index 02016887ea..c1b5ae7519 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -3785,49 +3785,38 @@ find_dl_min_and_max_delay(download_status_t *dls, const or_options_t *options,
}
/** Advance one delay step. The algorithm is to use the previous delay to
- * compute an increment. Consuming one byte of entropy per step, we use 7
- * bits to construct an increment between 0 and (127/128)*delay by adding
- * right-shifted copies of delay, controlled by each bit. Then, to prevent
- * getting stuck at zero if we start from zero, we use one last bit to add
- * 1 with probability 50%. Finally, we add the increment to the original
- * delay, clamp the value <= max_delay, and return it.
+ * compute an increment, we construct a value uniformly at random between
+ * delay and MAX(delay*2,delay+1). We then clamp that value to be no larger
+ * than max_delay, and return it.
+ *
+ * Requires that delay is less than INT_MAX, and delay is in [0,max_delay].
*/
STATIC int
next_random_exponential_delay(int delay, int max_delay)
{
- int delay_increment, i;
- uint8_t entropy;
+ /* Check preconditions */
+ if (BUG(delay > max_delay))
+ delay = max_delay;
+ if (BUG(delay == INT_MAX))
+ delay -= 1; /* prevent overflow */
+ if (BUG(delay < 0))
+ delay = 0;
+
+ /* How much are we willing to add to the delay? */
+ int max_increment;
+
+ if (delay)
+ max_increment = delay; /* no more than double. */
+ else
+ max_increment = 1; /* we're always willing to slow down a little. */
- /*
- * Backoff step: we want to multiply by something ~1.5, and then add
- * 1 with non-zero probability so we can't get stuck at zero even if
- * we start out with zero delay. To do this, pick a uint8_t of
- * entropy in the range [0,255], and use it to construct an
- * increment.
- */
- delay_increment = 0;
- /* Get a byte of entropy */
- crypto_rand((char *)(&entropy), sizeof(entropy));
- /* Clamp it just to be sure */
- entropy &= 0xff;
- /* If we have non-zero delay; otherwise this is a no-op */
- if (delay > 0) {
- /* Use the low 7 bits for the increment */
- for (i = 0; i < 7; ++i) {
- if (entropy & (0x1 << i)) delay_increment += (delay >> (i + 1));
- }
- }
- /*
- * Using the remaining bit of entropy, add 1 with probability 50% so
- * we can't get stuck at 0
- */
- if (entropy & 0x80) delay_increment += 1;
- /* Increment delay, make sure to saturate if we would wrap around */
- if (delay_increment < max_delay - delay) delay += delay_increment;
- else delay = max_delay;
+ /* the + 1 here is so that we include the end of the interval */
+ int increment = crypto_rand_int(max_increment+1);
- /* Return the updated delay */
- return delay;
+ if (increment < max_delay - delay)
+ return delay + increment;
+ else
+ return max_delay;
}
/** Find the current delay for dls based on schedule or min_delay/