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

Rework Ipv6Addr::is_global to check for global reachability rather than global scope #86634

Closed
wants to merge 2 commits into from

Conversation

CDirkx
Copy link
Contributor

@CDirkx CDirkx commented Jun 25, 2021

This PR changes the unstable method Ipv6Addr::is_global to make it consistent with Ipv4Addr::is_global, checking for reachability rather than global scope (see also #85696 fixing this conflation in Ipv6Addr::is_unicast_global).

To summarize, there are two concepts; an address can be globally reachable, and an address can have global scope. These concepts have been conflated in the past, but are not the same thing. There exist addresses with global scope that are not globally reachable (for example unique local addresses), and addresses that are globally reachable without having global scope (multicast addresses with non-global scope). is_unicast_global should be used to check for global scope, and is_global for global reachability according to the IANA IPv6 Special-Purpose Address Registry, like is done in Ipv4Addr::is_global and other language implementations. (To prevent this confusion in the future, #85696 renames is_unicast_global to has_unicast_global_scope)

The documentation of Ipv4Addr::is_global is also updated to make the two methods have similar descriptions and examples.

@rustbot rustbot added A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jun 25, 2021
@rust-highfive
Copy link
Collaborator

r? @kennytm

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 25, 2021
Comment on lines -477 to +496
/// Returns [`true`] if the address appears to be globally routable.
/// See [iana-ipv4-special-registry][ipv4-sr].
///
/// The following return [`false`]:
///
/// - private addresses (see [`Ipv4Addr::is_private()`])
/// - the loopback address (see [`Ipv4Addr::is_loopback()`])
/// - the link-local address (see [`Ipv4Addr::is_link_local()`])
/// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
/// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
/// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
/// `0.0.0.0/8` block
/// - addresses reserved for future protocols (see
/// [`Ipv4Addr::is_ietf_protocol_assignment()`], except
/// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
/// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`]
/// - addresses reserved for networking devices benchmarking (see
/// [`Ipv4Addr::is_benchmarking()`])
///
/// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
/// Returns [`true`] if the address appears to be globally reachable
/// as specified by the [IANA IPv4 Special-Purpose Address Registry].
/// Whether or not an address is practically reachable will depend on your network configuration.
///
/// Most IPv4 addresses are globally reachable;
/// unless they are specifically defined as *not* globally reachable.
///
/// Non-exhaustive list of notable addresses that are not globally reachable:
///
/// - The [unspecified address] ([`is_unspecified`](Ipv4Addr::is_unspecified))
/// - Addresses reserved for private use ([`is_private`](Ipv4Addr::is_private))
/// - Addresses in the shared address space ([`is_shared`](Ipv4Addr::is_shared))
/// - Loopback addresses ([`is_loopback`](Ipv4Addr::is_loopback))
/// - Link-local addresses ([`is_link_local`](Ipv4Addr::is_link_local))
/// - Addresses reserved for documentation ([`is_documentation`](Ipv4Addr::is_documentation))
/// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv4Addr::is_benchmarking))
/// - Reserved addresses ([`is_reserved`](Ipv4Addr::is_reserved))
/// - The [broadcast address] ([`is_broadcast`](Ipv4Addr::is_broadcast))
///
/// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv4 Special-Purpose Address Registry].
Copy link
Contributor Author

@CDirkx CDirkx Jun 25, 2021

Choose a reason for hiding this comment

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

Reworded to a (in my opinion) less cluttered non-exhaustive list. Instead of trying to list every type of address and exceptions, we list the most notable ones (mostly the ones Rust has methods for) and refer to the Special Address Registry for the complete overview. A similar thing is done in the description of Ipv6Addr::is_global.

Comment on lines -550 to +567
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
// globally routable addresses in the 192.0.0.0/24 range.
if u32::from_be_bytes(self.octets()) == 0xc0000009
|| u32::from_be_bytes(self.octets()) == 0xc000000a
{
return true;
}
!self.is_private()
&& !self.is_loopback()
&& !self.is_link_local()
&& !self.is_broadcast()
&& !self.is_documentation()
&& !self.is_shared()
&& !self.is_ietf_protocol_assignment()
&& !self.is_reserved()
&& !self.is_benchmarking()
// Make sure the address is not in 0.0.0.0/8
&& self.octets()[0] != 0
!(self.octets()[0] == 0 // "This network"
|| self.is_private()
|| self.is_shared()
|| self.is_loopback()
|| self.is_link_local()
|| (self.is_ietf_protocol_assignment()
&& !(
// Port Control Protocol Anycast (`192.0.0.9`)
u32::from_be_bytes(self.octets()) == 0xc0000009
// Traversal Using Relays around NAT Anycast (`192.0.0.10`)
|| u32::from_be_bytes(self.octets()) == 0xc000000a
))
|| self.is_documentation()
|| self.is_benchmarking()
|| self.is_reserved()
|| self.is_broadcast())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reordered the checks to match the order in the Special Address Registry.

@@ -1214,13 +1214,33 @@ impl Ipv6Addr {
u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
}

/// Returns [`true`] if the address appears to be globally routable.
/// Returns [`true`] if the address appears to be globally reachable
Copy link
Contributor Author

Choose a reason for hiding this comment

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

"globally reachable" instead of "globally routable", as that is the terminology used in the Special Address Registry.

/// Returns [`true`] if the address appears to be globally routable.
/// Returns [`true`] if the address appears to be globally reachable
/// as specified by the [IANA IPv6 Special-Purpose Address Registry].
/// Whether or not an address is practically reachable will depend on your network configuration.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you're not connected to the internet, you still can't reach a "globally reachable" address. I hope this also makes it clear that this method doesn't actually do any network traffic.

Comment on lines +1235 to +1239
/// Note that an address having global scope is not the same as being globally reachable,
/// and there is no direct relation between the two concepts: There exist addresses with global scope
/// that are not globally reachable (for example unique local addresses),
/// and addresses that are globally reachable without having global scope
/// (multicast addresses with non-global scope).
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Trying to avoid the confusion between "globally reachable" and "global scope", the rename in #85696 from is_unicast_global to has_unicast_global_scope should hopefully help with this. Another possibility would be to rename is_global to is_globally_reachable.

Comment on lines -308 to +313
check!("ff01::", multicast);
check!("ff02::", multicast);
check!("ff03::", multicast);
check!("ff04::", multicast);
check!("ff05::", multicast);
check!("ff08::", multicast);
check!("ff01::", global | multicast);
check!("ff02::", global | multicast);
check!("ff03::", global | multicast);
check!("ff04::", global | multicast);
check!("ff05::", global | multicast);
check!("ff08::", global | multicast);
Copy link
Contributor Author

@CDirkx CDirkx Jun 25, 2021

Choose a reason for hiding this comment

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

As mentioned in the PR description, multicast addresses with non-global scope are actually still globally reachable.

@CDirkx CDirkx force-pushed the ip-globally-reachable branch from 2be1e92 to 9ddd5a5 Compare July 8, 2021 12:36
@CDirkx
Copy link
Contributor Author

CDirkx commented Jul 8, 2021

Addressed an incorrect check pointed out in #86969 (comment)

@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 25, 2021
@bors
Copy link
Contributor

bors commented Aug 2, 2021

☔ The latest upstream changes (presumably #87535) made this pull request unmergeable. Please resolve the merge conflicts.

@camelid camelid added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 20, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 6, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 27, 2021
Manishearth added a commit to Manishearth/rust that referenced this pull request Oct 4, 2021
…plett

Add `Ipv6Addr::is_benchmarking`

This PR adds the unstable method `Ipv6Addr::is_benchmarking`. This method is added for parity with `Ipv4Addr::is_benchmarking`, and I intend to use it in a future rework of `Ipv6Addr::is_global` (edit: rust-lang#86634) to more accurately follow the [IANA Special Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml) (like is done in `Ipv4Addr::is_global`).

With `Ipv6Addr::is_benchmarking` and `Ipv4Addr::is_benchmarking` now both existing, `IpAddr::is_benchmarking` is also added.
Manishearth added a commit to Manishearth/rust that referenced this pull request Oct 4, 2021
…plett

Add `Ipv6Addr::is_benchmarking`

This PR adds the unstable method `Ipv6Addr::is_benchmarking`. This method is added for parity with `Ipv4Addr::is_benchmarking`, and I intend to use it in a future rework of `Ipv6Addr::is_global` (edit: rust-lang#86634) to more accurately follow the [IANA Special Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml) (like is done in `Ipv4Addr::is_global`).

With `Ipv6Addr::is_benchmarking` and `Ipv4Addr::is_benchmarking` now both existing, `IpAddr::is_benchmarking` is also added.
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 19, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 8, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 5, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 6, 2022
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Mar 20, 2022
@JohnCSimon
Copy link
Member

Ping from triage:
@kennytm what is the status of this review?

@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 22, 2022
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 20, 2022
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 24, 2022
@Mark-Simulacrum
Copy link
Member

Approved #99957, so going to go ahead and close this PR. #99957 contains the commits from here though.

Thanks!

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Aug 22, 2022
…se, r=Mark-Simulacrum

Rework Ipv6Addr::is_global to check for global reachability rather than global scope - rebase

Rebasing of pull request rust-lang#86634 off of master to try and get the feature "ip" stabilized.

I also found a test failure in the rebase that is_global was considering the benchmark space to be globally reachable.

This is related to my other rebasing pull request rust-lang#99947
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants