server: use parsed record data to build response

This commit is contained in:
Peter Cai 2021-04-06 07:58:35 +08:00
parent d54b4f4a33
commit 94ce9142b2
3 changed files with 29 additions and 17 deletions

View file

@ -1,13 +1,9 @@
use crate::cache::DnsCache; use crate::cache::DnsCache;
use crate::r#override::OverrideResolver; use crate::r#override::OverrideResolver;
use domain::{ use domain::base::{
base::{ iana::{Opcode, Rcode},
iana::{Opcode, Rcode}, rdata::UnknownRecordData,
octets::Parser, Dname, Message, MessageBuilder, ParsedDname, Question, Record, ToDname,
rdata::{ParseRecordData, UnknownRecordData},
Dname, Message, MessageBuilder, ParsedDname, Question, Record, ToDname,
},
rdata::AllRecordData,
}; };
use js_sys::{ArrayBuffer, Uint8Array}; use js_sys::{ArrayBuffer, Uint8Array};
use wasm_bindgen_futures::JsFuture; use wasm_bindgen_futures::JsFuture;
@ -178,11 +174,7 @@ impl Client {
), ),
); );
// Try to parse the record; if failed, fail this entire query // Try to parse the record; if failed, fail this entire query
let parsed_record_data: Result<Option<AllRecordData<&[u8], ParsedDname<&[u8]>>>, _> = let parsed_record_data = crate::util::parse_record_data(record.data());
AllRecordData::parse_data(
owned_record.rtype(),
&mut Parser::from_ref(owned_record.data().data().as_slice()),
);
if let Err(_) = parsed_record_data { if let Err(_) = parsed_record_data {
return Err("Failed to parse response from upstream".to_string()); return Err("Failed to parse response from upstream".to_string());

View file

@ -222,9 +222,13 @@ impl Server {
// Set up the answer section // Set up the answer section
let mut answer_builder = question_builder.answer(); let mut answer_builder = question_builder.answer();
for r in records { for r in records {
answer_builder if let Ok(Some(data)) = crate::util::parse_record_data(r.data()) {
.push(r) answer_builder
.map_err(|_| "Max answer size exceeded".to_string())?; .push(Record::new(r.owner().clone(), r.class(), r.ttl(), data))
.map_err(|_| "Max answer size exceeded".to_string())?;
} else {
return Err("Cannot parse record data responded by resolver client".to_string());
}
} }
Ok(answer_builder.into_message()) Ok(answer_builder.into_message())
} }

View file

@ -1,4 +1,11 @@
use domain::base::Message; use domain::{
base::{
octets::{ParseError, Parser},
rdata::{ParseRecordData, UnknownRecordData},
Message, ParsedDname,
},
rdata::AllRecordData,
};
use js_sys::{Math, Promise}; use js_sys::{Math, Promise};
use std::ops::Add; use std::ops::Add;
use std::{collections::hash_map::DefaultHasher, hash::Hasher}; use std::{collections::hash_map::DefaultHasher, hash::Hasher};
@ -21,6 +28,15 @@ pub fn parse_dns_wireformat(msg: &[u8]) -> Result<Message<Vec<u8>>, String> {
.map_err(|_| "Failed to parse DNS wireformat message".to_string()) .map_err(|_| "Failed to parse DNS wireformat message".to_string())
} }
pub fn parse_record_data<T: AsRef<[u8]>>(
record: &UnknownRecordData<T>,
) -> Result<Option<AllRecordData<&[u8], ParsedDname<&[u8]>>>, ParseError> {
AllRecordData::parse_data(
record.rtype(),
&mut Parser::from_ref(record.data().as_ref()),
)
}
// Rust wrapper around JS functions // Rust wrapper around JS functions
// For convenience, and also to work around bugs in rust-analyzer // For convenience, and also to work around bugs in rust-analyzer
// which thinks all JS functions are "unsafe" // which thinks all JS functions are "unsafe"