Tracking issue for Ipv{4,6}Addr convenience methods
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!
- [ ]
Ip::is_global - [ ]
Ipv4::is_global - [ ]
Ipv6::is_global
- [ ]
Ipv4::is_shared - [ ]
Ipv4::is_ietf_protocol_assignment - [ ]
Ipv4::is_benchmarking - [ ]
Ipv4::is_reserved
- [ ]
Ipv6::is_unicast_global - [ ]
Ipv6::is_unicast_link_local - [ ]
Ipv6::is_unicast_link_local_strict - [ ]
Ipv6::is_unicast_site_local - [ ]
Ipv6::is_unique_local - [ ]
Ipv6::multicast_scope
The below is a list of methods left to be stabilized under the
ipfeature. 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_global - [ ]
Ipv4Addr::is_global - [ ]
Ipv6Addr::is_global
- [ ]
Ipv4Addr::is_shared - ~~
Ipv4Addr::is_ietf_protocol_assignment~~ https://github.com/rust-lang/rust/pull/86439 - [ ]
Ipv4Addr::is_benchmarking - [ ]
Ipv4Addr::is_reserved
- [ ]
Ipv6Addr::is_unicast_global - [ ]
Ipv6Addr::is_unicast_link_local - ~~
Ipv6Addr::is_unicast_link_local_strict~~ https://github.com/rust-lang/rust/pull/85819 - ~~
Ipv6Addr::is_unicast_site_local~~ https://github.com/rust-lang/rust/pull/85820 - [ ]
Ipv6Addr::is_unique_local - [ ]
Ipv6Addr::multicast_scope
- [ ]
Ipv6Addr::is_ipv4_mapped - [x]
Ipv6Addr::to_ipv4_mappedhttps://github.com/rust-lang/rust/pull/96906 - [x]
Ipv6Addr::to_canonicalhttps://github.com/rust-lang/rust/pull/115955 - [x]
IpAddr::to_canonicalhttps://github.com/rust-lang/rust/pull/115955
Steps
- [ ] Implementation https://github.com/rust-lang/rust/pull/22015
- [ ] Implementation https://github.com/rust-lang/rust/pull/34694
- [ ] Stabilization attempt https://github.com/rust-lang/rust/pull/66584
- [ ] Stabilization attempt https://github.com/rust-lang/rust/pull/76098
- [ ] Stabilization PR(s)
Subsets of the listed methods can be stabilized, rather than attempting to stabilize everything at once.
Unresolved Questions
- [ ]
is_documentationis not up to date #137821 - [ ] Differences between Rust and other languages https://github.com/rust-lang/rust/pull/76098#issuecomment-761234042
- [ ] More specific case of the above: does the IPv6 unicast interface do what we expect? https://github.com/rust-lang/rust/issues/85604
- [ ] Do the provided methods pass ipcheck? https://github.com/rust-lang/libs-team/tree/93b78eef2e0d455a3e69c05333cd8f276e4e95f1/tools/ipcheck. Last known run: https://github.com/rust-lang/rust/pull/76098#issuecomment-760651861
From @KodrAus in https://github.com/rust-lang/rust/pull/76098#issuecomment-760841554:
- [ ] Should we replace the
Ipv6Addr::is_unicast_*methods with aIpv6Addr::unicast_scopemethod that returns aIpv6UnicastScopeenum (https://github.com/rust-lang/rust/pull/76098#issuecomment-735019872)? - [ ] Should we change the behavior of
Ipv6Addr::to_ipv4to ignore deprecated IPv4-compatible addresses, or deprecate the whole method in favor of the more correctIpv6Addr::to_ipv4_mappedmethod (https://github.com/rust-lang/rust/pull/76098#discussion_r530465408)? - [ ] Are we ok with
Ipv6Addr::is_*methods now properly considering mapped (non-deprecated) IPv4 addresses? I'd personally be comfortable considering the old behavior a bug. - [ ] Are there any behavioral differences between other language implementations that we should investigate? (https://github.com/rust-lang/rust/pull/76098#issuecomment-760651861)
Lukas Kalbertodt at 2020-08-12 19:03:16
- [ ]
I think we should consider this for stabilization in 1.6. Nominating.
Aaron Turon at 2015-11-03 23:47:11
:bell: This issue is now entering its cycle-long final comment period for stabilization :bell:
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
enum-returning variants will likely remain unstable for now.Alex Crichton at 2015-11-05 17:44:49
What, exactly, is the "ip feature"? Could you link to the RustDoc(s) of the specific things that are supposed to be reviewed?
Brian Smith at 2015-11-05 19:20:54
I think "ip feature" in this context refers to things annotated with
#![unstable(feature = "ip", β¦)], which require#![feature(ip)]to be used.Simon Sapin at 2015-11-05 20:37:29
I think "ip feature" in this context refers to things annotated with #![unstable(feature = "ip", β¦)], which require #![feature(ip)] to be used.
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
#![no_std]mode. I suggest moving the#![no_std]-compatible parts tocore::net, or at least consider how making it work with#![no_std]would affect the API.It also seems odd that
Ipv4AddrandIpv6Addrhave things likeis_multicastandis_globalbut there's no trait that allows code to make these queries generically over those types of addresses. If such a trait were to bad added later, would the existence of these non-trait methods cause problems? If so, it might be worth considering building the trait first.Brian Smith at 2015-11-06 00:02:54
@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:
that the boolean accessors are likely ready for stabilization after verifying that they're all the canonical definitions,
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
-> boolbut the enum-returning variants will likely remain unstable for now.
http://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.multicast_scope is the only one I see that's unstable.
Steve Klabnik at 2015-11-06 00:23:00
FWIW, I filed https://github.com/rust-lang/rust/issues/29221 a while ago, which would make tracking down what these tracking issues refer to slightly easier.
Huon Wilson at 2015-11-06 00:32:40
Yes, to be concrete, I was proposing stabilizing:
Ipv4Addr::is_unspecifiedIpv4Addr::is_loopbackIpv4Addr::is_privateIpv4Addr::is_link_localIpv4Addr::is_globalIpv4Addr::is_multicastIpv4Addr::is_broadcastIpv4Addr::is_documentationIpv6Addr::is_unspecifiedIpv6Addr::is_loopbackIpv6Addr::is_globalIpv6Addr::is_unique_localIpv6Addr::is_unicast_link_localIpv6Addr::is_unicast_site_localIpv6Addr::is_unicast_globalIpv6Addr::is_multicast
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.
@briansmith
I suggest moving the #![no_std]-compatible parts to core::net
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
libcequivalent (e.g.libc::sockaddr_in6orlibc::in_addr) which unfortunately isn't available in libcore, so if we move it to core we'd have to invent our own storage format.It also seems odd that Ipv4Addr and Ipv6Addr have things like is_multicast and is_global but there's no trait that allows code to make these queries generically over those types of addresses. If such a trait were to bad added later, would the existence of these non-trait methods cause problems?
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
IpAddrif we end up stabilizing that as well.Alex Crichton at 2015-11-06 16:32:31
A couple of issues I have noticed with what we have:
0.0.0.0/8,::and many more ranges shouldn't return true foris_global()Ipv6Addr::is_documentationis missing and should be2001:db8::/32
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?
Oliver Middleton at 2015-11-09 11:00:56
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!
Alex Crichton at 2015-12-03 02:41:24
:bell: This issue is now yet again entering its final comment period :bell:
Hopefully I get a chance to researching this API this time around!
Alex Crichton at 2015-12-17 22:25:29
Better late than never! -- my analysis:
Of the ipv4 properties, there's more listed on wikipedia at least, for example:
- Current network
- Shared
- protocol assignments (and DS-Lite)
- ipv6 to ipv4 relay
- benchmark tests
- reserved
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:
- [x]
Ipv4Addr::is_unspecified- appears to be an ipv6 property, not ipv4? - [x]
Ipv4Addr::is_loopback- ref - [x]
Ipv4Addr::is_private- ref1, ref2, ref3 - [x]
Ipv4Addr::is_link_local- ref - [x]
Ipv4Addr::is_global- not found, this is a property, but haven't found exhaustive documentation - [x]
Ipv4Addr::is_multicast- ref - [x]
Ipv4Addr::is_broadcast- ref - [x]
Ipv4Addr::is_documentation- ref1, ref2, ref3
Like with ipv4 we're missing some ipv6 properties (according to RFC 6890):
- ipv4-ipv6 transit
- ipv4-mapped (although we have a method to access this, so probably ok)
- discard only
- protocol assignments
- TEREDO (wut?)
- benchmarking
- documentation
- ORCHID
- 6to4
Of the ipv6 methods:
- [x]
Ipv6Addr::is_unspecified- ref - [x]
Ipv6Addr::is_loopback- ref - [x]
Ipv6Addr::is_global- couldn't find a reference online quickly, seems to have some interesting logic though? - [x]
Ipv6Addr::is_unique_local- ref - [x]
Ipv6Addr::is_unicast_link_local- ref, called "Linked-Scope Unicast" in the RFC at least, not sure about the name in that case. - [x]
Ipv6Addr::is_unicast_site_local- didn't find a reference in this RFC at least - [x]
Ipv6Addr::is_unicast_global- same as above, didn't find a reference (doesn't mean it's wrong though!) - [x]
Ipv6Addr::is_multicast- ref
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.
Alex Crichton at 2016-01-12 23:45:24
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
is_loopbackwould be already useful for me. Having to use only one standard type to represent an ip, no matter whether v4 or v6, would be very useful already.VinΓcius dos Santos Oliveira at 2016-01-13 09:52:47
The libs team discussed this during triage yesterday and the decision was to stabilize the methods I've checked above
Alex Crichton at 2016-01-15 17:46:30
Removing from FCP as the initial round of stabilization has happened.
Alex Crichton at 2016-01-21 18:39:25
I know I'm late to the party on this, but I just got bitten by this issue when trying to implement a generic
IpAddris_unspecifiedmethod for my own use.The IPv4 unspecified address (which is not checked above at the time of this writing) definitely exists and is standard. It is defined on p891 of Stevens, Volume 1, Second Edition, which notes that it is all zeroes and is also referred to as INADDR_ANY. (There are numerous other references to it, but this is the most compact.) If you want an online reference, http://man7.org/linux/man-pages/man7/ip.7.html also confirms this.
Ben Stern at 2016-07-08 00:19:44
@therealbstern oh interesting! I think we're fine stabilizing if it's actually a property documented somewhere, I just couldn't find it at the time. Want to send a PR updating the docs accordingly? We may be able to consider it for stabilization next cycle.
Alex Crichton at 2016-07-08 05:53:53
I think PR #34739 does what you want, though I wasn't 100% sure what to put into the stable block. I defer future commentary to that PR.
Ben Stern at 2016-07-10 01:34:05
:bell: This issue is now entering a cycle-long final comment period π
Specifically, the libs team is considering stabilizing
Ipv4Addr::is_unspecifiedas proposed in https://github.com/rust-lang/rust/issues/34739. The other methods on these types will remain unstable.Alex Crichton at 2016-07-12 23:49:58
IPv6 site local is also in Stevens, p895. I'll look for an online reference. I take it that IPv4Addr.is_global will stay unstable, despite the (admittedly inelegant) discussion at the iana-ipv4-special-registry? [That link is already documented.]
Ben Stern at 2016-07-13 01:44:53
I apologize; IPv6 site local is deprecated by RFC 3879, so I don't think stabilizing it is as good an idea.
Ben Stern at 2016-07-13 01:46:41
@therealbstern probably, yeah. Most of the instability here is just because of a lack of motivation to push them towards stable, but if they're well accepted concepts elsewhere that can be documented, we'd be fine stabilizing!
Alex Crichton at 2016-07-13 17:58:41
The libs team has also decided to throw the methods introduced in https://github.com/rust-lang/rust/pull/34694 into FCP, which is just all of these methods that are shared between v4 and v6 addrs also being exported from
IpAddrAlex Crichton at 2016-07-19 04:22:50
Discussed recently, the libs team decided to stabilize the shared methods and the
is_unspecifiedmethod onIpv4AddrAlex Crichton at 2016-08-11 21:14:51
@rfcbot fcp close
I feel like the remaining methods have languished long enough in the standard library. Anything that's not stable I'd think we should just deprecate/remove at this point.
Alex Crichton at 2016-11-01 23:10:01
Team member @alexcrichton has proposed to close this. The next step is review by the rest of the tagged teams:
- [ ] @BurntSushi
- [ ] @Kimundi
- [x] @alexcrichton
- [ ] @aturon
- [ ] @brson
- [ ] @sfackler
No concerns currently listed.
Once these reviewers reach consensus, 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.
Rust RFC bot at 2016-11-01 23:48:52
Looks like
- Ipv4Addr::is_global
- Ipv6Addr::is_global
- Ipv6Addr::is_unique_local
- Ipv6Addr::is_unicast_link_local
- Ipv6Addr::is_unicast_site_local
- Ipv6Addr::is_documentation
- Ipv6Addr::is_unicast_global
- Ipv6Addr::multicast_scope
- Ipv6MulticastScope.
Why is
Ipv4Addr::is_documentationstable but notIpv6::is_documentation?Brian Anderson at 2016-11-03 23:52:02
Seems like perhaps is_documentation should be stabilized, everything else deprecated.
Brian Anderson at 2016-11-03 23:53:36
@brson I was able to find documentation for
Ipv4Addr::is_documentationbut couldn't find documentation on theIpv6Addr. That being said, briefly taking a look at the ipv4 docs points me to https://tools.ietf.org/html/rfc3849 which has documentation for ipv6. In that sense I'd be fine considering stabilization of that and deprecation of everything else.Alex Crichton at 2016-11-04 02:03:04
Some more docs:
Ipv4Addr::is_globalhttps://tools.ietf.org/html/rfc5735#page-3Ipv6Addr::is_globalhttps://tools.ietf.org/html/rfc4291#section-2.5.4Ipv6Addr::is_unicast_link_localhttps://tools.ietf.org/html/rfc4291#section-2.5.6Ipv6Addr::is_unicast_site_localhttps://tools.ietf.org/html/rfc4291#section-2.5.7Ipv6Addr::is_unicast_globalhttps://tools.ietf.org/html/rfc4291#section-2.5.4Ipv6Addr::multicast_scopeandIpv6MulticastScopehttps://tools.ietf.org/html/rfc4291#section-2.7Abhishek Chanda at 2016-11-04 09:29:35
@rfcbot fcp cancel
ok, seems like we shouldn't deprecate!
Alex Crichton at 2016-11-04 20:08:19
Can we fcp to stabilize then (assuming that the implementations correspond to what they should be)?
Steven Fackler at 2016-11-04 20:11:57
@alexcrichton proposal cancelled.
Rust RFC bot at 2016-11-04 20:12:29
@sfackler presumably, yeah, but I don't really have the time right now to audit everything much less deal with
Ipv6MulticastScope, so I'll leave that to someone else to propose FCP :)Alex Crichton at 2016-11-04 21:43:51
@alexcrichton let me know if I can help with anything here
Abhishek Chanda at 2016-11-04 22:44:49
@achanda sure yeah the next step for stabilizing this would be to audit all implementations to ensure they match precisely what the RFCs mention, and then ensure all document references the relevant RFC as well. We may want to leave
multicast_scopeout for now as it has an enum, but it'd be good to read up on that and ensure it matches the RFC.Alex Crichton at 2016-11-07 05:19:08
ping @achanda, any updates? I just came across a use for
is_globaland possiblyis_link_local, would be nice to get them in stable.Kamal Al Marhubi at 2017-01-30 05:40:53
@kamalmarhubi sorry, I forgot about this one. Let me get back to this as soon as I can (should be a few days).
Abhishek Chanda at 2017-01-30 09:54:04
@achanda no worries!
Kamal Al Marhubi at 2017-02-08 04:22:51
Any update on this?
James Brown at 2017-12-07 05:09:32
I'd also love to have
is_globalstabilized.Craig Hills at 2017-12-07 20:30:04
I have updated the original issue description to include a list of the methods currently unstable under the
ipfeature. If anyone is interested in pushing any given method to stability, I believe a PR with associated documentation (as in the description above) would be welcomed.Mark Rousskov at 2018-01-15 23:22:34
The implementation of
Ipv4::is_globalis 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_unspecifiedis 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
There are also no methods that identify the netblocks identified above.
Ben Stern at 2018-01-16 03:48:50
- It compares the address to 0.0.0.0, but anything in 0.0.0.0/8 should not be considered global.
I may be wrong but
Ipv6::is_unicast_link_local()seems wrong to me. The current implementation is:pub fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 }But the RFC says:
Link-Local addresses are for use on a single link. Link-Local addresses have the following format: | 10 | | bits | 54 bits | 64 bits | +----------+-------------------------+----------------------------+ |1111111010| 0 | interface ID | +----------+-------------------------+----------------------------+ Link-Local addresses are designed to be used for addressing on a single link for purposes such as automatic address configuration, neighbor discovery, or when no routers are present. Routers must not forward any packets with Link-Local source or destination addresses to other links.So I think this should be:
pub fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffff) == 0xfe80 && (self.segments()[1] & 0xffff) == 0 && (self.segments()[2] & 0xffff) == 0 && (self.segments()[3] & 0xffff) == 0 }If you agree I'll open a PR.
little-dude at 2018-06-25 23:13:47
Also, I think it would be worth having
Ipv6::is_ipv4_compatibleandIpv6::is_ipv4_mapped(). I can also open a PR for that.little-dude at 2018-06-25 23:17:01
@Mark-Simulacrum
I have updated the original issue description to include a list of the methods currently unstable under the ip feature. If anyone is interested in pushing any given method to stability, I believe a PR with associated documentation (as in the description above) would be welcomed.
I'd like to work on that. I'll try to send a first PR tonight.
little-dude at 2018-06-25 23:23:13
@little-dude, The errata for RFC 4291, and more specifically erratum 4406 make this much less clear than one might think. /10 is reserved for link-local and similar uses, though only /64 is defined right now, and they don't name what the rest of it for. RFC 7371 also takes the opportunity to mention that the link-local /10 exists and then appears to discuss multicast without regard to whether or not it's a new chunk of the /10 or not.
Anyway, the point is, although I agreed with your suggestion so much that I initially thought I had written it, I'm no longer so sure how to stand on this.
Ben Stern at 2018-06-26 05:48:25
I see, it's debatable indeed. To sum up:
fe80::/10is reservedfe80::/64is the currenttly defined link local unicast
I have slight preference for validating the second range since that as of today, the only valid unicast link local addresses are in
fe80::/64.Otherwise, why not having two methods with a detailed documentation of how they differ:
is_link_local()forfe80/10andis_link_local_strict()forfe80/64?little-dude at 2018-06-26 14:15:24
@therealbstern I've started working on fixing
Ipv4Addr::is_globalas per your comment.little-dude at 2018-06-26 14:17:44
Obviously, I'm not in charge of the API here, but I personally think your validation plan is the way to fly. Also, the looser method would help more with the "is this globally routable" question.
Did you understand what RFC 7371 was saying? I thought it meant that some of the /10 link-local space was going to become multicast, but I might have completely misunderstood. :-P
Ben Stern at 2018-06-26 16:11:46
Why is this still unstable?
Jens Hausdorf at 2018-10-07 07:31:53
This PR has not been finished. You can pick it up if you want, or I can try finishing it but I won't be able to this week.
little-dude at 2018-10-07 14:24:50
No, take your time. :) I'm terribly sorry for pressing hard, I just wondered, by no means did I want to attack you and your work. I do not know a lot about the RFC process here and marking things as stable. My laptop is too weak to test out the changes.
Jens Hausdorf at 2018-10-07 14:46:23
Hey, how do I stabilize these methods? What is the procedure?
Roman at 2018-11-16 10:28:38
@kpp you can start from my pr if you want https://github.com/rust-lang/rust/pull/51832
little-dude at 2018-11-16 14:39:04
Or I'll try to finish it off this weekend if you don't. I'm a bit disappointed that I did not push it to the finish line.
little-dude at 2018-11-16 14:41:13
I won't =) Push it to the finish line!
Roman at 2018-11-16 14:49:06
FYI, a bug was just filed related to
is_global: https://github.com/rust-lang/rust/issues/57558Corey Farwell at 2019-01-13 17:54:03
As above, this has been a problem for a while and is not a regression. I did not fix it because it looked like trying to figure how to name the reason that an IPv4 address might not be global looked like a maze of twisty little passages all alike.
If naming the various blocks or otherwise identifying them in the API is not significant, then I can pick this up and fix it for IPv4.
Ben Stern at 2019-01-13 19:39:19
@little-dude please finish https://github.com/rust-lang/rust/pull/56050
Roman at 2019-01-13 21:03:23
ping?
Roman at 2019-04-07 21:30:05
I'm stuck on nightly because of ip6.is_unicast_link_local(). Is this one ready to become stable yet?
Tom Pusateri at 2019-04-19 20:55:08
Sorry for the delay, I'll re-open the PR this afternoon. Looking at it, it seems some tests were missing/failing. I had a hard time debugging so I wanted to refactor the tests a bit.
little-dude at 2019-04-20 08:34:03
Not much has happened since https://github.com/rust-lang/rust/pull/60145. Should we go ahead an stabilize the
Ipv4AddrandIpv6Addrthat are behind theipfeature?little-dude at 2019-08-15 19:11:34
Do we know what rust release the stabilization would occur in? I'd love to know when I can move to stable for one of my apps that relies on this.
Craig Hills at 2019-11-20 15:48:41
@chills42 I just opened a PR to stabilize this.
little-dude at 2019-11-20 20:03:19
Stabilization concern: There are motions under way[0][1] to slowly free up some of the reserved ipv4 ranges to make them useable as unicast addresses at some point in the future.
We discussed a similar concerns in #60145. For ipv6 the spec already says that
is_globalis a heuristic and must include reserved ranges per spec, so it wasn't a concern there while IPv4 was presumed set in stone. I wasn't aware of the above-mentioned plans, so we should reconsider.Perhaps we could leave
Ipv4Addr::is_globalunstable or use the ipv6 approach (only exclude known non-global uses) instead. Or we could add a warning that these methods are subject to expected future standard changes, in fact there is an issue open for this #60239, perhaps that should be done before stabilizing.[0] https://www.netdevconf.info/0x13/session.html?talk-ipv4-unicast-expansions [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96125bf9985a
the8472 at 2019-11-20 21:23:17
I'd be in favor of stabilizing everything, because if I understand correctly
Ipv4Addr::is_globalis correct, as per the current state of the RFCs (Linux allows 0.x.y.z addresses, but it hasn't been enacted by an RFC yet).I prefer your second proposal: adding the disclaimer discussed in https://github.com/rust-lang/rust/issues/60239.
little-dude at 2019-11-20 22:03:47
@little-dude you can send a stabilisation PR that stabilises the functions / module and then we can see what's missing or left to be done.
Dylan DPC at 2019-12-20 09:41:23
@Dylan-DPC I did already: https://github.com/rust-lang/rust/pull/66584
little-dude at 2019-12-20 10:12:31
Add
Ipv6Addr::to_ipv4_mapped: #75019ε桦ζ at 2020-08-04 15:49:35
Hey so I think PR #76098 covers this stuff but I'm not sure? It's basically just an extension of #66584.
Cass Fridkin at 2020-09-04 03:33:24
By the way, why not have a trait Ip for common feature on both ipv4 and ipv6 ?
Stargateur at 2020-10-02 09:33:20
sorry, the ip interface detoriorated recently
- parsing of 001.001.001.001 does NOT work anymore. Broke lots stuff. ARguyable this is valid IP address even with leading zeroes b) where is is_unicast_link_local_strict all of a sudden on rustc 1.54.0-nightly (ed597e7e1 2021-06-08) ?
Tony Przygienda at 2021-06-09 13:25:03
Yes, code recently get more strict about ipv4 parsing.
ipv4 didn't have a official ABNF until ipv6 but according to it:
IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet dec-octet = DIGIT ; 0-9 / %x31-39 DIGIT ; 10-99 / "1" 2DIGIT ; 100-199 / "2" %x30-34 DIGIT ; 200-249 / "25" %x30-35 ; 250-255and so
001.001.001.001is not a valid text representation of an ipv4 address.is_unicast_link_local_strict()have never been stable so that can't be considered breaking change. See https://github.com/rust-lang/rust/pull/85819 for moreStargateur at 2021-06-09 13:46:40
So what is holding up the stabilization of methods like
Ipv6Addr::is_unicast_link_local()? Certainly that could be considered stable by now, right?Robert Quattlebaum at 2022-05-19 19:36:38
Regarding the
is_globalfunction applied toipv4andipv6addresses here, when looking at the IANA standard, I realized that there are several addresses considered asSpecial-Purpose Addresswhich are not listed in thestdis_globalcondition. Is this normal?ipv4IANA list: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml#note2ipv6IANA list: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
Despite the fact that some of the addresses in the IANA table are considered
globally reachable, it is notified at the beginning of the document: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
is_global, is there something I've misunderstood here?Thomas Coratger at 2023-04-27 17:46:08
Hi everyone,
The following concerns mostly
is_globaland a little bitis_unicast_global.I took the ipcheck tool[1] (which gave us some very useful data two years ago[2]) and modified it slightly to:
- Extend the range of addresses tested[3]
- Use the current Rust implementation as the baseline[4]
- Optionally compare against multiple Python versions (because I've been working on the Python side of things as well)
- Only include the differences on the
is_globalfront as the rest didn't interest me
I present you two tables. The content is collapsed because of its length, you'll have to click on the arrows to see everything.
<details> <summary>Table 1. The status quo as of today (Rust nightly, Python versions as specified, Go 1.21.5)</summary>| addr | Python 3.8 | Python 3.9 | Python 3.10 | Python 3.11 | Python 3.12 | Go | | - | - | - | - | - | - | - | |
</details> <details> <summary>Table 2. Patched Rust, patched CPython, regular Go.</summary>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 (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |192.0.0.9| β{ is_global : false (Rust) β true (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |192.0.0.10| β{ is_global : false (Rust) β true (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |192.0.0.169| β{ is_global : false (Rust) β true (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ 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 (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |192.0.0.255| β{ is_global : false (Rust) β true (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ 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| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |::ffff:0.1.2.3| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |::ffff:1.1.1.1| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:127.0.0.1| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |::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 (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:45.22.13.197| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:100.64.0.0| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:100.128.0.0| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:169.254.0.0| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |::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 (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.0.0.9| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.0.0.10| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.0.0.169| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ 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 (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.0.0.255| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ 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 (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.52.193.2| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.88.99.2| βοΈ | βοΈ | β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ 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 (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ 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::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |64:ff9b:1::| β{ is_global : false (Rust) β true (Python 3.8) }| β{ is_global : false (Rust) β true (Python 3.9) }| β{ is_global : false (Rust) β true (Python 3.10) }| β{ is_global : false (Rust) β true (Python 3.11) }| β{ is_global : false (Rust) β true (Python 3.12) }| β{ is_global : false (Rust) β true (Go) }| |100::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:1::1| β{ is_global : true (Rust) β false (Python 3.8) }| β{ is_global : true (Rust) β false (Python 3.9) }| β{ is_global : true (Rust) β false (Python 3.10) }| β{ is_global : true (Rust) β false (Python 3.11) }| β{ is_global : true (Rust) β false (Python 3.12) }| βοΈ | |2001:1::2| β{ is_global : true (Rust) β false (Python 3.8) }| β{ is_global : true (Rust) β false (Python 3.9) }| β{ is_global : true (Rust) β false (Python 3.10) }| β{ is_global : true (Rust) β false (Python 3.11) }| β{ is_global : true (Rust) β false (Python 3.12) }| βοΈ | |2001:2::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:0002:6c::430| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:3::| β{ is_global : true (Rust) β false (Python 3.8) }| β{ is_global : true (Rust) β false (Python 3.9) }| β{ is_global : true (Rust) β false (Python 3.10) }| β{ is_global : true (Rust) β false (Python 3.11) }| β{ is_global : true (Rust) β false (Python 3.12) }| βοΈ | |2001:4:112::| β{ is_global : true (Rust) β false (Python 3.8) }| β{ is_global : true (Rust) β false (Python 3.9) }| β{ is_global : true (Rust) β false (Python 3.10) }| β{ is_global : true (Rust) β false (Python 3.11) }| β{ is_global : true (Rust) β false (Python 3.12) }| βοΈ | |2001:10::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:10:240:ab::a| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:20::| β{ is_global : true (Rust) β false (Python 3.8) }| β{ is_global : true (Rust) β false (Python 3.9) }| β{ is_global : true (Rust) β false (Python 3.10) }| β{ is_global : true (Rust) β false (Python 3.11) }| β{ is_global : true (Rust) β false (Python 3.12) }| βοΈ | |2001:30::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:db8:8:4::2| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |2002::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |2002:cb0a:3cdd:1::1| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |2620:4f:8000::| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |fdf8:f53b:82e4::53| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : false (Rust) β true (Go) }| |fe80::200:5aee:feaa:20a2| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | |ff01:0:0:0:0:0:0:2| βοΈ | βοΈ | βοΈ | βοΈ | βοΈ | β{ is_global : true (Rust) β false (Go) }|| addr | Python | Go | | - | - | - | |
</details>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| βοΈ | βοΈ | |::ffff:0.1.2.3| βοΈ | β{ is_global : false (Rust) β true (Go) }| |::ffff:1.1.1.1| β{ is_global : false (Rust) β true (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:127.0.0.1| βοΈ | βοΈ | |::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 (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:45.22.13.197| β{ is_global : false (Rust) β true (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:100.64.0.0| β{ is_global : false (Rust) β true (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:100.128.0.0| β{ is_global : false (Rust) β true (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:169.254.0.0| βοΈ | βοΈ | |::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 (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.0.0.10| β{ is_global : false (Rust) β true (Python) }| β{ 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 (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.52.193.2| β{ is_global : false (Rust) β true (Python) }| β{ is_global : false (Rust) β true (Go) }| |::ffff:192.88.99.2| β{ is_global : false (Rust) β true (Python) }| β{ 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 (Python) }| β{ 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::| βοΈ | βοΈ | |64:ff9b:1::| βοΈ | β{ is_global : false (Rust) β true (Go) }| |100::| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001::| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:1::1| βοΈ | βοΈ | |2001:1::2| βοΈ | βοΈ | |2001:2::| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:0002:6c::430| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:3::| βοΈ | βοΈ | |2001:4:112::| βοΈ | βοΈ | |2001:10::| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:10:240:ab::a| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2001:20::| βοΈ | βοΈ | |2001:30::| βοΈ | βοΈ | |2001:db8:8:4::2| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2002::| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2002:cb0a:3cdd:1::1| βοΈ | β{ is_global : false (Rust) β true (Go) }| |2620:4f:8000::| βοΈ | βοΈ | |fdf8:f53b:82e4::53| βοΈ | β{ is_global : false (Rust) β true (Go) }| |fe80::200:5aee:feaa:20a2| βοΈ | βοΈ | |ff01:0:0:0:0:0:0:2| βοΈ | β{ is_global : true (Rust) β false (Go) }|In table 1 you'll see some Rust/Python disagreement in the following ranges:
192.0.0.0/24,64:ff9b:1::/48,2001::/23.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
is_globalβ it's not important to my message but I thought I'd mention it. I'm not particularly fond of that.I consider both Rust and Python implementations somewhat buggy, sometimes buggy in the same way (for example when it comes to the
2002::/16range).In table 2 we have Rust/Python/Go comparison where
- Rust is patched with https://github.com/rust-lang/rust/pull/119006
- Python is patched with https://github.com/python/cpython/pull/113179
With the patches in place Rust and Python are in almost perfect agreement on the
is_globalfront β the only exception is handling of the IPv4-mapped IPv6 addresses. I believe it's a direction worth pursuing.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 (https://github.com/rust-lang/rust/issues/27709#issuecomment-1526091769).
The tables don't capture the difference in
is_unicast_globalbehavior asipcheckdoesn't test that.[1] https://github.com/rust-lang/libs-team/tree/main/tools/ipcheck [2] https://github.com/rust-lang/rust/pull/76098#issuecomment-760651861 [3] https://github.com/rust-lang/libs-team/pull/317 [4] https://github.com/rust-lang/libs-team/pull/318
Jakub Stasiak at 2023-12-16 01:33:23
looking forward to stabilisation of
Ipv4Addr::is_reserved!could theses simple convenience methods be included? possibly also on
SocketAddrimpl 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), } } }Emilia Hane at 2024-05-20 07:13:14
How can I help with stabilizing
Ipv4Addr::is_global()?Charlotte Herngreen at 2025-01-27 13:18:35
Hi @alexcrichton , can you please mark stabilize
IpAddr::is_global?ssrlive at 2025-03-06 12:37:18