1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com> // // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or // http://opensource.org/licenses/MIT>, at your option. This file may not be // copied, modified, or distributed except according to those terms. //! Structs for creating and using a Resolver use std::cell::RefCell; use std::io; use tokio_core::reactor::Core; use config::{ResolverConfig, ResolverOpts}; use lookup_ip::LookupIp; use ResolverFuture; /// The Resolver is used for performing DNS queries. /// /// For forward (A) lookups, hostname -> IP address, see: `Resolver::lookup_ip` pub struct Resolver { resolver_future: RefCell<ResolverFuture>, io_loop: RefCell<Core>, } impl Resolver { /// Construct a new Resolver with the given ClientConnection, see UdpClientConnection and/or TcpCLientConnection /// /// # Arguments /// * `config` - configuration for the resolver /// * `options` - resolver options for performing lookups /// * `client_connection` - ClientConnection for establishing the connection to the DNS server /// /// # Returns /// A new Resolver pub fn new(config: ResolverConfig, options: ResolverOpts) -> io::Result<Self> { let io_loop = Core::new()?; let resolver = ResolverFuture::new(config, options, io_loop.handle()); Ok(Resolver { resolver_future: RefCell::new(resolver), io_loop: RefCell::new(io_loop), }) } // TODO: need to support ndot lookup options... /// Performs a DNS lookup for the IP for the given hostname. /// /// Based on the configuration and options passed in, this may do either a A or a AAAA lookup, /// returning IpV4 or IpV6 addresses. (*Note*: current release only queries A, IPv4) /// /// # Arguments /// * `host` - string hostname, if this is an invalid hostname, an error will be thrown. Currently this must be a FQDN, with a trailing `.`, e.g. `www.example.com.`. This will be fixed in a future release. pub fn lookup_ip(&mut self, host: &str) -> io::Result<LookupIp> { self.io_loop .borrow_mut() .run(self.resolver_future.borrow_mut().lookup_ip(host)) } } #[cfg(test)] mod tests { extern crate tokio_core; use std::net::{IpAddr, Ipv4Addr}; use super::*; #[test] fn test_lookup() { let mut resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap(); let mut response = resolver.lookup_ip("www.example.com.").unwrap(); println!("response records: {:?}", response); let address = response.next().expect("no addresses returned"); assert_eq!(address, IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34))); } }