Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat: reduce denial of service protection overhead #1157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 7, 2023
Merged
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
35 changes: 15 additions & 20 deletions 35 src/zeroconf/_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,6 @@ def _add_answers_additionals(out: DNSOutgoing, answers: _AnswerWithAdditionalsTy
sending.add(additional)


def sanitize_incoming_record(record: DNSRecord) -> None:
"""Protect zeroconf from records that can cause denial of service.

We enforce a minimum TTL for PTR records to avoid
ServiceBrowsers generating excessive queries refresh queries.
Apple uses a 15s minimum TTL, however we do not have the same
level of rate limit and safe guards so we use 1/4 of the recommended value.
"""
if record.ttl and record.ttl < _DNS_PTR_MIN_TTL and isinstance(record, DNSPointer):
log.debug(
"Increasing effective ttl of %s to minimum of %s to protect against excessive refreshes.",
record,
_DNS_PTR_MIN_TTL,
)
record.set_created_ttl(record.created, _DNS_PTR_MIN_TTL)


class _QueryResponse:
"""A pair for unicast and multicast DNSOutgoing responses."""

Expand Down Expand Up @@ -420,14 +403,26 @@ def async_updates_from_response(self, msg: DNSIncoming) -> None:
threadsafe.
"""
updates: List[RecordUpdate] = []
address_adds: List[DNSAddress] = []
address_adds: List[DNSRecord] = []
other_adds: List[DNSRecord] = []
removes: Set[DNSRecord] = set()
now = msg.now
unique_types: Set[Tuple[str, int, int]] = set()

for record in msg.answers:
sanitize_incoming_record(record)
# Protect zeroconf from records that can cause denial of service.
#
# We enforce a minimum TTL for PTR records to avoid
# ServiceBrowsers generating excessive queries refresh queries.
# Apple uses a 15s minimum TTL, however we do not have the same
# level of rate limit and safe guards so we use 1/4 of the recommended value.
if record.ttl and record.type == _TYPE_PTR and record.ttl < _DNS_PTR_MIN_TTL:
log.debug(
"Increasing effective ttl of %s to minimum of %s to protect against excessive refreshes.",
record,
_DNS_PTR_MIN_TTL,
)
record.set_created_ttl(record.created, _DNS_PTR_MIN_TTL)

if record.unique: # https://tools.ietf.org/html/rfc6762#section-10.2
unique_types.add((record.name, record.type, record.class_))
Expand All @@ -437,7 +432,7 @@ def async_updates_from_response(self, msg: DNSIncoming) -> None:
if maybe_entry is not None:
maybe_entry.reset_ttl(record)
else:
if isinstance(record, DNSAddress):
if record.type in _ADDRESS_RECORD_TYPES:
address_adds.append(record)
else:
other_adds.append(record)
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.