about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2012-06-17 20:36:36 -0700
committerBrian Anderson <banderson@mozilla.com>2012-06-29 15:41:55 -0700
commit30f26ddbc99e34c42f110625f66fc9399d6f38d1 (patch)
treeaf5f27465b1bd3d5c3913e17fd78e16ac6252a5a /src
parentc0272928464c9f3ec8aa2e4a7ed17de6157ad59b (diff)
downloadrust-30f26ddbc99e34c42f110625f66fc9399d6f38d1.tar.gz
rust-30f26ddbc99e34c42f110625f66fc9399d6f38d1.zip
std: adding uv::ll::ip4_name and refactored net::ip to use it
replaces net::ip's previously, hand-rolled impl for ipv4 addr parsing..
we're relying on libuv, now
Diffstat (limited to 'src')
-rw-r--r--src/libstd/net_ip.rs52
-rw-r--r--src/libstd/net_tcp.rs20
-rw-r--r--src/libstd/uv_ll.rs18
3 files changed, 55 insertions, 35 deletions
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index 64cded848d1..106f1baa8c5 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -5,6 +5,11 @@ Types/fns concerning Internet Protocol (IP), versions 4 & 6
 import vec;
 import uint;
 
+import sockaddr_in = uv::ll::sockaddr_in;
+import sockaddr_in6 = uv::ll::sockaddr_in6;
+import uv_ip4_addr = uv::ll::ip4_addr;
+import uv_ip4_name = uv::ll::ip4_name;
+
 export ip_addr, parse_addr_err;
 export format_addr;
 export v4;
@@ -12,7 +17,7 @@ export v4;
 #[doc = "An IP address"]
 enum ip_addr {
     #[doc="An IPv4 address"]
-    ipv4(u8, u8, u8, u8),
+    ipv4(sockaddr_in),
     ipv6(u16,u16,u16,u16,u16,u16,u16,u16)
 }
 
@@ -32,8 +37,14 @@ 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";
@@ -59,30 +70,19 @@ 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 }
+          // 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
           }
         }
     }
     fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
-        let parts = vec::map(str::split_char(ip, '.'), {|s|
-            alt uint::from_str(s) {
-              some(n) if n <= 255u { n }
-              _ { 256u }
-            }
-        });
-        if vec::len(parts) != 4u {
-            result::err({err_msg: #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)})
-        }
-        else {
-            result::ok(ipv4(parts[0] as u8, parts[1] as u8,
-                 parts[2] as u8, parts[3] as u8))
+        unsafe {
+            // need to figure out how to establish a parse failure..
+            result::ok(ipv4(uv_ip4_addr(ip, 22)))
         }
     }
 }
@@ -90,14 +90,8 @@ j    Fails if the string is not a valid IPv4 address
 #[cfg(test)]
 mod test {
     #[test]
-    fn test_format_ip() {
-        assert (format_addr(ipv4(127u8, 0u8, 0u8, 1u8))
+    fn test_ipv4_parse_and_format_ip() {
+        assert (format_addr(v4::parse_addr("127.0.0.1"))
                 == "127.0.0.1")
     }
-
-    #[test]
-    fn test_parse_ip() {
-        assert (v4::parse_addr("127.0.0.1") ==
-                ipv4(127u8, 0u8, 0u8, 1u8));
-    }
 }
\ No newline at end of file
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index 6718e3729f7..7c3349efae4 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -126,7 +126,7 @@ that can be used to send and receive data to/from the remote host. In the
 event of failure, a `net::tcp::tcp_connect_err_data` instance will be
 returned
 "]
-fn connect(input_ip: ip::ip_addr, port: uint,
+fn connect(-input_ip: ip::ip_addr, port: uint,
            iotask: iotask)
     -> result::result<tcp_socket, tcp_connect_err_data> unsafe {
     let result_po = comm::port::<conn_attempt>();
@@ -551,7 +551,7 @@ a `result` instance containing empty data of type `()` on a
 successful/normal shutdown, and a `tcp_listen_err_data` enum in the event
 of listen exiting because of an error
 "]
-fn listen(host_ip: ip::ip_addr, port: uint, backlog: uint,
+fn listen(-host_ip: ip::ip_addr, port: uint, backlog: uint,
           iotask: iotask,
           on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
           +new_connect_cb: fn~(tcp_new_connection,
@@ -568,7 +568,7 @@ fn listen(host_ip: ip::ip_addr, port: uint, backlog: uint,
     }
 }
 
-fn listen_common(host_ip: ip::ip_addr, port: uint, backlog: uint,
+fn listen_common(-host_ip: ip::ip_addr, port: uint, backlog: uint,
           iotask: iotask,
           on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
           -on_connect_cb: fn~(*uv::ll::uv_tcp_t))
@@ -589,8 +589,15 @@ fn listen_common(host_ip: ip::ip_addr, port: uint, backlog: uint,
     let server_data_ptr = ptr::addr_of(server_data);
 
     let setup_result = comm::listen {|setup_ch|
+        // FIXME this is to address a compiler warning about
+        // an implicit copy.. it seems that double nested
+        // will defeat a move sigil, as is done to the host_ip
+        // arg above.. this same pattern works w/o complaint in
+        // tcp::connect (because the iotask::interact cb isn't
+        // 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(host_ip,
+            let tcp_addr = ipv4_ip_addr_to_sockaddr_in(loc_ip,
                                                        port);
             alt uv::ll::tcp_init(loop_ptr, server_stream_ptr) {
               0i32 {
@@ -1201,9 +1208,10 @@ type tcp_buffered_socket_data = {
 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(_,_,_,_) {
-        uv::ll::ip4_addr(ip::format_addr(input_ip), port as int)
+      ip::ipv4(addr) {
+        uv::ll::ip4_addr(addr_str, port as int)
       }
       ip::ipv6(_,_,_,_,_,_,_,_) {
         fail "FIXME (#2656) ipv6 not yet supported";
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index 42dd5b93ea9..fb8ba36acd3 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -704,6 +704,24 @@ unsafe fn ip6_addr(ip: str, port: int)
     ret rustrt::rust_uv_ip6_addr(addr_vec_ptr,
                                  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;
+    vec::as_buf(dst) {|dst_buf|
+        let result = rustrt::rust_uv_ip4_name(src as *sockaddr_in,
+                                              dst_buf, size);
+        alt result {
+          0i32 {
+            str::unsafe::from_buf(dst_buf)
+          }
+          _ {
+            ""
+          }
+        }
+    }
+}
 
 unsafe fn timer_init(loop_ptr: *libc::c_void,
                      timer_ptr: *uv_timer_t) -> libc::c_int {