[3.12] gh-113171: gh-65056: Fix "private" (non-global) IP address ran… · encukou/cpython@f86b17a (original) (raw)
`@@ -1086,7 +1086,11 @@ def is_private(self):
`
1086
1086
` """
`
1087
1087
`return any(self.network_address in priv_network and
`
1088
1088
`self.broadcast_address in priv_network
`
1089
``
`-
for priv_network in self._constants._private_networks)
`
``
1089
`+
for priv_network in self._constants._private_networks) and all(
`
``
1090
`+
self.network_address not in network and
`
``
1091
`+
self.broadcast_address not in network
`
``
1092
`+
for network in self._constants._private_networks_exceptions
`
``
1093
`+
)
`
1090
1094
``
1091
1095
`@property
`
1092
1096
`def is_global(self):
`
`@@ -1333,18 +1337,41 @@ def is_reserved(self):
`
1333
1337
`@property
`
1334
1338
`@functools.lru_cache()
`
1335
1339
`def is_private(self):
`
1336
``
`-
"""Test if this address is allocated for private networks.
`
``
1340
"""``True`` if the address is defined as not globally reachable by
``
1341
`+
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
`
``
1342
`+
(for IPv6) with the following exceptions:
`
1337
1343
``
1338
``
`-
Returns:
`
1339
``
`-
A boolean, True if the address is reserved per
`
1340
``
`-
iana-ipv4-special-registry.
`
``
1344
* ``is_private`` is ``False`` for ``100.64.0.0/10``
``
1345
* For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
``
1346
`+
semantics of the underlying IPv4 addresses and the following condition holds
`
``
1347
`` +
(see :attr:IPv6Address.ipv4_mapped
)::
``
1341
1348
``
``
1349
`+
address.is_private == address.ipv4_mapped.is_private
`
``
1350
+
``
1351
``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10``
``
1352
IPv4 range where they are both ``False``.
1342
1353
` """
`
1343
``
`-
return any(self in net for net in self._constants._private_networks)
`
``
1354
`+
return (
`
``
1355
`+
any(self in net for net in self._constants._private_networks)
`
``
1356
`+
and all(self not in net for net in self._constants._private_networks_exceptions)
`
``
1357
`+
)
`
1344
1358
``
1345
1359
`@property
`
1346
1360
`@functools.lru_cache()
`
1347
1361
`def is_global(self):
`
``
1362
"""``True`` if the address is defined as globally reachable by
``
1363
`+
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
`
``
1364
`+
(for IPv6) with the following exception:
`
``
1365
+
``
1366
For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
``
1367
`+
semantics of the underlying IPv4 addresses and the following condition holds
`
``
1368
`` +
(see :attr:IPv6Address.ipv4_mapped
)::
``
``
1369
+
``
1370
`+
address.is_global == address.ipv4_mapped.is_global
`
``
1371
+
``
1372
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
``
1373
IPv4 range where they are both ``False``.
``
1374
`+
"""
`
1348
1375
`return self not in self._constants._public_network and not self.is_private
`
1349
1376
``
1350
1377
`@property
`
`@@ -1548,13 +1575,15 @@ class _IPv4Constants:
`
1548
1575
``
1549
1576
`_public_network = IPv4Network('100.64.0.0/10')
`
1550
1577
``
``
1578
`+
Not globally reachable address blocks listed on
`
``
1579
`+
https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
`
1551
1580
`_private_networks = [
`
1552
1581
`IPv4Network('0.0.0.0/8'),
`
1553
1582
`IPv4Network('10.0.0.0/8'),
`
1554
1583
`IPv4Network('127.0.0.0/8'),
`
1555
1584
`IPv4Network('169.254.0.0/16'),
`
1556
1585
`IPv4Network('172.16.0.0/12'),
`
1557
``
`-
IPv4Network('192.0.0.0/29'),
`
``
1586
`+
IPv4Network('192.0.0.0/24'),
`
1558
1587
`IPv4Network('192.0.0.170/31'),
`
1559
1588
`IPv4Network('192.0.2.0/24'),
`
1560
1589
`IPv4Network('192.168.0.0/16'),
`
`@@ -1565,6 +1594,11 @@ class _IPv4Constants:
`
1565
1594
`IPv4Network('255.255.255.255/32'),
`
1566
1595
` ]
`
1567
1596
``
``
1597
`+
_private_networks_exceptions = [
`
``
1598
`+
IPv4Network('192.0.0.9/32'),
`
``
1599
`+
IPv4Network('192.0.0.10/32'),
`
``
1600
`+
]
`
``
1601
+
1568
1602
`_reserved_network = IPv4Network('240.0.0.0/4')
`
1569
1603
``
1570
1604
`_unspecified_address = IPv4Address('0.0.0.0')
`
`@@ -2007,27 +2041,42 @@ def is_site_local(self):
`
2007
2041
`@property
`
2008
2042
`@functools.lru_cache()
`
2009
2043
`def is_private(self):
`
2010
``
`-
"""Test if this address is allocated for private networks.
`
``
2044
"""``True`` if the address is defined as not globally reachable by
``
2045
`+
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
`
``
2046
`+
(for IPv6) with the following exceptions:
`
2011
2047
``
2012
``
`-
Returns:
`
2013
``
`-
A boolean, True if the address is reserved per
`
2014
``
`-
iana-ipv6-special-registry, or is ipv4_mapped and is
`
2015
``
`-
reserved in the iana-ipv4-special-registry.
`
``
2048
* ``is_private`` is ``False`` for ``100.64.0.0/10``
``
2049
* For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
``
2050
`+
semantics of the underlying IPv4 addresses and the following condition holds
`
``
2051
`` +
(see :attr:IPv6Address.ipv4_mapped
)::
``
2016
2052
``
``
2053
`+
address.is_private == address.ipv4_mapped.is_private
`
``
2054
+
``
2055
``is_private`` has value opposite to :attr:`is_global`, except for the ``100.64.0.0/10``
``
2056
IPv4 range where they are both ``False``.
2017
2057
` """
`
2018
2058
`ipv4_mapped = self.ipv4_mapped
`
2019
2059
`if ipv4_mapped is not None:
`
2020
2060
`return ipv4_mapped.is_private
`
2021
``
`-
return any(self in net for net in self._constants._private_networks)
`
``
2061
`+
return (
`
``
2062
`+
any(self in net for net in self._constants._private_networks)
`
``
2063
`+
and all(self not in net for net in self._constants._private_networks_exceptions)
`
``
2064
`+
)
`
2022
2065
``
2023
2066
`@property
`
2024
2067
`def is_global(self):
`
2025
``
`-
"""Test if this address is allocated for public networks.
`
``
2068
"""``True`` if the address is defined as globally reachable by
``
2069
`+
iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_
`
``
2070
`+
(for IPv6) with the following exception:
`
2026
2071
``
2027
``
`-
Returns:
`
2028
``
`-
A boolean, true if the address is not reserved per
`
2029
``
`-
iana-ipv6-special-registry.
`
``
2072
For IPv4-mapped IPv6-addresses the ``is_private`` value is determined by the
``
2073
`+
semantics of the underlying IPv4 addresses and the following condition holds
`
``
2074
`` +
(see :attr:IPv6Address.ipv4_mapped
)::
``
``
2075
+
``
2076
`+
address.is_global == address.ipv4_mapped.is_global
`
2030
2077
``
``
2078
``is_global`` has value opposite to :attr:`is_private`, except for the ``100.64.0.0/10``
``
2079
IPv4 range where they are both ``False``.
2031
2080
` """
`
2032
2081
`return not self.is_private
`
2033
2082
``
`@@ -2268,19 +2317,31 @@ class _IPv6Constants:
`
2268
2317
``
2269
2318
`_multicast_network = IPv6Network('ff00::/8')
`
2270
2319
``
``
2320
`+
Not globally reachable address blocks listed on
`
``
2321
`+
https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
`
2271
2322
`_private_networks = [
`
2272
2323
`IPv6Network('::1/128'),
`
2273
2324
`IPv6Network('::/128'),
`
2274
2325
`IPv6Network('::ffff:0:0/96'),
`
``
2326
`+
IPv6Network('64:ff9b:1::/48'),
`
2275
2327
`IPv6Network('100::/64'),
`
2276
2328
`IPv6Network('2001::/23'),
`
2277
``
`-
IPv6Network('2001:2::/48'),
`
2278
2329
`IPv6Network('2001:db8::/32'),
`
2279
``
`-
IPv6Network('2001:10::/28'),
`
``
2330
`+
IANA says N/A, let's consider it not globally reachable to be safe
`
``
2331
`+
IPv6Network('2002::/16'),
`
2280
2332
`IPv6Network('fc00::/7'),
`
2281
2333
`IPv6Network('fe80::/10'),
`
2282
2334
` ]
`
2283
2335
``
``
2336
`+
_private_networks_exceptions = [
`
``
2337
`+
IPv6Network('2001:1::1/128'),
`
``
2338
`+
IPv6Network('2001:1::2/128'),
`
``
2339
`+
IPv6Network('2001:3::/32'),
`
``
2340
`+
IPv6Network('2001:4:112::/48'),
`
``
2341
`+
IPv6Network('2001:20::/28'),
`
``
2342
`+
IPv6Network('2001:30::/28'),
`
``
2343
`+
]
`
``
2344
+
2284
2345
`_reserved_networks = [
`
2285
2346
`IPv6Network('::/8'), IPv6Network('100::/8'),
`
2286
2347
`IPv6Network('200::/7'), IPv6Network('400::/6'),
`