Skip to content

Commit 8e12797

Browse files
committed
Break apart Zeroconf.handle_query to reduce branching
1 parent 558cec3 commit 8e12797

1 file changed

Lines changed: 57 additions & 43 deletions

File tree

zeroconf/__init__.py

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,9 +2947,59 @@ def handle_response(self, msg: DNSIncoming) -> None: # pylint: disable=too-many
29472947
for record in removes:
29482948
self.cache.remove(record)
29492949

2950-
def handle_query( # pylint: disable=too-many-branches
2951-
self, msg: DNSIncoming, addr: Optional[str], port: int
2952-
) -> None:
2950+
def _answer_service_type_enumeration_query(self, msg: DNSIncoming, out: DNSOutgoing) -> None:
2951+
"""Provide an answer to a service type enumeration query.
2952+
2953+
https://datatracker.ietf.org/doc/html/rfc6763#section-9
2954+
"""
2955+
for stype in self.registry.get_types():
2956+
out.add_answer(
2957+
msg,
2958+
DNSPointer(
2959+
_SERVICE_TYPE_ENUMERATION_NAME,
2960+
_TYPE_PTR,
2961+
_CLASS_IN,
2962+
_DNS_OTHER_TTL,
2963+
stype,
2964+
),
2965+
)
2966+
2967+
def _answer_ptr_query(self, msg: DNSIncoming, out: DNSOutgoing, question: DNSQuestion) -> None:
2968+
"""Answer a PTR query."""
2969+
for service in self.registry.get_infos_type(question.name):
2970+
out.add_answer(msg, service.dns_pointer())
2971+
# Add recommended additional answers according to
2972+
# https://tools.ietf.org/html/rfc6763#section-12.1.
2973+
out.add_additional_answer(service.dns_service())
2974+
out.add_additional_answer(service.dns_text())
2975+
for dns_address in service.dns_addresses():
2976+
out.add_additional_answer(dns_address)
2977+
2978+
def _answer_non_ptr_query(self, msg: DNSIncoming, out: DNSOutgoing, question: DNSQuestion) -> None:
2979+
"""Answer a query any query other then PTR.
2980+
2981+
Add answer(s) for A, AAAA, SRV, or TXT queries.
2982+
"""
2983+
name_to_find = question.name.lower()
2984+
# Answer A record queries for any service addresses we know
2985+
if question.type in (_TYPE_A, _TYPE_ANY):
2986+
for service in self.registry.get_infos_server(name_to_find):
2987+
for dns_address in service.dns_addresses():
2988+
out.add_answer(msg, dns_address)
2989+
2990+
service = self.registry.get_info_name(name_to_find) # type: ignore
2991+
if service is None:
2992+
return
2993+
2994+
if question.type in (_TYPE_SRV, _TYPE_ANY):
2995+
out.add_answer(msg, service.dns_service())
2996+
if question.type in (_TYPE_TXT, _TYPE_ANY):
2997+
out.add_answer(msg, service.dns_text())
2998+
if question.type == _TYPE_SRV:
2999+
for dns_address in service.dns_addresses():
3000+
out.add_additional_answer(dns_address)
3001+
3002+
def handle_query(self, msg: DNSIncoming, addr: Optional[str], port: int) -> None:
29533003
"""Deal with incoming query packets. Provides a response if
29543004
possible."""
29553005
# Support unicast client responses
@@ -2964,48 +3014,12 @@ def handle_query( # pylint: disable=too-many-branches
29643014
for question in msg.questions:
29653015
if question.type == _TYPE_PTR:
29663016
if question.name == _SERVICE_TYPE_ENUMERATION_NAME:
2967-
for stype in self.registry.get_types():
2968-
out.add_answer(
2969-
msg,
2970-
DNSPointer(
2971-
_SERVICE_TYPE_ENUMERATION_NAME,
2972-
_TYPE_PTR,
2973-
_CLASS_IN,
2974-
_DNS_OTHER_TTL,
2975-
stype,
2976-
),
2977-
)
2978-
continue
2979-
2980-
for service in self.registry.get_infos_type(question.name):
2981-
out.add_answer(msg, service.dns_pointer())
2982-
# Add recommended additional answers according to
2983-
# https://tools.ietf.org/html/rfc6763#section-12.1.
2984-
out.add_additional_answer(service.dns_service())
2985-
out.add_additional_answer(service.dns_text())
2986-
for dns_address in service.dns_addresses():
2987-
out.add_additional_answer(dns_address)
2988-
2989-
continue
2990-
2991-
name_to_find = question.name.lower()
2992-
# Answer A record queries for any service addresses we know
2993-
if question.type in (_TYPE_A, _TYPE_ANY):
2994-
for service in self.registry.get_infos_server(name_to_find):
2995-
for dns_address in service.dns_addresses():
2996-
out.add_answer(msg, dns_address)
2997-
2998-
service = self.registry.get_info_name(name_to_find) # type: ignore
2999-
if service is None:
3017+
self._answer_service_type_enumeration_query(msg, out)
3018+
else:
3019+
self._answer_ptr_query(msg, out, question)
30003020
continue
30013021

3002-
if question.type in (_TYPE_SRV, _TYPE_ANY):
3003-
out.add_answer(msg, service.dns_service())
3004-
if question.type in (_TYPE_TXT, _TYPE_ANY):
3005-
out.add_answer(msg, service.dns_text())
3006-
if question.type == _TYPE_SRV:
3007-
for dns_address in service.dns_addresses():
3008-
out.add_additional_answer(dns_address)
3022+
self._answer_non_ptr_query(msg, out, question)
30093023

30103024
if out is not None and out.answers:
30113025
out.id = msg.id

0 commit comments

Comments
 (0)