alnyan/yggdrasil: LookupHost from hosts file
This commit is contained in:
@@ -2,14 +2,19 @@ use yggdrasil_rt::net::dns::{
|
|||||||
self, DnsClass, DnsMessage, DnsRecordData, DnsReplyCode, DnsType, UdpRequester,
|
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::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
|
||||||
use crate::os::{
|
use crate::os::{
|
||||||
fd::AsRawFd,
|
fd::AsRawFd,
|
||||||
yggdrasil::io::{poll::PollChannel, timer::TimerFd},
|
yggdrasil::io::{poll::PollChannel, timer::TimerFd},
|
||||||
};
|
};
|
||||||
|
use crate::str::FromStr;
|
||||||
use crate::time::Duration;
|
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 {
|
pub struct LookupHost {
|
||||||
addresses: Vec<IpAddr>,
|
addresses: Vec<IpAddr>,
|
||||||
port: u16,
|
port: u16,
|
||||||
@@ -24,8 +29,6 @@ struct DnsRequester {
|
|||||||
socket: UdpSocket,
|
socket: UdpSocket,
|
||||||
}
|
}
|
||||||
|
|
||||||
const NAMESERVER: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 53);
|
|
||||||
|
|
||||||
impl DnsRequester {
|
impl DnsRequester {
|
||||||
pub fn new(nameserver: SocketAddr) -> io::Result<Self> {
|
pub fn new(nameserver: SocketAddr) -> io::Result<Self> {
|
||||||
let mut poll = PollChannel::new()?;
|
let mut poll = PollChannel::new()?;
|
||||||
@@ -111,12 +114,44 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
|||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn try_from((hostname, port): (&'a str, u16)) -> io::Result<Self> {
|
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)?;
|
let addresses = get_addresses_from_dns(hostname)?;
|
||||||
|
|
||||||
Ok(Self { addresses, port })
|
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>> {
|
fn get_addresses_from_dns(hostname: &str) -> io::Result<Vec<IpAddr>> {
|
||||||
// TODO randomize xid/cookie
|
// TODO randomize xid/cookie
|
||||||
let mut addresses = vec![];
|
let mut addresses = vec![];
|
||||||
|
|||||||
Reference in New Issue
Block a user