alnyan/yggdrasil: LookupHost from hosts file

This commit is contained in:
2024-01-28 18:23:40 +02:00
parent 4c8551a7a4
commit b46ba116ae
+38 -3
View File
@@ -2,14 +2,19 @@ use yggdrasil_rt::net::dns::{
self, DnsClass, DnsMessage, DnsRecordData, DnsReplyCode, DnsType, UdpRequester,
};
use crate::io;
use crate::fs::File;
use crate::io::{self, BufRead, BufReader};
use crate::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
use crate::os::{
fd::AsRawFd,
yggdrasil::io::{poll::PollChannel, timer::TimerFd},
};
use crate::str::FromStr;
use crate::time::Duration;
const NAMESERVER: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 53);
const HOSTS_PATH: &str = "/etc/hosts";
pub struct LookupHost {
addresses: Vec<IpAddr>,
port: u16,
@@ -24,8 +29,6 @@ struct DnsRequester {
socket: UdpSocket,
}
const NAMESERVER: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 53);
impl DnsRequester {
pub fn new(nameserver: SocketAddr) -> io::Result<Self> {
let mut poll = PollChannel::new()?;
@@ -111,12 +114,44 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
type Error = io::Error;
fn try_from((hostname, port): (&'a str, u16)) -> io::Result<Self> {
if let Ok(addresses) = get_addresses_from_hosts(hostname) {
if !addresses.is_empty() {
return Ok(Self { addresses, port });
}
}
let addresses = get_addresses_from_dns(hostname)?;
Ok(Self { addresses, port })
}
}
fn get_addresses_from_hosts(hostname: &str) -> io::Result<Vec<IpAddr>> {
let mut reader = BufReader::new(File::open(HOSTS_PATH)?);
let mut addresses = vec![];
for line in reader.lines() {
let line = line?;
let line = line.trim();
if line.starts_with('#') {
continue;
}
let Some((address, host)) = line.split_once(' ') else {
continue;
};
let address = address.trim();
let host = host.trim();
let Ok(address) = IpAddr::from_str(address) else {
continue;
};
if host == hostname {
addresses.push(address);
}
}
Ok(addresses)
}
fn get_addresses_from_dns(hostname: &str) -> io::Result<Vec<IpAddr>> {
// TODO randomize xid/cookie
let mut addresses = vec![];