std: net::ip::get_addr is working w/ happy path test. needs more.
This commit is contained in:
parent
bcc341f5fb
commit
5304698621
3 changed files with 77 additions and 32 deletions
|
@ -17,9 +17,10 @@ import uv_ip4_name = uv::ll::ip4_name;
|
||||||
import uv_ip6_addr = uv::ll::ip6_addr;
|
import uv_ip6_addr = uv::ll::ip6_addr;
|
||||||
import uv_ip6_name = uv::ll::ip6_name;
|
import uv_ip6_name = uv::ll::ip6_name;
|
||||||
import uv_getaddrinfo = uv::ll::getaddrinfo;
|
import uv_getaddrinfo = uv::ll::getaddrinfo;
|
||||||
|
import uv_freeaddrinfo = uv::ll::freeaddrinfo;
|
||||||
import create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t;
|
import create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t;
|
||||||
import set_data_for_uv_handle = uv::ll::set_data_for_uv_handle;
|
import set_data_for_req = uv::ll::set_data_for_req;
|
||||||
import get_data_for_uv_handle = uv::ll::get_data_for_uv_handle;
|
import get_data_for_req = uv::ll::get_data_for_req;
|
||||||
import ll = uv::ll;
|
import ll = uv::ll;
|
||||||
|
|
||||||
export ip_addr, parse_addr_err;
|
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,
|
crust fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int,
|
||||||
res: *addrinfo) unsafe {
|
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;
|
*get_addr_data;
|
||||||
if status == 0i32 {
|
if status == 0i32 {
|
||||||
if res != (ptr::null::<addrinfo>()) {
|
if res != (ptr::null::<addrinfo>()) {
|
||||||
let mut out_vec = [];
|
let mut out_vec = [];
|
||||||
|
let mut addr_strings = [];
|
||||||
|
log(debug, #fmt("initial addrinfo: %?", res));
|
||||||
let mut curr_addr = res;
|
let mut curr_addr = res;
|
||||||
loop {
|
loop {
|
||||||
if ll::is_ipv4_addrinfo(curr_addr) {
|
let new_ip_addr = if ll::is_ipv4_addrinfo(curr_addr) {
|
||||||
out_vec +=
|
ipv4(copy((
|
||||||
[ipv4(copy((
|
*ll::addrinfo_as_sockaddr_in(curr_addr))))
|
||||||
*ll::addrinfo_as_sockaddr_in(curr_addr))))];
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out_vec +=
|
ipv6(copy((
|
||||||
[ipv6(copy((
|
*ll::addrinfo_as_sockaddr_in6(curr_addr))))
|
||||||
*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);
|
let next_addr = ll::get_next_addrinfo(curr_addr);
|
||||||
if next_addr == ptr::null::<addrinfo>() as *addrinfo {
|
if next_addr == ptr::null::<addrinfo>() as *addrinfo {
|
||||||
|
log(debug, "null next_addr encountered. no mas");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
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));
|
(*handle_data).output_ch.send(result::ok(out_vec));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
log(debug, "addrinfo pointer is NULL");
|
||||||
(*handle_data).output_ch.send(
|
(*handle_data).output_ch.send(
|
||||||
result::err(get_addr_unknown_error));
|
result::err(get_addr_unknown_error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
log(debug, "status != 0 error in get_addr_cb");
|
||||||
(*handle_data).output_ch.send(
|
(*handle_data).output_ch.send(
|
||||||
result::err(get_addr_unknown_error));
|
result::err(get_addr_unknown_error));
|
||||||
}
|
}
|
||||||
|
if res != (ptr::null::<addrinfo>()) {
|
||||||
|
uv_freeaddrinfo(res);
|
||||||
|
}
|
||||||
|
log(debug, "leaving get_addr_cb");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc="
|
#[doc="
|
||||||
|
@ -128,7 +151,7 @@ fn get_addr(++node: str, iotask: iotask)
|
||||||
-> result::result<[ip_addr], ip_get_addr_err> unsafe {
|
-> result::result<[ip_addr], ip_get_addr_err> unsafe {
|
||||||
comm::listen {|output_ch|
|
comm::listen {|output_ch|
|
||||||
str::unpack_slice(node) {|node_ptr, len|
|
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 = create_uv_getaddrinfo_t();
|
||||||
let handle_ptr = ptr::addr_of(handle);
|
let handle_ptr = ptr::addr_of(handle);
|
||||||
let handle_data: get_addr_data = {
|
let handle_data: get_addr_data = {
|
||||||
|
@ -145,7 +168,7 @@ fn get_addr(++node: str, iotask: iotask)
|
||||||
ptr::null());
|
ptr::null());
|
||||||
alt result {
|
alt result {
|
||||||
0i32 {
|
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));
|
output_ch.send(result::err(get_addr_unknown_error));
|
||||||
|
@ -175,9 +198,6 @@ mod v4 {
|
||||||
"]
|
"]
|
||||||
fn parse_addr(ip: str) -> ip_addr {
|
fn parse_addr(ip: str) -> ip_addr {
|
||||||
alt try_parse_addr(ip) {
|
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::ok(addr) { copy(addr) }
|
||||||
result::err(err_data) {
|
result::err(err_data) {
|
||||||
fail err_data.err_msg
|
fail err_data.err_msg
|
||||||
|
@ -198,7 +218,7 @@ mod v4 {
|
||||||
ip)})
|
ip)})
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
fn parse_addr(ip: str) -> ip_addr {
|
||||||
alt try_parse_addr(ip) {
|
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::ok(addr) { copy(addr) }
|
||||||
result::err(err_data) {
|
result::err(err_data) {
|
||||||
fail err_data.err_msg
|
fail err_data.err_msg
|
||||||
|
@ -250,7 +267,7 @@ mod v6 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ipv4_parse_and_format_ip() {
|
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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -418,7 +418,7 @@ net::tcp::listen(remote_ip, remote_port, backlog)
|
||||||
let cont_ch = comm::chan(cont_po);
|
let cont_ch = comm::chan(cont_po);
|
||||||
task::spawn {||
|
task::spawn {||
|
||||||
let accept_result = net::tcp::accept(new_conn);
|
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));
|
comm::send(cont_ch, result::get_err(accept_result));
|
||||||
// fail?
|
// fail?
|
||||||
}
|
}
|
||||||
|
@ -754,7 +754,7 @@ impl tcp_socket_buf of io::reader for @tcp_socket_buf {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let read_result = read((*self).sock, 0u);
|
let read_result = read((*self).sock, 0u);
|
||||||
if read_result.is_failure() {
|
if read_result.is_err() {
|
||||||
let err_data = read_result.get_err();
|
let err_data = read_result.get_err();
|
||||||
log(debug, #fmt("ERROR sock_buf as io::reader.read err %? %?",
|
log(debug, #fmt("ERROR sock_buf as io::reader.read err %? %?",
|
||||||
err_data.err_name, err_data.err_msg));
|
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
|
self.read_bytes(1u)[0] as int
|
||||||
}
|
}
|
||||||
fn unread_byte(amt: int) {
|
fn unread_byte(amt: int) {
|
||||||
// FIXME: stubbing this out pending the
|
vec::unshift((*self).buf, amt as u8);
|
||||||
// return of vec::unshift
|
|
||||||
//vec::unshift((*self).buf, amt as u8);
|
|
||||||
}
|
}
|
||||||
fn eof() -> bool {
|
fn eof() -> bool {
|
||||||
false // noop
|
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 write_buf_vec_ptr = ptr::addr_of(write_buf_vec);
|
||||||
let w_result = write_common_impl(socket_data_ptr, write_buf_vec_ptr);
|
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();
|
let err_data = w_result.get_err();
|
||||||
log(debug, #fmt("ERROR sock_buf as io::writer.writer err: %? %?",
|
log(debug, #fmt("ERROR sock_buf as io::writer.writer err: %? %?",
|
||||||
err_data.err_name, err_data.err_msg));
|
err_data.err_name, err_data.err_msg));
|
||||||
|
@ -1321,7 +1319,7 @@ mod test {
|
||||||
client_ch,
|
client_ch,
|
||||||
hl_loop)
|
hl_loop)
|
||||||
};
|
};
|
||||||
assert actual_resp_result.is_success();
|
assert actual_resp_result.is_ok();
|
||||||
let actual_resp = actual_resp_result.get();
|
let actual_resp = actual_resp_result.get();
|
||||||
let actual_req = comm::recv(server_result_po);
|
let actual_req = comm::recv(server_result_po);
|
||||||
log(debug, #fmt("REQ: expected: '%s' actual: '%s'",
|
log(debug, #fmt("REQ: expected: '%s' actual: '%s'",
|
||||||
|
@ -1453,7 +1451,7 @@ mod test {
|
||||||
// client
|
// client
|
||||||
let server_addr = ip::v4::parse_addr(server_ip);
|
let server_addr = ip::v4::parse_addr(server_ip);
|
||||||
let conn_result = connect(server_addr, server_port, iotask);
|
let conn_result = connect(server_addr, server_port, iotask);
|
||||||
if result::is_failure(conn_result) {
|
if result::is_err(conn_result) {
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
let sock_buf = @socket_buf(result::unwrap(conn_result));
|
let sock_buf = @socket_buf(result::unwrap(conn_result));
|
||||||
|
@ -1589,7 +1587,7 @@ mod test {
|
||||||
new_conn, kill_ch);
|
new_conn, kill_ch);
|
||||||
});
|
});
|
||||||
// err check on listen_result
|
// err check on listen_result
|
||||||
if result::is_failure(listen_result) {
|
if result::is_err(listen_result) {
|
||||||
result::get_err(listen_result)
|
result::get_err(listen_result)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -567,6 +567,7 @@ native mod rustrt {
|
||||||
service_name_ptr: *u8,
|
service_name_ptr: *u8,
|
||||||
// should probably only pass ptr::null()
|
// should probably only pass ptr::null()
|
||||||
hints: *addrinfo) -> libc::c_int;
|
hints: *addrinfo) -> libc::c_int;
|
||||||
|
fn rust_uv_freeaddrinfo(res: *addrinfo);
|
||||||
|
|
||||||
// data accessors/helpers for rust-mapped uv structs
|
// data accessors/helpers for rust-mapped uv structs
|
||||||
fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
|
fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
|
||||||
|
@ -810,6 +811,9 @@ unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
|
||||||
service_name_ptr,
|
service_name_ptr,
|
||||||
hints)
|
hints)
|
||||||
}
|
}
|
||||||
|
unsafe fn freeaddrinfo(res: *addrinfo) {
|
||||||
|
rustrt::rust_uv_freeaddrinfo(res);
|
||||||
|
}
|
||||||
|
|
||||||
// libuv struct initializers
|
// libuv struct initializers
|
||||||
unsafe fn tcp_t() -> uv_tcp_t {
|
unsafe fn tcp_t() -> uv_tcp_t {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue