From d6237cefcb9fae0286a920b182e9bbc928a57c8a Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 3 Jun 2016 23:10:36 +0200 Subject: [PATCH 1/3] 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. --- src/libstd/net/addr.rs | 7 +------ src/libstd/net/mod.rs | 4 ++-- src/libstd/sys/common/net.rs | 14 +++++++++----- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index d510339f1c5b4..44a7823f82acd 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -448,12 +448,7 @@ impl ToSocketAddrs for (Ipv6Addr, u16) { fn resolve_socket_addr(s: &str, p: u16) -> io::Result> { 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 4507046028271..95df7f7eaeb3e 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; - fn next(&mut self) -> Option> { self.0.next() } + type Item = SocketAddr; + fn next(&mut self) -> Option { self.0.next() } } /// Resolve the host specified by `host` as a number of `SocketAddr` instances. diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 54b9b466c4224..3e2a0a8f39a8f 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -119,14 +119,18 @@ pub struct LookupHost { } impl Iterator for LookupHost { - type Item = io::Result; - fn next(&mut self) -> Option> { + type Item = SocketAddr; + fn next(&mut self) -> Option { + let result; 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); + result = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr), + (*self.cur).ai_addrlen as usize).ok(); self.cur = (*self.cur).ai_next as *mut c::addrinfo; - Some(ret) + } + match result { + Some(r) => Some(r), + None => self.next(), } } } From a03a82e5e0ae59b0c0b11b671e058fda9f7bb3d0 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sat, 4 Jun 2016 20:09:19 +0200 Subject: [PATCH 2/3] Convert a simple tail call to a loop --- src/libstd/sys/common/net.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 3e2a0a8f39a8f..274e495d70eb6 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -121,16 +121,20 @@ pub struct LookupHost { impl Iterator for LookupHost { type Item = SocketAddr; fn next(&mut self) -> Option { - let result; - unsafe { - if self.cur.is_null() { return None } - result = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr), - (*self.cur).ai_addrlen as usize).ok(); - self.cur = (*self.cur).ai_next as *mut c::addrinfo; - } - match result { - Some(r) => Some(r), - None => self.next(), + 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, + } + } } } } From 6aa01825204e8c3c29d104935de78df74a8e51d3 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 29 Jun 2016 11:44:33 +0200 Subject: [PATCH 3/3] Update documentation to reflect ignoring of unknown addresses --- src/libstd/net/addr.rs | 3 +++ src/libstd/net/mod.rs | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 44a7823f82acd..b93ca8277e636 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 diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index 95df7f7eaeb3e..ac13b23ebee50 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -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(()) /// # }