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:
parent
e097ff6398
commit
9edcb104ff
@ -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})
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user