resolve.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //! Specifying the address of the DNS server to send requests to.
  2. use std::io;
  3. use log::*;
  4. /// A **resolver** is used to obtain the IP address of the server we should
  5. /// send DNS requests to.
  6. #[derive(PartialEq, Debug)]
  7. pub enum Resolver {
  8. /// Read the list of nameservers from the system, and use that.
  9. SystemDefault,
  10. // Use a specific nameserver specified by the user.
  11. Specified(Nameserver),
  12. }
  13. pub type Nameserver = String;
  14. impl Resolver {
  15. /// Returns a nameserver that queries should be sent to, possibly by
  16. /// obtaining one based on the system, returning an error if there was a
  17. /// problem looking one up.
  18. pub fn lookup(self) -> io::Result<Option<Nameserver>> {
  19. match self {
  20. Self::Specified(ns) => Ok(Some(ns)),
  21. Self::SystemDefault => system_nameservers(),
  22. }
  23. }
  24. }
  25. /// Looks up the system default nameserver on Unix, by querying
  26. /// `/etc/resolv.conf` and returning the first line that specifies one.
  27. /// Returns an error if there’s a problem reading the file, or `None` if no
  28. /// nameserver is specified in the file.
  29. #[cfg(unix)]
  30. fn system_nameservers() -> io::Result<Option<Nameserver>> {
  31. use std::io::{BufRead, BufReader};
  32. use std::fs::File;
  33. let f = File::open("/etc/resolv.conf")?;
  34. let reader = BufReader::new(f);
  35. let mut nameservers = Vec::new();
  36. for line in reader.lines() {
  37. let line = line?;
  38. if let Some(nameserver_str) = line.strip_prefix("nameserver ") {
  39. let ip: Result<std::net::Ipv4Addr, _> = nameserver_str.parse();
  40. // TODO: This will need to be changed for IPv6 support.
  41. match ip {
  42. Ok(_ip) => nameservers.push(nameserver_str.into()),
  43. Err(e) => warn!("Failed to parse nameserver line {:?}: {}", line, e),
  44. }
  45. }
  46. }
  47. Ok(nameservers.first().cloned())
  48. }
  49. /// Looks up the system default nameserver on Windows, by iterating through
  50. /// the list of network adapters and returning the first nameserver it finds.
  51. #[cfg(windows)]
  52. fn system_nameservers() -> io::Result<Option<Nameserver>> {
  53. let adapters = match ipconfig::get_adapters() {
  54. Ok(a) => a,
  55. Err(e) => {
  56. warn!("Error getting network adapters: {}", e);
  57. return Ok(None);
  58. }
  59. };
  60. for adapter in adapters.iter().filter(|a| {
  61. a.oper_status() == ipconfig::OperStatus::IfOperStatusUp && !a.gateways().is_empty()
  62. }) {
  63. for dns_server in adapter.dns_servers().iter() {
  64. // TODO: This will need to be changed for IPv6 support.
  65. if dns_server.is_ipv4() {
  66. debug!("Found first nameserver {:?}", dns_server);
  67. return Ok(Some(dns_server.to_string()));
  68. }
  69. }
  70. }
  71. warn!("No nameservers available");
  72. return Ok(None)
  73. }
  74. /// The fall-back system default nameserver determinator that is not very
  75. /// determined as it returns nothing without actually checking anything.
  76. #[cfg(all(not(unix), not(windows)))]
  77. fn system_nameservers() -> io::Result<Option<Nameserver>> {
  78. warn!("Unable to fetch default nameservers on this platform.");
  79. Ok(None)
  80. }