-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking issue for Ipv{4,6}Addr convenience methods #27709
Comments
I think we should consider this for stabilization in 1.6. Nominating. |
🔔 This issue is now entering its cycle-long final comment period for stabilization 🔔 Concretely, we discussed this in the libs meeting and the conclusion was that the boolean accessors are likely ready for stabilization after verifying that they're all the canonical definitions, but the |
What, exactly, is the "ip feature"? Could you link to the RustDoc(s) of the specific things that are supposed to be reviewed? |
I think "ip feature" in this context refers to things annotated with |
I don't mean to be rude, but that's just a restating my question as the answer. if you want people to actually give feedback on the proposal, it should be easier to understand what the proposal is. In this case, it is pretty difficult to tell what is being proposed because the module mixes stable and unstable features. I noticed that a large part of this module could work in It also seems odd that |
@briansmith I don't think that's being rude, there's just tension here between "we've been doing this a while so we're a bit short" and "newer people might not know what that is." @SimonSapin leaned a bit towards a literal explanation, but you're right to point out that more detail is good. I read @alexcrichton 's comment as:
http://doc.rust-lang.org/std/net/struct.Ipv4Addr.html and http://doc.rust-lang.org/std/net/struct.Ipv6Addr.html <- all the stuff here that is
http://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.multicast_scope is the only one I see that's unstable. |
FWIW, I filed #29221 a while ago, which would make tracking down what these tracking issues refer to slightly easier. |
Yes, to be concrete, I was proposing stabilizing:
Note that this is all pending actually verifying that these are standard properties of the respective IP address space and are well known with canonical implementations. I believe they fit this requirement already but would like to double-check.
Yeah these things can certainly move around over time (it's backwards compatible to move them at a later date). I'd be a little wary of putting things in core "just because" without a concrete purpose, and these kinda fall into the category I'd be wary of. For example the internal representation of each of these primitives is the
Method resolution favors inherent methods (methods defined on the type itself) over trait methods (e.g. impl'd traits plus the trait being in scope), so in that sense we're covered to add a trait at a future date. That being said the standard library doesn't have too many traits like this for abstracting between one or two types, so I would personally want to hold off on this extension for now. A possible alternative, however, could be adding the common set of methods to |
A couple of issues I have noticed with what we have:
On a more general note, might some of these functions need to be updated in the future if new ranges are assigned? How would that be handled? |
Ah I unfortunately did not have time to do an audit of these APIs this cycle, so when the libs team talked about this during triage today the conclusion was to punt this to next cycle, I hope to have the time to investigate it then and incorportate @ollie27's suggestions! |
🔔 This issue is now yet again entering its final comment period 🔔 Hopefully I get a chance to researching this API this time around! |
Better late than never! -- my analysis: Of the ipv4 properties, there's more listed on wikipedia at least, for example:
These sound relatively obscure (at least to me) though, so it seems fine that we don't add them just yet. In terms of what we currently have:
Like with ipv4 we're missing some ipv6 properties (according to RFC 6890):
Of the ipv6 methods:
From this I'm comfortable stabilizing the checked methods (they've got verified names and implementations at least), but I would personally want some more verification of the unchecked methods before stabilizing. |
Sounds like a good start. The |
The libs team discussed this during triage yesterday and the decision was to stabilize the methods I've checked above |
This commit stabilizes and deprecates the FCP (final comment period) APIs for the upcoming 1.7 beta release. The specific APIs which changed were: Stabilized * `Path::strip_prefix` (renamed from `relative_from`) * `path::StripPrefixError` (new error type returned from `strip_prefix`) * `Ipv4Addr::is_loopback` * `Ipv4Addr::is_private` * `Ipv4Addr::is_link_local` * `Ipv4Addr::is_multicast` * `Ipv4Addr::is_broadcast` * `Ipv4Addr::is_documentation` * `Ipv6Addr::is_unspecified` * `Ipv6Addr::is_loopback` * `Ipv6Addr::is_unique_local` * `Ipv6Addr::is_multicast` * `Vec::as_slice` * `Vec::as_mut_slice` * `String::as_str` * `String::as_mut_str` * `<[T]>::clone_from_slice` - the `usize` return value is removed * `<[T]>::sort_by_key` * `i32::checked_rem` (and other signed types) * `i32::checked_neg` (and other signed types) * `i32::checked_shl` (and other signed types) * `i32::checked_shr` (and other signed types) * `i32::saturating_mul` (and other signed types) * `i32::overflowing_add` (and other signed types) * `i32::overflowing_sub` (and other signed types) * `i32::overflowing_mul` (and other signed types) * `i32::overflowing_div` (and other signed types) * `i32::overflowing_rem` (and other signed types) * `i32::overflowing_neg` (and other signed types) * `i32::overflowing_shl` (and other signed types) * `i32::overflowing_shr` (and other signed types) * `u32::checked_rem` (and other unsigned types) * `u32::checked_neg` (and other unsigned types) * `u32::checked_shl` (and other unsigned types) * `u32::saturating_mul` (and other unsigned types) * `u32::overflowing_add` (and other unsigned types) * `u32::overflowing_sub` (and other unsigned types) * `u32::overflowing_mul` (and other unsigned types) * `u32::overflowing_div` (and other unsigned types) * `u32::overflowing_rem` (and other unsigned types) * `u32::overflowing_neg` (and other unsigned types) * `u32::overflowing_shl` (and other unsigned types) * `u32::overflowing_shr` (and other unsigned types) * `ffi::IntoStringError` * `CString::into_string` * `CString::into_bytes` * `CString::into_bytes_with_nul` * `From<CString> for Vec<u8>` * `From<CString> for Vec<u8>` * `IntoStringError::into_cstring` * `IntoStringError::utf8_error` * `Error for IntoStringError` Deprecated * `Path::relative_from` - renamed to `strip_prefix` * `Path::prefix` - use `components().next()` instead * `os::unix::fs` constants - moved to the `libc` crate * `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize * `IntoCow` - conflicts with `Into` and may come back later * `i32::{BITS, BYTES}` (and other integers) - not pulling their weight * `DebugTuple::formatter` - will be removed * `sync::Semaphore` - not used enough and confused with system semaphores Closes rust-lang#23284 cc rust-lang#27709 (still lots more methods though) Closes rust-lang#27712 Closes rust-lang#27722 Closes rust-lang#27728 Closes rust-lang#27735 Closes rust-lang#27729 Closes rust-lang#27755 Closes rust-lang#27782 Closes rust-lang#27798
Stabilize `Ipv6Addr::to_ipv4_mapped` CC rust-lang/rust#27709 (tracking issue for the `ip` feature which contains more functions) The function `Ipv6Addr::to_ipv4` is bad because it also returns an IPv4 address for the IPv6 loopback address `::1`. Stabilize `Ipv6Addr::to_ipv4_mapped` so we can recommend that function instead.
This avoids the otherwise confusing errors in the shape of > Error binding socket to [fe80::...]:0: Invalid argument (os error 22) Code for this was already in place but pending on is_unicast_link_local stabilization. As this has not happened in several years, a manual workaround (with the same note to wait for stabilization) is chosen. Workaround-For: rust-lang/rust#27709
Regarding the
Despite the fact that some of the addresses in the IANA table are considered Address prefixes listed in the Special-Purpose Address Registry are not guaranteed routability in any particular local or global context. So in my view all addresses in the IANA table should be considered in the condition as not being |
Make `IpAddr::to_canonical` and `IpV6Addr::to_canonical` stable, as well as const stabilize `Ipv6Addr::to_ipv4_mapped`. Newly stable API: impl IpAddr { // Now stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; } impl Ipv6Addr { // Now stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; // Already stable, this makes it const stable under // `const_ipv6_to_ipv4_mapped const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> } These stabilize a subset of the following tracking issues: - rust-lang#27709 - rust-lang#76205
Make `IpAddr::to_canonical` and `IpV6Addr::to_canonical` stable, as well as const stabilize `Ipv6Addr::to_ipv4_mapped`. Newly stable API: impl IpAddr { // Now stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; } impl Ipv6Addr { // Now stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; // Already stable, this makes it const stable under // `const_ipv6_to_ipv4_mapped` const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> } These stabilize a subset of the following tracking issues: - rust-lang#27709 - rust-lang#76205
Stabilize `{IpAddr, Ipv6Addr}::to_canonical` Make `IpAddr::to_canonical` and `IpV6Addr::to_canonical` stable (+const), as well as const stabilize `Ipv6Addr::to_ipv4_mapped`. Newly stable API: ```rust impl IpAddr { // Newly stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; } impl Ipv6Addr { // Newly stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; // Already stable, this makes it const stable under // `const_ipv6_to_ipv4_mapped` const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> } ``` These stabilize a subset of the following tracking issues: - rust-lang#27709 - rust-lang#76205 Stabilization of all methods under the `ip` gate was attempted once at rust-lang#66584 then again at rust-lang#76098. These were not successful because there are still unknowns about `is_documentation` `is_benchmarking` and similar; `to_canonical` is much more straightforward. I have looked and could not find any known issues with `to_canonical`. These were added in 2021 in rust-lang#87708 cc implementor `@the8472` r? libs-api `@rustbot` label +T-libs-api +needs-fcp
Stabilize `{IpAddr, Ipv6Addr}::to_canonical` Make `IpAddr::to_canonical` and `IpV6Addr::to_canonical` stable (+const), as well as const stabilize `Ipv6Addr::to_ipv4_mapped`. Newly stable API: ```rust impl IpAddr { // Newly stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; } impl Ipv6Addr { // Newly stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; // Already stable, this makes it const stable under // `const_ipv6_to_ipv4_mapped` const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> } ``` These stabilize a subset of the following tracking issues: - rust-lang#27709 - rust-lang#76205 Stabilization of all methods under the `ip` gate was attempted once at rust-lang#66584 then again at rust-lang#76098. These were not successful because there are still unknowns about `is_documentation` `is_benchmarking` and similar; `to_canonical` is much more straightforward. I have looked and could not find any known issues with `to_canonical`. These were added in 2021 in rust-lang#87708 cc implementor ``@the8472`` r? libs-api ``@rustbot`` label +T-libs-api +needs-fcp
Rollup merge of rust-lang#115955 - tgross35:ip-to-canonical, r=dtolnay Stabilize `{IpAddr, Ipv6Addr}::to_canonical` Make `IpAddr::to_canonical` and `IpV6Addr::to_canonical` stable (+const), as well as const stabilize `Ipv6Addr::to_ipv4_mapped`. Newly stable API: ```rust impl IpAddr { // Newly stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; } impl Ipv6Addr { // Newly stable under `ip_to_canonical` const fn to_canonical(&self) -> IpAddr; // Already stable, this makes it const stable under // `const_ipv6_to_ipv4_mapped` const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> } ``` These stabilize a subset of the following tracking issues: - rust-lang#27709 - rust-lang#76205 Stabilization of all methods under the `ip` gate was attempted once at rust-lang#66584 then again at rust-lang#76098. These were not successful because there are still unknowns about `is_documentation` `is_benchmarking` and similar; `to_canonical` is much more straightforward. I have looked and could not find any known issues with `to_canonical`. These were added in 2021 in rust-lang#87708 cc implementor ``@the8472`` r? libs-api ``@rustbot`` label +T-libs-api +needs-fcp
Hi everyone, The following concerns mostly I took the ipcheck tool[1] (which gave us some very useful data two years ago[2]) and modified it slightly to:
I present you two tables. The content is collapsed because of its length, you'll have to click on the arrows to see everything. Table 1. The status quo as of today (Rust nightly, Python versions as specified, Go 1.21.5)
Table 2. Patched Rust, patched CPython, regular Go.
In table 1 you'll see some Rust/Python disagreement in the following ranges: You'll also notice that starting with version 3.10 Python started to interpret IPv4-mapped IPv6 addresses as their IPv4 counterparts for the purposes of evaluating I consider both Rust and Python implementations somewhat buggy, sometimes buggy in the same way (for example when it comes to the In table 2 we have Rust/Python/Go comparison where
With the patches in place Rust and Python are in almost perfect agreement on the With the Rust patch the number of Rust/Go disagreements decreases by 1 (I think) but the nature of the disagreements changes (in both ways, it's roughly equalized). The implementation I propose is consistent with what's proposed by @tcoratger above (#27709 (comment)). The tables don't capture the difference in [1] https://github.com/rust-lang/libs-team/tree/main/tools/ipcheck |
looking forward to stabilisation of could theses simple convenience methods be included? possibly also on impl IpAddr {
pub fn ipv4(&self) -> Option<&Ipv4Addr> {
match self {
IpAddr::V4(ip) => Some(ip),
IpAddr::V6(_) => None,
}
}
pub fn ipv6(&self) -> Option<&Ipv6Addr> {
match self {
IpAddr::V4(_) => None,
IpAddr::V6(ip) => Some(ip),
}
}
} |
core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments. Adds: - `Ipv4Address::from_octets([u8;4])` - `Ipv6Address::from_octets([u8;16])` - `Ipv6Address::from_segments([u16;8])` equivalent to the existing `From` impls. Advantages: - Consistent with `to_bits, from_bits`. - More discoverable than the `From` impls. - Helps with type inference: it's common to want to convert byte slices to IP addrs. If you try this ```rust fn foo(x: &[u8]) -> Ipv4Addr { Ipv4Addr::from(foo.try_into().unwrap()) } ``` it [doesn't work](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0e2873312de275a58fa6e33d1b213bec). You have to write `Ipv4Addr::from(<[u8;4]>::try_from(x).unwrap())` instead, which is not great. With `from_octets` it is able to infer the right types. Found this while porting [smoltcp](https://github.com/smoltcp-rs/smoltcp/) from its own IP address types to the `core::net` types. ~~Tracking issues rust-lang#27709 rust-lang#76205~~ Tracking issue: rust-lang#131360
core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments. Adds: - `Ipv4Address::from_octets([u8;4])` - `Ipv6Address::from_octets([u8;16])` - `Ipv6Address::from_segments([u16;8])` equivalent to the existing `From` impls. Advantages: - Consistent with `to_bits, from_bits`. - More discoverable than the `From` impls. - Helps with type inference: it's common to want to convert byte slices to IP addrs. If you try this ```rust fn foo(x: &[u8]) -> Ipv4Addr { Ipv4Addr::from(foo.try_into().unwrap()) } ``` it [doesn't work](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0e2873312de275a58fa6e33d1b213bec). You have to write `Ipv4Addr::from(<[u8;4]>::try_from(x).unwrap())` instead, which is not great. With `from_octets` it is able to infer the right types. Found this while porting [smoltcp](https://github.com/smoltcp-rs/smoltcp/) from its own IP address types to the `core::net` types. ~~Tracking issues rust-lang#27709 rust-lang#76205~~ Tracking issue: rust-lang#131360
Rollup merge of rust-lang#130629 - Dirbaio:net-from-octets, r=tgross35 core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments. Adds: - `Ipv4Address::from_octets([u8;4])` - `Ipv6Address::from_octets([u8;16])` - `Ipv6Address::from_segments([u16;8])` equivalent to the existing `From` impls. Advantages: - Consistent with `to_bits, from_bits`. - More discoverable than the `From` impls. - Helps with type inference: it's common to want to convert byte slices to IP addrs. If you try this ```rust fn foo(x: &[u8]) -> Ipv4Addr { Ipv4Addr::from(foo.try_into().unwrap()) } ``` it [doesn't work](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0e2873312de275a58fa6e33d1b213bec). You have to write `Ipv4Addr::from(<[u8;4]>::try_from(x).unwrap())` instead, which is not great. With `from_octets` it is able to infer the right types. Found this while porting [smoltcp](https://github.com/smoltcp-rs/smoltcp/) from its own IP address types to the `core::net` types. ~~Tracking issues rust-lang#27709 rust-lang#76205~~ Tracking issue: rust-lang#131360
…ocal, r=dtolnay Stabilize `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` Make `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` stable (+const). Newly stable API: ```rust impl Ipv6Addr { // Newly stable under `ipv6_is_unique_local` const fn is_unique_local(&self) -> bool; // Newly stable under `ipv6_is_unique_local` const fn is_unicast_link_local(&self) -> bool; } ``` These stabilise a subset of the following tracking issue: - rust-lang#27709 I have looked and could not find any issues with `is_unique_local` and `is_unicast_link_local`. There is a well received comment calling for stabilisation of the latter function. Both functions are well defined and consistent with implementations in other languages: - [Go](https://cs.opensource.google/go/go/+/refs/tags/go1.23.0:src/net/netip/netip.go;l=518) - [Python](https://github.com/python/cpython/blob/e9d1bf353c3ccafc0d9b61b1b3688051bc976604/Lib/ipaddress.py#L2319-L2321) - [Ruby (unique local)](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html#private-3F-source) - [Ruby (unicast link local)](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html#link_local-3F-source) cc implementor `@little-dude` (I can't find the original PR for `is_unqiue_local`) r? libs-api `@rustbot` label +T-libs-api +needs-fcp
…al, r=dtolnay Stabilize `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` Make `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` stable (+const). Newly stable API: ```rust impl Ipv6Addr { // Newly stable under `ipv6_is_unique_local` const fn is_unique_local(&self) -> bool; // Newly stable under `ipv6_is_unique_local` const fn is_unicast_link_local(&self) -> bool; } ``` These stabilise a subset of the following tracking issue: - rust-lang#27709 I have looked and could not find any issues with `is_unique_local` and `is_unicast_link_local`. There is a well received comment calling for stabilisation of the latter function. Both functions are well defined and consistent with implementations in other languages: - [Go](https://cs.opensource.google/go/go/+/refs/tags/go1.23.0:src/net/netip/netip.go;l=518) - [Python](https://github.com/python/cpython/blob/e9d1bf353c3ccafc0d9b61b1b3688051bc976604/Lib/ipaddress.py#L2319-L2321) - [Ruby (unique local)](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html#private-3F-source) - [Ruby (unicast link local)](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html#link_local-3F-source) cc implementor `@little-dude` (I can't find the original PR for `is_unqiue_local`) r? libs-api `@rustbot` label +T-libs-api +needs-fcp
…al, r=dtolnay Stabilize `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` Make `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` stable (+const). Newly stable API: ```rust impl Ipv6Addr { // Newly stable under `ipv6_is_unique_local` const fn is_unique_local(&self) -> bool; // Newly stable under `ipv6_is_unique_local` const fn is_unicast_link_local(&self) -> bool; } ``` These stabilise a subset of the following tracking issue: - rust-lang#27709 I have looked and could not find any issues with `is_unique_local` and `is_unicast_link_local`. There is a well received comment calling for stabilisation of the latter function. Both functions are well defined and consistent with implementations in other languages: - [Go](https://cs.opensource.google/go/go/+/refs/tags/go1.23.0:src/net/netip/netip.go;l=518) - [Python](https://github.com/python/cpython/blob/e9d1bf353c3ccafc0d9b61b1b3688051bc976604/Lib/ipaddress.py#L2319-L2321) - [Ruby (unique local)](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html#private-3F-source) - [Ruby (unicast link local)](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html#link_local-3F-source) cc implementor `@little-dude` (I can't find the original PR for `is_unqiue_local`) r? libs-api `@rustbot` label +T-libs-api +needs-fcp
The below is a list of methods left to be stabilized under the
ip
feature. The path forward today is unclear; if you'd like to push through any method on here the libs team is interested in a PR with links to the associated RFCs or other official documentation. Let us know!IpAddr::is_documentation
Ipv6Addr::is_documentation
IpAddr::is_global
Ipv4Addr::is_global
Ipv6Addr::is_global
Ipv4Addr::is_shared
RemoveIpv4Addr::is_ietf_protocol_assignment
Ipv4Addr::is_ietf_protocol_assignment
#86439Ipv4Addr::is_benchmarking
Ipv4Addr::is_reserved
Ipv6Addr::is_unicast_global
Ipv6Addr::is_unicast_link_local
RemoveIpv6Addr::is_unicast_link_local_strict
Ipv6Addr::is_unicast_link_local_strict
#85819RemoveIpv6Addr::is_unicast_site_local
Ipv6Addr::is_unicast_site_local
#85820Ipv6Addr::is_unique_local
Ipv6Addr::multicast_scope
Ipv6Addr::is_ipv4_mapped
Ipv6Addr::to_ipv4_mapped
StabilizeIpv6Addr::to_ipv4_mapped
#96906Ipv6Addr::to_canonical
Stabilize{IpAddr, Ipv6Addr}::to_canonical
#115955IpAddr::to_canonical
Stabilize{IpAddr, Ipv6Addr}::to_canonical
#115955Steps
net
module for TCP/UDP #22015Subsets of the listed methods can be stabilized, rather than attempting to stabilize everything at once.
Unresolved Questions
From @KodrAus in #76098 (comment):
Ipv6Addr::is_unicast_*
methods with aIpv6Addr::unicast_scope
method that returns aIpv6UnicastScope
enum (Stabilize the "IP" feature #76098 (comment))?Ipv6Addr::to_ipv4
to ignore deprecated IPv4-compatible addresses, or deprecate the whole method in favor of the more correctIpv6Addr::to_ipv4_mapped
method (Stabilize the "IP" feature #76098 (comment))?Ipv6Addr::is_*
methods now properly considering mapped (non-deprecated) IPv4 addresses? I'd personally be comfortable considering the old behavior a bug.The text was updated successfully, but these errors were encountered: