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
This commit is contained in:
committed by
Brian Anderson
parent
c027292846
commit
30f26ddbc9
@@ -5,6 +5,11 @@ Types/fns concerning Internet Protocol (IP), versions 4 & 6
|
|||||||
import vec;
|
import vec;
|
||||||
import uint;
|
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 ip_addr, parse_addr_err;
|
||||||
export format_addr;
|
export format_addr;
|
||||||
export v4;
|
export v4;
|
||||||
@@ -12,7 +17,7 @@ export v4;
|
|||||||
#[doc = "An IP address"]
|
#[doc = "An IP address"]
|
||||||
enum ip_addr {
|
enum ip_addr {
|
||||||
#[doc="An IPv4 address"]
|
#[doc="An IPv4 address"]
|
||||||
ipv4(u8, u8, u8, u8),
|
ipv4(sockaddr_in),
|
||||||
ipv6(u16,u16,u16,u16,u16,u16,u16,u16)
|
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 {
|
fn format_addr(ip: ip_addr) -> str {
|
||||||
alt ip {
|
alt ip {
|
||||||
ipv4(a, b, c, d) {
|
ipv4(addr) {
|
||||||
#fmt["%u.%u.%u.%u", a as uint, b as uint, c as uint, d as uint]
|
unsafe {
|
||||||
|
let result = uv_ip4_name(&addr);
|
||||||
|
if result == "" {
|
||||||
|
fail "failed to convert inner sockaddr_in address to str"
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ipv6(_, _, _, _, _, _, _, _) {
|
ipv6(_, _, _, _, _, _, _, _) {
|
||||||
fail "FIXME (#2651) impl parsing of ipv6 addr";
|
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 {
|
fn parse_addr(ip: str) -> ip_addr {
|
||||||
alt try_parse_addr(ip) {
|
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) {
|
result::err(err_data) {
|
||||||
fail err_data.err_msg
|
fail err_data.err_msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
|
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
|
||||||
let parts = vec::map(str::split_char(ip, '.'), {|s|
|
unsafe {
|
||||||
alt uint::from_str(s) {
|
// need to figure out how to establish a parse failure..
|
||||||
some(n) if n <= 255u { n }
|
result::ok(ipv4(uv_ip4_addr(ip, 22)))
|
||||||
_ { 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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,14 +90,8 @@ j Fails if the string is not a valid IPv4 address
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_format_ip() {
|
fn test_ipv4_parse_and_format_ip() {
|
||||||
assert (format_addr(ipv4(127u8, 0u8, 0u8, 1u8))
|
assert (format_addr(v4::parse_addr("127.0.0.1"))
|
||||||
== "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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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
|
event of failure, a `net::tcp::tcp_connect_err_data` instance will be
|
||||||
returned
|
returned
|
||||||
"]
|
"]
|
||||||
fn connect(input_ip: ip::ip_addr, port: uint,
|
fn connect(-input_ip: ip::ip_addr, port: uint,
|
||||||
iotask: iotask)
|
iotask: iotask)
|
||||||
-> result::result<tcp_socket, tcp_connect_err_data> unsafe {
|
-> result::result<tcp_socket, tcp_connect_err_data> unsafe {
|
||||||
let result_po = comm::port::<conn_attempt>();
|
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
|
successful/normal shutdown, and a `tcp_listen_err_data` enum in the event
|
||||||
of listen exiting because of an error
|
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,
|
iotask: iotask,
|
||||||
on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
|
on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
|
||||||
+new_connect_cb: fn~(tcp_new_connection,
|
+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,
|
iotask: iotask,
|
||||||
on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
|
on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
|
||||||
-on_connect_cb: fn~(*uv::ll::uv_tcp_t))
|
-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 server_data_ptr = ptr::addr_of(server_data);
|
||||||
|
|
||||||
let setup_result = comm::listen {|setup_ch|
|
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|
|
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);
|
port);
|
||||||
alt uv::ll::tcp_init(loop_ptr, server_stream_ptr) {
|
alt uv::ll::tcp_init(loop_ptr, server_stream_ptr) {
|
||||||
0i32 {
|
0i32 {
|
||||||
@@ -1201,9 +1208,10 @@ type tcp_buffered_socket_data = {
|
|||||||
fn ipv4_ip_addr_to_sockaddr_in(input_ip: ip::ip_addr,
|
fn ipv4_ip_addr_to_sockaddr_in(input_ip: ip::ip_addr,
|
||||||
port: uint) -> uv::ll::sockaddr_in unsafe {
|
port: uint) -> uv::ll::sockaddr_in unsafe {
|
||||||
// FIXME (#2656): ipv6
|
// FIXME (#2656): ipv6
|
||||||
|
let addr_str = ip::format_addr(input_ip);
|
||||||
alt input_ip {
|
alt input_ip {
|
||||||
ip::ipv4(_,_,_,_) {
|
ip::ipv4(addr) {
|
||||||
uv::ll::ip4_addr(ip::format_addr(input_ip), port as int)
|
uv::ll::ip4_addr(addr_str, port as int)
|
||||||
}
|
}
|
||||||
ip::ipv6(_,_,_,_,_,_,_,_) {
|
ip::ipv6(_,_,_,_,_,_,_,_) {
|
||||||
fail "FIXME (#2656) ipv6 not yet supported";
|
fail "FIXME (#2656) ipv6 not yet supported";
|
||||||
|
|||||||
@@ -704,6 +704,24 @@ unsafe fn ip6_addr(ip: str, port: int)
|
|||||||
ret rustrt::rust_uv_ip6_addr(addr_vec_ptr,
|
ret rustrt::rust_uv_ip6_addr(addr_vec_ptr,
|
||||||
port as libc::c_int);
|
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,
|
unsafe fn timer_init(loop_ptr: *libc::c_void,
|
||||||
timer_ptr: *uv_timer_t) -> libc::c_int {
|
timer_ptr: *uv_timer_t) -> libc::c_int {
|
||||||
|
|||||||
Reference in New Issue
Block a user