alnyan/yggdrasil: use local DNS resolver

This commit is contained in:
2024-01-28 15:24:21 +02:00
parent 69c5a7f895
commit 4c8551a7a4
+32 -29
View File
@@ -24,9 +24,7 @@ struct DnsRequester {
socket: UdpSocket,
}
// TODO remove hardcoded nameserver
// Maybe use local resolver?
const NAMESERVER: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(11, 0, 0, 1)), 53);
const NAMESERVER: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 53);
impl DnsRequester {
pub fn new(nameserver: SocketAddr) -> io::Result<Self> {
@@ -113,33 +111,38 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
type Error = io::Error;
fn try_from((hostname, port): (&'a str, u16)) -> io::Result<Self> {
// TODO randomize xid/cookie
let mut requester = DnsRequester::new(NAMESERVER)?;
let message = dns::perform_query(&mut requester, hostname, DnsType::A, 12341, 0x12313121)?;
if message.reply_code != DnsReplyCode::NO_ERROR {
return Err(io::Error::new(io::ErrorKind::Other, "DNS server returned error"));
}
let mut addresses = vec![];
for answer in message.answers {
let Some(name) = answer.name.0.as_ref() else {
continue;
};
let name = name.trim_end_matches('.');
if name != hostname {
continue;
}
match (answer.ty, answer.class, &answer.rdata) {
(DnsType::A, DnsClass::IN, DnsRecordData::A(address)) => {
addresses.push(IpAddr::V4(u32::from(*address).into()));
}
_ => (),
}
}
let addresses = get_addresses_from_dns(hostname)?;
Ok(Self { addresses, port })
}
}
fn get_addresses_from_dns(hostname: &str) -> io::Result<Vec<IpAddr>> {
// TODO randomize xid/cookie
let mut addresses = vec![];
let mut requester = DnsRequester::new(NAMESERVER)?;
let message = dns::perform_query(&mut requester, hostname, DnsType::A, 12341, 0x12313121)?;
if message.reply_code != DnsReplyCode::NO_ERROR {
return Err(io::Error::new(io::ErrorKind::Other, "DNS server returned error"));
}
for answer in message.answers {
let Some(name) = answer.name.0.as_ref() else {
continue;
};
let name = name.trim_end_matches('.');
if name != hostname {
continue;
}
match (answer.ty, answer.class, &answer.rdata) {
(DnsType::A, DnsClass::IN, DnsRecordData::A(address)) => {
addresses.push(IpAddr::V4(u32::from(*address).into()));
}
_ => (),
}
}
Ok(addresses)
}