server: implement query retries

This commit is contained in:
Peter Cai 2021-04-03 21:24:07 +08:00
parent 30b091ae27
commit 3bcd677a27
2 changed files with 22 additions and 2 deletions

View File

@ -34,6 +34,21 @@ impl Client {
Self::extract_answers(resp) Self::extract_answers(resp)
} }
pub async fn query_with_retry(
&self,
questions: Vec<Question<ParsedDname>>,
retries: usize,
) -> Result<Vec<Record<ParsedDname, AllRecordData<ParsedDname>>>, String> {
let mut last_res = Err("Dummy".to_string());
for i in (0..retries) {
last_res = self.query(questions.clone()).await;
if last_res.is_ok() {
break;
}
}
return last_res;
}
// Select an upstream randomly // Select an upstream randomly
fn select_upstream(&self) -> String { fn select_upstream(&self) -> String {
let idx = unsafe { Math::random() } * self.options.upstream_urls.len() as f64; let idx = unsafe { Math::random() } * self.options.upstream_urls.len() as f64;
@ -51,7 +66,7 @@ impl Client {
header.set_qr(false); // For queries, QR = false header.set_qr(false); // For queries, QR = false
header.set_opcode(Opcode::Query); header.set_opcode(Opcode::Query);
header.set_rd(true); // Ask for recursive queries header.set_rd(true); // Ask for recursive queries
// Set up the questions // Set up the questions
for q in questions { for q in questions {
builder builder
.push(q) .push(q)

View File

@ -44,6 +44,7 @@ enum DnsResponseFormat {
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct ServerOptions { pub struct ServerOptions {
upstream_urls: Vec<String>, upstream_urls: Vec<String>,
retries: usize,
} }
pub struct Server { pub struct Server {
@ -75,7 +76,11 @@ impl Server {
let body = err_response!(Self::parse_dns_body(&req).await); let body = err_response!(Self::parse_dns_body(&req).await);
let query_id = body.header().id(); // random ID that needs to be preserved in response let query_id = body.header().id(); // random ID that needs to be preserved in response
let questions = err_response!(Self::extract_questions(body)); let questions = err_response!(Self::extract_questions(body));
let records = err_response!(self.client.query(questions).await); let records = err_response!(
self.client
.query_with_retry(questions, self.options.retries)
.await
);
let resp_format = Self::get_response_format(&req); let resp_format = Self::get_response_format(&req);
let mut resp_body = err_response!(match &resp_format { let mut resp_body = err_response!(match &resp_format {