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
This commit is contained in:
Alex Crichton 2013-11-25 21:59:08 -08:00
parent 679a2c042f
commit 7f3501275d
2 changed files with 18 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -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
};