RPKI: ask a cache without data yet again soon
A validator that is still running its first validation answers a query with No Data Available (error code 2). That ended the session, and the next attempt came after the retry interval: 600 seconds when the cache had not yet said otherwise, which it cannot have before it has data. For those ten minutes after a validator started, nothing was validated. No Data Available is now asked again after 30 seconds, or after retry_seconds if that is shorter, and logged as information rather than as a warning. Other failures wait as before, after trying the next cache if there is one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9362ba9e34
commit
52593bb2c2
2 files changed
+54
-7
No files matched your search
@@ -54,6 +54,12 @@ const MAX_RECORDS: usize = 8_000_000;
|
||||
/// How long to wait before trying the next cache after one has failed.
|
||||
const NEXT_CACHE_DELAY: Duration = Duration::from_secs(1);
|
||||
|
||||
/// How long to wait before asking a cache again that said it has no data
|
||||
/// yet, rather than the retry interval: it is up and validating, which
|
||||
/// takes minutes after it starts, and the retry interval is ten unless it
|
||||
/// has said otherwise, which it has not had the chance to.
|
||||
const NO_DATA_RETRY: Duration = Duration::from_secs(30);
|
||||
|
||||
/// How long a cache that is being left is given to take the reason.
|
||||
const ERROR_REPORT_TIMEOUT: Duration = Duration::from_secs(1);
|
||||
|
||||
@@ -419,23 +425,29 @@ impl Client {
|
||||
self.protocol_version = version;
|
||||
continue;
|
||||
}
|
||||
let no_data = matches!(
|
||||
ended,
|
||||
SessionError::Reported {
|
||||
code: error_code::NO_DATA_AVAILABLE,
|
||||
..
|
||||
}
|
||||
);
|
||||
if no_data {
|
||||
info!(%cache, "RPKI cache has no data yet; asking again soon");
|
||||
} else {
|
||||
warn!(%cache, err = %ended, "RPKI cache session ended");
|
||||
}
|
||||
self.status(|status| {
|
||||
status.state = CacheState::Connecting;
|
||||
status.last_error = Some(ended.to_string());
|
||||
});
|
||||
|
||||
// The next cache at once; when all have been tried, a rest.
|
||||
attempt += 1;
|
||||
// The next cache, or this one when it is back, may speak a
|
||||
// newer version.
|
||||
self.protocol_version = VERSION_2;
|
||||
let wait = if attempt.is_multiple_of(self.config.caches.len()) {
|
||||
self.retry()
|
||||
} else {
|
||||
NEXT_CACHE_DELAY
|
||||
};
|
||||
self.wait(wait).await;
|
||||
let all_tried = attempt.is_multiple_of(self.config.caches.len());
|
||||
self.wait(rest(all_tried, no_data, self.retry())).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,3 +901,33 @@ enum Answer {
|
||||
/// With a request to ask for everything instead.
|
||||
Reset,
|
||||
}
|
||||
|
||||
/// How long to rest after a session ended: the next cache at once; when
|
||||
/// all have been tried, the retry interval, or less if the last one is
|
||||
/// only still validating.
|
||||
fn rest(all_tried: bool, no_data: bool, retry: Duration) -> Duration {
|
||||
match (all_tried, no_data) {
|
||||
(false, _) => NEXT_CACHE_DELAY,
|
||||
(true, true) => NO_DATA_RETRY.min(retry),
|
||||
(true, false) => retry,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// A cache that is still validating after it started is asked again
|
||||
/// in half a minute, not the ten the retry interval is by default.
|
||||
#[test]
|
||||
fn a_cache_without_data_yet_is_asked_again_soon() {
|
||||
let ten_minutes = Duration::from_secs(600);
|
||||
assert_eq!(rest(true, true, ten_minutes), NO_DATA_RETRY);
|
||||
assert_eq!(rest(true, false, ten_minutes), ten_minutes);
|
||||
// Never later than the retry interval says.
|
||||
let short = Duration::from_secs(5);
|
||||
assert_eq!(rest(true, true, short), short);
|
||||
// Another cache first, whatever this one said.
|
||||
assert_eq!(rest(false, true, ten_minutes), NEXT_CACHE_DELAY);
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,11 @@ rpki {
|
||||
When the data expires, Ferrix discards it, and no route is considered
|
||||
invalid until new data is received.
|
||||
|
||||
A validator that has just started reports that it has no data available
|
||||
until its first validation run is complete, which takes several minutes.
|
||||
Ferrix then asks again after 30 seconds, or after `retry_seconds` if that
|
||||
is shorter, rather than after the retry interval.
|
||||
|
||||
### Running a Validator
|
||||
|
||||
The following command starts Routinator with an RTR server on port 3323:
|
||||
|
||||
Reference in new issue
Block a user