-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
ipaddress: Shared Address Space (100.64.0.0/10) is neither private nor global #119812
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
Comments
It seems to me that if |
If we decide to deprecate something, it should keep its existing warts. |
Are you saying we should should deprecate and eventually remove IMO such deprecation and removal would have to be connected to a claim about the Shared Address Space exception being needless or unwarranted. Please help me understand what should happen here (a hypothetical sequence or a timeline of events could be useful). |
This needs an expert, or someone looking at the usage and use cases and related context, to determine if this is a problem that needs fixing. Right now I can't commit the necessary time to do this. If it should be fixed, with a deprecation we can avoid changing existing behaviour and make the (non-deprecated) API smaller/simpler. |
Re-reading the old issue, I'm still of the view that since there are 3 categories of interest (global, private, private-to-carrier), there should be three flags rather than having the third category be soley implied by the first two flags both being false. The fact that one of the categories is much smaller than the other two shouldn't be a major consideration. Peter didn't want a public I still think it would be wrong to make If the documentation of |
The Considering options for new properties, I wonder if the following might be the best option:
There's no way for the standard library to know how the carrier shared address space should be handled in a given application unless it's told whether it's an endpoint use case or a carrier use case. If we went down this road, the four new property implementations would be:
It feels like a fairly heavy solution for a relatively rare case, but I'm thinking that "Complex is better than complicated" applies here: exposing separate property pairs for endpoint use cases and carrier use cases (in addition to the existing "for all" flag attributes) forces people to decide which pair they want for their use case, but once you've made that decision, you can just ignore the other two property pairs. The main alternative to that "choose a pair of properties and use them consistently" solution is the following:
While superficially simpler (only 2 new properties rather than 4), this feels more complicated to use in practice, since endpoint use cases will want the |
I thought of a potential solution that moves the handling of this problem to the point where addresses/networks/etc are defined rather than every time Network range semanticsWe want to define 3 different sets of potential network range categorisation semantics for IPv6 address and network instances to follow:
The first case will ideally be transitional - the eventual default should be To allow for deprecation of the
Which implies a public API to query the default semantics as well:
Defining a real enum seems like overkill here ( IPv6 address and network changesIPv6 address and network instances would take a new tri-state boolean That option (and potentially the module default setting) would control how They would gain a new string property Defaulting to "endpoint" semanticsWe don't actually know if telcos and other backbone operators are relying on the current
Alternatively, we could decide that endpoint use cases so massively outweigh carrier use cases that it's OK to skip the deprecation period, and instead just add a porting note that carriers relying on Addresses in the private range could still be specifically identified with that default behaviour, but you'd have to create two address instances (one with carrier range semantics, one with endpoint semantics) and see if they reported different We'd need SC approval for that (as per PEP 387), and I'm not sure they'd grant it (we can reasonably issue a deprecation notice, it's just highly arguable how useful it would be to do so when we're pretty sure 99.9% of the userbase will want the new behaviour and would see it as a bug fix rather than as functional change). A straw poll on discuss.python.org might be helpful to get a sense of whether folks think it's OK to spend a couple of years getting away from the currently ambiguous default range handling semantics. Edit: changed the suggested name of the current default semantics from "unknown" to "universal" ("unknown" made it sound like the range semantics were unknown, which isn't the case. Calling that case "universal range semantics" reflects the fact that Edit 2: I realised what this case was reminding me of: the Edit 3: An even simpler third option would be to never change the default. |
There's a concrete problem in the "Default range semantics" idea as currently written: if instances eagerly save the default semantics that were in effect when the application started up, then attempting to change the default later will end up with an unpredictable mix of instances using universal range semantics and those using specifically carrier or endpoint semantics. So maybe a true enum solution would be justified: @enum
class NetworkRangeSemantics:
Universal = "Common range properties for carrier and endpoint networks"
Carrier = "Range properties for carrier networks"
Endpoint = "Range properties for endpoint networks" Given a true enum, the initial solution could completely ignore any prospect of changing the default behaviour, and instead just accept a |
IMO, we're getting into a situation where it's better to ask interested people to put a better-ipaddress module on PyPI, and after the design is solid, start talking about including it (or parts of it) back in the stdlib. |
Something I discovered when working on GH-65056 and GH-113171.
IPv4Address
' andIPv4Network
'sis_global
andis_private
are false at the same time for addresses in this range:I don't believe this is right and I'll explain why.
Historical context
Initial additions
is_private
introduced in dc9b255 ("Issue #14814: addition of the ipaddress module (stage 1 - code and tests)") on 2012-05-20.It only handled the actual private-use ranges for IPv4 (
10.0.0.0/8
,172.16.0.0/12
,192.168.0.0/16
).Documented as such.
100.64.0.0/10
handling andis_private
semantics changesThere have been four
ipaddress
patches involving this range:The first three were part of GH-61602 (https://bugs.python.org/issue17400), the fourth one just adds a missing
IPv4Address.is_global
property to match theIPv4Network.is_global
semantics and follows the semantics established in commits 1-3.Commit 1 changed the semantics of
is_private
from "Is this a Private-use IPv4 address or a Unique-Local IPv6 address?" to roughly "Do [1] and [2] say globally reachable = false for this address". The documentation change was not quite precisebut the intent of the implementation is quite clear.
Commit 1 also added
is_global
that was effectivelynot is_private
.In commit 3 an exception for
100.64.0.0/10
is made and bothis_global
andis_private
are false for that range.is_global
/is_private
semantics clarificationAs part of GH-65056 we changed the documentation to make it clear that we follow the "globally reachable" information from IANA (with some caveats, like special handling of IPv4-mapped IPv6 addresses, see 83f0f8d ("bpo-33433 Fix private address checking for IPv4 mapped IPv6. (GH-26172)")).
The problem
The motivation for handling
100.64.0.0/10
like this can be found here:#61602 (comment)
I have to admit I don't find it convincing enough to make an exception for it.
[1] says the range is not globally reachable so in my opinion
is_private
should return true for it as it does for the rest of the not globally reachable address blocks (again, with the exception of IPv4-mapped IPv6 address handling).I'd find
is_private
being false for the range surprising if I wasn't clearly aware of the semantics after reading this code multiple times. I believe it may lead to real-world issues.Additionally the behavior where
is_private
is not the opposite ofis_global
is likely to be surprising too.In short: IMO there should be no exception.
The downside of the proposed solution: this is technically breaking backwards compatibility if some code depends on the current semantics. I'm not sure I'd classify the proposed change strictly as a bug fix.
[1] https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
[2] https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
Linked PRs
The text was updated successfully, but these errors were encountered: