Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add std::net::lookup_addr for reverse DNS lookup #23419

Merged
merged 1 commit into from
Mar 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/libstd/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ pub struct SocketAddrV4 { inner: libc::sockaddr_in }
pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }

impl SocketAddr {
/// Creates a new socket address from the (ip, port) pair.
#[unstable(feature = "ip_addr", reason = "recent addition")]
pub fn new(ip: IpAddr, port: u16) -> SocketAddr {
match ip {
IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
}
}

/// Gets the IP address associated with this socket address.
#[unstable(feature = "ip_addr", reason = "recent addition")]
pub fn ip(&self) -> IpAddr {
Expand Down
10 changes: 10 additions & 0 deletions src/libstd/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,13 @@ impl Iterator for LookupHost {
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
net_imp::lookup_host(host).map(LookupHost)
}

/// Resolve the given address to a hostname.
///
/// This function may perform a DNS query to resolve `addr` and may also inspect
/// system configuration to resolve the specified address. If the address
/// cannot be resolved, it is returned in string format.
#[unstable(feature = "lookup_addr", reason = "recent addition")]
pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
net_imp::lookup_addr(addr)
}
39 changes: 38 additions & 1 deletion src/libstd/sys/common/net2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@

use prelude::v1::*;

use ffi::CString;
use ffi::{CStr, CString};
use io::{self, Error, ErrorKind};
use libc::{self, c_int, c_char, c_void, socklen_t};
use mem;
use net::{SocketAddr, Shutdown, IpAddr};
use str::from_utf8;
use sys::c;
use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
use sys_common::{AsInner, FromInner, IntoInner};
Expand Down Expand Up @@ -126,6 +127,42 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
}
}

////////////////////////////////////////////////////////////////////////////////
// lookup_addr
////////////////////////////////////////////////////////////////////////////////

extern "system" {
fn getnameinfo(sa: *const libc::sockaddr, salen: socklen_t,
host: *mut c_char, hostlen: libc::size_t,
serv: *mut c_char, servlen: libc::size_t,
flags: c_int) -> c_int;
}

const NI_MAXHOST: usize = 1025;

pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
init();

let saddr = SocketAddr::new(*addr, 0);
let (inner, len) = saddr.into_inner();
let mut hostbuf = [0 as c_char; NI_MAXHOST];

let data = unsafe {
try!(cvt_gai(getnameinfo(inner, len,
hostbuf.as_mut_ptr(), NI_MAXHOST as libc::size_t,
0 as *mut _, 0, 0)));

CStr::from_ptr(hostbuf.as_ptr())
};

match from_utf8(data.to_bytes()) {
Ok(name) => Ok(name.to_string()),
Err(_) => Err(io::Error::new(io::ErrorKind::Other,
"failed to lookup address information",
Some("invalid host name".to_string())))
}
}

////////////////////////////////////////////////////////////////////////////////
// TCP streams
////////////////////////////////////////////////////////////////////////////////
Expand Down