use std::{
borrow::Cow,
fs::File,
io::Read,
net::SocketAddr,
path::{Path, PathBuf},
};
use serde::Deserialize;
use crate::error::ConfigError;
use crate::proto::{
rr::{RData, Record, RecordSet},
serialize::txt::{Lexer, Parser},
};
use crate::resolver::Name;
#[derive(Clone, Deserialize, Eq, PartialEq, Debug)]
pub struct RecursiveConfig {
pub roots: PathBuf,
}
impl RecursiveConfig {
pub(crate) fn read_roots(
&self,
root_dir: Option<&Path>,
) -> Result<Vec<SocketAddr>, ConfigError> {
let path = if let Some(root_dir) = root_dir {
Cow::Owned(root_dir.join(&self.roots))
} else {
Cow::Borrowed(&self.roots)
};
let mut roots = File::open(path.as_ref())?;
let mut roots_str = String::new();
roots.read_to_string(&mut roots_str)?;
let lexer = Lexer::new(&roots_str);
let mut parser = Parser::new();
let (_zone, roots_zone) = parser.parse(lexer, Some(Name::root()))?;
Ok(roots_zone
.values()
.flat_map(RecordSet::records_without_rrsigs)
.filter_map(Record::data)
.filter_map(RData::ip_addr) .map(|ip| SocketAddr::from((ip, 53))) .collect())
}
}