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
use std::net::*; use std::str::FromStr; use trust_dns::client::{Client, SyncClient}; use trust_dns::op::DnsResponse; use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType}; use trust_dns::udp::UdpClientConnection; use failure::*; mod dns_ip; pub use dns_ip::{Provider as DnsIpProvider}; #[derive(Fail, Debug)] enum Errors { #[fail(display = "No response.")] NoResponse, } pub enum Provider { OpenDNS, } impl Default for Provider { fn default() -> Provider { Provider::OpenDNS } } impl Provider { pub fn query_ipv4(&self) -> Result<Ipv4Addr, Error> { match self { Provider::OpenDNS => self.query_ipv4_opendns(), } } pub fn query_ipv6(&self) -> Result<Ipv6Addr, Error> { match self { Provider::OpenDNS => self.query_ipv6_opendns(), } } fn query_ipv4_opendns(&self) -> Result<Ipv4Addr, Error> { let address = "208.67.222.222:53".parse()?; let conn = UdpClientConnection::new(address)?; let client = SyncClient::new(conn); let name = Name::from_str("myip.opendns.com.")?; let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::A)?; let answers: &[Record] = response.answers(); if let &RData::A(ref ip) = answers[0].rdata() { Ok(*ip) } else { bail!(Errors::NoResponse) } } fn query_ipv6_opendns(&self) -> Result<Ipv6Addr, Error> { let address = "[2620:119:35::35]:53".parse()?; let conn = UdpClientConnection::new(address)?; let client = SyncClient::new(conn); let name = Name::from_str("myip.opendns.com.")?; let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AAAA)?; let answers: &[Record] = response.answers(); if let &RData::AAAA(ref ip) = answers[0].rdata() { Ok(*ip) } else { bail!(Errors::NoResponse) } } }