Skip to content

Commit

Permalink
Rollup merge of #41582 - jonhoo:reread-nameservers-on-lookup-fail, r=…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
frewsxcv authored May 5, 2017
2 parents 69f4e31 + 68ae617 commit b091d6e
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/libstd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
19 changes: 16 additions & 3 deletions src/libstd/sys_common/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/test/run-make/tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ else
endif
else
ifeq ($(UNAME),Darwin)
EXTRACFLAGS := -lresolv
else
ifeq ($(UNAME),FreeBSD)
EXTRACFLAGS := -lm -lpthread -lgcc_s
Expand Down

0 comments on commit b091d6e

Please sign in to comment.