std::rt: Add get_host_addresses function
This is a very simplistic method for host name resolution. It converts a host name to a vector of IP addresses. Should be enough to get started.
This commit is contained in:
parent
c218694cec
commit
0948f54e65
@ -269,13 +269,7 @@ pub use self::extensions::WriterByteConversions;
|
||||
pub mod file;
|
||||
|
||||
/// Synchronous, non-blocking network I/O.
|
||||
pub mod net {
|
||||
pub mod tcp;
|
||||
pub mod udp;
|
||||
pub mod ip;
|
||||
#[cfg(unix)]
|
||||
pub mod unix;
|
||||
}
|
||||
pub mod net;
|
||||
|
||||
/// Readers and Writers for memory buffers and strings.
|
||||
pub mod mem;
|
||||
|
@ -8,14 +8,55 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use option::{Option, Some, None};
|
||||
use result::{Ok, Err};
|
||||
use rt::io::io_error;
|
||||
use rt::io::net::ip::IpAddr;
|
||||
use rt::rtio::{IoFactory, IoFactoryObject};
|
||||
use rt::local::Local;
|
||||
|
||||
fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
|
||||
pub mod tcp;
|
||||
pub mod udp;
|
||||
pub mod ip;
|
||||
#[cfg(unix)]
|
||||
pub mod unix;
|
||||
|
||||
/// Simplistic name resolution
|
||||
pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
|
||||
/*!
|
||||
* Get the IP addresses for a given host name.
|
||||
*
|
||||
* Raises io_error on failure.
|
||||
*/
|
||||
|
||||
fail!()
|
||||
let ipaddrs = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).get_host_addresses(host)
|
||||
};
|
||||
|
||||
match ipaddrs {
|
||||
Ok(i) => Some(i),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use option::Some;
|
||||
use rt::io::net::ip::Ipv4Addr;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn dns_smoke_test() {
|
||||
let ipaddrs = get_host_addresses("localhost").unwrap();
|
||||
let mut found_local = false;
|
||||
let local_addr = &Ipv4Addr(127, 0, 0, 1);
|
||||
for addr in ipaddrs.iter() {
|
||||
found_local = found_local || addr == local_addr;
|
||||
}
|
||||
assert!(found_local);
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ pub trait IoFactory {
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~RtioFileStream, IoError>;
|
||||
fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
|
||||
fn get_host_addresses(&mut self, host: &str) -> Result<~[IpAddr], IoError>;
|
||||
}
|
||||
|
||||
pub trait RtioTcpListener : RtioSocket {
|
||||
|
@ -29,7 +29,8 @@ use rt::tube::Tube;
|
||||
use rt::task::SchedHome;
|
||||
use rt::uv::*;
|
||||
use rt::uv::idle::IdleWatcher;
|
||||
use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
|
||||
use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr, accum_sockaddrs};
|
||||
use rt::uv::addrinfo::GetAddrInfoRequest;
|
||||
use unstable::sync::Exclusive;
|
||||
use super::super::io::support::PathLike;
|
||||
use libc::{lseek, off_t, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
|
||||
@ -596,6 +597,37 @@ impl IoFactory for UvIoFactory {
|
||||
assert!(!result_cell.is_empty());
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn get_host_addresses(&mut self, host: &str) -> Result<~[IpAddr], IoError> {
|
||||
let result_cell = Cell::new_empty();
|
||||
let result_cell_ptr: *Cell<Result<~[IpAddr], IoError>> = &result_cell;
|
||||
let host_ptr: *&str = &host;
|
||||
let addrinfo_req = GetAddrInfoRequest::new();
|
||||
let addrinfo_req_cell = Cell::new(addrinfo_req);
|
||||
do task::unkillable { // FIXME(#8674)
|
||||
let scheduler: ~Scheduler = Local::take();
|
||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||
let task_cell = Cell::new(task);
|
||||
let mut addrinfo_req = addrinfo_req_cell.take();
|
||||
unsafe {
|
||||
do addrinfo_req.getaddrinfo(self.uv_loop(),
|
||||
Some(*host_ptr),
|
||||
None, None) |_, addrinfo, err| {
|
||||
let res = match err {
|
||||
None => Ok(accum_sockaddrs(addrinfo).map(|addr| addr.ip.clone())),
|
||||
Some(err) => Err(uv_error_to_io_error(err))
|
||||
};
|
||||
(*result_cell_ptr).put_back(res);
|
||||
let scheduler: ~Scheduler = Local::take();
|
||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
addrinfo_req.delete();
|
||||
assert!(!result_cell.is_empty());
|
||||
return result_cell.take();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UvTcpListener {
|
||||
|
Loading…
Reference in New Issue
Block a user