Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IpAddr common methods #34694

Merged
merged 4 commits into from
Jul 20, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions src/libstd/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,66 @@ pub enum Ipv6MulticastScope {
Global
}

impl IpAddr {
/// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
#[unstable(feature="ip", issue="27709",
reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")]
Copy link
Contributor

@therealbstern therealbstern Jul 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per #27709 (comment), ipv4Addr.is_unspecified shouldn't be unstable (PR #34739 for stabilization).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@therealbstern I'll keep an eye out for that PR and update this once it gets merged.

pub fn is_unspecified(&self) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These will all want to be marked unstable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sfackler Should I use feature="ip" and issue="27709" or should I use a different feature or issue? (#27709 and feature="ip" are what the Ipv4/v6Addr convenience methods already use.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think reusing that issue and feature makes sense, unless @alexcrichton disagrees.

match *self {
IpAddr::V4(ref a) => a.is_unspecified(),
IpAddr::V6(ref a) => a.is_unspecified(),
}
}

/// Returns true if this is a loopback address ([IPv4], [IPv6]).
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
#[unstable(feature="ip", reason="recently added", issue="27709")]
pub fn is_loopback(&self) -> bool {
match *self {
IpAddr::V4(ref a) => a.is_loopback(),
IpAddr::V6(ref a) => a.is_loopback(),
}
}

/// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
#[unstable(feature="ip", issue="27709",
reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")]
pub fn is_global(&self) -> bool {
match *self {
IpAddr::V4(ref a) => a.is_global(),
IpAddr::V6(ref a) => a.is_global(),
}
}

/// Returns true if this is a multicast address ([IPv4], [IPv6]).
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
#[unstable(feature="ip", reason="recently added", issue="27709")]
pub fn is_multicast(&self) -> bool {
match *self {
IpAddr::V4(ref a) => a.is_multicast(),
IpAddr::V6(ref a) => a.is_multicast(),
}
}

/// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
#[unstable(feature="ip", issue="27709",
reason="recently added and depends on unstable Ipv6Addr.is_documentation()")]
pub fn is_documentation(&self) -> bool {
match *self {
IpAddr::V4(ref a) => a.is_documentation(),
IpAddr::V6(ref a) => a.is_documentation(),
}
}
}

impl Ipv4Addr {
/// Creates a new IPv4 address from four eight-bit octets.
///
Expand Down Expand Up @@ -756,6 +816,67 @@ mod tests {
None);
}

#[test]
fn ip_properties() {
fn check4(octets: &[u8; 4], unspec: bool, loopback: bool,
global: bool, multicast: bool, documentation: bool) {
let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]));
assert_eq!(ip.is_unspecified(), unspec);
assert_eq!(ip.is_loopback(), loopback);
assert_eq!(ip.is_global(), global);
assert_eq!(ip.is_multicast(), multicast);
assert_eq!(ip.is_documentation(), documentation);
}

fn check6(str_addr: &str, unspec: bool, loopback: bool,
global: bool, u_doc: bool, mcast: bool) {
let ip = IpAddr::V6(str_addr.parse().unwrap());
assert_eq!(ip.is_unspecified(), unspec);
assert_eq!(ip.is_loopback(), loopback);
assert_eq!(ip.is_global(), global);
assert_eq!(ip.is_documentation(), u_doc);
assert_eq!(ip.is_multicast(), mcast);
}

// address unspec loopbk global multicast doc
check4(&[0, 0, 0, 0], true, false, false, false, false);
check4(&[0, 0, 0, 1], false, false, true, false, false);
check4(&[0, 1, 0, 0], false, false, true, false, false);
check4(&[10, 9, 8, 7], false, false, false, false, false);
check4(&[127, 1, 2, 3], false, true, false, false, false);
check4(&[172, 31, 254, 253], false, false, false, false, false);
check4(&[169, 254, 253, 242], false, false, false, false, false);
check4(&[192, 0, 2, 183], false, false, false, false, true);
check4(&[192, 1, 2, 183], false, false, true, false, false);
check4(&[192, 168, 254, 253], false, false, false, false, false);
check4(&[198, 51, 100, 0], false, false, false, false, true);
check4(&[203, 0, 113, 0], false, false, false, false, true);
check4(&[203, 2, 113, 0], false, false, true, false, false);
check4(&[224, 0, 0, 0], false, false, true, true, false);
check4(&[239, 255, 255, 255], false, false, true, true, false);
check4(&[255, 255, 255, 255], false, false, false, false, false);

// address unspec loopbk global doc mcast
check6("::", true, false, false, false, false);
check6("::1", false, true, false, false, false);
check6("::0.0.0.2", false, false, true, false, false);
check6("1::", false, false, true, false, false);
check6("fc00::", false, false, false, false, false);
check6("fdff:ffff::", false, false, false, false, false);
check6("fe80:ffff::", false, false, false, false, false);
check6("febf:ffff::", false, false, false, false, false);
check6("fec0::", false, false, false, false, false);
check6("ff01::", false, false, false, false, true);
check6("ff02::", false, false, false, false, true);
check6("ff03::", false, false, false, false, true);
check6("ff04::", false, false, false, false, true);
check6("ff05::", false, false, false, false, true);
check6("ff08::", false, false, false, false, true);
check6("ff0e::", false, false, true, false, true);
check6("2001:db8:85a3::8a2e:370:7334", false, false, false, true, false);
check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true, false, false);
}

#[test]
fn ipv4_properties() {
fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
Expand Down