about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-07-01 18:43:28 -0700
committerGitHub <noreply@github.com>2016-07-01 18:43:28 -0700
commit32a6373322d381c5778daea39a4f3b7ff94d9ee0 (patch)
treec9dc0b5377eef02cc968d9f68be600ec68275322
parent01411937ff6b2a2dfad03d060d636941b0034591 (diff)
parent6aa01825204e8c3c29d104935de78df74a8e51d3 (diff)
downloadrust-32a6373322d381c5778daea39a4f3b7ff94d9ee0.tar.gz
rust-32a6373322d381c5778daea39a4f3b7ff94d9ee0.zip
Auto merge of #34067 - tbu-:pr_lookup_host_ignore_other_addresses, r=alexcrichton
Ignore unknown address types when looking up hosts

Previously, any function using a `ToSocketAddrs` input would fail if
passed a hostname that resolves to an address type different from the
ones recognized by Rust.

This also changes the `LookupHost` iterator to only include the known
address types, as a result, it doesn't have to return `Result`s any
more, which are likely misinterpreted as failed name lookups.
-rw-r--r--src/libstd/net/addr.rs10
-rw-r--r--src/libstd/net/mod.rs9
-rw-r--r--src/libstd/sys/common/net.rs24
3 files changed, 26 insertions, 17 deletions
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index d510339f1c5..b93ca8277e6 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -344,6 +344,9 @@ impl hash::Hash for SocketAddrV6 {
 /// some other type (e.g. a string) just for it to be converted back to
 /// `SocketAddr` in constructor methods is pointless.
 ///
+/// Addresses returned by the operating system that are not IP addresses are
+/// silently ignored.
+///
 /// Some examples:
 ///
 /// ```no_run
@@ -448,12 +451,7 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {
 
 fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
     let ips = lookup_host(s)?;
-    let v: Vec<_> = ips.map(|a| {
-        a.map(|mut a| {
-            a.set_port(p);
-            a
-        })
-    }).collect()?;
+    let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
     Ok(v.into_iter())
 }
 
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index 45070460282..ac13b23ebee 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -98,8 +98,8 @@ pub struct LookupHost(net_imp::LookupHost);
                                               addresses",
            issue = "27705")]
 impl Iterator for LookupHost {
-    type Item = io::Result<SocketAddr>;
-    fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
 }
 
 /// Resolve the host specified by `host` as a number of `SocketAddr` instances.
@@ -107,6 +107,9 @@ impl Iterator for LookupHost {
 /// This method may perform a DNS query to resolve `host` and may also inspect
 /// system configuration to resolve the specified hostname.
 ///
+/// The returned iterator will skip over any unknown addresses returned by the
+/// operating system.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -116,7 +119,7 @@ impl Iterator for LookupHost {
 ///
 /// # fn foo() -> std::io::Result<()> {
 /// for host in try!(net::lookup_host("rust-lang.org")) {
-///     println!("found address: {}", try!(host));
+///     println!("found address: {}", host);
 /// }
 /// # Ok(())
 /// # }
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 54b9b466c42..274e495d70e 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -119,14 +119,22 @@ pub struct LookupHost {
 }
 
 impl Iterator for LookupHost {
-    type Item = io::Result<SocketAddr>;
-    fn next(&mut self) -> Option<io::Result<SocketAddr>> {
-        unsafe {
-            if self.cur.is_null() { return None }
-            let ret = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr),
-                                       (*self.cur).ai_addrlen as usize);
-            self.cur = (*self.cur).ai_next as *mut c::addrinfo;
-            Some(ret)
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> {
+        loop {
+            unsafe {
+                let cur = match self.cur.as_ref() {
+                    None => return None,
+                    Some(c) => c,
+                };
+                self.cur = cur.ai_next;
+                match sockaddr_to_addr(mem::transmute(cur.ai_addr),
+                                       cur.ai_addrlen as usize)
+                {
+                    Ok(addr) => return Some(addr),
+                    Err(_) => continue,
+                }
+            }
         }
     }
 }