]> git.lizzy.rs Git - rust.git/commitdiff
Reload nameserver information on lookup failure
authorJon Gjengset <jon@thesquareplanet.com>
Thu, 27 Apr 2017 16:58:52 +0000 (12:58 -0400)
committerJon Gjengset <jon@thesquareplanet.com>
Fri, 5 May 2017 03:59:55 +0000 (23:59 -0400)
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.

Introduces an std linkage dependency on libresolv on macOS/iOS (which
also makes it necessary to update run-make/tools.mk).

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

src/liblibc
src/libstd/build.rs
src/libstd/sys_common/net.rs
src/test/run-make/tools.mk

index c34a802d1eb037b44c5252078c7270b5472e0f65..03562b0cb26a00f49d4eaf18ca3e49608110b0c8 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c34a802d1eb037b44c5252078c7270b5472e0f65
+Subproject commit 03562b0cb26a00f49d4eaf18ca3e49608110b0c8
index 9fb83ad75980aeb399747ff2a8315d5645151c04..f84662c3f86828874498915842c732676e131b9b 100644 (file)
@@ -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");
index 9239c18e59717a2bf088859ff05a8dbbccfbe81a..a1897c8bd676e0ec53eb11893e668a4f4f20f56e 100644 (file)
@@ -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),
+        }
     }
 }
 
index 1db87d474bd72d185d395507d511f4b0a5f623e6..693573d53a4a27960c579a588d6b5f034707d0b8 100644 (file)
@@ -72,6 +72,7 @@ else
 endif
 else
 ifeq ($(UNAME),Darwin)
+       EXTRACFLAGS := -lresolv
 else
 ifeq ($(UNAME),FreeBSD)
        EXTRACFLAGS := -lm -lpthread -lgcc_s