Skip to content

Commit 0948f54

Browse files
committed
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.
1 parent c218694 commit 0948f54

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

src/libstd/rt/io/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,7 @@ pub use self::extensions::WriterByteConversions;
269269
pub mod file;
270270

271271
/// Synchronous, non-blocking network I/O.
272-
pub mod net {
273-
pub mod tcp;
274-
pub mod udp;
275-
pub mod ip;
276-
#[cfg(unix)]
277-
pub mod unix;
278-
}
272+
pub mod net;
279273

280274
/// Readers and Writers for memory buffers and strings.
281275
pub mod mem;

src/libstd/rt/io/net/mod.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,55 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use option::{Option, Some, None};
12+
use result::{Ok, Err};
13+
use rt::io::io_error;
1114
use rt::io::net::ip::IpAddr;
15+
use rt::rtio::{IoFactory, IoFactoryObject};
16+
use rt::local::Local;
1217

13-
fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
18+
pub mod tcp;
19+
pub mod udp;
20+
pub mod ip;
21+
#[cfg(unix)]
22+
pub mod unix;
23+
24+
/// Simplistic name resolution
25+
pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
1426
/*!
1527
* Get the IP addresses for a given host name.
1628
*
1729
* Raises io_error on failure.
1830
*/
1931

20-
fail!()
32+
let ipaddrs = unsafe {
33+
let io: *mut IoFactoryObject = Local::unsafe_borrow();
34+
(*io).get_host_addresses(host)
35+
};
36+
37+
match ipaddrs {
38+
Ok(i) => Some(i),
39+
Err(ioerr) => {
40+
io_error::cond.raise(ioerr);
41+
None
42+
}
43+
}
44+
}
45+
46+
#[cfg(test)]
47+
mod test {
48+
use option::Some;
49+
use rt::io::net::ip::Ipv4Addr;
50+
use super::*;
51+
52+
#[test]
53+
fn dns_smoke_test() {
54+
let ipaddrs = get_host_addresses("localhost").unwrap();
55+
let mut found_local = false;
56+
let local_addr = &Ipv4Addr(127, 0, 0, 1);
57+
for addr in ipaddrs.iter() {
58+
found_local = found_local || addr == local_addr;
59+
}
60+
assert!(found_local);
61+
}
2162
}

src/libstd/rt/rtio.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub trait IoFactory {
7373
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
7474
-> Result<~RtioFileStream, IoError>;
7575
fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
76+
fn get_host_addresses(&mut self, host: &str) -> Result<~[IpAddr], IoError>;
7677
}
7778

7879
pub trait RtioTcpListener : RtioSocket {

src/libstd/rt/uv/uvio.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ use rt::tube::Tube;
2929
use rt::task::SchedHome;
3030
use rt::uv::*;
3131
use rt::uv::idle::IdleWatcher;
32-
use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
32+
use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr, accum_sockaddrs};
33+
use rt::uv::addrinfo::GetAddrInfoRequest;
3334
use unstable::sync::Exclusive;
3435
use super::super::io::support::PathLike;
3536
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 {
596597
assert!(!result_cell.is_empty());
597598
return result_cell.take();
598599
}
600+
601+
fn get_host_addresses(&mut self, host: &str) -> Result<~[IpAddr], IoError> {
602+
let result_cell = Cell::new_empty();
603+
let result_cell_ptr: *Cell<Result<~[IpAddr], IoError>> = &result_cell;
604+
let host_ptr: *&str = &host;
605+
let addrinfo_req = GetAddrInfoRequest::new();
606+
let addrinfo_req_cell = Cell::new(addrinfo_req);
607+
do task::unkillable { // FIXME(#8674)
608+
let scheduler: ~Scheduler = Local::take();
609+
do scheduler.deschedule_running_task_and_then |_, task| {
610+
let task_cell = Cell::new(task);
611+
let mut addrinfo_req = addrinfo_req_cell.take();
612+
unsafe {
613+
do addrinfo_req.getaddrinfo(self.uv_loop(),
614+
Some(*host_ptr),
615+
None, None) |_, addrinfo, err| {
616+
let res = match err {
617+
None => Ok(accum_sockaddrs(addrinfo).map(|addr| addr.ip.clone())),
618+
Some(err) => Err(uv_error_to_io_error(err))
619+
};
620+
(*result_cell_ptr).put_back(res);
621+
let scheduler: ~Scheduler = Local::take();
622+
scheduler.resume_blocked_task_immediately(task_cell.take());
623+
}
624+
}
625+
}
626+
}
627+
addrinfo_req.delete();
628+
assert!(!result_cell.is_empty());
629+
return result_cell.take();
630+
}
599631
}
600632

601633
pub struct UvTcpListener {

0 commit comments

Comments
 (0)