Repository: rust
Issue: IP Utility Methods
Labels: T-libs-api,A-io

This issue is split out of the larger discussion around stabilization of the `ip` feature (tracking issue: #27709). The focus of this issue is on the question of what utility methods Rust should provide for handling IPv4 and IPv6 addresses.

For discussion about the conversion methods (`to_ipv6_mapped`, `to_ipv6_compatible`, `to_ipv4`, `to_ipv4_mapped`) see #85609 IPv4-in-IPv6 Address Support.

For discussion about the IPv6 unicast methods (`is_unicast_link_local`, `is_unicast_link_local_strict`, `is_unicast_site_local`, `is_unicast_global`) see #85604 IPv6 Unicast Interface.

Specifically this issue concerns itself with the various special address utility methods:

```rust
impl Ipv4Addr {
    #[unstable]
    fn is_benchmarking(&self) -> bool;
    fn is_documentation(&self) -> bool;
    #[unstable]
    fn is_ietf_protocol_assignment(&self) -> bool;
    #[unstable]
    fn is_global(&self) -> bool;
    fn is_private(&self) -> bool;
    #[unstable]
    fn is_reserved(&self) -> bool;
    #[unstable]
    fn is_shared(&self) -> bool;
}

impl Ipv6Addr {
    #[unstable]
    fn is_documentation(&self) -> bool;
    #[unstable]
    fn is_global(&self) -> bool;
}
```

All of these excluding `is_global` currently correspond to various special addresses in the [IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml) and [IANA IPv6 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml). 

Note that of these only `Ipv4Addr::is_documentation` and `is_private` are currently stable.

## Open Problems

### Semantics of utility methods

What should the exact semantics of `is_global` be? The current documentation of [`Ipv4Addr::is_global`](https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html#method.is_global) mentions the [IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml) and follows it exactly, [`Ipv6Addr::is_global`](https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.is_global) does not (https://github.com/rust-lang/rust/pull/76098#discussion_r558690082). For IPv6 specifically, should IPv4-mapped addresses be considered global? Python does not (https://github.com/rust-lang/rust/pull/76098#issuecomment-760651861). Is there an official definition for which addresses are globally reachable? What would be the least surprising to users.

There is a similar question for all the other methods: should we strictly adhere to standards and the address registry, or for IPv6 addresses also consider IPv4-mapped addresses. Is it a problem if the IPv4 version and IPv6 version of a method have different definitions?

Unresolved: Settle on the exact semantics of `is_global` and other methods. See also #85609 IPv4-in-IPv6 Address Support.

### Which utility methods are useful

Which utility methods do we want to offer? Maybe offer the equivalent of `is_reserved`, `is_benchmarking` etc. for `Ipv6Addr` as well? Maybe not expose `is_ietf_protocol_assignment` (what would be a real-world use case for this other than computing `is_global`?) A lot of these methods are not offered by other languages, but .NET does have [IsIPv6Teredo](https://docs.microsoft.com/en-us/dotnet/api/system.net.ipaddress.isipv6teredo?view=net-5.0#System_Net_IPAddress_IsIPv6Teredo). `is_ipv4_mapped` and maybe `is_ipv4_compatible` could also be useful. 

Unresolved: Which utility methods should be stabilized. How do we determine if a method is useful enough to be added.

### Methods on both `Ipv4Addr` and `Ipv6Addr`

If methods like `is_documentation` and `is_benchmarking` are added to both `Ipv4Addr` and `Ipv6Addr` they can also be implemented for `IpAddr`. Does this make sense semantically? Is the definition of `Ipv4Addr::is_documentation` equivalent to `Ipv6Addr::documentation`? Does a user ever needs to check in practice if they have an IPv4 documentation address or an IPv6 documentation address? It has been suggested that for these common methods on `IpAddr`, `Ipv4Addr` and `Ipv6Addr` there could be a trait.

Unresolved: Which utility methods should be implemented for `IpAddr`.

## Previous Discussion

- stabilize the "ip" feature: [PR #66584](https://github.com/rust-lang/rust/pull/66584)
- Stabilize the "IP" feature: [PR #76098](https://github.com/rust-lang/rust/pull/76098)
- Stabilize the "IP" feature (continued from #76098): [PR #85585](https://github.com/rust-lang/rust/pull/85585)