Skip to content

Commit 3081ec8

Browse files
committed
suppress early
1 parent 081f8c3 commit 3081ec8

1 file changed

Lines changed: 41 additions & 30 deletions

File tree

zeroconf/_handlers.py

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,10 @@
5858
class _QueryResponse:
5959
"""A pair for unicast and multicast DNSOutgoing responses."""
6060

61-
def __init__(
62-
self, cache: DNSCache, msg: DNSIncoming, ucast_source: bool, known_answers: DNSRRSet
63-
) -> None:
61+
def __init__(self, cache: DNSCache, msg: DNSIncoming, ucast_source: bool) -> None:
6462
"""Build a query response."""
6563
self._msg = msg
6664
self._is_probe = msg.num_authorities > 0
67-
self._known_answers = known_answers
6865
self._ucast_source = ucast_source
6966
self._now = current_time_millis()
7067
self._cache = cache
@@ -112,7 +109,6 @@ def _construct_outgoing_from_record_set(
112109
self, answers_rrset: Set[DNSRecord], multicast: bool
113110
) -> Optional[DNSOutgoing]:
114111
"""Add answers and additionals to a DNSOutgoing."""
115-
self._suppress_known_answers(answers_rrset)
116112
# Find additionals and suppress any additionals that are already in answers
117113
additionals_rrset = self._additionals_from_answers_rrset(answers_rrset) - answers_rrset
118114
if not answers_rrset:
@@ -129,10 +125,6 @@ def _additionals_from_answers_rrset(self, rrset: Set[DNSRecord]) -> Set[DNSRecor
129125
additionals: Set[DNSRecord] = set()
130126
return additionals.union(*[self._additionals[record] for record in rrset])
131127

132-
def _suppress_known_answers(self, rrset: Set[DNSRecord]) -> None:
133-
"""Remove any records suppressed by known answers."""
134-
rrset -= set(record for record in rrset if self._known_answers.suppresses(record))
135-
136128
def _suppress_mcasts_from_last_second(self, rrset: Set[DNSRecord]) -> None:
137129
"""Remove any records that were already sent in the last second."""
138130
rrset -= set(record for record in rrset if self._has_mcast_record_in_last_second(record))
@@ -168,67 +160,86 @@ def __init__(self, registry: ServiceRegistry, cache: DNSCache) -> None:
168160
self.registry = registry
169161
self.cache = cache
170162

171-
def _add_service_type_enumeration_query_answers(self, answer_set: _AnswerWithAdditionalsType) -> None:
163+
def _add_service_type_enumeration_query_answers(
164+
self, answer_set: _AnswerWithAdditionalsType, known_answers: DNSRRSet
165+
) -> None:
172166
"""Provide an answer to a service type enumeration query.
173167
174168
https://datatracker.ietf.org/doc/html/rfc6763#section-9
175169
"""
176170
for stype in self.registry.get_types():
177-
answer_set[
178-
DNSPointer(_SERVICE_TYPE_ENUMERATION_NAME, _TYPE_PTR, _CLASS_IN, _DNS_OTHER_TTL, stype)
179-
] = set()
171+
dns_pointer = DNSPointer(
172+
_SERVICE_TYPE_ENUMERATION_NAME, _TYPE_PTR, _CLASS_IN, _DNS_OTHER_TTL, stype
173+
)
174+
if not known_answers.suppresses(dns_pointer):
175+
answer_set[dns_pointer] = set()
180176

181-
def _add_pointer_answers(self, name: str, answer_set: _AnswerWithAdditionalsType) -> None:
177+
def _add_pointer_answers(
178+
self, name: str, answer_set: _AnswerWithAdditionalsType, known_answers: DNSRRSet
179+
) -> None:
182180
"""Answer PTR/ANY question."""
183181
for service in self.registry.get_infos_type(name):
184182
# Add recommended additional answers according to
185183
# https://tools.ietf.org/html/rfc6763#section-12.1.
186-
answer_set[service.dns_pointer()] = set(
187-
[service.dns_service(), service.dns_text(), *service.dns_addresses()]
188-
)
189-
190-
def _add_address_answers(self, name: str, answer_set: _AnswerWithAdditionalsType, type_: int) -> None:
184+
dns_pointer = service.dns_pointer()
185+
if not known_answers.suppresses(dns_pointer):
186+
answer_set[dns_pointer] = set(
187+
[service.dns_service(), service.dns_text(), *service.dns_addresses()]
188+
)
189+
190+
def _add_address_answers(
191+
self, name: str, answer_set: _AnswerWithAdditionalsType, known_answers: DNSRRSet, type_: int
192+
) -> None:
191193
"""Answer A/AAAA/ANY question."""
192194
for service in self.registry.get_infos_server(name):
193195
for dns_address in service.dns_addresses(version=_TYPE_TO_IP_VERSION[type_]):
194-
answer_set[dns_address] = set()
196+
if not known_answers.suppresses(dns_address):
197+
answer_set[dns_address] = set()
195198

196-
def _answer_question(self, question: DNSQuestion, answer_set: _AnswerWithAdditionalsType) -> None:
199+
def _answer_question(
200+
self, question: DNSQuestion, answer_set: _AnswerWithAdditionalsType, known_answers: DNSRRSet
201+
) -> None:
197202
type_ = question.type
198203

199204
if type_ in (_TYPE_PTR, _TYPE_ANY):
200-
self._add_pointer_answers(question.name, answer_set)
205+
self._add_pointer_answers(question.name, answer_set, known_answers)
201206

202207
if type_ in (_TYPE_A, _TYPE_AAAA, _TYPE_ANY):
203-
self._add_address_answers(question.name, answer_set, type_)
208+
self._add_address_answers(question.name, answer_set, known_answers, type_)
204209

205210
if type_ in (_TYPE_SRV, _TYPE_TXT, _TYPE_ANY):
206211
service = self.registry.get_info_name(question.name) # type: ignore
207212
if service is not None:
208213
if type_ in (_TYPE_SRV, _TYPE_ANY):
209214
# Add recommended additional answers according to
210215
# https://tools.ietf.org/html/rfc6763#section-12.2.
211-
answer_set[service.dns_service()] = set(service.dns_addresses())
216+
dns_service = service.dns_service()
217+
if not known_answers.suppresses(dns_service):
218+
answer_set[dns_service] = set(service.dns_addresses())
212219
if type_ in (_TYPE_TXT, _TYPE_ANY):
213-
answer_set[service.dns_text()] = set()
220+
dns_text = service.dns_text()
221+
if not known_answers.suppresses(dns_text):
222+
answer_set[dns_text] = set()
214223

215-
def _answer_any_question(self, question: DNSQuestion, answer_set: _AnswerWithAdditionalsType) -> None:
224+
def _answer_any_question(
225+
self, question: DNSQuestion, answer_set: _AnswerWithAdditionalsType, known_answers: DNSRRSet
226+
) -> None:
216227
if question.type == _TYPE_PTR and question.name.lower() == _SERVICE_TYPE_ENUMERATION_NAME:
217-
self._add_service_type_enumeration_query_answers(answer_set)
228+
self._add_service_type_enumeration_query_answers(answer_set, known_answers)
218229

219-
return self._answer_question(question, answer_set)
230+
return self._answer_question(question, answer_set, known_answers)
220231

221232
def response( # pylint: disable=unused-argument
222233
self, msgs: List[DNSIncoming], addr: Optional[str], port: int
223234
) -> Tuple[Optional[DNSOutgoing], Optional[DNSOutgoing]]:
224235
"""Deal with incoming query packets. Provides a response if possible."""
225236
ucast_source = port != _MDNS_PORT
226237
known_answers = DNSRRSet(itertools.chain(*[msg.answers for msg in msgs]))
227-
query_res = _QueryResponse(self.cache, msgs[0], ucast_source, known_answers)
238+
query_res = _QueryResponse(self.cache, msgs[0], ucast_source)
228239

229240
for question in itertools.chain(*[msg.questions for msg in msgs]):
230241
answer_set: _AnswerWithAdditionalsType = {}
231-
self._answer_any_question(question, answer_set)
242+
self._answer_any_question(question, answer_set, known_answers)
232243
if not ucast_source and question.unicast:
233244
query_res.add_qu_question_response(answer_set)
234245
else:

0 commit comments

Comments
 (0)