std: net::ip::get_addr is working w/ happy path test. needs more.

This commit is contained in:
Jeff Olson 2012-06-25 08:02:34 -07:00 committed by Brian Anderson
parent bcc341f5fb
commit 5304698621
3 changed files with 77 additions and 32 deletions

View File

@ -17,9 +17,10 @@ import uv_ip4_name = uv::ll::ip4_name;
import uv_ip6_addr = uv::ll::ip6_addr;
import uv_ip6_name = uv::ll::ip6_name;
import uv_getaddrinfo = uv::ll::getaddrinfo;
import uv_freeaddrinfo = uv::ll::freeaddrinfo;
import create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t;
import set_data_for_uv_handle = uv::ll::set_data_for_uv_handle;
import get_data_for_uv_handle = uv::ll::get_data_for_uv_handle;
import set_data_for_req = uv::ll::set_data_for_req;
import get_data_for_req = uv::ll::get_data_for_req;
import ll = uv::ll;
export ip_addr, parse_addr_err;
@ -77,43 +78,65 @@ type get_addr_data = {
crust fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int,
res: *addrinfo) unsafe {
let handle_data = get_data_for_uv_handle(handle) as
log(debug, "in get_addr_cb");
let handle_data = get_data_for_req(handle) as
*get_addr_data;
if status == 0i32 {
if res != (ptr::null::<addrinfo>()) {
let mut out_vec = [];
let mut addr_strings = [];
log(debug, #fmt("initial addrinfo: %?", res));
let mut curr_addr = res;
loop {
if ll::is_ipv4_addrinfo(curr_addr) {
out_vec +=
[ipv4(copy((
*ll::addrinfo_as_sockaddr_in(curr_addr))))];
let new_ip_addr = if ll::is_ipv4_addrinfo(curr_addr) {
ipv4(copy((
*ll::addrinfo_as_sockaddr_in(curr_addr))))
}
else {
out_vec +=
[ipv6(copy((
*ll::addrinfo_as_sockaddr_in6(curr_addr))))];
ipv6(copy((
*ll::addrinfo_as_sockaddr_in6(curr_addr))))
};
// we're doing this check to avoid adding multiple
// ip_addrs to the out_vec that are duplicates.. on
// 64bit unbuntu a call to uv_getaddrinfo against
// localhost seems to return three addrinfos, all
// distinct (by ptr addr), that are all ipv4
// addresses and all point to 127.0.0.1
let addr_str = format_addr(new_ip_addr);
if !vec::contains(addr_strings, addr_str) {
addr_strings += [addr_str];
out_vec += [new_ip_addr];
}
let next_addr = ll::get_next_addrinfo(curr_addr);
if next_addr == ptr::null::<addrinfo>() as *addrinfo {
log(debug, "null next_addr encountered. no mas");
break;
}
else {
curr_addr = next_addr
curr_addr = next_addr;
log(debug, #fmt("next_addr addrinfo: %?", curr_addr));
}
}
log(debug, #fmt("successful process addrinfo result, len: %?",
vec::len(out_vec)));
(*handle_data).output_ch.send(result::ok(out_vec));
}
else {
log(debug, "addrinfo pointer is NULL");
(*handle_data).output_ch.send(
result::err(get_addr_unknown_error));
}
}
else {
log(debug, "status != 0 error in get_addr_cb");
(*handle_data).output_ch.send(
result::err(get_addr_unknown_error));
}
if res != (ptr::null::<addrinfo>()) {
uv_freeaddrinfo(res);
}
log(debug, "leaving get_addr_cb");
}
#[doc="
@ -128,7 +151,7 @@ fn get_addr(++node: str, iotask: iotask)
-> result::result<[ip_addr], ip_get_addr_err> unsafe {
comm::listen {|output_ch|
str::unpack_slice(node) {|node_ptr, len|
log(debug, #fmt("sliace len %?", len));
log(debug, #fmt("slice len %?", len));
let handle = create_uv_getaddrinfo_t();
let handle_ptr = ptr::addr_of(handle);
let handle_data: get_addr_data = {
@ -145,7 +168,7 @@ fn get_addr(++node: str, iotask: iotask)
ptr::null());
alt result {
0i32 {
set_data_for_uv_handle(handle_ptr, handle_data_ptr);
set_data_for_req(handle_ptr, handle_data_ptr);
}
_ {
output_ch.send(result::err(get_addr_unknown_error));
@ -175,9 +198,6 @@ mod v4 {
"]
fn parse_addr(ip: str) -> ip_addr {
alt try_parse_addr(ip) {
// FIXME: more copies brought to light to due the implicit
// copy compiler warning.. what can be done? out pointers,
// ala c#?
result::ok(addr) { copy(addr) }
result::err(err_data) {
fail err_data.err_msg
@ -198,7 +218,7 @@ mod v4 {
ip)})
}
else {
result::ok(ipv4(new_addr))
result::ok(ipv4(copy(new_addr)))
}
}
}
@ -221,9 +241,6 @@ mod v6 {
"]
fn parse_addr(ip: str) -> ip_addr {
alt try_parse_addr(ip) {
// FIXME: more copies brought to light to due the implicit
// copy compiler warning.. what can be done? out pointers,
// ala c#?
result::ok(addr) { copy(addr) }
result::err(err_data) {
fail err_data.err_msg
@ -250,7 +267,7 @@ mod v6 {
}
}
//#[cfg(test)]
#[cfg(test)]
mod test {
#[test]
fn test_ipv4_parse_and_format_ip() {
@ -290,4 +307,30 @@ mod test {
}
}
}
#[test]
fn test_get_addr() {
let localhost_name = "localhost";
let iotask = uv::global_loop::get();
let ga_result = get_addr(localhost_name, iotask);
if result::is_err(ga_result) {
fail "got err result from net::ip::get_addr();"
}
// note really sure how to realiably test/assert
// this.. mostly just wanting to see it work, atm.
let results = result::unwrap(ga_result);
log(debug, #fmt("test_get_addr: Number of results for %s: %?",
localhost_name, vec::len(results)));
for vec::each(results) {|r|
let ipv_prefix = alt r {
ipv4(_) {
"IPv4"
}
ipv6(_) {
"IPv6"
}
};
log(debug, #fmt("test_get_addr: result %s: '%s'",
ipv_prefix, format_addr(r)));
}
}
}

View File

@ -418,7 +418,7 @@ net::tcp::listen(remote_ip, remote_port, backlog)
let cont_ch = comm::chan(cont_po);
task::spawn {||
let accept_result = net::tcp::accept(new_conn);
if accept_result.is_failure() {
if accept_result.is_err() {
comm::send(cont_ch, result::get_err(accept_result));
// fail?
}
@ -754,7 +754,7 @@ impl tcp_socket_buf of io::reader for @tcp_socket_buf {
}
else {
let read_result = read((*self).sock, 0u);
if read_result.is_failure() {
if read_result.is_err() {
let err_data = read_result.get_err();
log(debug, #fmt("ERROR sock_buf as io::reader.read err %? %?",
err_data.err_name, err_data.err_msg));
@ -771,9 +771,7 @@ impl tcp_socket_buf of io::reader for @tcp_socket_buf {
self.read_bytes(1u)[0] as int
}
fn unread_byte(amt: int) {
// FIXME: stubbing this out pending the
// return of vec::unshift
//vec::unshift((*self).buf, amt as u8);
vec::unshift((*self).buf, amt as u8);
}
fn eof() -> bool {
false // noop
@ -798,7 +796,7 @@ impl tcp_socket_buf of io::writer for @tcp_socket_buf {
};
let write_buf_vec_ptr = ptr::addr_of(write_buf_vec);
let w_result = write_common_impl(socket_data_ptr, write_buf_vec_ptr);
if w_result.is_failure() {
if w_result.is_err() {
let err_data = w_result.get_err();
log(debug, #fmt("ERROR sock_buf as io::writer.writer err: %? %?",
err_data.err_name, err_data.err_msg));
@ -1321,7 +1319,7 @@ mod test {
client_ch,
hl_loop)
};
assert actual_resp_result.is_success();
assert actual_resp_result.is_ok();
let actual_resp = actual_resp_result.get();
let actual_req = comm::recv(server_result_po);
log(debug, #fmt("REQ: expected: '%s' actual: '%s'",
@ -1453,7 +1451,7 @@ mod test {
// client
let server_addr = ip::v4::parse_addr(server_ip);
let conn_result = connect(server_addr, server_port, iotask);
if result::is_failure(conn_result) {
if result::is_err(conn_result) {
assert false;
}
let sock_buf = @socket_buf(result::unwrap(conn_result));
@ -1589,7 +1587,7 @@ mod test {
new_conn, kill_ch);
});
// err check on listen_result
if result::is_failure(listen_result) {
if result::is_err(listen_result) {
result::get_err(listen_result)
}
else {

View File

@ -567,6 +567,7 @@ native mod rustrt {
service_name_ptr: *u8,
// should probably only pass ptr::null()
hints: *addrinfo) -> libc::c_int;
fn rust_uv_freeaddrinfo(res: *addrinfo);
// data accessors/helpers for rust-mapped uv structs
fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
@ -755,7 +756,7 @@ unsafe fn ip4_name(src: &sockaddr_in) -> str {
rustrt::rust_uv_ip4_name(src as *sockaddr_in,
dst_buf, size);
// FIXME: seems that checking the result of uv_ip4_name
// doesn't work too well..
// doesn't work too well..
// libuv will actually map a malformed input ip to INADDR_NONE,
// which is going to be 255.255.255.255 on most
// platforms.
@ -810,6 +811,9 @@ unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
service_name_ptr,
hints)
}
unsafe fn freeaddrinfo(res: *addrinfo) {
rustrt::rust_uv_freeaddrinfo(res);
}
// libuv struct initializers
unsafe fn tcp_t() -> uv_tcp_t {
@ -1544,7 +1548,7 @@ mod test {
log(debug, output);
assert foreign_handle_size as uint == rust_handle_size;
}
#[test]
#[ignore(cfg(target_os = "freebsd"))]
fn test_uv_ll_struct_size_uv_getaddrinfo_t() {