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

std::net: Ipv4Addr and Ipv6Addr improvements #60145

Merged
merged 20 commits into from
Jun 1, 2019
Merged

Conversation

little-dude
Copy link
Contributor

@little-dude little-dude commented Apr 20, 2019

Picking this up again from my previous PR: #56050
Related to: #27709
Fixes: #57558

  • add add Ipv4Addr::is_reserved()
    • implementation
    • tests
  • add Ipv6Addr::is_unicast_link_local_strict() and update Ipv6Addr::is_unicast_link_local() documentation
    • implementation
    • test
  • add Ipv4Addr::is_benchmarking()
    • implementation
    • test
  • add Ipv4Addr::is_ietf_protocol_assignment()
    • implementation
    • test
  • add Ipv4Addr::is_shared()
    • implementation
    • test
  • fix Ipv4Addr:is_global()
    • implementation
    • test
  • refactor the tests for IP properties. This makes the tests more verbose, but using macros have two advantages:
    • it will now be easier to add tests for all the new methods
    • we get clear error messages when a test is failing. For instance:
---- net::ip::tests::ip_properties stdout ----
thread '<unnamed>' panicked at 'assertion failed: !ip!("fec0::").is_global()', src/libstd/net/ip.rs:2036:9

Whereas previously it was something like

thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
   left: `true`,
  right: `false`', libstd/net/ip.rs:1948:13

Ongoing discussions:

Should Ipv4Addr::is_global() return true or false for reserved addresses?

Reserved addresses are addresses that are matched by Ipv4Addr::is_reserved().
@the8472 pointed out that RFC 4291 says IPv6 reserved addresses should be considered global:

Future specifications may redefine one or more sub-ranges of the
Global Unicast space for other purposes, but unless and until that
happens, implementations must treat all addresses that do not start
with any of the above-listed prefixes as Global Unicast addresses.

We could extrapolate that this should also be the case for IPv4. However, it seems that IANA considers them non global (see my comment)

Final decision

There seems to be a consensus that reserved addresses have a different meaning for IPv4 and IPv6 (comment1 comment2, so we can consider that RFC4291 does not apply to IPv4, and that reserved IPv4 addresses are not global.

Should Ipv6Addr::is_unicast_site_local() exist?

@pusateri noted that site-local addresses have been deprecated for a while by RFC 3879 and new implementations must not support them. However, since this method is stable, removing does not seem possible. This kind of situation is covered by the RFC which stated that existing implementation may continue supporting site-local addresses.

Final decision

Let's keep this method. It is stable already, and the RFC explicitly states that existing implementation may remain.


Note: I'll be AFK from April 27th to May 11th. Anyone should feel free to pick this up if the PR hasn't been merged by then. Sorry for dragging that for so long already.

- quote the RFC
- add a link to the RFC
- fix markdown
RFC 4291 is a little unclear about what is a unicast link local address.
According to section 2.4, the entire fe80::/10 range is reserved for
these addresses, but section 2.5.3 defines a stricter format for such
addresses.

After a discussion[0] is has been decided to add a different method for
each definition, so this commit:

  - renames is_unicast_link_local() into is_unicast_link_local_strict()
  - relaxed the check in is_unicast_link_local()

[0]: rust-lang#27709 (comment)
@rust-highfive
Copy link
Collaborator

r? @bluss

(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 Apr 20, 2019
@little-dude
Copy link
Contributor Author

This was my first time writing a macro, so things may be very sub-optimal on that front.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:1c50ce88:start=1555795217421336216,finish=1555795307023823946,duration=89602487730
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
travis_time:start:test_assembly
Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:16:19] 
[01:16:19] running 9 tests
[01:16:19] iiiiiiiii
[01:16:19] 
[01:16:19]  finished in 0.156
[01:16:19] travis_fold:end:test_assembly

---
travis_time:start:test_debuginfo
Check compiletest suite=debuginfo mode=debuginfo-both (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:16:35] 
[01:16:35] running 121 tests
[01:17:01] .iiiii...i.....i..i...i..i.i.i..i.ii...i.....i..i....i..........iiii..........i...ii...i.......ii.i. 100/121
[01:17:06] i.i......iii.i.....ii
[01:17:06] 
[01:17:06]  finished in 30.771
[01:17:06] travis_fold:end:test_debuginfo

---
[01:36:22] .................................................................................................... 200/785
[01:36:22] thread '<unnamed>' panicked at 'explicit panic', src/libstd/io/buffered.rs:1367:17
[01:36:22] .................................................................................................... 300/785
[01:36:22] thread '<unnamed>' panicked at 'explicit panic', src/libstd/io/stdio.rs:854:13
[01:36:22] ....................................................F........F...................................... 400/785
[01:36:23] thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', src/libcore/result.rs:999:5
[01:36:23] thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', src/libcore/result.rs:999:5
[01:36:23] thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: "SendError(..)"', src/libcore/result.rs:999:5
[01:36:23] thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', src/libcore/result.rs:999:5
---
[01:36:25] thread '<unnamed>' panicked at 'Box<Any>', src/libstd/thread/mod.rs:1684:13
[01:36:34] .....................................................................................
[01:36:34] failures:
[01:36:34] 
[01:36:34] ---- net::ip::tests::ip_properties stdout ----
[01:36:34] thread '<unnamed>' panicked at 'assertion failed: !ip!("fec0::").is_global()', src/libstd/net/ip.rs:2035:9
[01:36:34] ---- net::ip::tests::ipv6_properties stdout ----
[01:36:34] ---- net::ip::tests::ipv6_properties stdout ----
[01:36:34] thread '<unnamed>' panicked at 'assertion failed: !ip!("fec0::").is_global()', src/libstd/net/ip.rs:2311:9
[01:36:34] 
[01:36:34] failures:
[01:36:34]     net::ip::tests::ip_properties
[01:36:34]     net::ip::tests::ipv6_properties
[01:36:34]     net::ip::tests::ipv6_properties
[01:36:34] 
[01:36:34] test result: FAILED. 783 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
[01:36:34] 
[01:36:34] error: test failed, to rerun pass '--lib'
[01:36:34] 
[01:36:34] 
[01:36:34] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "-p" "std" "--" "--quiet"
[01:36:34] 
[01:36:34] 
[01:36:34] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:36:34] Build completed unsuccessfully in 0:32:10
[01:36:34] Build completed unsuccessfully in 0:32:10
[01:36:34] make: *** [check] Error 1
[01:36:34] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:02e0b800
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Sat Apr 20 22:58:30 UTC 2019
---
travis_time:end:057d0d48:start=1555801112270158960,finish=1555801112276065832,duration=5906872
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0c4ae804
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@little-dude little-dude force-pushed the ip2 branch 2 times, most recently from 8cff09b to 793c653 Compare April 21, 2019 17:49
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:062f709c:start=1555869029121791978,finish=1555869113280110912,duration=84158318934
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
travis_time:start:test_assembly
Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:09:33] 
[01:09:33] running 9 tests
[01:09:33] iiiiiiiii
[01:09:33] 
[01:09:33]  finished in 0.142
[01:09:33] travis_fold:end:test_assembly

---
travis_time:start:test_debuginfo
Check compiletest suite=debuginfo mode=debuginfo-both (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:09:48] 
[01:09:48] running 121 tests
[01:10:12] .iiiii...i.....i..i...i..i.i.i..i.ii...i.....i..i....i..........iiii..........i...ii...i.......ii.i. 100/121
[01:10:16] i.i......iii.i.....ii
[01:10:16] 
[01:10:16]  finished in 28.010
[01:10:16] travis_fold:end:test_debuginfo

---
[01:35:58] travis_fold:end:stage0-linkchecker

[01:35:58] travis_time:end:stage0-linkchecker:start=1555874877649971373,finish=1555874879491024694,duration=1841053321

[01:35:59] std/net/struct.Ipv4Addr.html:111: broken link fragment `#method.is_reserved()` pointing to `std/net/struct.Ipv4Addr.html`
[01:36:06] thread 'main' panicked at 'found some broken links', src/tools/linkchecker/main.rs:41:9
[01:36:06] 
[01:36:06] 
[01:36:06] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/linkchecker" "/checkout/obj/build/x86_64-unknown-linux-gnu/doc"
[01:36:06] expected success, got: exit code: 101
[01:36:06] expected success, got: exit code: 101
[01:36:06] 
[01:36:06] 
[01:36:06] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:36:06] Build completed unsuccessfully in 0:37:27
[01:36:06] make: *** [check] Error 1
[01:36:06] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0e9293fa
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Sun Apr 21 19:28:07 UTC 2019

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@the8472
Copy link
Member

the8472 commented Apr 22, 2019

I don't think is_reserved including ranges marked for future use is a good idea since those future uses may be realized at at some point and then old software with is_reserved filters may have false positives. This is not a hypothetical concern, such issues have been encountered before when IANA assigned previously reserved /8 address blocks.

In that sense is_global should really mean "might be global today or in the future".

As per @therealbstern's comment[0]:

The implementation of Ipv4::is_global is not complete, according to the
IANA IPv4 Special-Purpose Address Registry.

        - It compares the address to 0.0.0.0, but anything in 0.0.0.0/8
          should not be considered global.
                - 0/8 is not global and is currently forbidden because
                  some systems used to treat it as the local network.
                - The implementation of Ipv4::is_unspecified is correct.
                  0.0.0.0 is the unspecified address.
        - It does not examine 100.64.0.0/10, which is "Shared Address
          Space" and not global.
        - Ditto 192.0.0.0/24 (IETF Protocol Assignments), except for
          192.0.0.9/32 and 192.0.0.10/32, which are carved out as
          globally reachable.
        - 198.18.0.0/15 is for "Benchmarking" and should not be globally
          reachable.
        - 240.0.0.0/4 is reserved and not currently reachable
Ipv4addr::is_global() previously considered 0/8 was global, but has
now been fixed, so these tests needed to be fixed as well.
Ipv6Addr::is_unicast_global() now returns `true` for unicast site
local addresses, since they are deprecated.
/// }
/// ```
pub fn is_shared(&self) -> bool {
self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
Copy link
Member

Choose a reason for hiding this comment

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

maybe for readability an is_in_netmask function would help?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm sorry I don't understand what you are suggesting here.

Copy link
Member

Choose a reason for hiding this comment

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

A private function is_in_cidr(&self, baseAddress: Ipv4Addr , bits: u8), so you can write self.is_in_cidr(Ipv4Addr:new(100, 64, 0, 0), 10). I think that would improve readability and crosschecking with iana allocations because they usually give those blocks in CIDR notation.

@little-dude
Copy link
Contributor Author

little-dude commented Apr 22, 2019

Thanks for reviewing @the8472.

I don't think is_reserved including ranges marked for future use is a good idea since those future uses may be realized at at some point and then old software with is_reserved filters may have false positives. This is not a hypothetical concern, such issues have been encountered before when IANA assigned previously reserved /8 address blocks.

That could be a problem indeed, but if we don't provide this method people who need it will just implement their own and will have the same issue. What about adding a warning to the documentation of this method?

In that sense is_global should really mean "might be global today or in the future".

I haven't yet looked at what's done in other implementations, but I tend to disagree because:

  • we could have the problem the other way around: we have is_global() return true for reserved addresses, IANA assigns them and makes them non-global, and old software that uses is_global() becomes buggy.
  • strictly speaking, this implementation is currently more correct

Edit: @therealbstern @kpp @pusateri @jens1o @ollie27 since you've commented on #27709 you might have an opinion about the two questions @the8472 raised.

also add test to Ipaddr, making sure that these addresses are not
global.
Also add tests to IpAddr to make sure these addresses are not global.
@Dylan-DPC-zz
Copy link

can someone from @rust-lang/libs review this?

@Centril
Copy link
Contributor

Centril commented May 29, 2019

r? @alexcrichton

@rust-highfive rust-highfive assigned alexcrichton and unassigned TimNN May 29, 2019
@alexcrichton
Copy link
Member

@bors: r+

Thanks so much for all the extensive updates here @little-dude, and sorry for the delay!

@bors
Copy link
Contributor

bors commented May 31, 2019

📌 Commit cddb838 has been approved by alexcrichton

@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 May 31, 2019
@little-dude
Copy link
Contributor Author

Thank you @alexcrichton !

@bors
Copy link
Contributor

bors commented Jun 1, 2019

⌛ Testing commit cddb838 with merge 8b40a18...

bors added a commit that referenced this pull request Jun 1, 2019
std::net: Ipv4Addr and Ipv6Addr improvements

Picking this up again from my previous PR: #56050
Related to: #27709
Fixes: #57558

- add `add Ipv4Addr::is_reserved()`
  - [X] implementation
  - [X] tests
- add `Ipv6Addr::is_unicast_link_local_strict()` and update `Ipv6Addr::is_unicast_link_local()` documentation
  - [X] implementation
  - [X] test
- add `Ipv4Addr::is_benchmarking()`
  - [X] implementation
  - [X] test
- add `Ipv4Addr::is_ietf_protocol_assignment()`
  - [X] implementation
  - [X] test
- add `Ipv4Addr::is_shared()`
  - [X] implementation
  - [x] test
- fix `Ipv4Addr:is_global()`
  - [X] implementation
  - [x] test
- [X] refactor the tests for IP properties. This makes the tests more verbose, but using macros have two advantages:
    - it will now be easier to add tests for all the new methods
    - we get clear error messages when a test is failing. For instance:

```
---- net::ip::tests::ip_properties stdout ----
thread '<unnamed>' panicked at 'assertion failed: !ip!("fec0::").is_global()', src/libstd/net/ip.rs:2036:9

```

Whereas previously it was something like

```
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
   left: `true`,
  right: `false`', libstd/net/ip.rs:1948:13
```

-----------------------

# Ongoing discussions:

## Should `Ipv4Addr::is_global()` return `true` or `false` for reserved addresses?

Reserved addresses are addresses that are matched by `Ipv4Addr::is_reserved()`.
@the8472 [pointed out](#60145 (comment)) that [RFC 4291](https://tools.ietf.org/html/rfc4291#section-2.4) says IPv6 reserved addresses should be considered global:

```
Future specifications may redefine one or more sub-ranges of the
Global Unicast space for other purposes, but unless and until that
happens, implementations must treat all addresses that do not start
with any of the above-listed prefixes as Global Unicast addresses.
```

We could extrapolate that this should also be the case for IPv4. However, it seems that [IANA considers them non global](https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml) (see [my comment](#60145 (comment)))

### Final decision

There seems to be a consensus that reserved addresses have a different meaning for IPv4 and IPv6 ([comment1](#60145 (comment)) [comment2](#60145 (comment)), so we can consider that RFC4291 does not apply to IPv4, and that reserved IPv4 addresses are _not_ global.

## Should `Ipv6Addr::is_unicast_site_local()` exist?

@pusateri [noted](#60145 (comment)) that site-local addresses have been deprecated for a while by [RFC 3879](https://tools.ietf.org/html/rfc3879) and new implementations _must not_ support them. However, since this method is stable, removing does not seem possible. This kind of situation is covered by the RFC which stated that existing implementation _may_ continue supporting site-local addresses.

### Final decision

Let's keep this method. It is stable already, and the RFC explicitly states that existing implementation may remain.

---------

Note: I'll be AFK from April 27th to May 11th. Anyone should feel free to pick this up if the PR hasn't been merged by then. Sorry for dragging that for so long already.
@bors
Copy link
Contributor

bors commented Jun 1, 2019

☀️ Test successful - checks-travis, status-appveyor
Approved by: alexcrichton
Pushing 8b40a18 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 1, 2019
@bors bors merged commit cddb838 into rust-lang:master Jun 1, 2019
@kumbayo
Copy link

kumbayo commented Jun 2, 2019

This introduces a few new pub fn is_shared, is_ietf_protocol_assignment, is_benchmarking, is_reserved, is_unicast_link_local_strict
but they seem to be missing stability/since attributes #[stable(feature = "xxx", since = "1.xx.0")]
Is this expected?

On a second look, already existing ones like pub fn is_global(&self) -> bool { are also missing stability attributes.

@SimonSapin
Copy link
Contributor

It looks like items in an unstable module default to inhering the unstable attribute of the module: https://doc.rust-lang.org/1.35.0/std/net/enum.IpAddr.html#method.is_global

@SimonSapin
Copy link
Contributor

… but since the std::net::ip module is private, it would be good to remove its stability attribute and instead add missing ones on each public item. @kumbayo, do you want to make a PR for that? You should see ./x test src/tools/tidy report an error after removing the module-level attribute and before adding the rest.

@little-dude little-dude deleted the ip2 branch June 3, 2019 13:30
@little-dude
Copy link
Contributor Author

@SimonSapin I'll make a PR Thursday or Friday if @kumbayo hasn't by then.

JohnTitor added a commit to JohnTitor/rust that referenced this pull request May 26, 2021
Move stability attribute for items under the `ip` feature

The `#[unstable]` attribute for items under the `ip` feature is currently located on the `std::net::ip` module itself. This is unusual, and less readable. This has sidetracked discussion about these items numerous times (rust-lang#60145 (comment), rust-lang#76098 (comment), rust-lang#76098 (comment), rust-lang#75019 (comment), rust-lang#75019 (comment)) and lead to incorrect assumptions about which items are actually stable (rust-lang#60145 (comment), rust-lang#76098 (comment)).

This PR moves the attribute from the module to the items themselves.
JohnTitor added a commit to JohnTitor/rust that referenced this pull request May 26, 2021
Move stability attribute for items under the `ip` feature

The `#[unstable]` attribute for items under the `ip` feature is currently located on the `std::net::ip` module itself. This is unusual, and less readable. This has sidetracked discussion about these items numerous times (rust-lang#60145 (comment), rust-lang#76098 (comment), rust-lang#76098 (comment), rust-lang#75019 (comment), rust-lang#75019 (comment)) and lead to incorrect assumptions about which items are actually stable (rust-lang#60145 (comment), rust-lang#76098 (comment)).

This PR moves the attribute from the module to the items themselves.
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Jun 16, 2021
…htriplett

Remove `Ipv6Addr::is_unicast_site_local`

Removes the unstable method `Ipv6Addr::is_unicast_site_local`, see also rust-lang#85604 where I have tried to summarize related discussion so far.

Unicast site-local addresses (`fec0::/10`) were deprecated in [IETF RFC rust-lang#3879](https://datatracker.ietf.org/doc/html/rfc3879), see also [RFC rust-lang#4291 Section 2.5.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.7). Any new implementation must no longer support the special behaviour of site-local addresses. This is mentioned in the docs of `is_unicast_site_local` and already implemented in `is_unicast_global`, which considers addresses in `fec0::/10` to have global scope, thus overlapping with `is_unicast_site_local`.

Given that RFC rust-lang#3879 was published in 2004, long before Rust existed, and it is specified that any new implementation must no longer support the special behaviour of site-local addresses, I don't see how a user would ever have a need for `is_unicast_site_local`. It is also confusing that currently both `is_unicast_site_local` and `is_unicast_global` can be `true` for an address, but an address can actually only have a single scope. The deprecating RFC mentions that Site-Local scope was confusing to work with and that the classification of an address as either Link-Local or Global better matches the mental model of users.

There has been earlier discussion of removing `is_unicast_site_local` (rust-lang#60145 (comment)) which decided against it, but that had the incorrect assumption that the method was already stable; it is not. (This confusion arose from the placement of the unstable attribute on the entire module, instead of on individual methods, resolved in rust-lang#85672)

r? `@joshtriplett` as reviewer of all the related PRs
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 16, 2021
…riplett

Remove `Ipv6Addr::is_unicast_site_local`

Removes the unstable method `Ipv6Addr::is_unicast_site_local`, see also rust-lang#85604 where I have tried to summarize related discussion so far.

Unicast site-local addresses (`fec0::/10`) were deprecated in [IETF RFC rust-lang#3879](https://datatracker.ietf.org/doc/html/rfc3879), see also [RFC rust-lang#4291 Section 2.5.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.7). Any new implementation must no longer support the special behaviour of site-local addresses. This is mentioned in the docs of `is_unicast_site_local` and already implemented in `is_unicast_global`, which considers addresses in `fec0::/10` to have global scope, thus overlapping with `is_unicast_site_local`.

Given that RFC rust-lang#3879 was published in 2004, long before Rust existed, and it is specified that any new implementation must no longer support the special behaviour of site-local addresses, I don't see how a user would ever have a need for `is_unicast_site_local`. It is also confusing that currently both `is_unicast_site_local` and `is_unicast_global` can be `true` for an address, but an address can actually only have a single scope. The deprecating RFC mentions that Site-Local scope was confusing to work with and that the classification of an address as either Link-Local or Global better matches the mental model of users.

There has been earlier discussion of removing `is_unicast_site_local` (rust-lang#60145 (comment)) which decided against it, but that had the incorrect assumption that the method was already stable; it is not. (This confusion arose from the placement of the unstable attribute on the entire module, instead of on individual methods, resolved in rust-lang#85672)

r? `@joshtriplett` as reviewer of all the related PRs
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Aug 2, 2021
…ou-se

Remove `Ipv4Addr::is_ietf_protocol_assignment`

This PR removes the unstable method `Ipv4Addr::is_ietf_protocol_assignment`, as I suggested in rust-lang#85612 (comment). The method was added in rust-lang#60145, as far as I can tell primarily for the implementation of `Ipv4Addr::is_global` (addresses reserved for IETF protocol assignment are not globally reachable unless otherwise specified).

The method was added in 2019, but I haven't been able to find any open-source code using this method so far. I'm also having a hard time coming up with a usecase for specifically this method; knowing that an address is reserved for future protocols doesn't allow you to do much with it, especially since now some of those addresses are indeed assigned to a protocol and have their own behaviour (and might even be defined to be globally reachable, so if that is what you care about it is always more accurate to call `!is_global()`, instead of `is_ietf_protocol_assignment()`).

Because of these reasons, I propose removing the method (or alternatively make it a private helper for `is_global`) and also not introduce `Ipv6Addr::is_ietf_protocol_assignment` and `IpAddr::is_ietf_protocol_assignment` in the future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ipv4Addr::is_global() returns true for non global address