From 5304698621bf73a060e7cc8055beb6f6ae08e410 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Mon, 25 Jun 2012 08:02:34 -0700 Subject: [PATCH] std: net::ip::get_addr is working w/ happy path test. needs more. --- src/libstd/net_ip.rs | 85 ++++++++++++++++++++++++++++++++----------- src/libstd/net_tcp.rs | 16 ++++---- src/libstd/uv_ll.rs | 8 +++- 3 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index d0eda904e836..9f19a3dcba8c 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -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::()) { 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::() 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::()) { + 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))); + } + } } \ No newline at end of file diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index f1436e7c83e1..d4fd65093390 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -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 { diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index e645050828ba..09f8c61d45d4 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -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() {