2012-04-29 23:53:17 -05:00
|
|
|
#[doc="
|
|
|
|
Types/fns concerning Internet Protocol (IP), versions 4 & 6
|
|
|
|
"];
|
|
|
|
|
|
|
|
import vec;
|
|
|
|
import uint;
|
|
|
|
|
2012-06-17 22:36:36 -05:00
|
|
|
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;
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
import uv_ip6_addr = uv::ll::ip6_addr;
|
|
|
|
import uv_ip6_name = uv::ll::ip6_name;
|
2012-06-17 22:36:36 -05:00
|
|
|
|
2012-05-19 16:06:48 -05:00
|
|
|
export ip_addr, parse_addr_err;
|
2012-04-30 17:10:24 -05:00
|
|
|
export format_addr;
|
2012-04-29 23:53:17 -05:00
|
|
|
export v4;
|
|
|
|
|
|
|
|
#[doc = "An IP address"]
|
|
|
|
enum ip_addr {
|
|
|
|
#[doc="An IPv4 address"]
|
2012-06-17 22:36:36 -05:00
|
|
|
ipv4(sockaddr_in),
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
ipv6(sockaddr_in6)
|
2012-04-29 23:53:17 -05:00
|
|
|
}
|
|
|
|
|
2012-05-19 16:06:48 -05:00
|
|
|
#[doc="
|
|
|
|
Human-friendly feedback on why a parse_addr attempt failed
|
|
|
|
"]
|
|
|
|
type parse_addr_err = {
|
|
|
|
err_msg: str
|
|
|
|
};
|
|
|
|
|
2012-04-29 23:53:17 -05:00
|
|
|
#[doc="
|
|
|
|
Convert a `ip_addr` to a str
|
|
|
|
|
|
|
|
# Arguments
|
|
|
|
|
|
|
|
* ip - a `std::net::ip::ip_addr`
|
|
|
|
"]
|
|
|
|
fn format_addr(ip: ip_addr) -> str {
|
|
|
|
alt ip {
|
2012-06-17 22:36:36 -05:00
|
|
|
ipv4(addr) {
|
|
|
|
unsafe {
|
|
|
|
let result = uv_ip4_name(&addr);
|
|
|
|
if result == "" {
|
|
|
|
fail "failed to convert inner sockaddr_in address to str"
|
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
2012-04-29 23:53:17 -05:00
|
|
|
}
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
ipv6(addr) {
|
|
|
|
unsafe {
|
|
|
|
let result = uv_ip6_name(&addr);
|
|
|
|
if result == "" {
|
|
|
|
fail "failed to convert inner sockaddr_in address to str"
|
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
2012-05-05 11:21:19 -05:00
|
|
|
}
|
2012-04-29 23:53:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mod v4 {
|
|
|
|
#[doc = "
|
|
|
|
Convert a str to `ip_addr`
|
|
|
|
|
|
|
|
# Failure
|
|
|
|
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
Fails if the string is not a valid IPv4 address
|
2012-04-29 23:53:17 -05:00
|
|
|
|
|
|
|
# Arguments
|
|
|
|
|
|
|
|
* ip - a string of the format `x.x.x.x`
|
|
|
|
|
|
|
|
# Returns
|
|
|
|
|
|
|
|
* an `ip_addr` of the `ipv4` variant
|
|
|
|
"]
|
|
|
|
fn parse_addr(ip: str) -> ip_addr {
|
2012-05-19 16:06:48 -05:00
|
|
|
alt try_parse_addr(ip) {
|
2012-06-17 22:36:36 -05:00
|
|
|
// 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) }
|
2012-05-19 16:06:48 -05:00
|
|
|
result::err(err_data) {
|
|
|
|
fail err_data.err_msg
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
|
2012-06-17 22:36:36 -05:00
|
|
|
unsafe {
|
|
|
|
// need to figure out how to establish a parse failure..
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
let new_addr = uv_ip4_addr(ip, 22);
|
|
|
|
let reformatted_name = uv_ip4_name(&new_addr);
|
|
|
|
log(debug, #fmt("try_parse_addr: input ip: %s reparsed ip: %s",
|
|
|
|
ip, reformatted_name));
|
|
|
|
// here we're going to
|
|
|
|
let inaddr_none_val = "255.255.255.255";
|
|
|
|
if ip != inaddr_none_val && reformatted_name == inaddr_none_val {
|
|
|
|
result::err({err_msg:#fmt("failed to parse '%s'",
|
|
|
|
ip)})
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
result::ok(ipv4(new_addr))
|
|
|
|
}
|
2012-05-19 16:06:48 -05:00
|
|
|
}
|
2012-04-29 23:53:17 -05:00
|
|
|
}
|
|
|
|
}
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
mod v6 {
|
|
|
|
#[doc = "
|
|
|
|
Convert a str to `ip_addr`
|
|
|
|
|
|
|
|
# Failure
|
|
|
|
|
|
|
|
Fails if the string is not a valid IPv6 address
|
2012-04-29 23:53:17 -05:00
|
|
|
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
# Arguments
|
|
|
|
|
|
|
|
* ip - an ipv6 string. See RFC2460 for spec.
|
|
|
|
|
|
|
|
# Returns
|
|
|
|
|
|
|
|
* an `ip_addr` of the `ipv6` variant
|
|
|
|
"]
|
|
|
|
fn parse_addr(ip: str) -> ip_addr {
|
|
|
|
alt try_parse_addr(ip) {
|
|
|
|
// 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> {
|
|
|
|
unsafe {
|
|
|
|
// need to figure out how to establish a parse failure..
|
|
|
|
let new_addr = uv_ip6_addr(ip, 22);
|
|
|
|
let reparsed_name = uv_ip6_name(&new_addr);
|
|
|
|
log(debug, #fmt("v6::try_parse_addr ip: '%s' reparsed '%s'",
|
|
|
|
ip, reparsed_name));
|
|
|
|
// '::' appears to be uv_ip6_name() returns for bogus
|
|
|
|
// parses..
|
|
|
|
if ip != "::" && reparsed_name == "::" {
|
|
|
|
result::err({err_msg:#fmt("failed to parse '%s'",
|
|
|
|
ip)})
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
result::ok(ipv6(new_addr))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//#[cfg(test)]
|
2012-04-29 23:53:17 -05:00
|
|
|
mod test {
|
|
|
|
#[test]
|
2012-06-17 22:36:36 -05:00
|
|
|
fn test_ipv4_parse_and_format_ip() {
|
std: adding net::ip::v6 utils and rudimentary tests, huzzah! (see caveats)
libuv's own ip vetting code appears to in a somewhat woeful state,
for both ipv4 and ipv6 (there are some notes in the tests for net_ip, as
well as stuff added in uv_ll). They are aware of this and welcome patches.
I have rudimentary code in place that can verify whether the provided str
ip was, in fact, validly parsed by libuv, making a few assumptions:
* for ipv4, we assume that the platform's INADDR_NONE val is 0xffffffff ,
I should write a helper to return this value from the platform's libc
headers instead of hard-coding it in rust.
* for ipv6, we assume that the library will always return '::' for
malformed inputs.. as is the case in 64bit ubuntu. I need to verify this
on other platforms.. but at least the debugging output is in place, so
if expectations don't line up, it'll be straightforward to address
2012-06-17 22:42:48 -05:00
|
|
|
let localhost_str = "127.0.0.1";
|
|
|
|
assert (format_addr(v4::parse_addr(localhost_str))
|
|
|
|
== localhost_str)
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn test_ipv6_parse_and_format_ip() {
|
|
|
|
let localhost_str = "::1";
|
|
|
|
let format_result = format_addr(v6::parse_addr(localhost_str));
|
|
|
|
log(debug, #fmt("results: expected: '%s' actual: '%s'",
|
|
|
|
localhost_str, format_result));
|
|
|
|
assert format_result == localhost_str;
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn test_ipv4_bad_parse() {
|
|
|
|
alt v4::try_parse_addr("b4df00d") {
|
|
|
|
result::err(err_info) {
|
|
|
|
log(debug, #fmt("got error as expected %?", err_info));
|
|
|
|
assert true;
|
|
|
|
}
|
|
|
|
result::ok(addr) {
|
|
|
|
fail #fmt("Expected failure, but got addr %?", addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn test_ipv6_bad_parse() {
|
|
|
|
alt v6::try_parse_addr("::,~2234k;") {
|
|
|
|
result::err(err_info) {
|
|
|
|
log(debug, #fmt("got error as expected %?", err_info));
|
|
|
|
assert true;
|
|
|
|
}
|
|
|
|
result::ok(addr) {
|
|
|
|
fail #fmt("Expected failure, but got addr %?", addr);
|
|
|
|
}
|
|
|
|
}
|
2012-04-29 23:53:17 -05:00
|
|
|
}
|
|
|
|
}
|