std: addressing #2656 (ipv6 support in net::tcp)

.. there are some additional FIXME nags in net_tcp (L 1012) about blocking
because libuv is holding unsafe ptrs to task local data. the proposed
fix going is not really feasible w/ the current design, IMO, but i'll
leave it there in case someone really wants to make the case without
creating more hassle than it's worth.
This commit is contained in:
Jeff Olson 2012-06-26 12:47:44 -07:00 committed by Brian Anderson
parent e097ff6398
commit 9edcb104ff
5 changed files with 88 additions and 42 deletions

View File

@ -230,7 +230,7 @@ fn parse_to_ipv4_rep(ip: str) -> result::result<ipv4_rep, str> {
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);
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})
@ -243,7 +243,7 @@ fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
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);
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})

View File

@ -164,16 +164,35 @@ fn connect(-input_ip: ip::ip_addr, port: uint,
alt input_ip {
ipv4 {
log(debug, "dealing w/ ipv4 connection..");
let tcp_addr = ipv4_ip_addr_to_sockaddr_in(input_ip,
port);
let tcp_addr_ptr = ptr::addr_of(tcp_addr);
let connect_req_ptr =
ptr::addr_of((*socket_data_ptr).connect_req);
alt uv::ll::tcp_connect(
connect_req_ptr,
stream_handle_ptr,
tcp_addr_ptr,
tcp_connect_on_connect_cb) {
let addr_str = ip::format_addr(input_ip);
let connect_result = alt input_ip {
ip::ipv4(addr) {
// have to "recreate" the sockaddr_in/6
// since the ip_addr discards the port
// info.. should probably add an additional
// rust type that actually is closer to
// what the libuv API expects (ip str + port num)
log(debug, #fmt("addr: %?", addr));
let in_addr = uv::ll::ip4_addr(addr_str, port as int);
uv::ll::tcp_connect(
connect_req_ptr,
stream_handle_ptr,
ptr::addr_of(in_addr),
tcp_connect_on_connect_cb)
}
ip::ipv6(addr) {
log(debug, #fmt("addr: %?", addr));
let in_addr = uv::ll::ip6_addr(addr_str, port as int);
uv::ll::tcp_connect6(
connect_req_ptr,
stream_handle_ptr,
ptr::addr_of(in_addr),
tcp_connect_on_connect_cb)
}
};
alt connect_result {
0i32 {
log(debug, "tcp_connect successful");
// reusable data that we'll have for the
@ -598,15 +617,27 @@ fn listen_common(-host_ip: ip::ip_addr, port: uint, backlog: uint,
// nested within a comm::listen block)
let loc_ip = copy(host_ip);
iotask::interact(iotask) {|loop_ptr|
let tcp_addr = ipv4_ip_addr_to_sockaddr_in(loc_ip,
port);
alt uv::ll::tcp_init(loop_ptr, server_stream_ptr) {
0i32 {
uv::ll::set_data_for_uv_handle(
server_stream_ptr,
server_data_ptr);
alt uv::ll::tcp_bind(server_stream_ptr,
ptr::addr_of(tcp_addr)) {
let addr_str = ip::format_addr(loc_ip);
let bind_result = alt loc_ip {
ip::ipv4(addr) {
log(debug, #fmt("addr: %?", addr));
let in_addr = uv::ll::ip4_addr(addr_str, port as int);
uv::ll::tcp_bind(server_stream_ptr,
ptr::addr_of(in_addr))
}
ip::ipv6(addr) {
log(debug, #fmt("addr: %?", addr));
let in_addr = uv::ll::ip6_addr(addr_str, port as int);
uv::ll::tcp_bind6(server_stream_ptr,
ptr::addr_of(in_addr))
}
};
alt bind_result {
0i32 {
alt uv::ll::listen(server_stream_ptr,
backlog as libc::c_int,
@ -1205,19 +1236,6 @@ enum conn_attempt {
mut buf: [u8]
};
// convert rust ip_addr to libuv's native representation
fn ipv4_ip_addr_to_sockaddr_in(input_ip: ip::ip_addr,
port: uint) -> uv::ll::sockaddr_in unsafe {
// FIXME (#2656): ipv6
let addr_str = ip::format_addr(input_ip);
alt input_ip {
ip::ipv4(addr) {
uv::ll::ip4_addr(addr_str, port as int)
}
_ { fail "only works w/ ipv4";}
}
}
//#[cfg(test)]
mod test {
// FIXME don't run on fbsd or linux 32 bit (#2064)

View File

@ -542,6 +542,14 @@ fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
// 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)
@ -651,11 +659,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 {

View File

@ -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,
@ -328,7 +332,6 @@ 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;

View File

@ -116,6 +116,8 @@ 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