Skip to content

Commit 47ec4ba

Browse files
authored
fix: skip adapter scan for interface lists with no IPv6 entries (#1919)
1 parent 27ee975 commit 47ec4ba

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

‎src/zeroconf/_utils/net.py‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,21 @@ def ip6_addresses_to_indexes(
126126
:param interfaces: List of IP addresses and indexes.
127127
:returns: List of indexes.
128128
"""
129-
result = []
129+
result: list[tuple[tuple[str, int, int], int]] = []
130+
needs_scan = [
131+
iface
132+
for iface in interfaces
133+
if isinstance(iface, int) or (isinstance(iface, str) and ipaddress.ip_address(iface).version == 6)
134+
]
135+
if not needs_scan:
136+
return result
137+
130138
adapters = ifaddr.get_adapters()
131139

132-
for iface in interfaces:
140+
for iface in needs_scan:
133141
if isinstance(iface, int):
134142
result.append((interface_index_to_ip6_address(adapters, iface), iface)) # type: ignore[arg-type]
135-
elif isinstance(iface, str) and ipaddress.ip_address(iface).version == 6:
143+
else:
136144
result.append(ip6_to_address_and_index(adapters, iface)) # type: ignore[arg-type]
137145

138146
return result

‎tests/utils/test_net.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,35 @@ def test_ip6_addresses_to_indexes():
118118
assert netutils.ip6_addresses_to_indexes(interfaces_2) == [(("2001:db8::", 1, 1), 1)]
119119

120120

121+
@pytest.mark.parametrize("interfaces", [[], ["192.168.1.5"], ["192.168.1.5", "169.254.3.2"]])
122+
def test_ip6_addresses_to_indexes_skips_scan_without_ipv6(interfaces: list[str]) -> None:
123+
"""Test the adapters are not scanned when there are no IPv6 entries."""
124+
with patch("zeroconf._utils.net.ifaddr.get_adapters") as mock_get_adapters:
125+
assert netutils.ip6_addresses_to_indexes(interfaces) == []
126+
mock_get_adapters.assert_not_called()
127+
128+
129+
def test_ip6_addresses_to_indexes_scans_once() -> None:
130+
"""Test the adapters are scanned once for a mixed list."""
131+
with patch(
132+
"zeroconf._utils.net.ifaddr.get_adapters",
133+
return_value=_generate_mock_adapters(),
134+
) as mock_get_adapters:
135+
assert netutils.ip6_addresses_to_indexes(["192.168.1.5", "2001:db8::", 1, "fd00:db8::"]) == [
136+
(("2001:db8::", 1, 1), 1),
137+
(("2001:db8::", 1, 1), 1),
138+
(("fd00:db8::", 1, 1), 1),
139+
]
140+
mock_get_adapters.assert_called_once()
141+
142+
143+
def test_normalize_interface_choice_ipv4_list_skips_scan() -> None:
144+
"""Test an IPv4 only list is normalized without scanning the adapters."""
145+
with patch("zeroconf._utils.net.ifaddr.get_adapters") as mock_get_adapters:
146+
assert netutils.normalize_interface_choice(["192.168.1.5"]) == ["192.168.1.5"]
147+
mock_get_adapters.assert_not_called()
148+
149+
121150
def test_normalize_interface_choice_errors():
122151
"""Test we generate exception on invalid input."""
123152
with (

0 commit comments

Comments
 (0)