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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
// 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. //! Configuration for a resolver use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::time::Duration; /// Configuration for the upstream nameservers to use for resolution #[derive(Clone, Debug)] pub struct ResolverConfig { name_servers: Vec<NameServerConfig>, } impl ResolverConfig { /// Creates a new empty configuration pub fn new() -> Self { ResolverConfig { name_servers: vec![] } } // TODO: consider allowing options per NameServer... like different timeouts? /// Add the configuration for a name server pub fn add_name_server(&mut self, name_server: NameServerConfig) { self.name_servers.push(name_server); } /// Returns a reference to the name servers pub fn name_servers(&self) -> &[NameServerConfig] { &self.name_servers } } impl Default for ResolverConfig { /// Creates a default configuration, using 8.8.8.8:53 and 8.8.4.4:53 (thank you, Google). fn default() -> Self { let google_ns1 = NameServerConfig { socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53), protocol: Protocol::Udp, }; let google_ns2 = NameServerConfig { socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 4, 4)), 53), protocol: Protocol::Udp, }; ResolverConfig { name_servers: vec![google_ns1, google_ns2] } } } /// The protocol on which a NameServer should be communicated with #[derive(Clone, Debug, Eq, PartialEq)] pub enum Protocol { /// UDP is the traditional DNS port, this is generally the correct choice Udp, /// TCP can be used for large queries, but not all NameServers support it Tcp, // TODO: add client certificate for mTLS? // Tls, } /// Configuration for the NameServer #[derive(Clone, Debug, Eq, PartialEq)] pub struct NameServerConfig { /// The address which the DNS NameServer is registered at. pub socket_addr: SocketAddr, /// The protocol to use when communicating with the NameServer. pub protocol: Protocol, } /// Configuration for the Resolver #[derive(Clone, Copy)] #[allow(dead_code)] // TODO: remove after all params are supported pub struct ResolverOpts { /// Sets the number of dots that must appear (unless it's a final dot representing the root) /// that must appear before a query is assumted to include the TLD. The default is one, which /// means that `www` would never be assumed to be a TLD, and would always be appended to either /// the search /*pub*/ ndots: usize, /// Specify the timeout for a request. Defaults to 5 seconds pub timeout: Duration, /// Number of attempts before giving up. Defaults to 2 /*pub*/ attempts: usize, /// Rotate through the resource records in the response (if there is more than one for a given name) /*pub*/ rotate: bool, /// Validate the names in the response /*pub*/ check_names: bool, /// Enable edns, for larger records /*pub*/ edns0: bool, /// Use DNSSec to validate the request /*pub*/ validate: bool, } impl Default for ResolverOpts { /// Default values for the Reolver configuration. /// /// This follows the resolv.conf defaults as defined in the [Linux man pages](http://man7.org/linux/man-pages/man5/resolv.conf.5.html) fn default() -> Self { ResolverOpts { ndots: 1, timeout: Duration::from_secs(5), attempts: 2, rotate: false, check_names: true, edns0: false, validate: false, } } }