fix(proxy): apply source overrides to IPv4-mapped IPv6 sign-in sources

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yucheng 2026-09-16 01:33:54 +00:00
parent bc60b49e98
commit 3c972cb31f
2 changed files with 7 additions and 4 deletions

View file

@ -137,10 +137,14 @@ def _int_setting(settings: Mapping[str, object], key: str, default: int) -> int:
def _parse_address(client_ip: str) -> ipaddress.IPv4Address | ipaddress.IPv6Address | None:
"""The address as it is limited and counted: an IPv4-mapped IPv6 address is its IPv4 address."""
try:
return ipaddress.ip_address(client_ip)
address: Final = ipaddress.ip_address(client_ip)
except ValueError:
return None
if isinstance(address, ipaddress.IPv6Address) and address.ipv4_mapped is not None:
return address.ipv4_mapped
return address
def _parse_network(raw_range: str) -> _Network | None:
@ -183,9 +187,6 @@ def source_group(client_ip: str) -> str:
if address is None:
return client_ip
if isinstance(address, ipaddress.IPv6Address):
mapped: Final = address.ipv4_mapped
if mapped is not None:
return str(mapped)
return str(ipaddress.ip_network((address, IPV6_SOURCE_PREFIX_LENGTH), strict=False))
return str(address)

View file

@ -955,6 +955,8 @@ def test_source_overrides_pick_the_most_specific_matching_range():
assert _limit("203.0.1.1") == 100
assert _limit("192.0.2.1") == 7
assert _limit("198.51.100.1") == 7, "a garbage limit falls back to the default rather than a huge or zero budget"
assert _limit("::ffff:203.0.113.9") == 300, "a mapped address gets the limit of the IPv4 bucket it is counted in"
assert _limit("::ffff:203.0.113.10") == 200
def test_ipv6_sources_are_grouped_by_their_64_bit_prefix():