python / cpython

The Python programming language
https://www.python.org
Other
63.53k stars 30.44k forks source link

ipaddress.IPv6Address.is_private makes redundant checks #88333

Open 652782da-b5f3-46b2-ae1b-1f73662bb759 opened 3 years ago

652782da-b5f3-46b2-ae1b-1f73662bb759 commented 3 years ago
BPO 44167
Nosy @mjpieters
PRs
  • python/cpython#26209
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.8', '3.9', '3.10', 'performance', '3.11', 'library'] title = 'ipaddress.IPv6Address.is_private makes redundant checks' updated_at = user = 'https://github.com/mjpieters' ``` bugs.python.org fields: ```python activity = actor = 'mjpieters' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'mjpieters' dependencies = [] files = [] hgrepos = [] issue_num = 44167 keywords = ['patch'] message_count = 1.0 messages = ['393860'] nosy_count = 1.0 nosy_names = ['mjpieters'] pr_nums = ['26209'] priority = 'normal' resolution = None stage = 'patch review' status = 'open' superseder = None type = 'performance' url = 'https://bugs.python.org/issue44167' versions = ['Python 3.8', 'Python 3.9', 'Python 3.10', 'Python 3.11'] ```

    652782da-b5f3-46b2-ae1b-1f73662bb759 commented 3 years ago

    ipaddress.IPv6Address.is_private uses a hard-coded list of IPv6Network objects that cover private networks to test against.

    This list contains two networks that are subnets of a 3rd network in the list. IP addresses that are not private are tested against all 3 networks where only a single test is needed.

    The networks in question are:

        IPv6Network('2001::/23'),
        IPv6Network('2001:2::/48'),  # within 2001::/23
        ...
        IPv6Network('2001:10::/28'), # within 2001::/23

    The first is a supernet of the other two, so any IP address that is tested against the first and is not part of that network, will also not be part of the other two networks:

    >>> from ipaddress import IPv6Network
    >>> sub_tla_id = IPv6Network('2001::/23')
    >>> sub_tla_id.supernet_of(IPv6Network('2001:2::/48'))
    True
    >>> sub_tla_id.supernet_of(IPv6Network('2001:10::/28'))
    True

    We can safely drop these two network entries from the list.

    On a separate note: the definition here is inconsistent with IPv4Address's list of private networks. 2001::/23 is the whole subnet reserved for special purpose addresses (RFC 2928), regardless of what ranges have actually been assigned. The IPv4 list on the other hand only contains _actual assignments within the reserved subnet_, not the whole reserved block (RFC 5736 / RFC 6890, reserving 192.0.0.0/24, IPv4Address only considers 192.0.0.0/29 and 192.0.0.170/31). I'll file a separate issue for that if not already reported.