]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/net/addrinfo.rs
Doc says to avoid mixing allocator instead of forbiding it
[rust.git] / src / libstd / io / net / addrinfo.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12
13 Synchronous DNS Resolution
14
15 Contains the functionality to perform DNS resolution in a style related to
16 getaddrinfo()
17
18 */
19
20 #![allow(missing_doc)]
21
22 use iter::Iterator;
23 use io::{IoResult, IoError};
24 use io::net::ip::{SocketAddr, IpAddr};
25 use option::{Option, Some, None};
26 use result::{Ok, Err};
27 use rt::rtio::{IoFactory, LocalIo};
28 use rt::rtio;
29 use vec::Vec;
30
31 /// Hints to the types of sockets that are desired when looking up hosts
32 pub enum SocketType {
33     Stream, Datagram, Raw
34 }
35
36 /// Flags which can be or'd into the `flags` field of a `Hint`. These are used
37 /// to manipulate how a query is performed.
38 ///
39 /// The meaning of each of these flags can be found with `man -s 3 getaddrinfo`
40 pub enum Flag {
41     AddrConfig,
42     All,
43     CanonName,
44     NumericHost,
45     NumericServ,
46     Passive,
47     V4Mapped,
48 }
49
50 /// A transport protocol associated with either a hint or a return value of
51 /// `lookup`
52 pub enum Protocol {
53     TCP, UDP
54 }
55
56 /// This structure is used to provide hints when fetching addresses for a
57 /// remote host to control how the lookup is performed.
58 ///
59 /// For details on these fields, see their corresponding definitions via
60 /// `man -s 3 getaddrinfo`
61 pub struct Hint {
62     pub family: uint,
63     pub socktype: Option<SocketType>,
64     pub protocol: Option<Protocol>,
65     pub flags: uint,
66 }
67
68 pub struct Info {
69     pub address: SocketAddr,
70     pub family: uint,
71     pub socktype: Option<SocketType>,
72     pub protocol: Option<Protocol>,
73     pub flags: uint,
74 }
75
76 /// Easy name resolution. Given a hostname, returns the list of IP addresses for
77 /// that hostname.
78 pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> {
79     lookup(Some(host), None, None).map(|a| a.move_iter().map(|i| i.address.ip).collect())
80 }
81
82 /// Full-fledged resolution. This function will perform a synchronous call to
83 /// getaddrinfo, controlled by the parameters
84 ///
85 /// # Arguments
86 ///
87 /// * hostname - an optional hostname to lookup against
88 /// * servname - an optional service name, listed in the system services
89 /// * hint - see the hint structure, and "man -s 3 getaddrinfo", for how this
90 ///          controls lookup
91 ///
92 /// FIXME: this is not public because the `Hint` structure is not ready for public
93 ///      consumption just yet.
94 #[allow(unused_variable)]
95 fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
96           -> IoResult<Vec<Info>> {
97     let hint = hint.map(|Hint { family, socktype, protocol, flags }| {
98         rtio::AddrinfoHint {
99             family: family,
100             socktype: 0, // FIXME: this should use the above variable
101             protocol: 0, // FIXME: this should use the above variable
102             flags: flags,
103         }
104     });
105     match LocalIo::maybe_raise(|io| {
106         io.get_host_addresses(hostname, servname, hint)
107     }) {
108         Ok(v) => Ok(v.move_iter().map(|info| {
109             Info {
110                 address: SocketAddr {
111                     ip: super::from_rtio(info.address.ip),
112                     port: info.address.port,
113                 },
114                 family: info.family,
115                 socktype: None, // FIXME: this should use the above variable
116                 protocol: None, // FIXME: this should use the above variable
117                 flags: info.flags,
118             }
119         }).collect()),
120         Err(e) => Err(IoError::from_rtio_error(e)),
121     }
122 }
123
124 // Ignored on android since we cannot give tcp/ip
125 // permission without help of apk
126 #[cfg(test, not(target_os = "android"))]
127 mod test {
128     iotest!(fn dns_smoke_test() {
129         let ipaddrs = get_host_addresses("localhost").unwrap();
130         let mut found_local = false;
131         let local_addr = &Ipv4Addr(127, 0, 0, 1);
132         for addr in ipaddrs.iter() {
133             found_local = found_local || addr == local_addr;
134         }
135         assert!(found_local);
136     })
137
138     iotest!(fn issue_10663() {
139         // Something should happen here, but this certainly shouldn't cause
140         // everything to die. The actual outcome we don't care too much about.
141         get_host_addresses("example.com").unwrap();
142     } #[ignore])
143 }