diff options
| author | Corey Farwell <coreyf@rwell.org> | 2017-05-05 17:35:26 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-05 17:35:26 -0400 |
| commit | b091d6ed428a5edb67ad24850374e75e7f615c93 (patch) | |
| tree | d23c1b6b2c0db4d1fcd51fbf95be04e7ce601a98 /src/libstd | |
| parent | 69f4e318a0280d3cffda9fd9ca60ba084c5a27fd (diff) | |
| parent | 68ae6173fea7411a5d9e5bde6624f5606caf8fe8 (diff) | |
| download | rust-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.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys_common/net.rs | 19 |
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), + } } } |
