Implementing the trait and macro in this crate will expose a
gethostbyname4_r FFI hook for NSS in your Rust cdylib.
use libnss_host4::{Addr, HostResolver, err::NssErr, impl_gethostbyname4_r};
use std::net::Ipv6Addr;
/// This resolver maps "localhost" to [::1%0].
struct LocalDns;
impl_gethostbyname4_r!(local, LocalDns);
impl HostResolver for LocalDns {
fn resolve_host(hostname: &str) -> Result<impl IntoIterator<Item = Addr>, NssErr> {
if hostname == "localhost" {
return Ok([Addr {
ip: Ipv6Addr::LOCALHOST.into(),
scope_id: 0,
}]);
}
Err(NssErr::NO_RESULT)
}
}See examples/nss_example.rs for more info.
Building the example as an NSS module requires the crate-type = ["cdylib"]
declaration shown in Cargo.toml.
glibc defines a Name Service Switch interface for querying hostnames.
https://sourceware.org/glibc/manual/2.43/html_mono/libc.html#Host-Names
This once-simple lookup API has unfortunately degenerated into a sedimentary
chaos of numbered functions differentiated by reentrance and lack thereof.
An early indication of which is the conspicuous absence of gethostbyname3_r
and gethostbyname4_r in the docs linked above.
However, as of writing, gethostbyname4_r is the only NSS host hook that
can return IPv6 addresses with a scope_id, which makes it a big deal
for the chosen few who care about such things.
Other Rust NSS usage is already well supported by the libnss crate.
The motivating cause for this crate cannot accomodate its GPL license,
which is why this is standalone. Presumably both crates can be used in
the same cdylib to cover the full NSS host API.
If the other hooks aren't needed, though, a cdylib with just gethostbyname4_r
is sufficient for getaddrinfo-based resolution via /etc/nsswitch.conf.
Licensed under either of the following at your option:
- MIT license (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)
Unless explicitly stated otherwise, any contribution to this crate shall be dual licensed as above without any additional terms or conditions.