summary refs log tree commit diff
path: root/src/libstd/sys_common
diff options
context:
space:
mode:
authorJon Gjengset <jon@thesquareplanet.com>2017-04-27 12:58:52 -0400
committerJon Gjengset <jon@thesquareplanet.com>2017-05-04 23:59:55 -0400
commit68ae6173fea7411a5d9e5bde6624f5606caf8fe8 (patch)
treefa1a3d6909c73b8045d94d1930a3ef1ac0b93f93 /src/libstd/sys_common
parent4961d724f8d02870087c1912a55378458b0d6a90 (diff)
downloadrust-68ae6173fea7411a5d9e5bde6624f5606caf8fe8.tar.gz
rust-68ae6173fea7411a5d9e5bde6624f5606caf8fe8.zip
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.

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.
Diffstat (limited to 'src/libstd/sys_common')
-rw-r--r--src/libstd/sys_common/net.rs19
1 files changed, 16 insertions, 3 deletions
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),
+        }
     }
 }