Skip to content

Stabilize Ipv6Addr::is_unique_local and Ipv6Addr::is_unicast_link_local - #129238

Merged
bors merged 1 commit into
rust-lang:masterfrom
umgefahren:stabilize-ipv6-unique-local
Nov 22, 2024
Merged

Stabilize Ipv6Addr::is_unique_local and Ipv6Addr::is_unicast_link_local#129238
bors merged 1 commit into
rust-lang:masterfrom
umgefahren:stabilize-ipv6-unique-local

Conversation

@umgefahren

Copy link
Copy Markdown
Contributor

Make Ipv6Addr::is_unique_local and Ipv6Addr::is_unicast_link_local stable (+const).

Newly stable API:

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:

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:

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

@rustbot

rustbot commented Aug 18, 2024

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @joshtriplett (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Aug 18, 2024
@umgefahren

umgefahren commented Aug 18, 2024

Copy link
Copy Markdown
Contributor Author

r? dtolnay

Since @dtolnay reviewed the last stabilisation PR in this domain.

@rustbot

rustbot commented Aug 18, 2024

Copy link
Copy Markdown
Collaborator

Failed to set assignee to dtolney: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@rustbot rustbot assigned dtolnay and unassigned joshtriplett Aug 18, 2024
@dtolnay dtolnay removed the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Aug 19, 2024
@dtolnay

dtolnay commented Aug 19, 2024

Copy link
Copy Markdown
Member

Both functions are well defined and consistent with implementations in other languages:

  • Go

This one isn't entirely true. (I didn't try any of the other languages.)

Rust: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=6770cd0cf0a2e5439580dfaf5bf41471

#![feature(ip)]

fn main() {
    let ip = std::net::Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 169, 254, 0, 0]);
    println!("{} {}", ip, ip.is_unicast_link_local());
}
::ffff:169.254.0.0 false

Go: https://go.dev/play/p/b4E92eet5Yg

package main

import (
    "fmt"
    "net/netip"
)

func main() {
    ip := netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 169, 254, 0, 0})
    fmt.Println(ip, ip.IsLinkLocalUnicast())
}
::ffff:169.254.0.0 true

The difference comes down to this "not assigned any special meaning", which is not the case in Go:

/// To assist in the transition from IPv4 to IPv6 two types of IPv6 addresses that embed an IPv4 address were defined:
/// IPv4-compatible and IPv4-mapped addresses. Of these IPv4-compatible addresses have been officially deprecated.
///
/// Both types of addresses are not assigned any special meaning by this implementation,
/// other than what the relevant standards prescribe. This means that an address like `::ffff:127.0.0.1`,
/// while representing an IPv4 loopback address, is not itself an IPv6 loopback address; only `::1` is.
/// To handle these so called "IPv4-in-IPv6" addresses, they have to first be converted to their canonical IPv4 address.

@dtolnay

dtolnay commented Aug 19, 2024

Copy link
Copy Markdown
Member

@rust-lang/libs-api:
@rfcbot fcp merge

@rfcbot

rfcbot commented Aug 19, 2024

Copy link
Copy Markdown

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Aug 19, 2024
@tgross35

Copy link
Copy Markdown
Contributor

Is is_unicast_global worth including as part of the unicast family?

These methods, along with similar unstabilized ones, have unfortunately had a pretty rough time getting finalized. I added unresolved questions to the tracking issue at #27709 to list some of these concerns. Most relevant here:

There is a tool designed to check our IP methods against those from other languages, could you try to run it to see where we stand? https://github.com/rust-lang/libs-team/tree/main/tools/ipcheck?

(I can't find the original PR for is_unqiue_local)

It predates rust 1 :) #22015 also typo unqiue/unique if you were searching for that exact string.

@umgefahren

umgefahren commented Oct 2, 2024

Copy link
Copy Markdown
Contributor Author

I ran the ipcheck tool, some of my changes I applied can be seen in my PR: rust-lang/libs-team#454

Complete output of a run

Found Rust implementation.
Found .NET implementation.
Found Go implementation.
Found Java implementation.

addr .NET Go Java
0.0.0.0 ✔️ ✔️ ✔️
0.1.2.3 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
1.1.1.1 ✔️ ✔️ ✔️
127.0.0.1 ✔️ ✔️ ✔️
255.255.255.255 ✔️ ✔️ ✔️
10.0.0.1 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
16.89.10.65 ✔️ ✔️ ✔️
45.22.13.197 ✔️ ✔️ ✔️
100.64.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
100.128.0.0 ✔️ ✔️ ✔️
169.254.0.0 ✔️ ✔️ ✔️
172.16.10.10 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.7 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.8 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.9 ✔️ ✔️ ✔️
192.0.0.10 ✔️ ✔️ ✔️
192.0.0.169 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.170 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.171 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.172 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.0.255 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.0.2.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.31.196.2 ✔️ ✔️ ✔️
192.52.193.2 ✔️ ✔️ ✔️
192.88.99.2 ✔️ ✔️ ✔️
192.168.0.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
192.175.48.2 ✔️ ✔️ ✔️
198.18.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
198.51.100.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
203.0.113.6 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
240.0.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
255.255.255.254 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:0.0.0.0 ✔️ { is_unspecified : false (Rust) ≠ true (Go) } ✔️
::ffff:0.1.2.3 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:1.1.1.1 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:127.0.0.1 { is_loopback : false (Rust) ≠ true (.NET) } { is_loopback : false (Rust) ≠ true (Go) } { is_loopback : false (Rust) ≠ true (Java) }
::ffff:255.255.255.255 ✔️ ✔️ ✔️
::ffff:10.0.0.1 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:16.89.10.65 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:45.22.13.197 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:100.64.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:100.128.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:169.254.0.0 ✔️ { is_unicast_link_local : false (Rust) ≠ true (Go) } ✔️
::ffff:172.16.10.10 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.7 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.8 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.9 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.10 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.169 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.170 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.171 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.172 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.0.255 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.0.2.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.31.196.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.52.193.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.88.99.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.168.0.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:192.175.48.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:198.18.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:198.51.100.2 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:203.0.113.6 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:240.0.0.0 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::ffff:255.255.255.254 ✔️ { is_global : false (Rust) ≠ true (Go) } ✔️
::1 ✔️ ✔️ ✔️
:: ✔️ ✔️ ✔️
64:ff9b:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } ✔️ ✔️
64:ff9b:1:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
100:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2001:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2001:1::1 { to_ipv4 : null (Rust) ≠ "0.0.0.1" (.NET) } ✔️ ✔️
2001:1::2 { to_ipv4 : null (Rust) ≠ "0.0.0.2" (.NET) } ✔️ ✔️
2001:2:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2001:0002:6c::430 { to_ipv4 : null (Rust) ≠ "0.0.4.48" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2001:3:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } ✔️ ✔️
2001:4:112:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } ✔️ ✔️
2001:10:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2001:10:240:ab::a { to_ipv4 : null (Rust) ≠ "0.0.0.10" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2001:20:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } ✔️ ✔️
2001:30:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } ✔️ ✔️
2001:db8:8:4::2 { to_ipv4 : null (Rust) ≠ "0.0.0.2" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2002:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2002:cb0a:3cdd:1::1 { to_ipv4 : null (Rust) ≠ "0.0.0.1" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
2620:4f:8000:: { to_ipv4 : null (Rust) ≠ "0.0.0.0" (.NET) } ✔️ ✔️
fdf8:f53b:82e4::53 { to_ipv4 : null (Rust) ≠ "0.0.0.83" (.NET) } { is_global : false (Rust) ≠ true (Go) } ✔️
fe80::200:5aee:feaa:20a2 { to_ipv4 : null (Rust) ≠ "254.170.32.162" (.NET) } ✔️ ✔️
ff01:0:0:0:0:0:0:2 { to_ipv4 : null (Rust) ≠ "0.0.0.2" (.NET) } { is_global : true (Rust) ≠ false (Go) } ✔️

Operations with only a Rust implementation:

  • is_benchmarking
  • is_documentation
  • is_reserved
  • is_shared
  • is_unique_local
  • mc_scope_admin_local
  • mc_scope_realm_local
  • mc_scope_reserved
  • mc_scope_unassigned

Summary

As far as I can see the difference in output in is_loopback and is_unicast_link_local is a matter of opinion. They boil down to the differentiation of how IPv4 to IPv6 addresses are handled, as @dtolnay already pointed out: #129238 (comment)

However since Rust went a different way anyway in handling these cases, I would recon that we can assume Rust is compatible with other languages, however there exists a pitfall.

@umgefahren

Copy link
Copy Markdown
Contributor Author

I'm open to discussion here. If you want to see how it looks, I could include it in this.

@thvdveld

thvdveld commented Oct 8, 2024

Copy link
Copy Markdown
Contributor

I agree with @tgross35 that adding this would make it more consistent with Ipv6MulticastScope. I'd be in favour of adding this.

@tgross35

tgross35 commented Oct 8, 2024

Copy link
Copy Markdown
Contributor

@thvdveld do you have an idea how this should look? If so, that could be submitted as an ACP (or just put up a PR changing it)

@thvdveld

Copy link
Copy Markdown
Contributor

What I get from https://www.rfc-editor.org/rfc/rfc4291#section-2.5: there are only two scope types for unicast addresses: global unicast and link-local unicast. However, I think we could also add UniqueLocal, Unspecified, Benchmarking, Documentation, Loopback, but I'm not sure if those are really a scope.

@bors

bors commented Oct 14, 2024

Copy link
Copy Markdown
Collaborator

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

@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Oct 23, 2024
@rfcbot

rfcbot commented Oct 23, 2024

Copy link
Copy Markdown

🔔 This is now entering its final comment period, as per the review above. 🔔

@tgross35

Copy link
Copy Markdown
Contributor

@joshtriplett (or others who checked for FCP) could you ack that the Ipv6UnicastScope enum idea mentioned above was considered & rejected rather than overlooked? Just making sure :)

@rfcbot rfcbot added the finished-final-comment-period The final comment period is finished for this PR / Issue. label Nov 2, 2024
@dtolnay

dtolnay commented Nov 21, 2024

Copy link
Copy Markdown
Member

@bors r+

@dtolnay

dtolnay commented Nov 21, 2024

Copy link
Copy Markdown
Member

@bors ping

@dtolnay dtolnay closed this Nov 21, 2024
@dtolnay dtolnay reopened this Nov 21, 2024
@dtolnay

dtolnay commented Nov 21, 2024

Copy link
Copy Markdown
Member

@bors ping

@bors

bors commented Nov 21, 2024

Copy link
Copy Markdown
Collaborator

😪 I'm awake I'm awake

@dtolnay

dtolnay commented Nov 21, 2024

Copy link
Copy Markdown
Member

@bors r+

@bors

bors commented Nov 21, 2024

Copy link
Copy Markdown
Collaborator

📌 Commit 9cca296 has been approved by dtolnay

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 21, 2024
@bors

bors commented Nov 22, 2024

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 9cca296 with merge 6b5b526...

@compiler-errors

Copy link
Copy Markdown
Contributor

Yield to rollup

@bors retry

@bors

bors commented Nov 22, 2024

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 9cca296 with merge 2cf7908...

@bors

bors commented Nov 22, 2024

Copy link
Copy Markdown
Collaborator

☀️ Test successful - checks-actions
Approved by: dtolnay
Pushing 2cf7908 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 22, 2024
@bors
bors merged commit 2cf7908 into rust-lang:master Nov 22, 2024
@rustbot rustbot added this to the 1.84.0 milestone Nov 22, 2024
@umgefahren
umgefahren deleted the stabilize-ipv6-unique-local branch November 22, 2024 10:10
@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (2cf7908): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results (primary -1.3%, secondary 3.2%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.2% [3.1%, 3.2%] 2
Improvements ✅
(primary)
-1.3% [-1.3%, -1.3%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -1.3% [-1.3%, -1.3%] 1

Cycles

Results (primary -2.2%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.2% [-2.2%, -2.2%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -2.2% [-2.2%, -2.2%] 1

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 796.222s -> 796.948s (0.09%)
Artifact size: 336.06 MiB -> 335.99 MiB (-0.02%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.