Don't abort zeroconf discovery for IPv6-only devices (#66455)
This commit is contained in:
parent
ffcac67d99
commit
bc2cc42955
2 changed files with 21 additions and 5 deletions
|
@ -541,9 +541,9 @@ def info_from_service(service: AsyncServiceInfo) -> ZeroconfServiceInfo | None:
|
||||||
if isinstance(value, bytes):
|
if isinstance(value, bytes):
|
||||||
properties[key] = value.decode("utf-8")
|
properties[key] = value.decode("utf-8")
|
||||||
|
|
||||||
if not (addresses := service.addresses):
|
if not (addresses := service.addresses or service.parsed_addresses()):
|
||||||
return None
|
return None
|
||||||
if (host := _first_non_link_local_or_v6_address(addresses)) is None:
|
if (host := _first_non_link_local_address(addresses)) is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return ZeroconfServiceInfo(
|
return ZeroconfServiceInfo(
|
||||||
|
@ -557,11 +557,18 @@ def info_from_service(service: AsyncServiceInfo) -> ZeroconfServiceInfo | None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _first_non_link_local_or_v6_address(addresses: list[bytes]) -> str | None:
|
def _first_non_link_local_address(
|
||||||
"""Return the first ipv6 or non-link local ipv4 address."""
|
addresses: list[bytes] | list[str],
|
||||||
|
) -> str | None:
|
||||||
|
"""Return the first ipv6 or non-link local ipv4 address, preferring IPv4."""
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
ip_addr = ip_address(address)
|
ip_addr = ip_address(address)
|
||||||
if not ip_addr.is_link_local or ip_addr.version == 6:
|
if not ip_addr.is_link_local and ip_addr.version == 4:
|
||||||
|
return str(ip_addr)
|
||||||
|
# If we didn't find a good IPv4 address, check for IPv6 addresses.
|
||||||
|
for address in addresses:
|
||||||
|
ip_addr = ip_address(address)
|
||||||
|
if not ip_addr.is_link_local and ip_addr.version == 6:
|
||||||
return str(ip_addr)
|
return str(ip_addr)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -780,6 +780,15 @@ async def test_info_from_service_prefers_ipv4(hass):
|
||||||
assert info.host == "192.168.66.12"
|
assert info.host == "192.168.66.12"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_info_from_service_can_return_ipv6(hass):
|
||||||
|
"""Test that IPv6-only devices can be discovered."""
|
||||||
|
service_type = "_test._tcp.local."
|
||||||
|
service_info = get_service_info_mock(service_type, f"test.{service_type}")
|
||||||
|
service_info.addresses = ["fd11:1111:1111:0:1234:1234:1234:1234"]
|
||||||
|
info = zeroconf.info_from_service(service_info)
|
||||||
|
assert info.host == "fd11:1111:1111:0:1234:1234:1234:1234"
|
||||||
|
|
||||||
|
|
||||||
async def test_get_instance(hass, mock_async_zeroconf):
|
async def test_get_instance(hass, mock_async_zeroconf):
|
||||||
"""Test we get an instance."""
|
"""Test we get an instance."""
|
||||||
assert await async_setup_component(hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {}})
|
assert await async_setup_component(hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {}})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue