about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2012-06-26 12:47:44 -0700
committerBrian Anderson <banderson@mozilla.com>2012-06-29 15:41:56 -0700
commit9edcb104ff2bbedd389ec519aea1de9c88c2beb1 (patch)
tree173c02072d90a961305fab063d017320783bb070 /src/libstd
parente097ff6398bdf08a6f5f8d6abe2ad4521ab3d09a (diff)
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.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/net_ip.rs4
-rw-r--r--src/libstd/net_tcp.rs68
-rw-r--r--src/libstd/uv_ll.rs23
3 files changed, 68 insertions, 27 deletions
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index 95a8e953a5e..6087def6624 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -230,7 +230,7 @@ mod v4 {
     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 @@ mod v4 {
             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})
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index da8c55c3d95..585307b8266 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -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 @@ type tcp_buffered_socket_data = {
     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)
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index e0668ebd44f..7921a84175a 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -542,6 +542,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)
@@ -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 {