about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-05-05 17:35:26 -0400
committerGitHub <noreply@github.com>2017-05-05 17:35:26 -0400
commitb091d6ed428a5edb67ad24850374e75e7f615c93 (patch)
treed23c1b6b2c0db4d1fcd51fbf95be04e7ce601a98 /src/libstd
parent69f4e318a0280d3cffda9fd9ca60ba084c5a27fd (diff)
parent68ae6173fea7411a5d9e5bde6624f5606caf8fe8 (diff)
downloadrust-b091d6ed428a5edb67ad24850374e75e7f615c93.tar.gz
rust-b091d6ed428a5edb67ad24850374e75e7f615c93.zip
Rollup merge of #41582 - jonhoo:reread-nameservers-on-lookup-fail, r=alexcrichton
Reload nameserver information on lookup failure

As discussed in #41570, UNIX systems often cache the contents of `/etc/resolv.conf`, which can cause lookup failures to persist even after a network connection becomes available. This patch modifies lookup_host to force a reload of the nameserver entries following a lookup failure. This is in line with what many C programs already do (see #41570 for details). On systems with nscd, this should not be necessary, but not all systems run nscd.

Fixes #41570.
Depends on rust-lang/libc#585.

r? @alexcrichton
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/build.rs5
-rw-r--r--src/libstd/sys_common/net.rs19
2 files changed, 21 insertions, 3 deletions
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 9fb83ad7598..f84662c3f86 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -43,11 +43,16 @@ fn main() {
         println!("cargo:rustc-link-lib=pthread");
     } else if target.contains("apple-darwin") {
         println!("cargo:rustc-link-lib=System");
+
+        // res_init and friends require -lresolv on macOS/iOS.
+        // See #41582 and http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
+        println!("cargo:rustc-link-lib=resolv");
     } else if target.contains("apple-ios") {
         println!("cargo:rustc-link-lib=System");
         println!("cargo:rustc-link-lib=objc");
         println!("cargo:rustc-link-lib=framework=Security");
         println!("cargo:rustc-link-lib=framework=Foundation");
+        println!("cargo:rustc-link-lib=resolv");
     } else if target.contains("windows") {
         println!("cargo:rustc-link-lib=advapi32");
         println!("cargo:rustc-link-lib=ws2_32");
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index 9239c18e597..a1897c8bd67 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -177,9 +177,22 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     };
     let mut res = ptr::null_mut();
     unsafe {
-        cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints,
-                               &mut res))?;
-        Ok(LookupHost { original: res, cur: res })
+        match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) {
+            Ok(_) => {
+                Ok(LookupHost { original: res, cur: res })
+            },
+            #[cfg(unix)]
+            Err(e) => {
+                // The lookup failure could be caused by using a stale /etc/resolv.conf.
+                // See https://github.com/rust-lang/rust/issues/41570.
+                // We therefore force a reload of the nameserver information.
+                c::res_init();
+                Err(e)
+            },
+            // the cfg is needed here to avoid an "unreachable pattern" warning
+            #[cfg(not(unix))]
+            Err(e) => Err(e),
+        }
     }
 }