mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 10:45:18 +00:00
Merge remote-tracking branch 'brson/uv'
This commit is contained in:
commit
2ea8922b8a
@ -31,6 +31,7 @@ export splitn;
|
||||
export rsplit;
|
||||
export rsplitn;
|
||||
export shift;
|
||||
export unshift;
|
||||
export pop;
|
||||
export push, push_all, push_all_move;
|
||||
export grow;
|
||||
|
@ -4,16 +4,35 @@ Types/fns concerning Internet Protocol (IP), versions 4 & 6
|
||||
|
||||
import vec;
|
||||
import uint;
|
||||
import iotask = uv::iotask::iotask;
|
||||
import interact = uv::iotask::interact;
|
||||
import comm::methods;
|
||||
|
||||
import sockaddr_in = uv::ll::sockaddr_in;
|
||||
import sockaddr_in6 = uv::ll::sockaddr_in6;
|
||||
import addrinfo = uv::ll::addrinfo;
|
||||
import uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t;
|
||||
import uv_ip4_addr = uv::ll::ip4_addr;
|
||||
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_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;
|
||||
export format_addr;
|
||||
export v4;
|
||||
export v4, v6;
|
||||
export get_addr;
|
||||
|
||||
#[doc = "An IP address"]
|
||||
enum ip_addr {
|
||||
#[doc="An IPv4 address"]
|
||||
ipv4(u8, u8, u8, u8),
|
||||
ipv6(u16,u16,u16,u16,u16,u16,u16,u16)
|
||||
ipv4(sockaddr_in),
|
||||
ipv6(sockaddr_in6)
|
||||
}
|
||||
|
||||
#[doc="
|
||||
@ -32,22 +51,88 @@ Convert a `ip_addr` to a str
|
||||
"]
|
||||
fn format_addr(ip: ip_addr) -> str {
|
||||
alt ip {
|
||||
ipv4(a, b, c, d) {
|
||||
#fmt["%u.%u.%u.%u", a as uint, b as uint, c as uint, d as uint]
|
||||
ipv4(addr) {
|
||||
unsafe {
|
||||
let result = uv_ip4_name(&addr);
|
||||
if result == "" {
|
||||
fail "failed to convert inner sockaddr_in address to str"
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
ipv6(_, _, _, _, _, _, _, _) {
|
||||
fail "FIXME (#2651) impl parsing of ipv6 addr";
|
||||
ipv6(addr) {
|
||||
unsafe {
|
||||
let result = uv_ip6_name(&addr);
|
||||
if result == "" {
|
||||
fail "failed to convert inner sockaddr_in address to str"
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Represents errors returned from `net::ip::get_addr()`
|
||||
"]
|
||||
enum ip_get_addr_err {
|
||||
get_addr_unknown_error
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Attempts name resolution on the provided `node` string
|
||||
|
||||
# Arguments
|
||||
|
||||
* `node` - a string representing some host address
|
||||
* `iotask` - a `uv::iotask` used to interact with the underlying event loop
|
||||
|
||||
# Returns
|
||||
|
||||
A `result<[ip_addr]/~, ip_get_addr_err>` instance that will contain
|
||||
a vector of `ip_addr` results, in the case of success, or an error
|
||||
object in the case of failure
|
||||
"]
|
||||
fn get_addr(++node: str, iotask: iotask)
|
||||
-> result::result<[ip_addr]/~, ip_get_addr_err> unsafe {
|
||||
do comm::listen |output_ch| {
|
||||
do str::unpack_slice(node) |node_ptr, 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 = {
|
||||
output_ch: output_ch
|
||||
};
|
||||
let handle_data_ptr = ptr::addr_of(handle_data);
|
||||
do interact(iotask) |loop_ptr| {
|
||||
let result = uv_getaddrinfo(
|
||||
loop_ptr,
|
||||
handle_ptr,
|
||||
get_addr_cb,
|
||||
node_ptr,
|
||||
ptr::null(),
|
||||
ptr::null());
|
||||
alt result {
|
||||
0i32 {
|
||||
set_data_for_req(handle_ptr, handle_data_ptr);
|
||||
}
|
||||
_ {
|
||||
output_ch.send(result::err(get_addr_unknown_error));
|
||||
}
|
||||
}
|
||||
};
|
||||
output_ch.recv()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod v4 {
|
||||
#[doc = "
|
||||
Convert a str to `ip_addr`
|
||||
|
||||
# Failure
|
||||
|
||||
j Fails if the string is not a valid IPv4 address
|
||||
Fails if the string is not a valid IPv4 address
|
||||
|
||||
# Arguments
|
||||
|
||||
@ -59,13 +144,22 @@ j Fails if the string is not a valid IPv4 address
|
||||
"]
|
||||
fn parse_addr(ip: str) -> ip_addr {
|
||||
alt try_parse_addr(ip) {
|
||||
result::ok(addr) { addr }
|
||||
result::ok(addr) { copy(addr) }
|
||||
result::err(err_data) {
|
||||
fail err_data.err_msg
|
||||
}
|
||||
}
|
||||
}
|
||||
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
|
||||
// the simple, old style numberic representation of
|
||||
// ipv4
|
||||
type ipv4_rep = { a: u8, b: u8, c: u8, d:u8 };
|
||||
impl x for ipv4_rep {
|
||||
// this is pretty dastardly, i know
|
||||
unsafe fn as_u32() -> u32 {
|
||||
*((ptr::addr_of(self)) as *u32)
|
||||
}
|
||||
}
|
||||
fn parse_to_ipv4_rep(ip: str) -> result::result<ipv4_rep, str> {
|
||||
let parts = vec::map(str::split_char(ip, '.'), |s| {
|
||||
alt uint::from_str(s) {
|
||||
some(n) if n <= 255u { n }
|
||||
@ -73,31 +167,232 @@ j Fails if the string is not a valid IPv4 address
|
||||
}
|
||||
});
|
||||
if vec::len(parts) != 4u {
|
||||
result::err({err_msg: #fmt("'%s' doesn't have 4 parts",
|
||||
ip)})
|
||||
}
|
||||
result::err(#fmt("'%s' doesn't have 4 parts", ip))
|
||||
}
|
||||
else if vec::contains(parts, 256u) {
|
||||
result::err({err_msg: #fmt("invalid octal in provided addr '%s'",
|
||||
ip)})
|
||||
}
|
||||
result::err(#fmt("invalid octal in addr '%s'", ip))
|
||||
}
|
||||
else {
|
||||
result::ok(ipv4(parts[0] as u8, parts[1] as u8,
|
||||
parts[2] as u8, parts[3] as u8))
|
||||
result::ok({a: parts[0] as u8, b: parts[1] as u8,
|
||||
c: parts[2] as u8, d: parts[3] as u8})
|
||||
}
|
||||
}
|
||||
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
|
||||
unsafe {
|
||||
let INADDR_NONE = ll::get_INADDR_NONE();
|
||||
let ip_rep_result = parse_to_ipv4_rep(ip);
|
||||
if result::is_err(ip_rep_result) {
|
||||
let err_str = result::get_err(ip_rep_result);
|
||||
ret result::err({err_msg: err_str})
|
||||
}
|
||||
// ipv4_rep.as_u32 is unsafe :/
|
||||
let input_is_inaddr_none =
|
||||
result::get(ip_rep_result).as_u32() == INADDR_NONE;
|
||||
|
||||
let new_addr = uv_ip4_addr(ip, 22);
|
||||
let reformatted_name = uv_ip4_name(&new_addr);
|
||||
log(debug, #fmt("try_parse_addr: input ip: %s reparsed ip: %s",
|
||||
ip, reformatted_name));
|
||||
let ref_ip_rep_result = parse_to_ipv4_rep(reformatted_name);
|
||||
if result::is_err(ref_ip_rep_result) {
|
||||
let err_str = result::get_err(ref_ip_rep_result);
|
||||
ret result::err({err_msg: err_str})
|
||||
}
|
||||
if result::get(ref_ip_rep_result).as_u32() == INADDR_NONE &&
|
||||
!input_is_inaddr_none {
|
||||
ret result::err(
|
||||
{err_msg: "uv_ip4_name produced invalid result."})
|
||||
}
|
||||
else {
|
||||
result::ok(ipv4(copy(new_addr)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mod v6 {
|
||||
#[doc = "
|
||||
Convert a str to `ip_addr`
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the string is not a valid IPv6 address
|
||||
|
||||
# Arguments
|
||||
|
||||
* ip - an ipv6 string. See RFC2460 for spec.
|
||||
|
||||
# Returns
|
||||
|
||||
* an `ip_addr` of the `ipv6` variant
|
||||
"]
|
||||
fn parse_addr(ip: str) -> ip_addr {
|
||||
alt try_parse_addr(ip) {
|
||||
result::ok(addr) { copy(addr) }
|
||||
result::err(err_data) {
|
||||
fail err_data.err_msg
|
||||
}
|
||||
}
|
||||
}
|
||||
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
|
||||
unsafe {
|
||||
// need to figure out how to establish a parse failure..
|
||||
let new_addr = uv_ip6_addr(ip, 22);
|
||||
let reparsed_name = uv_ip6_name(&new_addr);
|
||||
log(debug, #fmt("v6::try_parse_addr ip: '%s' reparsed '%s'",
|
||||
ip, reparsed_name));
|
||||
// '::' appears to be uv_ip6_name() returns for bogus
|
||||
// parses..
|
||||
if ip != "::" && reparsed_name == "::" {
|
||||
result::err({err_msg:#fmt("failed to parse '%s'",
|
||||
ip)})
|
||||
}
|
||||
else {
|
||||
result::ok(ipv6(new_addr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type get_addr_data = {
|
||||
output_ch: comm::chan<result::result<[ip_addr]/~,ip_get_addr_err>>
|
||||
};
|
||||
|
||||
crust fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int,
|
||||
res: *addrinfo) unsafe {
|
||||
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 = []/~;
|
||||
log(debug, #fmt("initial addrinfo: %?", res));
|
||||
let mut curr_addr = res;
|
||||
loop {
|
||||
let new_ip_addr = if ll::is_ipv4_addrinfo(curr_addr) {
|
||||
ipv4(copy((
|
||||
*ll::addrinfo_as_sockaddr_in(curr_addr))))
|
||||
}
|
||||
else if ll::is_ipv6_addrinfo(curr_addr) {
|
||||
ipv6(copy((
|
||||
*ll::addrinfo_as_sockaddr_in6(curr_addr))))
|
||||
}
|
||||
else {
|
||||
log(debug, "curr_addr is not of family AF_INET or "+
|
||||
"AF_INET6. Error.");
|
||||
(*handle_data).output_ch.send(
|
||||
result::err(get_addr_unknown_error));
|
||||
break;
|
||||
};
|
||||
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;
|
||||
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");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_format_ip() {
|
||||
assert (format_addr(ipv4(127u8, 0u8, 0u8, 1u8))
|
||||
== "127.0.0.1")
|
||||
fn test_ip_ipv4_parse_and_format_ip() {
|
||||
let localhost_str = "127.0.0.1";
|
||||
assert (format_addr(v4::parse_addr(localhost_str))
|
||||
== localhost_str)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_ip() {
|
||||
assert (v4::parse_addr("127.0.0.1") ==
|
||||
ipv4(127u8, 0u8, 0u8, 1u8));
|
||||
fn test_ip_ipv6_parse_and_format_ip() {
|
||||
let localhost_str = "::1";
|
||||
let format_result = format_addr(v6::parse_addr(localhost_str));
|
||||
log(debug, #fmt("results: expected: '%s' actual: '%s'",
|
||||
localhost_str, format_result));
|
||||
assert format_result == localhost_str;
|
||||
}
|
||||
#[test]
|
||||
fn test_ip_ipv4_bad_parse() {
|
||||
alt v4::try_parse_addr("b4df00d") {
|
||||
result::err(err_info) {
|
||||
log(debug, #fmt("got error as expected %?", err_info));
|
||||
assert true;
|
||||
}
|
||||
result::ok(addr) {
|
||||
fail #fmt("Expected failure, but got addr %?", addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
#[ignore(target_os="win32")]
|
||||
fn test_ip_ipv6_bad_parse() {
|
||||
alt v6::try_parse_addr("::,~2234k;") {
|
||||
result::err(err_info) {
|
||||
log(debug, #fmt("got error as expected %?", err_info));
|
||||
assert true;
|
||||
}
|
||||
result::ok(addr) {
|
||||
fail #fmt("Expected failure, but got addr %?", addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
#[ignore(reason = "valgrind says it's leaky")]
|
||||
fn test_ip_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)));
|
||||
}
|
||||
// at least one result.. this is going to vary from system
|
||||
// to system, based on stuff like the contents of /etc/hosts
|
||||
assert vec::len(results) > 0;
|
||||
}
|
||||
#[test]
|
||||
#[ignore(reason = "valgrind says it's leaky")]
|
||||
fn test_ip_get_addr_bad_input() {
|
||||
let localhost_name = "sjkl234m,./sdf";
|
||||
let iotask = uv::global_loop::get();
|
||||
let ga_result = get_addr(localhost_name, iotask);
|
||||
assert result::is_err(ga_result);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
use core(vers = "0.2");
|
||||
import core::*;
|
||||
|
||||
export net, net_tcp;
|
||||
export net, net_tcp, net_ip;
|
||||
export uv, uv_ll, uv_iotask, uv_global_loop;
|
||||
export c_vec, util, timer;
|
||||
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap;
|
||||
|
@ -223,10 +223,82 @@ type sockaddr_in = {
|
||||
mut sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8)
|
||||
};
|
||||
|
||||
// unix size: 28 .. make due w/ 32
|
||||
// unix size: 28 .. FIXME #1645
|
||||
// stuck with 32 becuse of rust padding structs?
|
||||
#[cfg(target_arch="x86_64")]
|
||||
type sockaddr_in6 = {
|
||||
a0: *u8, a1: *u8,
|
||||
a2: *u8, a3: (u8, u8, u8, u8)
|
||||
a2: *u8, a3: *u8
|
||||
};
|
||||
#[cfg(target_arch="x86")]
|
||||
type sockaddr_in6 = {
|
||||
a0: *u8, a1: *u8,
|
||||
a2: *u8, a3: *u8,
|
||||
a4: *u8, a5: *u8,
|
||||
a6: *u8, a7: *u8
|
||||
};
|
||||
|
||||
// unix size: 28 .. FIXME #1645
|
||||
// stuck with 32 becuse of rust padding structs?
|
||||
type addr_in = addr_in_impl::addr_in;
|
||||
#[cfg(unix)]
|
||||
mod addr_in_impl {
|
||||
#[cfg(target_arch="x86_64")]
|
||||
type addr_in = {
|
||||
a0: *u8, a1: *u8,
|
||||
a2: *u8, a3: *u8
|
||||
};
|
||||
#[cfg(target_arch="x86")]
|
||||
type addr_in = {
|
||||
a0: *u8, a1: *u8,
|
||||
a2: *u8, a3: *u8,
|
||||
a4: *u8, a5: *u8,
|
||||
a6: *u8, a7: *u8,
|
||||
};
|
||||
}
|
||||
#[cfg(windows)]
|
||||
mod addr_in_impl {
|
||||
type addr_in = {
|
||||
a0: *u8, a1: *u8,
|
||||
a2: *u8, a3: *u8
|
||||
};
|
||||
}
|
||||
|
||||
// unix size: 48, 32bit: 32
|
||||
type addrinfo = addrinfo_impl::addrinfo;
|
||||
#[cfg(target_os="linux")]
|
||||
mod addrinfo_impl {
|
||||
#[cfg(target_arch="x86_64")]
|
||||
type addrinfo = {
|
||||
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
||||
a04: *u8, a05: *u8
|
||||
};
|
||||
#[cfg(target_arch="x86")]
|
||||
type addrinfo = {
|
||||
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
||||
a04: *u8, a05: *u8, a06: *u8, a07: *u8
|
||||
};
|
||||
}
|
||||
#[cfg(target_os="macos")]
|
||||
#[cfg(target_os="freebsd")]
|
||||
mod addrinfo_impl {
|
||||
type addrinfo = {
|
||||
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
||||
a04: *u8, a05: *u8
|
||||
};
|
||||
}
|
||||
#[cfg(windows)]
|
||||
mod addrinfo_impl {
|
||||
type addrinfo = {
|
||||
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
||||
a04: *u8, a05: *u8
|
||||
};
|
||||
}
|
||||
|
||||
// unix size: 72
|
||||
type uv_getaddrinfo_t = {
|
||||
a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8,
|
||||
a06: *u8, a07: *u8, a08: *u8
|
||||
};
|
||||
|
||||
mod uv_ll_struct_stubgen {
|
||||
@ -474,10 +546,18 @@ mod uv_ll_struct_stubgen {
|
||||
a12: 0 as *u8
|
||||
};
|
||||
}
|
||||
fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
|
||||
{
|
||||
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8,
|
||||
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8, a07: 0 as *u8,
|
||||
a08: 0 as *u8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[nolink]
|
||||
native mod rustrt {
|
||||
// libuv public API
|
||||
fn rust_uv_loop_new() -> *libc::c_void;
|
||||
fn rust_uv_loop_delete(lp: *libc::c_void);
|
||||
fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
|
||||
@ -500,6 +580,12 @@ native mod rustrt {
|
||||
fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
|
||||
fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
|
||||
-> sockaddr_in;
|
||||
fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
|
||||
-> sockaddr_in6;
|
||||
fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: libc::size_t)
|
||||
-> libc::c_int;
|
||||
fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t)
|
||||
-> libc::c_int;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
@ -508,6 +594,14 @@ native mod rustrt {
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
|
||||
++addr: *sockaddr_in) -> libc::c_int;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
++after_cb: *u8,
|
||||
++addr: *sockaddr_in6) -> libc::c_int;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
|
||||
++addr: *sockaddr_in6) -> libc::c_int;
|
||||
fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
|
||||
cb: *u8) -> libc::c_int;
|
||||
fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
|
||||
@ -527,7 +621,22 @@ native mod rustrt {
|
||||
repeat: libc::c_uint) -> libc::c_int;
|
||||
fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
|
||||
|
||||
fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
|
||||
handle: *uv_getaddrinfo_t,
|
||||
cb: *u8,
|
||||
node_name_ptr: *u8,
|
||||
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_helper_get_INADDR_NONE() -> u32;
|
||||
fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
|
||||
fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
|
||||
fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
|
||||
fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in;
|
||||
fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6;
|
||||
fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
|
||||
fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
|
||||
fn rust_uv_get_stream_handle_from_connect_req(
|
||||
@ -558,8 +667,12 @@ native mod rustrt {
|
||||
fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
|
||||
fn rust_uv_helper_addr_in_size() -> libc::c_uint;
|
||||
}
|
||||
|
||||
unsafe fn loop_new() -> *libc::c_void {
|
||||
@ -598,11 +711,26 @@ unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
|
||||
after_connect_cb, addr_ptr);
|
||||
}
|
||||
// FIXME ref #2064
|
||||
unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
addr_ptr: *sockaddr_in6,
|
||||
++after_connect_cb: *u8)
|
||||
-> libc::c_int {
|
||||
ret rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
|
||||
after_connect_cb, addr_ptr);
|
||||
}
|
||||
// FIXME ref #2064
|
||||
unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
|
||||
addr_ptr: *sockaddr_in) -> libc::c_int {
|
||||
ret rustrt::rust_uv_tcp_bind(tcp_server_ptr,
|
||||
addr_ptr);
|
||||
}
|
||||
// FIXME ref #2064
|
||||
unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
|
||||
addr_ptr: *sockaddr_in6) -> libc::c_int {
|
||||
ret rustrt::rust_uv_tcp_bind6(tcp_server_ptr,
|
||||
addr_ptr);
|
||||
}
|
||||
|
||||
unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
|
||||
cb: *u8) -> libc::c_int {
|
||||
@ -677,14 +805,59 @@ unsafe fn buf_init(++input: *u8, len: uint) -> uv_buf_t {
|
||||
}
|
||||
unsafe fn ip4_addr(ip: str, port: int)
|
||||
-> sockaddr_in {
|
||||
let mut addr_vec = str::bytes(ip);
|
||||
vec::push(addr_vec, 0u8); // add null terminator
|
||||
let addr_vec_ptr = vec::unsafe::to_ptr(addr_vec);
|
||||
let ip_back = str::from_bytes(addr_vec);
|
||||
log(debug, #fmt("vec val: '%s' length: %u",
|
||||
ip_back, vec::len(addr_vec)));
|
||||
ret rustrt::rust_uv_ip4_addr(addr_vec_ptr,
|
||||
port as libc::c_int);
|
||||
do str::as_c_str(ip) |ip_buf| {
|
||||
rustrt::rust_uv_ip4_addr(ip_buf as *u8,
|
||||
port as libc::c_int)
|
||||
}
|
||||
}
|
||||
unsafe fn ip6_addr(ip: str, port: int)
|
||||
-> sockaddr_in6 {
|
||||
do str::as_c_str(ip) |ip_buf| {
|
||||
rustrt::rust_uv_ip6_addr(ip_buf as *u8,
|
||||
port as libc::c_int)
|
||||
}
|
||||
}
|
||||
unsafe fn ip4_name(src: &sockaddr_in) -> str {
|
||||
// ipv4 addr max size: 15 + 1 trailing null byte
|
||||
let dst: [u8]/~ = [0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
||||
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8]/~;
|
||||
let size = 16 as libc::size_t;
|
||||
do vec::as_buf(dst) |dst_buf| {
|
||||
rustrt::rust_uv_ip4_name(src as *sockaddr_in,
|
||||
dst_buf, size);
|
||||
// seems that checking the result of uv_ip4_name
|
||||
// doesn't work too well..
|
||||
// you're stuck looking at the value of dst_buf
|
||||
// to see if it is the string representation of
|
||||
// INADDR_NONE (0xffffffff or 255.255.255.255 on
|
||||
// many platforms)
|
||||
str::unsafe::from_buf(dst_buf)
|
||||
}
|
||||
}
|
||||
unsafe fn ip6_name(src: &sockaddr_in6) -> str {
|
||||
// ipv6 addr max size: 45 + 1 trailing null byte
|
||||
let dst: [u8]/~ = [0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
||||
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
||||
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
||||
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
||||
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
||||
0u8,0u8,0u8,0u8,0u8,0u8]/~;
|
||||
let size = 46 as libc::size_t;
|
||||
do vec::as_buf(dst) |dst_buf| {
|
||||
let src_unsafe_ptr = src as *sockaddr_in6;
|
||||
log(debug, #fmt("val of src *sockaddr_in6: %? sockaddr_in6: %?",
|
||||
src_unsafe_ptr, src));
|
||||
let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
|
||||
dst_buf, size);
|
||||
alt result {
|
||||
0i32 {
|
||||
str::unsafe::from_buf(dst_buf)
|
||||
}
|
||||
_ {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn timer_init(loop_ptr: *libc::c_void,
|
||||
@ -699,6 +872,22 @@ unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
|
||||
unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
|
||||
ret rustrt::rust_uv_timer_stop(timer_ptr);
|
||||
}
|
||||
unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
|
||||
handle: *uv_getaddrinfo_t,
|
||||
cb: *u8,
|
||||
node_name_ptr: *u8,
|
||||
service_name_ptr: *u8,
|
||||
hints: *addrinfo) -> libc::c_int {
|
||||
rustrt::rust_uv_getaddrinfo(loop_ptr,
|
||||
handle,
|
||||
cb,
|
||||
node_name_ptr,
|
||||
service_name_ptr,
|
||||
hints)
|
||||
}
|
||||
unsafe fn freeaddrinfo(res: *addrinfo) {
|
||||
rustrt::rust_uv_freeaddrinfo(res);
|
||||
}
|
||||
|
||||
// libuv struct initializers
|
||||
unsafe fn tcp_t() -> uv_tcp_t {
|
||||
@ -716,6 +905,9 @@ unsafe fn async_t() -> uv_async_t {
|
||||
unsafe fn timer_t() -> uv_timer_t {
|
||||
ret uv_ll_struct_stubgen::gen_stub_uv_timer_t();
|
||||
}
|
||||
unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
|
||||
ret uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
|
||||
}
|
||||
|
||||
// data access helpers
|
||||
unsafe fn get_loop_for_uv_handle<T>(handle: *T)
|
||||
@ -791,6 +983,25 @@ type uv_err_data = {
|
||||
err_msg: str
|
||||
};
|
||||
|
||||
unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
|
||||
rustrt::rust_uv_is_ipv4_addrinfo(input)
|
||||
}
|
||||
unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
|
||||
rustrt::rust_uv_is_ipv6_addrinfo(input)
|
||||
}
|
||||
unsafe fn get_INADDR_NONE() -> u32 {
|
||||
rustrt::rust_uv_helper_get_INADDR_NONE()
|
||||
}
|
||||
unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
|
||||
rustrt::rust_uv_get_next_addrinfo(input)
|
||||
}
|
||||
unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
|
||||
rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
|
||||
}
|
||||
unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
|
||||
rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
enum tcp_read_data {
|
||||
@ -1366,6 +1577,33 @@ 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_sockaddr_in6() {
|
||||
let native_handle_size =
|
||||
rustrt::rust_uv_helper_sockaddr_in6_size();
|
||||
let rust_handle_size = sys::size_of::<sockaddr_in6>();
|
||||
let output = #fmt("sockaddr_in6 -- native: %u rust: %u",
|
||||
native_handle_size as uint, rust_handle_size);
|
||||
log(debug, output);
|
||||
// FIXME #1645 .. rust appears to pad structs to the nearest byte..?
|
||||
// .. can't get the uv::ll::sockaddr_in6 to == 28 :/
|
||||
// .. so the type always appears to be 32 in size.. which is
|
||||
// good, i guess.. better too big than too little
|
||||
assert (4u+native_handle_size as uint) == rust_handle_size;
|
||||
}
|
||||
#[test]
|
||||
#[ignore(reason = "questionable size calculations")]
|
||||
fn test_uv_ll_struct_size_addr_in() {
|
||||
let native_handle_size =
|
||||
rustrt::rust_uv_helper_addr_in_size();
|
||||
let rust_handle_size = sys::size_of::<addr_in>();
|
||||
let output = #fmt("addr_in -- native: %u rust: %u",
|
||||
native_handle_size as uint, rust_handle_size);
|
||||
log(debug, output);
|
||||
// FIXME #1645 .. see note above about struct padding
|
||||
assert (4u+native_handle_size as uint) == rust_handle_size;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(target_os = "freebsd"))]
|
||||
@ -1390,4 +1628,30 @@ mod test {
|
||||
log(debug, output);
|
||||
assert foreign_handle_size as uint == rust_handle_size;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(target_os = "freebsd"))]
|
||||
#[ignore(cfg(target_os = "win32"))]
|
||||
fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
|
||||
let native_handle_size =
|
||||
rustrt::rust_uv_helper_uv_getaddrinfo_t_size();
|
||||
let rust_handle_size = sys::size_of::<uv_getaddrinfo_t>();
|
||||
let output = #fmt("uv_getaddrinfo_t -- native: %u rust: %u",
|
||||
native_handle_size as uint, rust_handle_size);
|
||||
log(debug, output);
|
||||
assert native_handle_size as uint == rust_handle_size;
|
||||
}
|
||||
#[test]
|
||||
#[ignore(cfg(target_os = "freebsd"))]
|
||||
#[ignore(cfg(target_os = "macos"))]
|
||||
#[ignore(cfg(target_os = "win32"))]
|
||||
fn test_uv_ll_struct_size_addrinfo() {
|
||||
let native_handle_size =
|
||||
rustrt::rust_uv_helper_addrinfo_size();
|
||||
let rust_handle_size = sys::size_of::<addrinfo>();
|
||||
let output = #fmt("addrinfo -- native: %u rust: %u",
|
||||
native_handle_size as uint, rust_handle_size);
|
||||
log(debug, output);
|
||||
assert native_handle_size as uint == rust_handle_size;
|
||||
}
|
||||
}
|
||||
|
@ -238,32 +238,36 @@ rust_uv_tcp_connect(uv_connect_t* connect_ptr,
|
||||
uv_tcp_t* tcp_ptr,
|
||||
uv_connect_cb cb,
|
||||
sockaddr_in* addr_ptr) {
|
||||
rust_task* task = rust_get_current_task();
|
||||
LOG(task, stdlib, "inside rust_uv_tcp_connect");
|
||||
// FIXME ref #2064
|
||||
sockaddr_in addr = *addr_ptr;
|
||||
LOG(task, stdlib, "before tcp_connect .. port: %d",
|
||||
addr.sin_port);
|
||||
LOG(task, stdlib, "before tcp_connect.. tcp stream:" \
|
||||
"%lu cb ptr: %lu",
|
||||
(unsigned long int)tcp_ptr, (unsigned long int)cb);
|
||||
int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
|
||||
LOG(task, stdlib, "leaving rust_uv_tcp_connect.." \
|
||||
"and result: %d",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
rust_uv_tcp_bind(uv_tcp_t* tcp_server, sockaddr_in* addr_ptr) {
|
||||
// FIXME ref #2064
|
||||
rust_task* task = rust_get_current_task();
|
||||
sockaddr_in addr = *addr_ptr;
|
||||
LOG(task, stdlib, "before uv_tcp_bind .. tcp_server:" \
|
||||
"%lu port: %d",
|
||||
(unsigned long int)tcp_server, addr.sin_port);
|
||||
return uv_tcp_bind(tcp_server, addr);
|
||||
}
|
||||
extern "C" int
|
||||
rust_uv_tcp_connect6(uv_connect_t* connect_ptr,
|
||||
uv_tcp_t* tcp_ptr,
|
||||
uv_connect_cb cb,
|
||||
sockaddr_in6* addr_ptr) {
|
||||
// FIXME ref #2064
|
||||
sockaddr_in6 addr = *addr_ptr;
|
||||
int result = uv_tcp_connect6(connect_ptr, tcp_ptr, addr, cb);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
rust_uv_tcp_bind6
|
||||
(uv_tcp_t* tcp_server, sockaddr_in6* addr_ptr) {
|
||||
// FIXME ref #2064
|
||||
sockaddr_in6 addr = *addr_ptr;
|
||||
return uv_tcp_bind6(tcp_server, addr);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
rust_uv_listen(uv_stream_t* stream, int backlog,
|
||||
@ -301,6 +305,10 @@ rust_uv_helper_sockaddr_in_size() {
|
||||
return sizeof(sockaddr_in);
|
||||
}
|
||||
extern "C" size_t
|
||||
rust_uv_helper_sockaddr_in6_size() {
|
||||
return sizeof(sockaddr_in6);
|
||||
}
|
||||
extern "C" size_t
|
||||
rust_uv_helper_uv_async_t_size() {
|
||||
return sizeof(uv_async_t);
|
||||
}
|
||||
@ -308,7 +316,22 @@ extern "C" size_t
|
||||
rust_uv_helper_uv_timer_t_size() {
|
||||
return sizeof(uv_timer_t);
|
||||
}
|
||||
|
||||
extern "C" size_t
|
||||
rust_uv_helper_addr_in_size() {
|
||||
return sizeof(sockaddr_in6);
|
||||
}
|
||||
extern "C" size_t
|
||||
rust_uv_helper_uv_getaddrinfo_t_size() {
|
||||
return sizeof(uv_getaddrinfo_t);
|
||||
}
|
||||
extern "C" size_t
|
||||
rust_uv_helper_addrinfo_size() {
|
||||
return sizeof(addrinfo);
|
||||
}
|
||||
extern "C" unsigned int
|
||||
rust_uv_helper_get_INADDR_NONE() {
|
||||
return INADDR_NONE;
|
||||
}
|
||||
extern "C" uv_stream_t*
|
||||
rust_uv_get_stream_handle_from_connect_req(uv_connect_t* connect) {
|
||||
return connect->handle;
|
||||
@ -436,11 +459,27 @@ extern "C" struct sockaddr_in
|
||||
rust_uv_ip4_addr(const char* ip, int port) {
|
||||
rust_task* task = rust_get_current_task();
|
||||
LOG(task, stdlib, "before creating addr_ptr.. ip %s" \
|
||||
"port %d", ip, port);
|
||||
" port %d\n", ip, port);
|
||||
struct sockaddr_in addr = uv_ip4_addr(ip, port);
|
||||
LOG(task, stdlib, "after creating .. port: %d", addr.sin_port);
|
||||
return addr;
|
||||
}
|
||||
extern "C" struct sockaddr_in6
|
||||
rust_uv_ip6_addr(const char* ip, int port) {
|
||||
rust_task* task = rust_get_current_task();
|
||||
LOG(task, stdlib, "before creating addr_ptr.. ip %s" \
|
||||
" port %d\n", ip, port);
|
||||
return uv_ip6_addr(ip, port);
|
||||
}
|
||||
extern "C" int
|
||||
rust_uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
|
||||
return uv_ip4_name(src, dst, size);
|
||||
}
|
||||
extern "C" int
|
||||
rust_uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
|
||||
int result = uv_ip6_name(src, dst, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" uintptr_t*
|
||||
rust_uv_get_kernel_global_chan_ptr() {
|
||||
@ -460,3 +499,35 @@ extern "C" void
|
||||
rust_uv_current_kernel_free(void* mem) {
|
||||
current_kernel_free(mem);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
rust_uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* handle,
|
||||
uv_getaddrinfo_cb cb,
|
||||
char* node, char* service,
|
||||
addrinfo* hints) {
|
||||
return uv_getaddrinfo(loop, handle, cb, node, service, hints);
|
||||
}
|
||||
extern "C" void
|
||||
rust_uv_freeaddrinfo(addrinfo* res) {
|
||||
uv_freeaddrinfo(res);
|
||||
}
|
||||
extern "C" bool
|
||||
rust_uv_is_ipv4_addrinfo(addrinfo* input) {
|
||||
return input->ai_family == AF_INET;
|
||||
}
|
||||
extern "C" bool
|
||||
rust_uv_is_ipv6_addrinfo(addrinfo* input) {
|
||||
return input->ai_family == AF_INET6;
|
||||
}
|
||||
extern "C" addrinfo*
|
||||
rust_uv_get_next_addrinfo(addrinfo* input) {
|
||||
return input->ai_next;
|
||||
}
|
||||
extern "C" sockaddr_in*
|
||||
rust_uv_addrinfo_as_sockaddr_in(addrinfo* input) {
|
||||
return (sockaddr_in*)input->ai_addr;
|
||||
}
|
||||
extern "C" sockaddr_in6*
|
||||
rust_uv_addrinfo_as_sockaddr_in6(addrinfo* input) {
|
||||
return (sockaddr_in6*)input->ai_addr;
|
||||
}
|
||||
|
@ -111,8 +111,13 @@ rust_uv_last_error
|
||||
rust_uv_strerror
|
||||
rust_uv_err_name
|
||||
rust_uv_ip4_addr
|
||||
rust_uv_ip4_name
|
||||
rust_uv_ip6_addr
|
||||
rust_uv_ip6_name
|
||||
rust_uv_tcp_connect
|
||||
rust_uv_tcp_bind
|
||||
rust_uv_tcp_connect6
|
||||
rust_uv_tcp_bind6
|
||||
rust_uv_listen
|
||||
rust_uv_accept
|
||||
rust_uv_write
|
||||
@ -120,12 +125,22 @@ rust_uv_read_start
|
||||
rust_uv_read_stop
|
||||
rust_uv_malloc_buf_base_of
|
||||
rust_uv_free_base_of_buf
|
||||
rust_uv_is_ipv4_addrinfo
|
||||
rust_uv_is_ipv6_addrinfo
|
||||
rust_uv_get_next_addrinfo
|
||||
rust_uv_addrinfo_as_sockaddr_in
|
||||
rust_uv_addrinfo_as_sockaddr_in6
|
||||
rust_uv_helper_uv_tcp_t_size
|
||||
rust_uv_helper_uv_connect_t_size
|
||||
rust_uv_helper_uv_buf_t_size
|
||||
rust_uv_helper_uv_write_t_size
|
||||
rust_uv_helper_uv_err_t_size
|
||||
rust_uv_helper_sockaddr_in_size
|
||||
rust_uv_helper_sockaddr_in6_size
|
||||
rust_uv_helper_addr_in_size
|
||||
rust_uv_helper_addrinfo_size
|
||||
rust_uv_helper_uv_getaddrinfo_t_size
|
||||
rust_uv_helper_get_INADDR_NONE
|
||||
rust_uv_helper_uv_async_t_size
|
||||
rust_uv_helper_uv_timer_t_size
|
||||
rust_uv_get_stream_handle_from_connect_req
|
||||
@ -142,6 +157,8 @@ rust_uv_get_len_from_buf
|
||||
rust_uv_get_kernel_global_chan_ptr
|
||||
rust_uv_current_kernel_malloc
|
||||
rust_uv_current_kernel_free
|
||||
rust_uv_getaddrinfo
|
||||
rust_uv_freeaddrinfo
|
||||
rust_dbg_lock_create
|
||||
rust_dbg_lock_destroy
|
||||
rust_dbg_lock_lock
|
||||
|
Loading…
Reference in New Issue
Block a user