Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/zeroconf/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,10 @@ def __init__(
raise RuntimeError("Option `apple_p2p` is not supported on non-Apple platforms.")

self.unicast = unicast
listen_socket, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
log.debug("Listen socket %s, respond sockets %s", listen_socket, respond_sockets)
listen_sockets, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
log.debug("Listen socket %s, respond sockets %s", listen_sockets, respond_sockets)

self.engine = AsyncEngine(self, listen_socket, respond_sockets)
self.engine = AsyncEngine(self, listen_sockets, respond_sockets)

self.browsers: dict[ServiceListener, ServiceBrowser] = {}
self.registry = ServiceRegistry()
Expand Down
26 changes: 17 additions & 9 deletions src/zeroconf/_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import threading
from typing import TYPE_CHECKING, cast

from ._logger import log
from ._record_update import RecordUpdate
from ._utils.asyncio import get_running_loop, run_coro_with_timeout
from ._utils.time import current_time_millis
Expand All @@ -48,7 +49,7 @@ class AsyncEngine:

__slots__ = (
"_cleanup_timer",
"_listen_socket",
"_listen_sockets",
"_respond_sockets",
"_setup_task",
"loop",
Expand All @@ -62,7 +63,7 @@ class AsyncEngine:
def __init__(
self,
zeroconf: Zeroconf,
listen_socket: socket.socket | None,
listen_sockets: list[tuple[socket.socket, int]],
respond_sockets: list[socket.socket],
) -> None:
self.loop: asyncio.AbstractEventLoop | None = None
Expand All @@ -71,7 +72,7 @@ def __init__(
self.readers: list[_WrappedTransport] = []
self.senders: list[_WrappedTransport] = []
self.running_future: asyncio.Future[bool | None] | None = None
self._listen_socket = listen_socket
self._listen_sockets = listen_sockets
self._respond_sockets = respond_sockets
self._cleanup_timer: asyncio.TimerHandle | None = None
self._setup_task: asyncio.Task[None] | None = None
Expand Down Expand Up @@ -100,20 +101,27 @@ async def _async_create_endpoints(self) -> None:
"""Create endpoints to send and receive."""
assert self.loop is not None
loop = self.loop
reader_sockets = []
reader_socket_tuples = self._listen_sockets.copy()
sender_sockets = []
if self._listen_socket:
reader_sockets.append(self._listen_socket)
reader_sockets = (t[0] for t in reader_socket_tuples)
for s in self._respond_sockets:
if s not in reader_sockets:
reader_sockets.append(s)
reader_socket_tuples.append((s, 0))
sender_sockets.append(s)

for s in reader_sockets:
log.info(
"Creating %d reader sockets (%s) and %d sender sockets",
len(reader_socket_tuples),
reader_socket_tuples,
len(sender_sockets),
)
for s, interface_idx in reader_socket_tuples:
log.debug("Creating endpoint for socket %s", s)
transport, protocol = await loop.create_datagram_endpoint( # type: ignore[type-var]
lambda: AsyncListener(self.zc), # type: ignore[arg-type, return-value]
lambda: AsyncListener(self.zc, interface_idx), # type: ignore[arg-type, return-value]
sock=s,
)
log.debug("Creating endpoint for socket %s, transport %s, protocol %s", s, transport, protocol)
self.protocols.append(cast(AsyncListener, protocol))
self.readers.append(make_wrapped_transport(cast(asyncio.DatagramTransport, transport)))
if s in sender_sockets:
Expand Down
1 change: 1 addition & 0 deletions src/zeroconf/_listener.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ cdef cython.uint _DUPLICATE_PACKET_SUPPRESSION_INTERVAL
cdef class AsyncListener:

cdef public object zc
cdef public cython.uint interface_idx
cdef ServiceRegistry _registry
cdef RecordManager _record_manager
cdef QueryHandler _query_handler
Expand Down
8 changes: 4 additions & 4 deletions src/zeroconf/_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ class AsyncListener:
"_registry",
"_timers",
"data",
"interface_idx",
"last_message",
"last_time",
"sock_description",
"transport",
"zc",
)

def __init__(self, zc: Zeroconf) -> None:
def __init__(self, zc: Zeroconf, interface_idx: int = 0) -> None:
self.zc = zc
self.interface_idx = interface_idx
self._registry = zc.registry
self._record_manager = zc.record_manager
self._query_handler = zc.query_handler
Expand Down Expand Up @@ -139,12 +141,10 @@ def _process_datagram_at_time(
else:
# https://github.com/python/mypy/issues/1178
addr, port, flow, scope = addrs
if debug: # pragma: no branch
log.debug("IPv6 scope_id %d associated to the receiving interface", scope)
v6_flow_scope = (flow, scope)
addr_port = (addr, port)

msg = DNSIncoming(data, addr_port, scope, now)
msg = DNSIncoming(data, addr_port, self.interface_idx, now)
self.data = data
self.last_time = now
self.last_message = msg
Expand Down
8 changes: 8 additions & 0 deletions src/zeroconf/_services/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ def __init__(
interface_index: int | None = None,
) -> None:
# Accept both none, or one, but not both.
log.info("ServiceInfo.__init__() called with %s", properties)
if addresses is not None and parsed_addresses is not None:
raise TypeError("addresses and parsed_addresses cannot be provided together")
if not type_.endswith(service_type_name(name, strict=False)):
Expand Down Expand Up @@ -505,6 +506,8 @@ def _process_record_threadsafe(self, zc: Zeroconf, record: DNSRecord, now: float
if TYPE_CHECKING:
assert isinstance(dns_address_record, DNSAddress)
ip_addr = get_ip_address_object_from_record(dns_address_record)

# log.info("Got ip addr: %r with scope %d from %r", ip_addr, ip_addr.scope_id if ip_addr.scope_id else 0, dns_address_record)
if ip_addr is None:
log.warning(
"Encountered invalid address while processing %s: %s",
Expand Down Expand Up @@ -533,6 +536,9 @@ def _process_record_threadsafe(self, zc: Zeroconf, record: DNSRecord, now: float
if TYPE_CHECKING:
assert isinstance(ip_addr, ZeroconfIPv6Address)
ipv6_addresses = self._ipv6_addresses
if ip_addr.is_link_local and not ip_addr.scope_id:
log.debug("Ignoring link-local address without scope %s", ip_addr)
return False
if ip_addr not in self._ipv6_addresses:
ipv6_addresses.insert(0, ip_addr)
return True
Expand Down Expand Up @@ -838,6 +844,7 @@ async def async_request(
:param addr: address to send the request to
:param port: port to send the request to
"""
log.info("Asking for %s %s", question_type, self._name)
if not zc.started:
await zc.async_wait_for_start()

Expand All @@ -860,6 +867,7 @@ async def async_request(
return False
if next_ <= now:
this_question_type = question_type or (QU_QUESTION if first_request else QM_QUESTION)
log.info("Generating request for %s %s", this_question_type, self._name)
out = self._generate_request_query(zc, now, this_question_type)
first_request = False
if out.questions:
Expand Down
9 changes: 9 additions & 0 deletions src/zeroconf/_utils/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from typing import Any

from .._dns import DNSAddress
from .._logger import log
from ..const import _TYPE_AAAA

bytes_ = bytes
Expand Down Expand Up @@ -123,6 +124,14 @@ def get_ip_address_object_from_record(
record: DNSAddress,
) -> ZeroconfIPv4Address | ZeroconfIPv6Address | None:
"""Get the IP address object from the record."""

log.info(
"Got ip addr: %r from %r with scope %d",
record.address,
record,
record.scope_id if record.scope_id else 0,
)

if record.type == _TYPE_AAAA and record.scope_id:
return ip_bytes_and_scope_to_address(record.address, record.scope_id)
return cached_ip_addresses_wrapper(record.address)
Expand Down
Loading
Loading