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:
parent
679a2c042f
commit
7f3501275d
|
@ -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 {
|
mod test {
|
||||||
use std::io::net::ip::{SocketAddr, Ipv4Addr};
|
use std::io::net::ip::{SocketAddr, Ipv4Addr};
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::local_loop;
|
use super::super::local_loop;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore(cfg(target_os="android"))] // cannot give tcp/ip permission without help of apk
|
|
||||||
fn getaddrinfo_test() {
|
fn getaddrinfo_test() {
|
||||||
match GetAddrInfoRequest::run(local_loop(), Some("localhost"), None, None) {
|
match GetAddrInfoRequest::run(local_loop(), Some("localhost"), None, None) {
|
||||||
Ok(infos) => {
|
Ok(infos) => {
|
||||||
|
@ -208,4 +208,12 @@ mod test {
|
||||||
Err(e) => fail!("{:?}", e),
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,12 +59,17 @@ pub fn sockaddr_to_socket_addr(addr: *sockaddr) -> SocketAddr {
|
||||||
fail!("unknown address?");
|
fail!("unknown address?");
|
||||||
};
|
};
|
||||||
let ip_name = {
|
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 = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
|
||||||
let buf_ptr = vec::raw::to_ptr(buf);
|
let buf_ptr = vec::raw::to_ptr(buf);
|
||||||
if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
|
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);
|
uvll::uv_ip4_name(addr, buf_ptr as *c_char, ip_size as size_t)
|
||||||
} else {
|
} 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
|
buf
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue