Skip to content

Commit

Permalink
Add std::net::lookup_addr for reverse DNS lookup
Browse files Browse the repository at this point in the history
Closes #22608
  • Loading branch information
murarth committed Mar 27, 2015
1 parent 1501f33 commit c0dd239
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
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

0 comments on commit c0dd239

Please sign in to comment.