about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-11-25 21:59:08 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-11-26 09:10:10 -0800
commit7f3501275d8f54d6a393db5bafc0a189a01dc200 (patch)
treef8565cc994f280cb21fd4fed36ff31d0f9e87faf
parent679a2c042fb2541f55f1192ca97672907b258337 (diff)
downloadrust-7f3501275d8f54d6a393db5bafc0a189a01dc200.tar.gz
rust-7f3501275d8f54d6a393db5bafc0a189a01dc200.zip
Correctly handle libuv errors in addrinfo calls
It turns out that libuv was returning ENOSPC to us in our usage of the
uv_ipX_name functions. It also turns out that there may be an off-by-one in
libuv. For now just add one to the buffer size and handle the return value
correctly.

Closes #10663
-rw-r--r--src/librustuv/addrinfo.rs12
-rw-r--r--src/librustuv/net.rs11
2 files changed, 18 insertions, 5 deletions
diff --git a/src/librustuv/addrinfo.rs b/src/librustuv/addrinfo.rs
index 49782c62838..5a8a1a1ee20 100644
--- a/src/librustuv/addrinfo.rs
+++ b/src/librustuv/addrinfo.rs
@@ -184,14 +184,14 @@ pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] {
     }
 }
 
-#[cfg(test)]
+// cannot give tcp/ip permission without help of apk
+#[cfg(test, not(target_os="android"))]
 mod test {
     use std::io::net::ip::{SocketAddr, Ipv4Addr};
     use super::*;
     use super::super::local_loop;
 
     #[test]
-    #[ignore(cfg(target_os="android"))] // cannot give tcp/ip permission without help of apk
     fn getaddrinfo_test() {
         match GetAddrInfoRequest::run(local_loop(), Some("localhost"), None, None) {
             Ok(infos) => {
@@ -208,4 +208,12 @@ mod test {
             Err(e) => fail!("{:?}", e),
         }
     }
+
+    #[test]
+    fn issue_10663() {
+        // Something should happen here, but this certainly shouldn't cause
+        // everything to die. The actual outcome we don't care too much about.
+        GetAddrInfoRequest::run(local_loop(), Some("irc.n0v4.com"), None,
+                                None);
+    }
 }
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index c009cc3998c..3ea466b16e6 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -59,12 +59,17 @@ pub fn sockaddr_to_socket_addr(addr: *sockaddr) -> SocketAddr {
             fail!("unknown address?");
         };
         let ip_name = {
+            // apparently there's an off-by-one in libuv?
+            let ip_size = ip_size + 1;
             let buf = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
             let buf_ptr = vec::raw::to_ptr(buf);
-            if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
-                uvll::uv_ip4_name(addr, buf_ptr as *c_char, ip_size as size_t);
+            let ret = if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
+                uvll::uv_ip4_name(addr, buf_ptr as *c_char, ip_size as size_t)
             } else {
-                uvll::uv_ip6_name(addr, buf_ptr as *c_char, ip_size as size_t);
+                uvll::uv_ip6_name(addr, buf_ptr as *c_char, ip_size as size_t)
+            };
+            if ret != 0 {
+                fail!("error parsing sockaddr: {}", UvError(ret).desc());
             }
             buf
         };