1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-17 10:42:21 +01:00
This commit is contained in:
J. Nick Koston
2025-09-11 18:28:28 -05:00
parent bc9d16289e
commit 29525febe1
3 changed files with 44 additions and 30 deletions

View File

@@ -40,6 +40,25 @@ class AddressCache:
self.mdns_cache = mdns_cache or {} self.mdns_cache = mdns_cache or {}
self.dns_cache = dns_cache or {} self.dns_cache = dns_cache or {}
def _get_cached_addresses(
self, hostname: str, cache: dict[str, list[str]], cache_type: str
) -> list[str] | None:
"""Get cached addresses from a specific cache.
Args:
hostname: The hostname to look up
cache: The cache dictionary to check
cache_type: Type of cache for logging ("mDNS" or "DNS")
Returns:
List of IP addresses if found in cache, None otherwise
"""
normalized = normalize_hostname(hostname)
if addresses := cache.get(normalized):
_LOGGER.debug("Using %s cache for %s: %s", cache_type, hostname, addresses)
return addresses
return None
def get_mdns_addresses(self, hostname: str) -> list[str] | None: def get_mdns_addresses(self, hostname: str) -> list[str] | None:
"""Get cached mDNS addresses for a hostname. """Get cached mDNS addresses for a hostname.
@@ -49,11 +68,7 @@ class AddressCache:
Returns: Returns:
List of IP addresses if found in cache, None otherwise List of IP addresses if found in cache, None otherwise
""" """
normalized = normalize_hostname(hostname) return self._get_cached_addresses(hostname, self.mdns_cache, "mDNS")
if addresses := self.mdns_cache.get(normalized):
_LOGGER.debug("Using mDNS cache for %s: %s", hostname, addresses)
return addresses
return None
def get_dns_addresses(self, hostname: str) -> list[str] | None: def get_dns_addresses(self, hostname: str) -> list[str] | None:
"""Get cached DNS addresses for a hostname. """Get cached DNS addresses for a hostname.
@@ -64,11 +79,7 @@ class AddressCache:
Returns: Returns:
List of IP addresses if found in cache, None otherwise List of IP addresses if found in cache, None otherwise
""" """
normalized = normalize_hostname(hostname) return self._get_cached_addresses(hostname, self.dns_cache, "DNS")
if addresses := self.dns_cache.get(normalized):
_LOGGER.debug("Using DNS cache for %s: %s", hostname, addresses)
return addresses
return None
def get_addresses(self, hostname: str) -> list[str] | None: def get_addresses(self, hostname: str) -> list[str] | None:
"""Get cached addresses for a hostname. """Get cached addresses for a hostname.

View File

@@ -6,6 +6,7 @@ import typing
from zeroconf import AddressResolver, IPVersion from zeroconf import AddressResolver, IPVersion
from esphome.address_cache import normalize_hostname
from esphome.zeroconf import ( from esphome.zeroconf import (
ESPHOME_SERVICE_TYPE, ESPHOME_SERVICE_TYPE,
AsyncEsphomeZeroconf, AsyncEsphomeZeroconf,
@@ -60,8 +61,8 @@ class MDNSStatus:
if not self.aiozc: if not self.aiozc:
return None return None
# Normalize hostname: remove trailing dots and get the base name # Normalize hostname and get the base name
normalized = host_name.rstrip(".").lower() normalized = normalize_hostname(host_name)
base_name = normalized.partition(".")[0] base_name = normalized.partition(".")[0]
# Try to load from zeroconf cache without triggering resolution # Try to load from zeroconf cache without triggering resolution

View File

@@ -210,28 +210,30 @@ def resolve_ip_address(
res.sort(key=addr_preference_) res.sort(key=addr_preference_)
return res return res
# Check if we have cached addresses for these hosts # Process hosts
cached_hosts: list[str] = [] cached_addresses: list[str] = []
uncached_hosts: list[str] = [] uncached_hosts: list[str] = []
has_cache = address_cache is not None
for h in hosts: for h in hosts:
# Check if it's already an IP address
if is_ip_address(h): if is_ip_address(h):
cached_hosts.append(h) if has_cache:
continue # If we have a cache, treat IPs as cached
cached_addresses.append(h)
else:
# If no cache, pass IPs through to resolver with hostnames
uncached_hosts.append(h)
elif address_cache and (cached := address_cache.get_addresses(h)):
# Found in cache
cached_addresses.extend(cached)
else:
# Not cached, need to resolve
if address_cache and address_cache.has_cache():
_LOGGER.info("Host %s not in cache, will need to resolve", h)
uncached_hosts.append(h)
# Check cache if provided # Process cached addresses (includes direct IPs and cached lookups)
if address_cache and (cached_addresses := address_cache.get_addresses(h)): for addr in cached_addresses:
cached_hosts.extend(cached_addresses)
continue
# Not in cache, need to resolve
if address_cache and address_cache.has_cache():
_LOGGER.info("Host %s not in cache, will need to resolve", h)
uncached_hosts.append(h)
# Process cached addresses (all should be IP addresses)
for addr in cached_hosts:
try: try:
res += socket.getaddrinfo( res += socket.getaddrinfo(
addr, port, proto=socket.IPPROTO_TCP, flags=socket.AI_NUMERICHOST addr, port, proto=socket.IPPROTO_TCP, flags=socket.AI_NUMERICHOST
@@ -239,7 +241,7 @@ def resolve_ip_address(
except OSError: except OSError:
_LOGGER.debug("Failed to parse IP address '%s'", addr) _LOGGER.debug("Failed to parse IP address '%s'", addr)
# If we have uncached hosts, resolve them # If we have uncached hosts (only non-IP hostnames), resolve them
if uncached_hosts: if uncached_hosts:
from esphome.resolver import AsyncResolver from esphome.resolver import AsyncResolver