Skip to content

Commit c1ed987

Browse files
authored
Break apart Zeroconf.handle_query to reduce branching (#462)
1 parent 4c4b529 commit c1ed987

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
@@ -2948,9 +2948,59 @@ def handle_response(self, msg: DNSIncoming) -> None: # pylint: disable=too-many
29482948
for record in removes:
29492949
self.cache.remove(record)
29502950

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

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

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

0 commit comments

Comments
 (0)