diff options
| author | Jon Gjengset <jon@thesquareplanet.com> | 2017-04-27 12:58:52 -0400 |
|---|---|---|
| committer | Jon Gjengset <jon@thesquareplanet.com> | 2017-05-04 23:59:55 -0400 |
| commit | 68ae6173fea7411a5d9e5bde6624f5606caf8fe8 (patch) | |
| tree | fa1a3d6909c73b8045d94d1930a3ef1ac0b93f93 /src/libstd/sys_common | |
| parent | 4961d724f8d02870087c1912a55378458b0d6a90 (diff) | |
| download | rust-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.rs | 19 |
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), + } } } |
