From 667ba776b1d91c8d1229319be88191008975d6eb Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 7 Nov 2016 09:38:49 -0500 Subject: [PATCH 1/5] Adjust download schedules per teor's #20534 recommendataions --- changes/bug20534 | 6 ++++-- src/or/config.c | 4 ++-- src/or/directory.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/changes/bug20534 b/changes/bug20534 index 1ffa1f32e..49db433a0 100644 --- a/changes/bug20534 +++ b/changes/bug20534 @@ -2,5 +2,7 @@ - Remove the maximum delay on exponential-backoff scheduling. Since we now allow an infinite number of failures (see ticket 20536), we must now allow the time to grow longer on each failure. - Fixes bug 20534; bugfix on 0.2.9.1-alpha. - + Fixes part of bug 20534; bugfix on 0.2.9.1-alpha. + - Use initial delays and decrements in download scheduling closer to + those from 0.2.8. Fixes another part of bug 20534; bugfix on + 0.2.9.1-alpha. diff --git a/src/or/config.c b/src/or/config.c index 08c576e3d..9ad5d63f8 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -501,7 +501,7 @@ static config_var_t option_vars_[] = { * When clients have authorities and fallbacks available, they use these * schedules: (we stagger the times to avoid thundering herds) */ V(ClientBootstrapConsensusAuthorityDownloadSchedule, CSV_INTERVAL, - "10, 11, 3600, 10800, 25200, 54000, 111600, 262800" /* 3 days + 1 hour */), + "6, 11, 3600, 10800, 25200, 54000, 111600, 262800" /* 3 days + 1 hour */), V(ClientBootstrapConsensusFallbackDownloadSchedule, CSV_INTERVAL, "0, 1, 4, 11, 3600, 10800, 25200, 54000, 111600, 262800"), /* When clients only have authorities available, they use this schedule: */ @@ -512,7 +512,7 @@ static config_var_t option_vars_[] = { * blackholed. Clients will try 3 directories simultaneously. * (Relays never use simultaneous connections.) */ V(ClientBootstrapConsensusMaxInProgressTries, UINT, "3"), - V(TestingBridgeDownloadSchedule, CSV_INTERVAL, "3600, 900, 900, 3600"), + V(TestingBridgeDownloadSchedule, CSV_INTERVAL, "1200, 900, 900, 3600"), V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "10 minutes"), V(TestingDirConnectionMaxStall, INTERVAL, "5 minutes"), V(TestingConsensusMaxDownloadTries, UINT, "8"), diff --git a/src/or/directory.c b/src/or/directory.c index 5fc15724c..02f14387a 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3798,7 +3798,7 @@ next_random_exponential_delay(int delay, int max_delay) int max_increment; if (delay) - max_increment = delay; /* no more than double. */ + max_increment = delay * 4; /* no more than quintuple. */ else max_increment = 1; /* we're always willing to slow down a little. */ From 864c42f4d66641028005f8d11868368260a37b84 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 7 Nov 2016 09:43:12 -0500 Subject: [PATCH 2/5] Count HTTP 503 as a download failure. Because as Teor puts it: "[Resetting on 503] is exactly what we don't want when relays are busy - imagine clients doing an automatic reset every time they DoS a relay..." Fixes bug 20593. --- changes/bug20593 | 6 ++++++ src/or/directory.c | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 changes/bug20593 diff --git a/changes/bug20593 b/changes/bug20593 new file mode 100644 index 000000000..e9f54d317 --- /dev/null +++ b/changes/bug20593 @@ -0,0 +1,6 @@ + o Minor bugfixes (client directory scheduling): + - Treat "relay too busy to answer request" as a failed request and a + reason to back off on our retry frequency. This is safe now that + exponential backups retry indefinitely, and avoids a bug where we would + reset our download schedule erroneously. + Fixes bug 20593; bugfix on 0.2.9.1-alpha. diff --git a/src/or/directory.c b/src/or/directory.c index 02f14387a..d1333a866 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3933,15 +3933,16 @@ time_t download_status_increment_failure(download_status_t *dls, int status_code, const char *item, int server, time_t now) { + (void) status_code; // XXXX no longer used. + (void) server; // XXXX no longer used. int increment = -1; int min_delay = 0, max_delay = INT_MAX; tor_assert(dls); - /* only count the failure if it's permanent, or we're a server */ - if (status_code != 503 || server) { - if (dls->n_download_failures < IMPOSSIBLE_TO_DOWNLOAD-1) - ++dls->n_download_failures; + /* count the failure */ + if (dls->n_download_failures < IMPOSSIBLE_TO_DOWNLOAD-1) { + ++dls->n_download_failures; } if (dls->increment_on == DL_SCHED_INCREMENT_FAILURE) { From 1fdf6e5814ae50ed93338644f97c65b497463141 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 7 Nov 2016 09:58:29 -0500 Subject: [PATCH 3/5] Avoid integer overflow in delay calculation. --- src/or/directory.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/or/directory.c b/src/or/directory.c index d1333a866..f83f62203 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3796,11 +3796,15 @@ next_random_exponential_delay(int delay, int max_delay) /* How much are we willing to add to the delay? */ int max_increment; + const int multiplier = 4; /* no more than quintuple. */ - if (delay) - max_increment = delay * 4; /* no more than quintuple. */ - else + if (delay && delay < (INT_MAX-1) / multiplier) { + max_increment = delay * multiplier; + } else if (delay) { + max_increment = INT_MAX-1; + } else { max_increment = 1; /* we're always willing to slow down a little. */ + } /* the + 1 here is so that we include the end of the interval */ int increment = crypto_rand_int(max_increment+1); From 85970f70475af7f8bd6666cbdebf5bfa3095625d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 7 Nov 2016 10:17:13 -0500 Subject: [PATCH 4/5] Always increment delays by at least 1. --- src/or/directory.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/or/directory.c b/src/or/directory.c index f83f62203..ee42e2cd9 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3803,11 +3803,14 @@ next_random_exponential_delay(int delay, int max_delay) } else if (delay) { max_increment = INT_MAX-1; } else { - max_increment = 1; /* we're always willing to slow down a little. */ + max_increment = 1; } - /* the + 1 here is so that we include the end of the interval */ - int increment = crypto_rand_int(max_increment+1); + if (BUG(max_increment < 1)) + max_increment = 1; + + /* the + 1 here is so that we always wait longer than last time. */ + int increment = crypto_rand_int(max_increment)+1; if (increment < max_delay - delay) return delay + increment; From e51f105c417aff1840126fddd11875fec84c86a9 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 7 Nov 2016 10:55:33 -0500 Subject: [PATCH 5/5] Reduce multiplier to 3, per teor's recommendation on #20534 (Three _is_ a good number for anonymity!) --- src/or/directory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/or/directory.c b/src/or/directory.c index ee42e2cd9..1f399818c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3796,7 +3796,7 @@ next_random_exponential_delay(int delay, int max_delay) /* How much are we willing to add to the delay? */ int max_increment; - const int multiplier = 4; /* no more than quintuple. */ + const int multiplier = 3; /* no more than quadruple the previous delay */ if (delay && delay < (INT_MAX-1) / multiplier) { max_increment = delay * multiplier;