Skip to content

Commit 68ae617

Browse files
committed
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.
1 parent 4961d72 commit 68ae617

File tree

4 files changed

+23
-4
lines changed

4 files changed

+23
-4
lines changed

src/libstd/build.rs

+5
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,16 @@ fn main() {
4343
println!("cargo:rustc-link-lib=pthread");
4444
} else if target.contains("apple-darwin") {
4545
println!("cargo:rustc-link-lib=System");
46+
47+
// res_init and friends require -lresolv on macOS/iOS.
48+
// See #41582 and http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
49+
println!("cargo:rustc-link-lib=resolv");
4650
} else if target.contains("apple-ios") {
4751
println!("cargo:rustc-link-lib=System");
4852
println!("cargo:rustc-link-lib=objc");
4953
println!("cargo:rustc-link-lib=framework=Security");
5054
println!("cargo:rustc-link-lib=framework=Foundation");
55+
println!("cargo:rustc-link-lib=resolv");
5156
} else if target.contains("windows") {
5257
println!("cargo:rustc-link-lib=advapi32");
5358
println!("cargo:rustc-link-lib=ws2_32");

src/libstd/sys_common/net.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,22 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
177177
};
178178
let mut res = ptr::null_mut();
179179
unsafe {
180-
cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints,
181-
&mut res))?;
182-
Ok(LookupHost { original: res, cur: res })
180+
match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) {
181+
Ok(_) => {
182+
Ok(LookupHost { original: res, cur: res })
183+
},
184+
#[cfg(unix)]
185+
Err(e) => {
186+
// The lookup failure could be caused by using a stale /etc/resolv.conf.
187+
// See https://github.com/rust-lang/rust/issues/41570.
188+
// We therefore force a reload of the nameserver information.
189+
c::res_init();
190+
Err(e)
191+
},
192+
// the cfg is needed here to avoid an "unreachable pattern" warning
193+
#[cfg(not(unix))]
194+
Err(e) => Err(e),
195+
}
183196
}
184197
}
185198

src/test/run-make/tools.mk

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ else
7272
endif
7373
else
7474
ifeq ($(UNAME),Darwin)
75+
EXTRACFLAGS := -lresolv
7576
else
7677
ifeq ($(UNAME),FreeBSD)
7778
EXTRACFLAGS := -lm -lpthread -lgcc_s

0 commit comments

Comments
 (0)