123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- use std::io;
- use log::*;
- #[derive(PartialEq, Debug)]
- pub enum Resolver {
-
- SystemDefault,
-
- Specified(Nameserver),
- }
- pub type Nameserver = String;
- impl Resolver {
-
-
-
- pub fn lookup(self) -> io::Result<Option<Nameserver>> {
- match self {
- Self::Specified(ns) => Ok(Some(ns)),
- Self::SystemDefault => system_nameservers(),
- }
- }
- }
- #[cfg(unix)]
- fn system_nameservers() -> io::Result<Option<Nameserver>> {
- use std::io::{BufRead, BufReader};
- use std::fs::File;
- let f = File::open("/etc/resolv.conf")?;
- let reader = BufReader::new(f);
- let mut nameservers = Vec::new();
- for line in reader.lines() {
- let line = line?;
- if let Some(nameserver_str) = line.strip_prefix("nameserver ") {
- let ip: Result<std::net::Ipv4Addr, _> = nameserver_str.parse();
-
- match ip {
- Ok(_ip) => nameservers.push(nameserver_str.into()),
- Err(e) => warn!("Failed to parse nameserver line {:?}: {}", line, e),
- }
- }
- }
- Ok(nameservers.first().cloned())
- }
- #[cfg(windows)]
- fn system_nameservers() -> io::Result<Option<Nameserver>> {
- let adapters = match ipconfig::get_adapters() {
- Ok(a) => a,
- Err(e) => {
- warn!("Error getting network adapters: {}", e);
- return Ok(None);
- }
- };
- for adapter in adapters.iter().filter(|a| {
- a.oper_status() == ipconfig::OperStatus::IfOperStatusUp && !a.gateways().is_empty()
- }) {
- for dns_server in adapter.dns_servers().iter() {
-
- if dns_server.is_ipv4() {
- debug!("Found first nameserver {:?}", dns_server);
- return Ok(Some(dns_server.to_string()));
- }
- }
- }
- warn!("No nameservers available");
- return Ok(None)
- }
- #[cfg(all(not(unix), not(windows)))]
- fn system_nameservers() -> io::Result<Option<Nameserver>> {
- warn!("Unable to fetch default nameservers on this platform.");
- Ok(None)
- }
|