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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.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. //! Synchronous DNS Resolution //! //! Contains the functionality to perform DNS resolution or reverse lookup, //! in a style related to `getaddrinfo()` and `getnameinfo()`, respectively. #![allow(missing_docs)] pub use self::SocketType::*; pub use self::Flag::*; pub use self::Protocol::*; use iter::IteratorExt; use io::{IoResult}; use io::net::ip::{SocketAddr, IpAddr}; use option::Option; use option::Option::{Some, None}; use string::String; use sys; use vec::Vec; /// Hints to the types of sockets that are desired when looking up hosts #[deriving(Copy)] pub enum SocketType { Stream, Datagram, Raw } /// Flags which can be or'd into the `flags` field of a `Hint`. These are used /// to manipulate how a query is performed. /// /// The meaning of each of these flags can be found with `man -s 3 getaddrinfo` #[deriving(Copy)] pub enum Flag { AddrConfig, All, CanonName, NumericHost, NumericServ, Passive, V4Mapped, } /// A transport protocol associated with either a hint or a return value of /// `lookup` #[deriving(Copy)] pub enum Protocol { TCP, UDP } /// This structure is used to provide hints when fetching addresses for a /// remote host to control how the lookup is performed. /// /// For details on these fields, see their corresponding definitions via /// `man -s 3 getaddrinfo` #[deriving(Copy)] pub struct Hint { pub family: uint, pub socktype: Option<SocketType>, pub protocol: Option<Protocol>, pub flags: uint, } #[deriving(Copy)] pub struct Info { pub address: SocketAddr, pub family: uint, pub socktype: Option<SocketType>, pub protocol: Option<Protocol>, pub flags: uint, } /// Easy name resolution. Given a hostname, returns the list of IP addresses for /// that hostname. pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> { lookup(Some(host), None, None).map(|a| a.into_iter().map(|i| i.address.ip).collect()) } /// Reverse name resolution. Given an address, returns the corresponding /// hostname. pub fn get_address_name(addr: IpAddr) -> IoResult<String> { sys::addrinfo::get_address_name(addr) } /// Full-fledged resolution. This function will perform a synchronous call to /// getaddrinfo, controlled by the parameters /// /// # Arguments /// /// * hostname - an optional hostname to lookup against /// * servname - an optional service name, listed in the system services /// * hint - see the hint structure, and "man -s 3 getaddrinfo", for how this /// controls lookup /// /// FIXME: this is not public because the `Hint` structure is not ready for public /// consumption just yet. #[allow(unused_variables)] fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>) -> IoResult<Vec<Info>> { sys::addrinfo::get_host_addresses(hostname, servname, hint) } // Ignored on android since we cannot give tcp/ip // permission without help of apk #[cfg(all(test, not(target_os = "android")))] mod test { use prelude::*; use super::*; use io::net::ip::*; #[test] fn dns_smoke_test() { let ipaddrs = get_host_addresses("localhost").unwrap(); let mut found_local = false; let local_addr = &Ipv4Addr(127, 0, 0, 1); for addr in ipaddrs.iter() { found_local = found_local || addr == local_addr; } assert!(found_local); } #[ignore] #[test] fn issue_10663() { // Something should happen here, but this certainly shouldn't cause // everything to die. The actual outcome we don't care too much about. get_host_addresses("example.com").unwrap(); } }