Merge branch 'maint-0.3.3' into release-0.3.3
This commit is contained in:
commit
ac93889ee8
|
@ -0,0 +1,4 @@
|
||||||
|
o Code simplification and refactoring:
|
||||||
|
- Remove the old (deterministic) directory retry logic entirely:
|
||||||
|
We've used exponential backoff exclusively for some time.
|
||||||
|
Closes ticket 23814.
|
|
@ -1757,14 +1757,6 @@ The following options are useful only for clients (that is, if
|
||||||
which are advanced by connection failures. (Default: 0, 3, 7, 3600,
|
which are advanced by connection failures. (Default: 0, 3, 7, 3600,
|
||||||
10800, 25200, 54000, 111600, 262800)
|
10800, 25200, 54000, 111600, 262800)
|
||||||
|
|
||||||
[[ClientBootstrapConsensusMaxDownloadTries]] **ClientBootstrapConsensusMaxDownloadTries** __NUM__::
|
|
||||||
Try this many times to download a consensus while bootstrapping using
|
|
||||||
fallback directory mirrors before giving up. (Default: 7)
|
|
||||||
|
|
||||||
[[ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries]] **ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries** __NUM__::
|
|
||||||
Try this many times to download a consensus while bootstrapping using
|
|
||||||
authorities before giving up. (Default: 4)
|
|
||||||
|
|
||||||
[[ClientBootstrapConsensusMaxInProgressTries]] **ClientBootstrapConsensusMaxInProgressTries** __NUM__::
|
[[ClientBootstrapConsensusMaxInProgressTries]] **ClientBootstrapConsensusMaxInProgressTries** __NUM__::
|
||||||
Try this many simultaneous connections to download a consensus before
|
Try this many simultaneous connections to download a consensus before
|
||||||
waiting for one to complete, timeout, or error out. (Default: 3)
|
waiting for one to complete, timeout, or error out. (Default: 3)
|
||||||
|
@ -2871,8 +2863,6 @@ The following options are used for running a testing Tor network.
|
||||||
4 (for 40 seconds), 8, 16, 32, 60
|
4 (for 40 seconds), 8, 16, 32, 60
|
||||||
ClientBootstrapConsensusAuthorityOnlyDownloadSchedule 0, 1,
|
ClientBootstrapConsensusAuthorityOnlyDownloadSchedule 0, 1,
|
||||||
4 (for 40 seconds), 8, 16, 32, 60
|
4 (for 40 seconds), 8, 16, 32, 60
|
||||||
ClientBootstrapConsensusMaxDownloadTries 80
|
|
||||||
ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries 80
|
|
||||||
ClientDNSRejectInternalAddresses 0
|
ClientDNSRejectInternalAddresses 0
|
||||||
ClientRejectInternalAddresses 0
|
ClientRejectInternalAddresses 0
|
||||||
CountPrivateBandwidth 1
|
CountPrivateBandwidth 1
|
||||||
|
@ -2895,10 +2885,6 @@ The following options are used for running a testing Tor network.
|
||||||
TestingBridgeBootstrapDownloadSchedule 0, 0, 5, 10, 15, 20, 30, 60
|
TestingBridgeBootstrapDownloadSchedule 0, 0, 5, 10, 15, 20, 30, 60
|
||||||
TestingClientMaxIntervalWithoutRequest 5 seconds
|
TestingClientMaxIntervalWithoutRequest 5 seconds
|
||||||
TestingDirConnectionMaxStall 30 seconds
|
TestingDirConnectionMaxStall 30 seconds
|
||||||
TestingConsensusMaxDownloadTries 80
|
|
||||||
TestingDescriptorMaxDownloadTries 80
|
|
||||||
TestingMicrodescMaxDownloadTries 80
|
|
||||||
TestingCertMaxDownloadTries 80
|
|
||||||
TestingEnableConnBwEvent 1
|
TestingEnableConnBwEvent 1
|
||||||
TestingEnableCellStatsEvent 1
|
TestingEnableCellStatsEvent 1
|
||||||
TestingEnableTbEmptyEvent 1
|
TestingEnableTbEmptyEvent 1
|
||||||
|
@ -2979,22 +2965,6 @@ The following options are used for running a testing Tor network.
|
||||||
Changing this requires that **TestingTorNetwork** is set. (Default:
|
Changing this requires that **TestingTorNetwork** is set. (Default:
|
||||||
5 minutes)
|
5 minutes)
|
||||||
|
|
||||||
[[TestingConsensusMaxDownloadTries]] **TestingConsensusMaxDownloadTries** __NUM__::
|
|
||||||
Try this many times to download a consensus before giving up. Changing
|
|
||||||
this requires that **TestingTorNetwork** is set. (Default: 8)
|
|
||||||
|
|
||||||
[[TestingDescriptorMaxDownloadTries]] **TestingDescriptorMaxDownloadTries** __NUM__::
|
|
||||||
Try this often to download a server descriptor before giving up.
|
|
||||||
Changing this requires that **TestingTorNetwork** is set. (Default: 8)
|
|
||||||
|
|
||||||
[[TestingMicrodescMaxDownloadTries]] **TestingMicrodescMaxDownloadTries** __NUM__::
|
|
||||||
Try this often to download a microdesc descriptor before giving up.
|
|
||||||
Changing this requires that **TestingTorNetwork** is set. (Default: 8)
|
|
||||||
|
|
||||||
[[TestingCertMaxDownloadTries]] **TestingCertMaxDownloadTries** __NUM__::
|
|
||||||
Try this often to download a v3 authority certificate before giving up.
|
|
||||||
Changing this requires that **TestingTorNetwork** is set. (Default: 8)
|
|
||||||
|
|
||||||
[[TestingDirAuthVoteExit]] **TestingDirAuthVoteExit** __node__,__node__,__...__::
|
[[TestingDirAuthVoteExit]] **TestingDirAuthVoteExit** __node__,__node__,__...__::
|
||||||
A list of identity fingerprints, country codes, and
|
A list of identity fingerprints, country codes, and
|
||||||
address patterns of nodes to vote Exit for regardless of their
|
address patterns of nodes to vote Exit for regardless of their
|
||||||
|
|
|
@ -458,7 +458,6 @@ bridge_add_from_config(bridge_line_t *bridge_line)
|
||||||
if (bridge_line->transport_name)
|
if (bridge_line->transport_name)
|
||||||
b->transport_name = bridge_line->transport_name;
|
b->transport_name = bridge_line->transport_name;
|
||||||
b->fetch_status.schedule = DL_SCHED_BRIDGE;
|
b->fetch_status.schedule = DL_SCHED_BRIDGE;
|
||||||
b->fetch_status.backoff = DL_SCHED_RANDOM_EXPONENTIAL;
|
|
||||||
b->fetch_status.increment_on = DL_SCHED_INCREMENT_ATTEMPT;
|
b->fetch_status.increment_on = DL_SCHED_INCREMENT_ATTEMPT;
|
||||||
/* We can't reset the bridge's download status here, because UseBridges
|
/* We can't reset the bridge's download status here, because UseBridges
|
||||||
* might be 0 now, and it might be changed to 1 much later. */
|
* might be 0 now, and it might be changed to 1 much later. */
|
||||||
|
@ -637,8 +636,7 @@ fetch_bridge_descriptors(const or_options_t *options, time_t now)
|
||||||
SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
|
SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
|
||||||
{
|
{
|
||||||
/* This resets the download status on first use */
|
/* This resets the download status on first use */
|
||||||
if (!download_status_is_ready(&bridge->fetch_status, now,
|
if (!download_status_is_ready(&bridge->fetch_status, now))
|
||||||
IMPOSSIBLE_TO_DOWNLOAD))
|
|
||||||
continue; /* don't bother, no need to retry yet */
|
continue; /* don't bother, no need to retry yet */
|
||||||
if (routerset_contains_bridge(options->ExcludeNodes, bridge)) {
|
if (routerset_contains_bridge(options->ExcludeNodes, bridge)) {
|
||||||
download_status_mark_impossible(&bridge->fetch_status);
|
download_status_mark_impossible(&bridge->fetch_status);
|
||||||
|
|
|
@ -645,15 +645,12 @@ static config_var_t option_vars_[] = {
|
||||||
"0, 30, 90, 600, 3600, 10800, 25200, 54000, 111600, 262800"),
|
"0, 30, 90, 600, 3600, 10800, 25200, 54000, 111600, 262800"),
|
||||||
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "10 minutes"),
|
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "10 minutes"),
|
||||||
V(TestingDirConnectionMaxStall, INTERVAL, "5 minutes"),
|
V(TestingDirConnectionMaxStall, INTERVAL, "5 minutes"),
|
||||||
V(TestingConsensusMaxDownloadTries, UINT, "8"),
|
OBSOLETE("TestingConsensusMaxDownloadTries"),
|
||||||
/* Since we try connections rapidly and simultaneously, we can afford
|
OBSOLETE("ClientBootstrapConsensusMaxDownloadTries"),
|
||||||
* to give up earlier. (This protects against overloading directories.) */
|
OBSOLETE("ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries"),
|
||||||
V(ClientBootstrapConsensusMaxDownloadTries, UINT, "7"),
|
OBSOLETE("TestingDescriptorMaxDownloadTries"),
|
||||||
/* We want to give up much earlier if we're only using authorities. */
|
OBSOLETE("TestingMicrodescMaxDownloadTries"),
|
||||||
V(ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries, UINT, "4"),
|
OBSOLETE("TestingCertMaxDownloadTries"),
|
||||||
V(TestingDescriptorMaxDownloadTries, UINT, "8"),
|
|
||||||
V(TestingMicrodescMaxDownloadTries, UINT, "8"),
|
|
||||||
V(TestingCertMaxDownloadTries, UINT, "8"),
|
|
||||||
V(TestingDirAuthVoteExit, ROUTERSET, NULL),
|
V(TestingDirAuthVoteExit, ROUTERSET, NULL),
|
||||||
V(TestingDirAuthVoteExitIsStrict, BOOL, "0"),
|
V(TestingDirAuthVoteExitIsStrict, BOOL, "0"),
|
||||||
V(TestingDirAuthVoteGuard, ROUTERSET, NULL),
|
V(TestingDirAuthVoteGuard, ROUTERSET, NULL),
|
||||||
|
@ -678,8 +675,6 @@ static const config_var_t testing_tor_network_defaults[] = {
|
||||||
"0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
|
"0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
|
||||||
V(ClientBootstrapConsensusAuthorityOnlyDownloadSchedule, CSV_INTERVAL,
|
V(ClientBootstrapConsensusAuthorityOnlyDownloadSchedule, CSV_INTERVAL,
|
||||||
"0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
|
"0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 16, 32, 60"),
|
||||||
V(ClientBootstrapConsensusMaxDownloadTries, UINT, "80"),
|
|
||||||
V(ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries, UINT, "80"),
|
|
||||||
V(ClientDNSRejectInternalAddresses, BOOL,"0"),
|
V(ClientDNSRejectInternalAddresses, BOOL,"0"),
|
||||||
V(ClientRejectInternalAddresses, BOOL, "0"),
|
V(ClientRejectInternalAddresses, BOOL, "0"),
|
||||||
V(CountPrivateBandwidth, BOOL, "1"),
|
V(CountPrivateBandwidth, BOOL, "1"),
|
||||||
|
@ -707,10 +702,6 @@ static const config_var_t testing_tor_network_defaults[] = {
|
||||||
"15, 20, 30, 60"),
|
"15, 20, 30, 60"),
|
||||||
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "5 seconds"),
|
V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "5 seconds"),
|
||||||
V(TestingDirConnectionMaxStall, INTERVAL, "30 seconds"),
|
V(TestingDirConnectionMaxStall, INTERVAL, "30 seconds"),
|
||||||
V(TestingConsensusMaxDownloadTries, UINT, "80"),
|
|
||||||
V(TestingDescriptorMaxDownloadTries, UINT, "80"),
|
|
||||||
V(TestingMicrodescMaxDownloadTries, UINT, "80"),
|
|
||||||
V(TestingCertMaxDownloadTries, UINT, "80"),
|
|
||||||
V(TestingEnableConnBwEvent, BOOL, "1"),
|
V(TestingEnableConnBwEvent, BOOL, "1"),
|
||||||
V(TestingEnableCellStatsEvent, BOOL, "1"),
|
V(TestingEnableCellStatsEvent, BOOL, "1"),
|
||||||
V(TestingEnableTbEmptyEvent, BOOL, "1"),
|
V(TestingEnableTbEmptyEvent, BOOL, "1"),
|
||||||
|
@ -4418,10 +4409,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||||
CHECK_DEFAULT(TestingBridgeBootstrapDownloadSchedule);
|
CHECK_DEFAULT(TestingBridgeBootstrapDownloadSchedule);
|
||||||
CHECK_DEFAULT(TestingClientMaxIntervalWithoutRequest);
|
CHECK_DEFAULT(TestingClientMaxIntervalWithoutRequest);
|
||||||
CHECK_DEFAULT(TestingDirConnectionMaxStall);
|
CHECK_DEFAULT(TestingDirConnectionMaxStall);
|
||||||
CHECK_DEFAULT(TestingConsensusMaxDownloadTries);
|
|
||||||
CHECK_DEFAULT(TestingDescriptorMaxDownloadTries);
|
|
||||||
CHECK_DEFAULT(TestingMicrodescMaxDownloadTries);
|
|
||||||
CHECK_DEFAULT(TestingCertMaxDownloadTries);
|
|
||||||
CHECK_DEFAULT(TestingAuthKeyLifetime);
|
CHECK_DEFAULT(TestingAuthKeyLifetime);
|
||||||
CHECK_DEFAULT(TestingLinkCertLifetime);
|
CHECK_DEFAULT(TestingLinkCertLifetime);
|
||||||
CHECK_DEFAULT(TestingSigningKeySlop);
|
CHECK_DEFAULT(TestingSigningKeySlop);
|
||||||
|
@ -4496,33 +4483,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||||
COMPLAIN("TestingDirConnectionMaxStall is insanely high.");
|
COMPLAIN("TestingDirConnectionMaxStall is insanely high.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->TestingConsensusMaxDownloadTries < 2) {
|
|
||||||
REJECT("TestingConsensusMaxDownloadTries must be greater than 2.");
|
|
||||||
} else if (options->TestingConsensusMaxDownloadTries > 800) {
|
|
||||||
COMPLAIN("TestingConsensusMaxDownloadTries is insanely high.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->ClientBootstrapConsensusMaxDownloadTries < 2) {
|
|
||||||
REJECT("ClientBootstrapConsensusMaxDownloadTries must be greater "
|
|
||||||
"than 2."
|
|
||||||
);
|
|
||||||
} else if (options->ClientBootstrapConsensusMaxDownloadTries > 800) {
|
|
||||||
COMPLAIN("ClientBootstrapConsensusMaxDownloadTries is insanely "
|
|
||||||
"high.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries
|
|
||||||
< 2) {
|
|
||||||
REJECT("ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries must "
|
|
||||||
"be greater than 2."
|
|
||||||
);
|
|
||||||
} else if (
|
|
||||||
options->ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries
|
|
||||||
> 800) {
|
|
||||||
COMPLAIN("ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries is "
|
|
||||||
"insanely high.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->ClientBootstrapConsensusMaxInProgressTries < 1) {
|
if (options->ClientBootstrapConsensusMaxInProgressTries < 1) {
|
||||||
REJECT("ClientBootstrapConsensusMaxInProgressTries must be greater "
|
REJECT("ClientBootstrapConsensusMaxInProgressTries must be greater "
|
||||||
"than 0.");
|
"than 0.");
|
||||||
|
@ -4532,24 +4492,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||||
"high.");
|
"high.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->TestingDescriptorMaxDownloadTries < 2) {
|
|
||||||
REJECT("TestingDescriptorMaxDownloadTries must be greater than 1.");
|
|
||||||
} else if (options->TestingDescriptorMaxDownloadTries > 800) {
|
|
||||||
COMPLAIN("TestingDescriptorMaxDownloadTries is insanely high.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->TestingMicrodescMaxDownloadTries < 2) {
|
|
||||||
REJECT("TestingMicrodescMaxDownloadTries must be greater than 1.");
|
|
||||||
} else if (options->TestingMicrodescMaxDownloadTries > 800) {
|
|
||||||
COMPLAIN("TestingMicrodescMaxDownloadTries is insanely high.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->TestingCertMaxDownloadTries < 2) {
|
|
||||||
REJECT("TestingCertMaxDownloadTries must be greater than 1.");
|
|
||||||
} else if (options->TestingCertMaxDownloadTries > 800) {
|
|
||||||
COMPLAIN("TestingCertMaxDownloadTries is insanely high.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->TestingEnableConnBwEvent &&
|
if (options->TestingEnableConnBwEvent &&
|
||||||
!options->TestingTorNetwork && !options->UsingTestNetworkDefaults_) {
|
!options->TestingTorNetwork && !options->UsingTestNetworkDefaults_) {
|
||||||
REJECT("TestingEnableConnBwEvent may only be changed in testing "
|
REJECT("TestingEnableConnBwEvent may only be changed in testing "
|
||||||
|
|
|
@ -2252,7 +2252,7 @@ digest_list_to_string(const smartlist_t *sl)
|
||||||
static char *
|
static char *
|
||||||
download_status_to_string(const download_status_t *dl)
|
download_status_to_string(const download_status_t *dl)
|
||||||
{
|
{
|
||||||
char *rv = NULL, *tmp;
|
char *rv = NULL;
|
||||||
char tbuf[ISO_TIME_LEN+1];
|
char tbuf[ISO_TIME_LEN+1];
|
||||||
const char *schedule_str, *want_authority_str;
|
const char *schedule_str, *want_authority_str;
|
||||||
const char *increment_on_str, *backoff_str;
|
const char *increment_on_str, *backoff_str;
|
||||||
|
@ -2300,49 +2300,28 @@ download_status_to_string(const download_status_t *dl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (dl->backoff) {
|
backoff_str = "DL_SCHED_RANDOM_EXPONENTIAL";
|
||||||
case DL_SCHED_DETERMINISTIC:
|
|
||||||
backoff_str = "DL_SCHED_DETERMINISTIC";
|
|
||||||
break;
|
|
||||||
case DL_SCHED_RANDOM_EXPONENTIAL:
|
|
||||||
backoff_str = "DL_SCHED_RANDOM_EXPONENTIAL";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
backoff_str = "unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now assemble them */
|
/* Now assemble them */
|
||||||
tor_asprintf(&tmp,
|
tor_asprintf(&rv,
|
||||||
"next-attempt-at %s\n"
|
"next-attempt-at %s\n"
|
||||||
"n-download-failures %u\n"
|
"n-download-failures %u\n"
|
||||||
"n-download-attempts %u\n"
|
"n-download-attempts %u\n"
|
||||||
"schedule %s\n"
|
"schedule %s\n"
|
||||||
"want-authority %s\n"
|
"want-authority %s\n"
|
||||||
"increment-on %s\n"
|
"increment-on %s\n"
|
||||||
"backoff %s\n",
|
"backoff %s\n"
|
||||||
|
"last-backoff-position %u\n"
|
||||||
|
"last-delay-used %d\n",
|
||||||
tbuf,
|
tbuf,
|
||||||
dl->n_download_failures,
|
dl->n_download_failures,
|
||||||
dl->n_download_attempts,
|
dl->n_download_attempts,
|
||||||
schedule_str,
|
schedule_str,
|
||||||
want_authority_str,
|
want_authority_str,
|
||||||
increment_on_str,
|
increment_on_str,
|
||||||
backoff_str);
|
backoff_str,
|
||||||
|
dl->last_backoff_position,
|
||||||
if (dl->backoff == DL_SCHED_RANDOM_EXPONENTIAL) {
|
dl->last_delay_used);
|
||||||
/* Additional fields become relevant in random-exponential mode */
|
|
||||||
tor_asprintf(&rv,
|
|
||||||
"%s"
|
|
||||||
"last-backoff-position %u\n"
|
|
||||||
"last-delay-used %d\n",
|
|
||||||
tmp,
|
|
||||||
dl->last_backoff_position,
|
|
||||||
dl->last_delay_used);
|
|
||||||
tor_free(tmp);
|
|
||||||
} else {
|
|
||||||
/* That was it */
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -5362,17 +5362,14 @@ find_dl_schedule(const download_status_t *dls, const or_options_t *options)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decide which minimum and maximum delay step we want to use based on
|
/** Decide which minimum delay step we want to use based on
|
||||||
* descriptor type in <b>dls</b> and <b>options</b>.
|
* descriptor type in <b>dls</b> and <b>options</b>.
|
||||||
* Helper function for download_status_schedule_get_delay(). */
|
* Helper function for download_status_schedule_get_delay(). */
|
||||||
STATIC void
|
STATIC int
|
||||||
find_dl_min_and_max_delay(download_status_t *dls, const or_options_t *options,
|
find_dl_min_delay(download_status_t *dls, const or_options_t *options)
|
||||||
int *min, int *max)
|
|
||||||
{
|
{
|
||||||
tor_assert(dls);
|
tor_assert(dls);
|
||||||
tor_assert(options);
|
tor_assert(options);
|
||||||
tor_assert(min);
|
|
||||||
tor_assert(max);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For now, just use the existing schedule config stuff and pick the
|
* For now, just use the existing schedule config stuff and pick the
|
||||||
|
@ -5380,13 +5377,7 @@ find_dl_min_and_max_delay(download_status_t *dls, const or_options_t *options,
|
||||||
*/
|
*/
|
||||||
const smartlist_t *schedule = find_dl_schedule(dls, options);
|
const smartlist_t *schedule = find_dl_schedule(dls, options);
|
||||||
tor_assert(schedule != NULL && smartlist_len(schedule) >= 2);
|
tor_assert(schedule != NULL && smartlist_len(schedule) >= 2);
|
||||||
*min = *((int *)(smartlist_get(schedule, 0)));
|
return *(int *)(smartlist_get(schedule, 0));
|
||||||
/* Increment on failure schedules always use exponential backoff, but they
|
|
||||||
* have a smaller limit when they're deterministic */
|
|
||||||
if (dls->backoff == DL_SCHED_DETERMINISTIC)
|
|
||||||
*max = *((int *)((smartlist_get(schedule, smartlist_len(schedule) - 1))));
|
|
||||||
else
|
|
||||||
*max = INT_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** As next_random_exponential_delay() below, but does not compute a random
|
/** As next_random_exponential_delay() below, but does not compute a random
|
||||||
|
@ -5424,55 +5415,39 @@ next_random_exponential_delay_range(int *low_bound_out,
|
||||||
* zero); the <b>backoff_position</b> parameter is the number of times we've
|
* zero); the <b>backoff_position</b> parameter is the number of times we've
|
||||||
* generated a delay; and the <b>delay</b> argument is the most recently used
|
* generated a delay; and the <b>delay</b> argument is the most recently used
|
||||||
* delay.
|
* delay.
|
||||||
*
|
|
||||||
* Requires that delay is less than INT_MAX, and delay is in [0,max_delay].
|
|
||||||
*/
|
*/
|
||||||
STATIC int
|
STATIC int
|
||||||
next_random_exponential_delay(int delay,
|
next_random_exponential_delay(int delay,
|
||||||
int base_delay,
|
int base_delay)
|
||||||
int max_delay)
|
|
||||||
{
|
{
|
||||||
/* Check preconditions */
|
/* Check preconditions */
|
||||||
if (BUG(max_delay < 0))
|
|
||||||
max_delay = 0;
|
|
||||||
if (BUG(delay > max_delay))
|
|
||||||
delay = max_delay;
|
|
||||||
if (BUG(delay < 0))
|
if (BUG(delay < 0))
|
||||||
delay = 0;
|
delay = 0;
|
||||||
|
|
||||||
if (base_delay < 1)
|
if (base_delay < 1)
|
||||||
base_delay = 1;
|
base_delay = 1;
|
||||||
|
|
||||||
int low_bound=0, high_bound=max_delay;
|
int low_bound=0, high_bound=INT_MAX;
|
||||||
|
|
||||||
next_random_exponential_delay_range(&low_bound, &high_bound,
|
next_random_exponential_delay_range(&low_bound, &high_bound,
|
||||||
delay, base_delay);
|
delay, base_delay);
|
||||||
|
|
||||||
int rand_delay = crypto_rand_int_range(low_bound, high_bound);
|
return crypto_rand_int_range(low_bound, high_bound);
|
||||||
|
|
||||||
return MIN(rand_delay, max_delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find the current delay for dls based on schedule or min_delay/
|
/** Find the current delay for dls based on min_delay.
|
||||||
* max_delay if we're using exponential backoff. If dls->backoff is
|
*
|
||||||
* DL_SCHED_RANDOM_EXPONENTIAL, we must have 0 <= min_delay <= max_delay <=
|
|
||||||
* INT_MAX, but schedule may be set to NULL; otherwise schedule is required.
|
|
||||||
* This function sets dls->next_attempt_at based on now, and returns the delay.
|
* This function sets dls->next_attempt_at based on now, and returns the delay.
|
||||||
* Helper for download_status_increment_failure and
|
* Helper for download_status_increment_failure and
|
||||||
* download_status_increment_attempt. */
|
* download_status_increment_attempt. */
|
||||||
STATIC int
|
STATIC int
|
||||||
download_status_schedule_get_delay(download_status_t *dls,
|
download_status_schedule_get_delay(download_status_t *dls,
|
||||||
const smartlist_t *schedule,
|
int min_delay,
|
||||||
int min_delay, int max_delay,
|
|
||||||
time_t now)
|
time_t now)
|
||||||
{
|
{
|
||||||
tor_assert(dls);
|
tor_assert(dls);
|
||||||
/* We don't need a schedule if we're using random exponential backoff */
|
|
||||||
tor_assert(dls->backoff == DL_SCHED_RANDOM_EXPONENTIAL ||
|
|
||||||
schedule != NULL);
|
|
||||||
/* If we're using random exponential backoff, we do need min/max delay */
|
/* If we're using random exponential backoff, we do need min/max delay */
|
||||||
tor_assert(dls->backoff != DL_SCHED_RANDOM_EXPONENTIAL ||
|
tor_assert(min_delay >= 0);
|
||||||
(min_delay >= 0 && max_delay >= min_delay));
|
|
||||||
|
|
||||||
int delay = INT_MAX;
|
int delay = INT_MAX;
|
||||||
uint8_t dls_schedule_position = (dls->increment_on
|
uint8_t dls_schedule_position = (dls->increment_on
|
||||||
|
@ -5480,43 +5455,33 @@ download_status_schedule_get_delay(download_status_t *dls,
|
||||||
? dls->n_download_attempts
|
? dls->n_download_attempts
|
||||||
: dls->n_download_failures);
|
: dls->n_download_failures);
|
||||||
|
|
||||||
if (dls->backoff == DL_SCHED_DETERMINISTIC) {
|
/* Check if we missed a reset somehow */
|
||||||
if (dls_schedule_position < smartlist_len(schedule))
|
IF_BUG_ONCE(dls->last_backoff_position > dls_schedule_position) {
|
||||||
delay = *(int *)smartlist_get(schedule, dls_schedule_position);
|
dls->last_backoff_position = 0;
|
||||||
else if (dls_schedule_position == IMPOSSIBLE_TO_DOWNLOAD)
|
dls->last_delay_used = 0;
|
||||||
delay = INT_MAX;
|
|
||||||
else
|
|
||||||
delay = *(int *)smartlist_get(schedule, smartlist_len(schedule) - 1);
|
|
||||||
} else if (dls->backoff == DL_SCHED_RANDOM_EXPONENTIAL) {
|
|
||||||
/* Check if we missed a reset somehow */
|
|
||||||
IF_BUG_ONCE(dls->last_backoff_position > dls_schedule_position) {
|
|
||||||
dls->last_backoff_position = 0;
|
|
||||||
dls->last_delay_used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dls_schedule_position > 0) {
|
|
||||||
delay = dls->last_delay_used;
|
|
||||||
|
|
||||||
while (dls->last_backoff_position < dls_schedule_position) {
|
|
||||||
/* Do one increment step */
|
|
||||||
delay = next_random_exponential_delay(delay, min_delay, max_delay);
|
|
||||||
/* Update our position */
|
|
||||||
++(dls->last_backoff_position);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* If we're just starting out, use the minimum delay */
|
|
||||||
delay = min_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clamp it within min/max if we have them */
|
|
||||||
if (min_delay >= 0 && delay < min_delay) delay = min_delay;
|
|
||||||
if (max_delay != INT_MAX && delay > max_delay) delay = max_delay;
|
|
||||||
|
|
||||||
/* Store it for next time */
|
|
||||||
dls->last_backoff_position = dls_schedule_position;
|
|
||||||
dls->last_delay_used = delay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dls_schedule_position > 0) {
|
||||||
|
delay = dls->last_delay_used;
|
||||||
|
|
||||||
|
while (dls->last_backoff_position < dls_schedule_position) {
|
||||||
|
/* Do one increment step */
|
||||||
|
delay = next_random_exponential_delay(delay, min_delay);
|
||||||
|
/* Update our position */
|
||||||
|
++(dls->last_backoff_position);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If we're just starting out, use the minimum delay */
|
||||||
|
delay = min_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clamp it within min/max if we have them */
|
||||||
|
if (min_delay >= 0 && delay < min_delay) delay = min_delay;
|
||||||
|
|
||||||
|
/* Store it for next time */
|
||||||
|
dls->last_backoff_position = dls_schedule_position;
|
||||||
|
dls->last_delay_used = delay;
|
||||||
|
|
||||||
/* A negative delay makes no sense. Knowing that delay is
|
/* A negative delay makes no sense. Knowing that delay is
|
||||||
* non-negative allows us to safely do the wrapping check below. */
|
* non-negative allows us to safely do the wrapping check below. */
|
||||||
tor_assert(delay >= 0);
|
tor_assert(delay >= 0);
|
||||||
|
@ -5578,7 +5543,7 @@ download_status_increment_failure(download_status_t *dls, int status_code,
|
||||||
(void) status_code; // XXXX no longer used.
|
(void) status_code; // XXXX no longer used.
|
||||||
(void) server; // XXXX no longer used.
|
(void) server; // XXXX no longer used.
|
||||||
int increment = -1;
|
int increment = -1;
|
||||||
int min_delay = 0, max_delay = INT_MAX;
|
int min_delay = 0;
|
||||||
|
|
||||||
tor_assert(dls);
|
tor_assert(dls);
|
||||||
|
|
||||||
|
@ -5603,10 +5568,8 @@ download_status_increment_failure(download_status_t *dls, int status_code,
|
||||||
|
|
||||||
/* only return a failure retry time if this schedule increments on failures
|
/* only return a failure retry time if this schedule increments on failures
|
||||||
*/
|
*/
|
||||||
const smartlist_t *schedule = find_dl_schedule(dls, get_options());
|
min_delay = find_dl_min_delay(dls, get_options());
|
||||||
find_dl_min_and_max_delay(dls, get_options(), &min_delay, &max_delay);
|
increment = download_status_schedule_get_delay(dls, min_delay, now);
|
||||||
increment = download_status_schedule_get_delay(dls, schedule,
|
|
||||||
min_delay, max_delay, now);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
download_status_log_helper(item, !dls->increment_on, "failed",
|
download_status_log_helper(item, !dls->increment_on, "failed",
|
||||||
|
@ -5637,7 +5600,7 @@ download_status_increment_attempt(download_status_t *dls, const char *item,
|
||||||
time_t now)
|
time_t now)
|
||||||
{
|
{
|
||||||
int delay = -1;
|
int delay = -1;
|
||||||
int min_delay = 0, max_delay = INT_MAX;
|
int min_delay = 0;
|
||||||
|
|
||||||
tor_assert(dls);
|
tor_assert(dls);
|
||||||
|
|
||||||
|
@ -5657,10 +5620,8 @@ download_status_increment_attempt(download_status_t *dls, const char *item,
|
||||||
if (dls->n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD-1)
|
if (dls->n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD-1)
|
||||||
++dls->n_download_attempts;
|
++dls->n_download_attempts;
|
||||||
|
|
||||||
const smartlist_t *schedule = find_dl_schedule(dls, get_options());
|
min_delay = find_dl_min_delay(dls, get_options());
|
||||||
find_dl_min_and_max_delay(dls, get_options(), &min_delay, &max_delay);
|
delay = download_status_schedule_get_delay(dls, min_delay, now);
|
||||||
delay = download_status_schedule_get_delay(dls, schedule,
|
|
||||||
min_delay, max_delay, now);
|
|
||||||
|
|
||||||
download_status_log_helper(item, dls->increment_on, "attempted",
|
download_status_log_helper(item, dls->increment_on, "attempted",
|
||||||
"on failure", dls->n_download_attempts,
|
"on failure", dls->n_download_attempts,
|
||||||
|
@ -5769,8 +5730,7 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
|
||||||
} else {
|
} else {
|
||||||
dls = router_get_dl_status_by_descriptor_digest(digest);
|
dls = router_get_dl_status_by_descriptor_digest(digest);
|
||||||
}
|
}
|
||||||
if (!dls || dls->n_download_failures >=
|
if (!dls)
|
||||||
get_options()->TestingDescriptorMaxDownloadTries)
|
|
||||||
continue;
|
continue;
|
||||||
download_status_increment_failure(dls, status_code, cp, server, now);
|
download_status_increment_failure(dls, status_code, cp, server, now);
|
||||||
} SMARTLIST_FOREACH_END(cp);
|
} SMARTLIST_FOREACH_END(cp);
|
||||||
|
@ -5807,10 +5767,6 @@ dir_microdesc_download_failed(smartlist_t *failed,
|
||||||
if (!rs)
|
if (!rs)
|
||||||
continue;
|
continue;
|
||||||
dls = &rs->dl_status;
|
dls = &rs->dl_status;
|
||||||
if (dls->n_download_failures >=
|
|
||||||
get_options()->TestingMicrodescMaxDownloadTries) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ /* Increment the failure count for this md fetch */
|
{ /* Increment the failure count for this md fetch */
|
||||||
char buf[BASE64_DIGEST256_LEN+1];
|
char buf[BASE64_DIGEST256_LEN+1];
|
||||||
|
|
|
@ -132,29 +132,19 @@ time_t download_status_increment_attempt(download_status_t *dls,
|
||||||
time(NULL))
|
time(NULL))
|
||||||
|
|
||||||
void download_status_reset(download_status_t *dls);
|
void download_status_reset(download_status_t *dls);
|
||||||
static int download_status_is_ready(download_status_t *dls, time_t now,
|
static int download_status_is_ready(download_status_t *dls, time_t now);
|
||||||
int max_failures);
|
|
||||||
time_t download_status_get_next_attempt_at(const download_status_t *dls);
|
time_t download_status_get_next_attempt_at(const download_status_t *dls);
|
||||||
|
|
||||||
/** Return true iff, as of <b>now</b>, the resource tracked by <b>dls</b> is
|
/** Return true iff, as of <b>now</b>, the resource tracked by <b>dls</b> is
|
||||||
* ready to get its download reattempted. */
|
* ready to get its download reattempted. */
|
||||||
static inline int
|
static inline int
|
||||||
download_status_is_ready(download_status_t *dls, time_t now,
|
download_status_is_ready(download_status_t *dls, time_t now)
|
||||||
int max_failures)
|
|
||||||
{
|
{
|
||||||
/* dls wasn't reset before it was used */
|
/* dls wasn't reset before it was used */
|
||||||
if (dls->next_attempt_at == 0) {
|
if (dls->next_attempt_at == 0) {
|
||||||
download_status_reset(dls);
|
download_status_reset(dls);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dls->backoff == DL_SCHED_DETERMINISTIC) {
|
|
||||||
/* Deterministic schedules can hit an endpoint; exponential backoff
|
|
||||||
* schedules just wait longer and longer. */
|
|
||||||
int under_failure_limit = (dls->n_download_failures <= max_failures
|
|
||||||
&& dls->n_download_attempts <= max_failures);
|
|
||||||
if (!under_failure_limit)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return download_status_get_next_attempt_at(dls) <= now;
|
return download_status_get_next_attempt_at(dls) <= now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,8 +250,7 @@ MOCK_DECL(STATIC int, directory_handle_command_post,(dir_connection_t *conn,
|
||||||
const char *body,
|
const char *body,
|
||||||
size_t body_len));
|
size_t body_len));
|
||||||
STATIC int download_status_schedule_get_delay(download_status_t *dls,
|
STATIC int download_status_schedule_get_delay(download_status_t *dls,
|
||||||
const smartlist_t *schedule,
|
int min_delay,
|
||||||
int min_delay, int max_delay,
|
|
||||||
time_t now);
|
time_t now);
|
||||||
|
|
||||||
STATIC int handle_post_hs_descriptor(const char *url, const char *body);
|
STATIC int handle_post_hs_descriptor(const char *url, const char *body);
|
||||||
|
@ -272,13 +261,11 @@ STATIC int should_use_directory_guards(const or_options_t *options);
|
||||||
STATIC compression_level_t choose_compression_level(ssize_t n_bytes);
|
STATIC compression_level_t choose_compression_level(ssize_t n_bytes);
|
||||||
STATIC const smartlist_t *find_dl_schedule(const download_status_t *dls,
|
STATIC const smartlist_t *find_dl_schedule(const download_status_t *dls,
|
||||||
const or_options_t *options);
|
const or_options_t *options);
|
||||||
STATIC void find_dl_min_and_max_delay(download_status_t *dls,
|
STATIC int find_dl_min_delay(download_status_t *dls,
|
||||||
const or_options_t *options,
|
const or_options_t *options);
|
||||||
int *min, int *max);
|
|
||||||
|
|
||||||
STATIC int next_random_exponential_delay(int delay,
|
STATIC int next_random_exponential_delay(int delay,
|
||||||
int base_delay,
|
int base_delay);
|
||||||
int max_delay);
|
|
||||||
|
|
||||||
STATIC void next_random_exponential_delay_range(int *low_bound_out,
|
STATIC void next_random_exponential_delay_range(int *low_bound_out,
|
||||||
int *high_bound_out,
|
int *high_bound_out,
|
||||||
|
|
|
@ -920,8 +920,7 @@ microdesc_list_missing_digest256(networkstatus_t *ns, microdesc_cache_t *cache,
|
||||||
if (microdesc_cache_lookup_by_digest256(cache, rs->descriptor_digest))
|
if (microdesc_cache_lookup_by_digest256(cache, rs->descriptor_digest))
|
||||||
continue;
|
continue;
|
||||||
if (downloadable_only &&
|
if (downloadable_only &&
|
||||||
!download_status_is_ready(&rs->dl_status, now,
|
!download_status_is_ready(&rs->dl_status, now))
|
||||||
get_options()->TestingMicrodescMaxDownloadTries))
|
|
||||||
continue;
|
continue;
|
||||||
if (skip && digest256map_get(skip, (const uint8_t*)rs->descriptor_digest))
|
if (skip && digest256map_get(skip, (const uint8_t*)rs->descriptor_digest))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -107,9 +107,9 @@ static time_t time_to_download_next_consensus[N_CONSENSUS_FLAVORS];
|
||||||
static download_status_t consensus_dl_status[N_CONSENSUS_FLAVORS] =
|
static download_status_t consensus_dl_status[N_CONSENSUS_FLAVORS] =
|
||||||
{
|
{
|
||||||
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 },
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 },
|
||||||
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 },
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define N_CONSENSUS_BOOTSTRAP_SCHEDULES 2
|
#define N_CONSENSUS_BOOTSTRAP_SCHEDULES 2
|
||||||
|
@ -126,10 +126,10 @@ static download_status_t
|
||||||
consensus_bootstrap_dl_status[N_CONSENSUS_BOOTSTRAP_SCHEDULES] =
|
consensus_bootstrap_dl_status[N_CONSENSUS_BOOTSTRAP_SCHEDULES] =
|
||||||
{
|
{
|
||||||
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
|
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
|
||||||
DL_SCHED_INCREMENT_ATTEMPT, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 },
|
DL_SCHED_INCREMENT_ATTEMPT, 0, 0 },
|
||||||
/* During bootstrap, DL_WANT_ANY_DIRSERVER means "use fallbacks". */
|
/* During bootstrap, DL_WANT_ANY_DIRSERVER means "use fallbacks". */
|
||||||
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_ATTEMPT, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 },
|
DL_SCHED_INCREMENT_ATTEMPT, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/** True iff we have logged a warning about this OR's version being older than
|
/** True iff we have logged a warning about this OR's version being older than
|
||||||
|
@ -943,14 +943,11 @@ update_consensus_networkstatus_downloads(time_t now)
|
||||||
update_consensus_bootstrap_multiple_downloads(now, options);
|
update_consensus_bootstrap_multiple_downloads(now, options);
|
||||||
} else {
|
} else {
|
||||||
/* Check if we failed downloading a consensus too recently */
|
/* Check if we failed downloading a consensus too recently */
|
||||||
int max_dl_tries = options->TestingConsensusMaxDownloadTries;
|
|
||||||
|
|
||||||
/* Let's make sure we remembered to update consensus_dl_status */
|
/* Let's make sure we remembered to update consensus_dl_status */
|
||||||
tor_assert(consensus_dl_status[i].schedule == DL_SCHED_CONSENSUS);
|
tor_assert(consensus_dl_status[i].schedule == DL_SCHED_CONSENSUS);
|
||||||
|
|
||||||
if (!download_status_is_ready(&consensus_dl_status[i],
|
if (!download_status_is_ready(&consensus_dl_status[i], now)) {
|
||||||
now,
|
|
||||||
max_dl_tries)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,17 +974,9 @@ update_consensus_networkstatus_downloads(time_t now)
|
||||||
static void
|
static void
|
||||||
update_consensus_bootstrap_attempt_downloads(
|
update_consensus_bootstrap_attempt_downloads(
|
||||||
time_t now,
|
time_t now,
|
||||||
const or_options_t *options,
|
|
||||||
download_status_t *dls,
|
download_status_t *dls,
|
||||||
download_want_authority_t want_authority)
|
download_want_authority_t want_authority)
|
||||||
{
|
{
|
||||||
int use_fallbacks = networkstatus_consensus_can_use_extra_fallbacks(options);
|
|
||||||
int max_dl_tries = options->ClientBootstrapConsensusMaxDownloadTries;
|
|
||||||
if (!use_fallbacks) {
|
|
||||||
max_dl_tries =
|
|
||||||
options->ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *resource = networkstatus_get_flavor_name(
|
const char *resource = networkstatus_get_flavor_name(
|
||||||
usable_consensus_flavor());
|
usable_consensus_flavor());
|
||||||
|
|
||||||
|
@ -996,7 +985,7 @@ update_consensus_bootstrap_attempt_downloads(
|
||||||
|
|
||||||
/* Allow for multiple connections in the same second, if the schedule value
|
/* Allow for multiple connections in the same second, if the schedule value
|
||||||
* is 0. */
|
* is 0. */
|
||||||
while (download_status_is_ready(dls, now, max_dl_tries)) {
|
while (download_status_is_ready(dls, now)) {
|
||||||
log_info(LD_DIR, "Launching %s bootstrap %s networkstatus consensus "
|
log_info(LD_DIR, "Launching %s bootstrap %s networkstatus consensus "
|
||||||
"download.", resource, (want_authority == DL_WANT_AUTHORITY
|
"download.", resource, (want_authority == DL_WANT_AUTHORITY
|
||||||
? "authority"
|
? "authority"
|
||||||
|
@ -1047,7 +1036,7 @@ update_consensus_bootstrap_multiple_downloads(time_t now,
|
||||||
|
|
||||||
if (!check_consensus_waiting_for_certs(usable_flavor, now, dls_f)) {
|
if (!check_consensus_waiting_for_certs(usable_flavor, now, dls_f)) {
|
||||||
/* During bootstrap, DL_WANT_ANY_DIRSERVER means "use fallbacks". */
|
/* During bootstrap, DL_WANT_ANY_DIRSERVER means "use fallbacks". */
|
||||||
update_consensus_bootstrap_attempt_downloads(now, options, dls_f,
|
update_consensus_bootstrap_attempt_downloads(now, dls_f,
|
||||||
DL_WANT_ANY_DIRSERVER);
|
DL_WANT_ANY_DIRSERVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1046,7 @@ update_consensus_bootstrap_multiple_downloads(time_t now,
|
||||||
&consensus_bootstrap_dl_status[CONSENSUS_BOOTSTRAP_SOURCE_AUTHORITY];
|
&consensus_bootstrap_dl_status[CONSENSUS_BOOTSTRAP_SOURCE_AUTHORITY];
|
||||||
|
|
||||||
if (!check_consensus_waiting_for_certs(usable_flavor, now, dls_a)) {
|
if (!check_consensus_waiting_for_certs(usable_flavor, now, dls_a)) {
|
||||||
update_consensus_bootstrap_attempt_downloads(now, options, dls_a,
|
update_consensus_bootstrap_attempt_downloads(now, dls_a,
|
||||||
DL_WANT_AUTHORITY);
|
DL_WANT_AUTHORITY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
src/or/or.h
40
src/or/or.h
|
@ -2070,15 +2070,6 @@ typedef enum {
|
||||||
#define download_schedule_increment_bitfield_t \
|
#define download_schedule_increment_bitfield_t \
|
||||||
ENUM_BF(download_schedule_increment_t)
|
ENUM_BF(download_schedule_increment_t)
|
||||||
|
|
||||||
/** Enumeration: do we want to use the random exponential backoff
|
|
||||||
* mechanism? */
|
|
||||||
typedef enum {
|
|
||||||
DL_SCHED_DETERMINISTIC = 0,
|
|
||||||
DL_SCHED_RANDOM_EXPONENTIAL = 1,
|
|
||||||
} download_schedule_backoff_t;
|
|
||||||
#define download_schedule_backoff_bitfield_t \
|
|
||||||
ENUM_BF(download_schedule_backoff_t)
|
|
||||||
|
|
||||||
/** Information about our plans for retrying downloads for a downloadable
|
/** Information about our plans for retrying downloads for a downloadable
|
||||||
* directory object.
|
* directory object.
|
||||||
* Each type of downloadable directory object has a corresponding retry
|
* Each type of downloadable directory object has a corresponding retry
|
||||||
|
@ -2125,11 +2116,6 @@ typedef struct download_status_t {
|
||||||
download_schedule_increment_bitfield_t increment_on : 1; /**< does this
|
download_schedule_increment_bitfield_t increment_on : 1; /**< does this
|
||||||
* schedule increment on each attempt,
|
* schedule increment on each attempt,
|
||||||
* or after each failure? */
|
* or after each failure? */
|
||||||
download_schedule_backoff_bitfield_t backoff : 1; /**< do we use the
|
|
||||||
* deterministic schedule, or random
|
|
||||||
* exponential backoffs?
|
|
||||||
* Increment on failure schedules
|
|
||||||
* always use exponential backoff. */
|
|
||||||
uint8_t last_backoff_position; /**< number of attempts/failures, depending
|
uint8_t last_backoff_position; /**< number of attempts/failures, depending
|
||||||
* on increment_on, when we last recalculated
|
* on increment_on, when we last recalculated
|
||||||
* the delay. Only updated if backoff
|
* the delay. Only updated if backoff
|
||||||
|
@ -4425,37 +4411,11 @@ typedef struct {
|
||||||
* it? Only altered on testing networks. */
|
* it? Only altered on testing networks. */
|
||||||
int TestingDirConnectionMaxStall;
|
int TestingDirConnectionMaxStall;
|
||||||
|
|
||||||
/** How many times will we try to fetch a consensus before we give
|
|
||||||
* up? Only altered on testing networks. */
|
|
||||||
int TestingConsensusMaxDownloadTries;
|
|
||||||
|
|
||||||
/** How many times will a client try to fetch a consensus while
|
|
||||||
* bootstrapping using a list of fallback directories, before it gives up?
|
|
||||||
* Only altered on testing networks. */
|
|
||||||
int ClientBootstrapConsensusMaxDownloadTries;
|
|
||||||
|
|
||||||
/** How many times will a client try to fetch a consensus while
|
|
||||||
* bootstrapping using only a list of authorities, before it gives up?
|
|
||||||
* Only altered on testing networks. */
|
|
||||||
int ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries;
|
|
||||||
|
|
||||||
/** How many simultaneous in-progress connections will we make when trying
|
/** How many simultaneous in-progress connections will we make when trying
|
||||||
* to fetch a consensus before we wait for one to complete, timeout, or
|
* to fetch a consensus before we wait for one to complete, timeout, or
|
||||||
* error out? Only altered on testing networks. */
|
* error out? Only altered on testing networks. */
|
||||||
int ClientBootstrapConsensusMaxInProgressTries;
|
int ClientBootstrapConsensusMaxInProgressTries;
|
||||||
|
|
||||||
/** How many times will we try to download a router's descriptor before
|
|
||||||
* giving up? Only altered on testing networks. */
|
|
||||||
int TestingDescriptorMaxDownloadTries;
|
|
||||||
|
|
||||||
/** How many times will we try to download a microdescriptor before
|
|
||||||
* giving up? Only altered on testing networks. */
|
|
||||||
int TestingMicrodescMaxDownloadTries;
|
|
||||||
|
|
||||||
/** How many times will we try to fetch a certificate before giving
|
|
||||||
* up? Only altered on testing networks. */
|
|
||||||
int TestingCertMaxDownloadTries;
|
|
||||||
|
|
||||||
/** If true, we take part in a testing network. Change the defaults of a
|
/** If true, we take part in a testing network. Change the defaults of a
|
||||||
* couple of other configuration options and allow to change the values
|
* couple of other configuration options and allow to change the values
|
||||||
* of certain configuration options. */
|
* of certain configuration options. */
|
||||||
|
|
|
@ -177,7 +177,7 @@ static void download_status_reset_by_sk_in_cl(cert_list_t *cl,
|
||||||
const char *digest);
|
const char *digest);
|
||||||
static int download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
|
static int download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
|
||||||
const char *digest,
|
const char *digest,
|
||||||
time_t now, int max_failures);
|
time_t now);
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
|
@ -246,7 +246,6 @@ download_status_cert_init(download_status_t *dlstatus)
|
||||||
dlstatus->schedule = DL_SCHED_CONSENSUS;
|
dlstatus->schedule = DL_SCHED_CONSENSUS;
|
||||||
dlstatus->want_authority = DL_WANT_ANY_DIRSERVER;
|
dlstatus->want_authority = DL_WANT_ANY_DIRSERVER;
|
||||||
dlstatus->increment_on = DL_SCHED_INCREMENT_FAILURE;
|
dlstatus->increment_on = DL_SCHED_INCREMENT_FAILURE;
|
||||||
dlstatus->backoff = DL_SCHED_RANDOM_EXPONENTIAL;
|
|
||||||
dlstatus->last_backoff_position = 0;
|
dlstatus->last_backoff_position = 0;
|
||||||
dlstatus->last_delay_used = 0;
|
dlstatus->last_delay_used = 0;
|
||||||
|
|
||||||
|
@ -288,7 +287,7 @@ download_status_reset_by_sk_in_cl(cert_list_t *cl, const char *digest)
|
||||||
static int
|
static int
|
||||||
download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
|
download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
|
||||||
const char *digest,
|
const char *digest,
|
||||||
time_t now, int max_failures)
|
time_t now)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
download_status_t *dlstatus = NULL;
|
download_status_t *dlstatus = NULL;
|
||||||
|
@ -305,7 +304,7 @@ download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
|
||||||
/* Got one? */
|
/* Got one? */
|
||||||
if (dlstatus) {
|
if (dlstatus) {
|
||||||
/* Use download_status_is_ready() */
|
/* Use download_status_is_ready() */
|
||||||
rv = download_status_is_ready(dlstatus, now, max_failures);
|
rv = download_status_is_ready(dlstatus, now);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If we don't know anything about it, return 1, since we haven't
|
* If we don't know anything about it, return 1, since we haven't
|
||||||
|
@ -1068,8 +1067,7 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now,
|
||||||
}
|
}
|
||||||
} SMARTLIST_FOREACH_END(cert);
|
} SMARTLIST_FOREACH_END(cert);
|
||||||
if (!found &&
|
if (!found &&
|
||||||
download_status_is_ready(&(cl->dl_status_by_id), now,
|
download_status_is_ready(&(cl->dl_status_by_id), now) &&
|
||||||
options->TestingCertMaxDownloadTries) &&
|
|
||||||
!digestmap_get(pending_id, ds->v3_identity_digest)) {
|
!digestmap_get(pending_id, ds->v3_identity_digest)) {
|
||||||
log_info(LD_DIR,
|
log_info(LD_DIR,
|
||||||
"No current certificate known for authority %s "
|
"No current certificate known for authority %s "
|
||||||
|
@ -1132,8 +1130,7 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (download_status_is_ready_by_sk_in_cl(
|
if (download_status_is_ready_by_sk_in_cl(
|
||||||
cl, sig->signing_key_digest,
|
cl, sig->signing_key_digest, now) &&
|
||||||
now, options->TestingCertMaxDownloadTries) &&
|
|
||||||
!fp_pair_map_get_by_digests(pending_cert,
|
!fp_pair_map_get_by_digests(pending_cert,
|
||||||
voter->identity_digest,
|
voter->identity_digest,
|
||||||
sig->signing_key_digest)) {
|
sig->signing_key_digest)) {
|
||||||
|
@ -5167,8 +5164,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
|
||||||
++n_inprogress;
|
++n_inprogress;
|
||||||
continue; /* We have an in-progress download. */
|
continue; /* We have an in-progress download. */
|
||||||
}
|
}
|
||||||
if (!download_status_is_ready(&rs->dl_status, now,
|
if (!download_status_is_ready(&rs->dl_status, now)) {
|
||||||
options->TestingDescriptorMaxDownloadTries)) {
|
|
||||||
++n_delayed; /* Not ready for retry. */
|
++n_delayed; /* Not ready for retry. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -5344,8 +5340,7 @@ update_extrainfo_downloads(time_t now)
|
||||||
++n_have;
|
++n_have;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!download_status_is_ready(&sd->ei_dl_status, now,
|
if (!download_status_is_ready(&sd->ei_dl_status, now)) {
|
||||||
options->TestingDescriptorMaxDownloadTries)) {
|
|
||||||
++n_delay;
|
++n_delay;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3809,7 +3809,6 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
|
||||||
ns->consensus_method,
|
ns->consensus_method,
|
||||||
flav))) {
|
flav))) {
|
||||||
/* Use exponential-backoff scheduling when downloading microdescs */
|
/* Use exponential-backoff scheduling when downloading microdescs */
|
||||||
rs->dl_status.backoff = DL_SCHED_RANDOM_EXPONENTIAL;
|
|
||||||
smartlist_add(ns->routerstatus_list, rs);
|
smartlist_add(ns->routerstatus_list, rs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,7 +396,7 @@ test_add_onion_helper_clientauth(void *arg)
|
||||||
|
|
||||||
static const download_status_t dl_status_default =
|
static const download_status_t dl_status_default =
|
||||||
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
{ 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 };
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 };
|
||||||
static download_status_t ns_dl_status[N_CONSENSUS_FLAVORS];
|
static download_status_t ns_dl_status[N_CONSENSUS_FLAVORS];
|
||||||
static download_status_t ns_dl_status_bootstrap[N_CONSENSUS_FLAVORS];
|
static download_status_t ns_dl_status_bootstrap[N_CONSENSUS_FLAVORS];
|
||||||
static download_status_t ns_dl_status_running[N_CONSENSUS_FLAVORS];
|
static download_status_t ns_dl_status_running[N_CONSENSUS_FLAVORS];
|
||||||
|
@ -407,7 +407,7 @@ static download_status_t ns_dl_status_running[N_CONSENSUS_FLAVORS];
|
||||||
*/
|
*/
|
||||||
static const download_status_t dls_sample_1 =
|
static const download_status_t dls_sample_1 =
|
||||||
{ 1467163900, 0, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER,
|
{ 1467163900, 0, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_DETERMINISTIC, 0, 0 };
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 };
|
||||||
static const char * dls_sample_1_str =
|
static const char * dls_sample_1_str =
|
||||||
"next-attempt-at 2016-06-29 01:31:40\n"
|
"next-attempt-at 2016-06-29 01:31:40\n"
|
||||||
"n-download-failures 0\n"
|
"n-download-failures 0\n"
|
||||||
|
@ -415,10 +415,12 @@ static const char * dls_sample_1_str =
|
||||||
"schedule DL_SCHED_GENERIC\n"
|
"schedule DL_SCHED_GENERIC\n"
|
||||||
"want-authority DL_WANT_ANY_DIRSERVER\n"
|
"want-authority DL_WANT_ANY_DIRSERVER\n"
|
||||||
"increment-on DL_SCHED_INCREMENT_FAILURE\n"
|
"increment-on DL_SCHED_INCREMENT_FAILURE\n"
|
||||||
"backoff DL_SCHED_DETERMINISTIC\n";
|
"backoff DL_SCHED_RANDOM_EXPONENTIAL\n"
|
||||||
|
"last-backoff-position 0\n"
|
||||||
|
"last-delay-used 0\n";
|
||||||
static const download_status_t dls_sample_2 =
|
static const download_status_t dls_sample_2 =
|
||||||
{ 1467164400, 1, 2, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
|
{ 1467164400, 1, 2, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_DETERMINISTIC, 0, 0 };
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 };
|
||||||
static const char * dls_sample_2_str =
|
static const char * dls_sample_2_str =
|
||||||
"next-attempt-at 2016-06-29 01:40:00\n"
|
"next-attempt-at 2016-06-29 01:40:00\n"
|
||||||
"n-download-failures 1\n"
|
"n-download-failures 1\n"
|
||||||
|
@ -426,10 +428,12 @@ static const char * dls_sample_2_str =
|
||||||
"schedule DL_SCHED_CONSENSUS\n"
|
"schedule DL_SCHED_CONSENSUS\n"
|
||||||
"want-authority DL_WANT_AUTHORITY\n"
|
"want-authority DL_WANT_AUTHORITY\n"
|
||||||
"increment-on DL_SCHED_INCREMENT_FAILURE\n"
|
"increment-on DL_SCHED_INCREMENT_FAILURE\n"
|
||||||
"backoff DL_SCHED_DETERMINISTIC\n";
|
"backoff DL_SCHED_RANDOM_EXPONENTIAL\n"
|
||||||
|
"last-backoff-position 0\n"
|
||||||
|
"last-delay-used 0\n";
|
||||||
static const download_status_t dls_sample_3 =
|
static const download_status_t dls_sample_3 =
|
||||||
{ 1467154400, 12, 25, DL_SCHED_BRIDGE, DL_WANT_ANY_DIRSERVER,
|
{ 1467154400, 12, 25, DL_SCHED_BRIDGE, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_ATTEMPT, DL_SCHED_DETERMINISTIC, 0, 0 };
|
DL_SCHED_INCREMENT_ATTEMPT, 0, 0 };
|
||||||
static const char * dls_sample_3_str =
|
static const char * dls_sample_3_str =
|
||||||
"next-attempt-at 2016-06-28 22:53:20\n"
|
"next-attempt-at 2016-06-28 22:53:20\n"
|
||||||
"n-download-failures 12\n"
|
"n-download-failures 12\n"
|
||||||
|
@ -437,10 +441,12 @@ static const char * dls_sample_3_str =
|
||||||
"schedule DL_SCHED_BRIDGE\n"
|
"schedule DL_SCHED_BRIDGE\n"
|
||||||
"want-authority DL_WANT_ANY_DIRSERVER\n"
|
"want-authority DL_WANT_ANY_DIRSERVER\n"
|
||||||
"increment-on DL_SCHED_INCREMENT_ATTEMPT\n"
|
"increment-on DL_SCHED_INCREMENT_ATTEMPT\n"
|
||||||
"backoff DL_SCHED_DETERMINISTIC\n";
|
"backoff DL_SCHED_RANDOM_EXPONENTIAL\n"
|
||||||
|
"last-backoff-position 0\n"
|
||||||
|
"last-delay-used 0\n";
|
||||||
static const download_status_t dls_sample_4 =
|
static const download_status_t dls_sample_4 =
|
||||||
{ 1467166600, 3, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER,
|
{ 1467166600, 3, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 };
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 };
|
||||||
static const char * dls_sample_4_str =
|
static const char * dls_sample_4_str =
|
||||||
"next-attempt-at 2016-06-29 02:16:40\n"
|
"next-attempt-at 2016-06-29 02:16:40\n"
|
||||||
"n-download-failures 3\n"
|
"n-download-failures 3\n"
|
||||||
|
@ -453,7 +459,7 @@ static const char * dls_sample_4_str =
|
||||||
"last-delay-used 0\n";
|
"last-delay-used 0\n";
|
||||||
static const download_status_t dls_sample_5 =
|
static const download_status_t dls_sample_5 =
|
||||||
{ 1467164600, 3, 7, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
{ 1467164600, 3, 7, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 1, 2112, };
|
DL_SCHED_INCREMENT_FAILURE, 1, 2112, };
|
||||||
static const char * dls_sample_5_str =
|
static const char * dls_sample_5_str =
|
||||||
"next-attempt-at 2016-06-29 01:43:20\n"
|
"next-attempt-at 2016-06-29 01:43:20\n"
|
||||||
"n-download-failures 3\n"
|
"n-download-failures 3\n"
|
||||||
|
@ -466,7 +472,7 @@ static const char * dls_sample_5_str =
|
||||||
"last-delay-used 2112\n";
|
"last-delay-used 2112\n";
|
||||||
static const download_status_t dls_sample_6 =
|
static const download_status_t dls_sample_6 =
|
||||||
{ 1467164200, 4, 9, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
|
{ 1467164200, 4, 9, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
|
||||||
DL_SCHED_INCREMENT_ATTEMPT, DL_SCHED_RANDOM_EXPONENTIAL, 3, 432 };
|
DL_SCHED_INCREMENT_ATTEMPT, 3, 432 };
|
||||||
static const char * dls_sample_6_str =
|
static const char * dls_sample_6_str =
|
||||||
"next-attempt-at 2016-06-29 01:36:40\n"
|
"next-attempt-at 2016-06-29 01:36:40\n"
|
||||||
"n-download-failures 4\n"
|
"n-download-failures 4\n"
|
||||||
|
|
|
@ -3965,164 +3965,11 @@ test_dir_packages(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dir_download_status_schedule(void *arg)
|
download_status_random_backoff_helper(int min_delay)
|
||||||
{
|
|
||||||
(void)arg;
|
|
||||||
download_status_t dls_failure = { 0, 0, 0, DL_SCHED_GENERIC,
|
|
||||||
DL_WANT_AUTHORITY,
|
|
||||||
DL_SCHED_INCREMENT_FAILURE,
|
|
||||||
DL_SCHED_DETERMINISTIC, 0, 0 };
|
|
||||||
download_status_t dls_attempt = { 0, 0, 0, DL_SCHED_CONSENSUS,
|
|
||||||
DL_WANT_ANY_DIRSERVER,
|
|
||||||
DL_SCHED_INCREMENT_ATTEMPT,
|
|
||||||
DL_SCHED_DETERMINISTIC, 0, 0 };
|
|
||||||
download_status_t dls_bridge = { 0, 0, 0, DL_SCHED_BRIDGE,
|
|
||||||
DL_WANT_AUTHORITY,
|
|
||||||
DL_SCHED_INCREMENT_FAILURE,
|
|
||||||
DL_SCHED_DETERMINISTIC, 0, 0 };
|
|
||||||
int increment = -1;
|
|
||||||
int expected_increment = -1;
|
|
||||||
time_t current_time = time(NULL);
|
|
||||||
int delay1 = -1;
|
|
||||||
int delay2 = -1;
|
|
||||||
smartlist_t *schedule = smartlist_new();
|
|
||||||
|
|
||||||
/* Make a dummy schedule */
|
|
||||||
smartlist_add(schedule, (void *)&delay1);
|
|
||||||
smartlist_add(schedule, (void *)&delay2);
|
|
||||||
|
|
||||||
/* check a range of values */
|
|
||||||
delay1 = 1000;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_failure,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
TIME_MIN);
|
|
||||||
expected_increment = delay1;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_failure.next_attempt_at == TIME_MIN + expected_increment);
|
|
||||||
|
|
||||||
delay1 = INT_MAX;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_failure,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
-1);
|
|
||||||
expected_increment = delay1;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_failure.next_attempt_at == TIME_MAX);
|
|
||||||
|
|
||||||
delay1 = 0;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_attempt,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
0);
|
|
||||||
expected_increment = delay1;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_attempt.next_attempt_at == 0 + expected_increment);
|
|
||||||
|
|
||||||
delay1 = 1000;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_attempt,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
1);
|
|
||||||
expected_increment = delay1;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_attempt.next_attempt_at == 1 + expected_increment);
|
|
||||||
|
|
||||||
delay1 = INT_MAX;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_bridge,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = delay1;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_bridge.next_attempt_at == TIME_MAX);
|
|
||||||
|
|
||||||
delay1 = 1;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_bridge,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
TIME_MAX);
|
|
||||||
expected_increment = delay1;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_bridge.next_attempt_at == TIME_MAX);
|
|
||||||
|
|
||||||
/* see what happens when we reach the end */
|
|
||||||
dls_attempt.n_download_attempts++;
|
|
||||||
dls_bridge.n_download_failures++;
|
|
||||||
|
|
||||||
delay2 = 100;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_attempt,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = delay2;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_attempt.next_attempt_at == current_time + delay2);
|
|
||||||
|
|
||||||
delay2 = 1;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_bridge,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = delay2;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_bridge.next_attempt_at == current_time + delay2);
|
|
||||||
|
|
||||||
/* see what happens when we try to go off the end */
|
|
||||||
dls_attempt.n_download_attempts++;
|
|
||||||
dls_bridge.n_download_failures++;
|
|
||||||
|
|
||||||
delay2 = 5;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_attempt,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = delay2;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_attempt.next_attempt_at == current_time + delay2);
|
|
||||||
|
|
||||||
delay2 = 17;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_bridge,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = delay2;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_bridge.next_attempt_at == current_time + delay2);
|
|
||||||
|
|
||||||
/* see what happens when we reach IMPOSSIBLE_TO_DOWNLOAD */
|
|
||||||
dls_attempt.n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD;
|
|
||||||
dls_bridge.n_download_failures = IMPOSSIBLE_TO_DOWNLOAD;
|
|
||||||
|
|
||||||
delay2 = 35;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_attempt,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = INT_MAX;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_attempt.next_attempt_at == TIME_MAX);
|
|
||||||
|
|
||||||
delay2 = 99;
|
|
||||||
increment = download_status_schedule_get_delay(&dls_bridge,
|
|
||||||
schedule,
|
|
||||||
0, INT_MAX,
|
|
||||||
current_time);
|
|
||||||
expected_increment = INT_MAX;
|
|
||||||
tt_assert(increment == expected_increment);
|
|
||||||
tt_assert(dls_bridge.next_attempt_at == TIME_MAX);
|
|
||||||
|
|
||||||
done:
|
|
||||||
/* the pointers in schedule are allocated on the stack */
|
|
||||||
smartlist_free(schedule);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
download_status_random_backoff_helper(int min_delay, int max_delay)
|
|
||||||
{
|
{
|
||||||
download_status_t dls_random =
|
download_status_t dls_random =
|
||||||
{ 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
|
{ 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
|
||||||
DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 };
|
DL_SCHED_INCREMENT_FAILURE, 0, 0 };
|
||||||
int increment = -1;
|
int increment = -1;
|
||||||
int old_increment = -1;
|
int old_increment = -1;
|
||||||
time_t current_time = time(NULL);
|
time_t current_time = time(NULL);
|
||||||
|
@ -4131,23 +3978,21 @@ download_status_random_backoff_helper(int min_delay, int max_delay)
|
||||||
int n_attempts = 0;
|
int n_attempts = 0;
|
||||||
do {
|
do {
|
||||||
increment = download_status_schedule_get_delay(&dls_random,
|
increment = download_status_schedule_get_delay(&dls_random,
|
||||||
NULL,
|
min_delay,
|
||||||
min_delay, max_delay,
|
|
||||||
current_time);
|
current_time);
|
||||||
|
|
||||||
log_debug(LD_DIR, "Min: %d, Max: %d, Inc: %d, Old Inc: %d",
|
log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
|
||||||
min_delay, max_delay, increment, old_increment);
|
min_delay, increment, old_increment);
|
||||||
|
|
||||||
/* Regression test for 20534 and friends
|
/* Regression test for 20534 and friends
|
||||||
* increment must always increase after the first */
|
* increment must always increase after the first */
|
||||||
if (dls_random.last_backoff_position > 0 && max_delay > 0) {
|
if (dls_random.last_backoff_position > 0) {
|
||||||
/* Always increment the exponential backoff */
|
/* Always increment the exponential backoff */
|
||||||
tt_int_op(increment, OP_GE, 1);
|
tt_int_op(increment, OP_GE, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test */
|
/* Test */
|
||||||
tt_int_op(increment, OP_GE, min_delay);
|
tt_int_op(increment, OP_GE, min_delay);
|
||||||
tt_int_op(increment, OP_LE, max_delay);
|
|
||||||
|
|
||||||
/* Advance */
|
/* Advance */
|
||||||
if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
|
if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
|
||||||
|
@ -4157,7 +4002,7 @@ download_status_random_backoff_helper(int min_delay, int max_delay)
|
||||||
|
|
||||||
/* Try another maybe */
|
/* Try another maybe */
|
||||||
old_increment = increment;
|
old_increment = increment;
|
||||||
} while (increment < max_delay && ++n_attempts < 1000);
|
} while (++n_attempts < 1000);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return;
|
return;
|
||||||
|
@ -4169,19 +4014,13 @@ test_dir_download_status_random_backoff(void *arg)
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|
||||||
/* Do a standard test */
|
/* Do a standard test */
|
||||||
download_status_random_backoff_helper(0, 1000000);
|
download_status_random_backoff_helper(0);
|
||||||
/* Regression test for 20534 and friends:
|
|
||||||
* try tighter bounds */
|
|
||||||
download_status_random_backoff_helper(0, 100);
|
|
||||||
/* regression tests for 17750: initial delay */
|
/* regression tests for 17750: initial delay */
|
||||||
download_status_random_backoff_helper(10, 1000);
|
download_status_random_backoff_helper(10);
|
||||||
download_status_random_backoff_helper(20, 30);
|
download_status_random_backoff_helper(20);
|
||||||
|
|
||||||
/* Pathological cases */
|
/* Pathological cases */
|
||||||
download_status_random_backoff_helper(0, 0);
|
download_status_random_backoff_helper(INT_MAX/2);
|
||||||
download_status_random_backoff_helper(1, 1);
|
|
||||||
download_status_random_backoff_helper(0, INT_MAX);
|
|
||||||
download_status_random_backoff_helper(INT_MAX/2, INT_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -4220,18 +4059,10 @@ static void
|
||||||
test_dir_download_status_increment(void *arg)
|
test_dir_download_status_increment(void *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
download_status_t dls_failure = { 0, 0, 0, DL_SCHED_GENERIC,
|
|
||||||
DL_WANT_AUTHORITY,
|
|
||||||
DL_SCHED_INCREMENT_FAILURE,
|
|
||||||
DL_SCHED_DETERMINISTIC, 0, 0 };
|
|
||||||
download_status_t dls_attempt = { 0, 0, 0, DL_SCHED_BRIDGE,
|
|
||||||
DL_WANT_ANY_DIRSERVER,
|
|
||||||
DL_SCHED_INCREMENT_ATTEMPT,
|
|
||||||
DL_SCHED_DETERMINISTIC, 0, 0 };
|
|
||||||
download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
|
download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
|
||||||
DL_WANT_ANY_DIRSERVER,
|
DL_WANT_ANY_DIRSERVER,
|
||||||
DL_SCHED_INCREMENT_ATTEMPT,
|
DL_SCHED_INCREMENT_ATTEMPT,
|
||||||
DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 };
|
0, 0 };
|
||||||
int no_delay = 0;
|
int no_delay = 0;
|
||||||
int delay0 = -1;
|
int delay0 = -1;
|
||||||
int delay1 = -1;
|
int delay1 = -1;
|
||||||
|
@ -4239,7 +4070,6 @@ test_dir_download_status_increment(void *arg)
|
||||||
smartlist_t *schedule = smartlist_new();
|
smartlist_t *schedule = smartlist_new();
|
||||||
smartlist_t *schedule_no_initial_delay = smartlist_new();
|
smartlist_t *schedule_no_initial_delay = smartlist_new();
|
||||||
or_options_t test_options;
|
or_options_t test_options;
|
||||||
time_t next_at = TIME_MAX;
|
|
||||||
time_t current_time = time(NULL);
|
time_t current_time = time(NULL);
|
||||||
|
|
||||||
/* Provide some values for the schedules */
|
/* Provide some values for the schedules */
|
||||||
|
@ -4272,26 +4102,6 @@ test_dir_download_status_increment(void *arg)
|
||||||
mock_get_options_calls = 0;
|
mock_get_options_calls = 0;
|
||||||
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
||||||
* an unrealiable test, because time(NULL) might change. */
|
* an unrealiable test, because time(NULL) might change. */
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
>= current_time + no_delay);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
!= TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* regression test for 17750: initial delay */
|
|
||||||
mock_options->TestingClientDownloadSchedule = schedule;
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
|
||||||
* an unrealiable test, because time(NULL) might change. */
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
>= current_time + delay0);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
!= TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* regression test for 17750: exponential, no initial delay */
|
/* regression test for 17750: exponential, no initial delay */
|
||||||
mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
|
mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
|
||||||
|
@ -4319,258 +4129,6 @@ test_dir_download_status_increment(void *arg)
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
|
tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
||||||
|
|
||||||
/* Check that a failure reset works */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
download_status_reset(&dls_failure);
|
|
||||||
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
|
||||||
* an unrealiable test, because time(NULL) might change. */
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
>= current_time + delay0);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
!= TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* avoid timing inconsistencies */
|
|
||||||
dls_failure.next_attempt_at = current_time + delay0;
|
|
||||||
|
|
||||||
/* check that a reset schedule becomes ready at the right time */
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay0 - 1, 1),
|
|
||||||
OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay0, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay0 + 1, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
|
|
||||||
/* Check that a failure increment works */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_failure(&dls_failure, 404, "test", 0,
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == current_time + delay1);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 1);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 1);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* check that an incremented schedule becomes ready at the right time */
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay1 - 1, 1),
|
|
||||||
OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay1, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay1 + 1, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
|
|
||||||
/* check that a schedule isn't ready if it's had too many failures */
|
|
||||||
tt_int_op(download_status_is_ready(&dls_failure,
|
|
||||||
current_time + delay1 + 10, 0),
|
|
||||||
OP_EQ, 0);
|
|
||||||
|
|
||||||
/* Check that failure increments do happen on 503 for clients, and
|
|
||||||
* attempt increments do too. */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_failure(&dls_failure, 503, "test", 0,
|
|
||||||
current_time);
|
|
||||||
tt_i64_op(next_at, OP_EQ, current_time + delay2);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 2);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 2);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check that failure increments do happen on 503 for servers */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_failure(&dls_failure, 503, "test", 1,
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == current_time + delay2);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 3);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 3);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check what happens when we run off the end of the schedule */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_failure(&dls_failure, 404, "test", 0,
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == current_time + delay2);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 4);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 4);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check what happens when we hit the failure limit */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
download_status_mark_impossible(&dls_failure);
|
|
||||||
next_at = download_status_increment_failure(&dls_failure, 404, "test", 0,
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check that a failure reset doesn't reset at the limit */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
download_status_reset(&dls_failure);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
== TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_EQ, 0);
|
|
||||||
|
|
||||||
/* Check that a failure reset resets just before the limit */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
dls_failure.n_download_failures = IMPOSSIBLE_TO_DOWNLOAD - 1;
|
|
||||||
dls_failure.n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD - 1;
|
|
||||||
download_status_reset(&dls_failure);
|
|
||||||
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
|
||||||
* an unrealiable test, because time(NULL) might change. */
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
>= current_time + delay0);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_failure)
|
|
||||||
!= TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check that failure increments do happen on attempt-based schedules,
|
|
||||||
* but that the retry is set at the end of time */
|
|
||||||
mock_options->UseBridges = 1;
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_failure(&dls_attempt, 404, "test", 0,
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ, 1);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check that an attempt reset works */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
download_status_reset(&dls_attempt);
|
|
||||||
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
|
||||||
* an unrealiable test, because time(NULL) might change. */
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_attempt)
|
|
||||||
>= current_time + delay0);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_attempt)
|
|
||||||
!= TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* avoid timing inconsistencies */
|
|
||||||
dls_attempt.next_attempt_at = current_time + delay0;
|
|
||||||
|
|
||||||
/* check that a reset schedule becomes ready at the right time */
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay0 - 1, 1),
|
|
||||||
OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay0, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay0 + 1, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
|
|
||||||
/* Check that an attempt increment works */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_attempt(&dls_attempt, "test",
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == current_time + delay1);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ, 1);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* check that an incremented schedule becomes ready at the right time */
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay1 - 1, 1),
|
|
||||||
OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay1, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay1 + 1, 1),
|
|
||||||
OP_EQ, 1);
|
|
||||||
|
|
||||||
/* check that a schedule isn't ready if it's had too many attempts */
|
|
||||||
tt_int_op(download_status_is_ready(&dls_attempt,
|
|
||||||
current_time + delay1 + 10, 0),
|
|
||||||
OP_EQ, 0);
|
|
||||||
|
|
||||||
/* Check what happens when we reach then run off the end of the schedule */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_attempt(&dls_attempt, "test",
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == current_time + delay2);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ, 2);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
next_at = download_status_increment_attempt(&dls_attempt, "test",
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == current_time + delay2);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ, 3);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check what happens when we hit the attempt limit */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
download_status_mark_impossible(&dls_attempt);
|
|
||||||
next_at = download_status_increment_attempt(&dls_attempt, "test",
|
|
||||||
current_time);
|
|
||||||
tt_assert(next_at == TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
|
|
||||||
/* Check that an attempt reset doesn't reset at the limit */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
download_status_reset(&dls_attempt);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_attempt)
|
|
||||||
== TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ,
|
|
||||||
IMPOSSIBLE_TO_DOWNLOAD);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_EQ, 0);
|
|
||||||
|
|
||||||
/* Check that an attempt reset resets just before the limit */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
dls_attempt.n_download_failures = IMPOSSIBLE_TO_DOWNLOAD - 1;
|
|
||||||
dls_attempt.n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD - 1;
|
|
||||||
download_status_reset(&dls_attempt);
|
|
||||||
/* we really want to test that it's equal to time(NULL) + delay0, but that's
|
|
||||||
* an unrealiable test, because time(NULL) might change. */
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_attempt)
|
|
||||||
>= current_time + delay0);
|
|
||||||
tt_assert(download_status_get_next_attempt_at(&dls_attempt)
|
|
||||||
!= TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_attempt), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_GE, 1);
|
|
||||||
mock_options->UseBridges = 0;
|
|
||||||
|
|
||||||
/* Check that attempt increments don't happen on failure-based schedules,
|
|
||||||
* and that the attempt is set at the end of time */
|
|
||||||
mock_get_options_calls = 0;
|
|
||||||
setup_full_capture_of_logs(LOG_WARN);
|
|
||||||
next_at = download_status_increment_attempt(&dls_failure, "test",
|
|
||||||
current_time);
|
|
||||||
expect_single_log_msg_containing(
|
|
||||||
"Tried to launch an attempt-based connection on a failure-based "
|
|
||||||
"schedule.");
|
|
||||||
teardown_capture_of_logs();
|
|
||||||
tt_assert(next_at == TIME_MAX);
|
|
||||||
tt_int_op(download_status_get_n_failures(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(download_status_get_n_attempts(&dls_failure), OP_EQ, 0);
|
|
||||||
tt_int_op(mock_get_options_calls, OP_EQ, 0);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* the pointers in schedule are allocated on the stack */
|
/* the pointers in schedule are allocated on the stack */
|
||||||
smartlist_free(schedule);
|
smartlist_free(schedule);
|
||||||
|
@ -6318,7 +5876,6 @@ struct testcase_t dir_tests[] = {
|
||||||
DIR(post_parsing, 0),
|
DIR(post_parsing, 0),
|
||||||
DIR(fetch_type, 0),
|
DIR(fetch_type, 0),
|
||||||
DIR(packages, 0),
|
DIR(packages, 0),
|
||||||
DIR(download_status_schedule, 0),
|
|
||||||
DIR(download_status_random_backoff, 0),
|
DIR(download_status_random_backoff, 0),
|
||||||
DIR(download_status_random_backoff_ranges, 0),
|
DIR(download_status_random_backoff_ranges, 0),
|
||||||
DIR(download_status_increment, TT_FORK),
|
DIR(download_status_increment, TT_FORK),
|
||||||
|
|
|
@ -377,17 +377,11 @@ fixed_get_uname(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_OPTIONS_OLD_VALUES "TestingV3AuthInitialVotingInterval 1800\n" \
|
#define TEST_OPTIONS_OLD_VALUES "TestingV3AuthInitialVotingInterval 1800\n" \
|
||||||
"ClientBootstrapConsensusMaxDownloadTries 7\n" \
|
|
||||||
"ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries 4\n" \
|
|
||||||
"ClientBootstrapConsensusMaxInProgressTries 3\n" \
|
"ClientBootstrapConsensusMaxInProgressTries 3\n" \
|
||||||
"TestingV3AuthInitialVoteDelay 300\n" \
|
"TestingV3AuthInitialVoteDelay 300\n" \
|
||||||
"TestingV3AuthInitialDistDelay 300\n" \
|
"TestingV3AuthInitialDistDelay 300\n" \
|
||||||
"TestingClientMaxIntervalWithoutRequest 600\n" \
|
"TestingClientMaxIntervalWithoutRequest 600\n" \
|
||||||
"TestingDirConnectionMaxStall 600\n" \
|
"TestingDirConnectionMaxStall 600\n" \
|
||||||
"TestingConsensusMaxDownloadTries 8\n" \
|
|
||||||
"TestingDescriptorMaxDownloadTries 8\n" \
|
|
||||||
"TestingMicrodescMaxDownloadTries 8\n" \
|
|
||||||
"TestingCertMaxDownloadTries 8\n"
|
|
||||||
|
|
||||||
#define TEST_OPTIONS_DEFAULT_VALUES TEST_OPTIONS_OLD_VALUES \
|
#define TEST_OPTIONS_DEFAULT_VALUES TEST_OPTIONS_OLD_VALUES \
|
||||||
"MaxClientCircuitsPending 1\n" \
|
"MaxClientCircuitsPending 1\n" \
|
||||||
|
@ -2081,10 +2075,6 @@ test_options_validate__testing(void *ignored)
|
||||||
ENSURE_DEFAULT(TestingBridgeBootstrapDownloadSchedule, 3000);
|
ENSURE_DEFAULT(TestingBridgeBootstrapDownloadSchedule, 3000);
|
||||||
ENSURE_DEFAULT(TestingClientMaxIntervalWithoutRequest, 3000);
|
ENSURE_DEFAULT(TestingClientMaxIntervalWithoutRequest, 3000);
|
||||||
ENSURE_DEFAULT(TestingDirConnectionMaxStall, 3000);
|
ENSURE_DEFAULT(TestingDirConnectionMaxStall, 3000);
|
||||||
ENSURE_DEFAULT(TestingConsensusMaxDownloadTries, 3000);
|
|
||||||
ENSURE_DEFAULT(TestingDescriptorMaxDownloadTries, 3000);
|
|
||||||
ENSURE_DEFAULT(TestingMicrodescMaxDownloadTries, 3000);
|
|
||||||
ENSURE_DEFAULT(TestingCertMaxDownloadTries, 3000);
|
|
||||||
ENSURE_DEFAULT(TestingAuthKeyLifetime, 3000);
|
ENSURE_DEFAULT(TestingAuthKeyLifetime, 3000);
|
||||||
ENSURE_DEFAULT(TestingLinkCertLifetime, 3000);
|
ENSURE_DEFAULT(TestingLinkCertLifetime, 3000);
|
||||||
ENSURE_DEFAULT(TestingSigningKeySlop, 3000);
|
ENSURE_DEFAULT(TestingSigningKeySlop, 3000);
|
||||||
|
@ -4069,15 +4059,6 @@ test_options_validate__testing_options(void *ignored)
|
||||||
"is way too low.");
|
"is way too low.");
|
||||||
TEST_TESTING_OPTION(TestingDirConnectionMaxStall, 1, 3601,
|
TEST_TESTING_OPTION(TestingDirConnectionMaxStall, 1, 3601,
|
||||||
"is way too low.");
|
"is way too low.");
|
||||||
// TODO: I think this points to a bug/regression in options_validate
|
|
||||||
TEST_TESTING_OPTION(TestingConsensusMaxDownloadTries, 1, 801,
|
|
||||||
"must be greater than 2.");
|
|
||||||
TEST_TESTING_OPTION(TestingDescriptorMaxDownloadTries, 1, 801,
|
|
||||||
"must be greater than 1.");
|
|
||||||
TEST_TESTING_OPTION(TestingMicrodescMaxDownloadTries, 1, 801,
|
|
||||||
"must be greater than 1.");
|
|
||||||
TEST_TESTING_OPTION(TestingCertMaxDownloadTries, 1, 801,
|
|
||||||
"must be greater than 1.");
|
|
||||||
|
|
||||||
free_options_test_data(tdata);
|
free_options_test_data(tdata);
|
||||||
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
|
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
|
||||||
|
|
Loading…
Reference in New Issue