python / python/cpython

ipaddress: Shared Address Space (100.64.0.0/10) is neither private nor global

Open
#119,812 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

stdlib
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Something I discovered when working on GH-65056 and GH-113171.

IPv4Address' and IPv4Network's is_global and is_private are false at the same time for addresses in this range:

>>> ipaddress.IPv4Address('100.64.0.0').is_global
False
>>> ipaddress.IPv4Address('100.64.0.0').is_private
False
>>> ipaddress.IPv4Network('100.64.0.0/10').is_global
False
>>> ipaddress.IPv4Network('100.64.0.0/10').is_private
False

I don't believe this is right and I'll explain why.

Historical context

Initial additions

is_private introduced in dc9b2555a875 ("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 and is_private semantics changes

There have been four ipaddress patches involving this range:

  1. 22c31764262b ("#17400; ipaddress should make it easy to identify rfc6598 addresses")
  2. be9c1b133b78 ("#17400: fix documentation, add cache to is_global and correctly handle 100.64.0.0/10")
  3. e5019d518304 ("#17400: correct handling of 100.64.0.0/10, fixing the docs and updating NEWS")
  4. 742192a4fea8 ("Issue #21386: Implement missing IPv4Address.is_global property")

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 the IPv4Network.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 precise

         A boolean, True if the address is reserved per
        iana-ipv4-special-registry or iana-ipv6-special-registry.

but the intent of the implementation is quite clear.

Commit 1 also added is_global that was effectively not is_private.

In commit 3 an exception for 100.64.0.0/10 is made and both is_global and is_private are false for that range.

is_global/is_private semantics clarification

As 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 83f0f8d62f27 ("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:

https://github.com/python/cpython/issues/61602#issuecomment-1093610325

The rationale for RFC 6598 is precisely that 100.64.0.0/10 is not private in the common sense, so it would deserve a different treatment in the ipaddress module as well.

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 of is_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
  • gh-119813

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the ipaddress implementation of IPv4Address and IPv4Network is_private and is_global, along with the discussion and linked PR gh-119813. Check how the 100.64.0.0/10 exception is represented and whether the proposed semantics are consistent across documentation and tests; done requires an agreed behavior, since the issue notes backward-compatibility concerns.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.