Skip to content

Commit

Permalink
feat: optimize incoming parser by reducing call stack (#1116)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Dec 18, 2022
1 parent bef9194 commit 11f3f0e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 19 deletions.
18 changes: 13 additions & 5 deletions src/zeroconf/_protocol/incoming.pxd
Expand Up @@ -42,10 +42,10 @@ cdef class DNSIncoming:
cdef public object questions
cdef object _answers
cdef public object id
cdef public object num_questions
cdef public object num_answers
cdef public object num_authorities
cdef public object num_additionals
cdef public cython.uint num_questions
cdef public cython.uint num_answers
cdef public cython.uint num_authorities
cdef public cython.uint num_additionals
cdef public object valid
cdef public object now
cdef public object scope_id
Expand All @@ -61,6 +61,14 @@ cdef class DNSIncoming:

cdef _read_header(self)

cdef _initial_parse(self)

@cython.locals(
end=cython.uint,
length=cython.uint
)
cdef _read_others(self)

cdef _read_questions(self)

@cython.locals(
Expand All @@ -73,7 +81,7 @@ cdef class DNSIncoming:
@cython.locals(
name_start=cython.uint
)
cdef _read_record(self, object domain, unsigned int type_, object class_, object ttl, object length)
cdef _read_record(self, object domain, unsigned int type_, object class_, object ttl, unsigned int length)

cdef _read_bitmap(self, unsigned int end)

Expand Down
32 changes: 18 additions & 14 deletions src/zeroconf/_protocol/incoming.py
Expand Up @@ -116,7 +116,15 @@ def __init__(
self.now = now or current_time_millis()
self.source = source
self.scope_id = scope_id
self._parse_data(self._initial_parse)
try:
self._initial_parse()
except DECODE_EXCEPTIONS:
self._log_exception_debug(
'Received invalid packet from %s at offset %d while unpacking %r',
self.source,
self.offset,
self.data,
)

def is_query(self) -> bool:
"""Returns true if this is a query."""
Expand All @@ -139,18 +147,6 @@ def _initial_parse(self) -> None:
self._read_others()
self.valid = True

def _parse_data(self, parser_call: Callable) -> None:
"""Parse part of the packet and catch exceptions."""
try:
parser_call()
except DECODE_EXCEPTIONS:
self._log_exception_debug(
'Received invalid packet from %s at offset %d while unpacking %r',
self.source,
self.offset,
self.data,
)

@classmethod
def _log_exception_debug(cls, *logger_data: Any) -> None:
log_exc_info = False
Expand All @@ -166,7 +162,15 @@ def _log_exception_debug(cls, *logger_data: Any) -> None:
def answers(self) -> List[DNSRecord]:
"""Answers in the packet."""
if not self._did_read_others:
self._parse_data(self._read_others)
try:
self._read_others()
except DECODE_EXCEPTIONS:
self._log_exception_debug(
'Received invalid packet from %s at offset %d while unpacking %r',
self.source,
self.offset,
self.data,
)
return self._answers

def __repr__(self) -> str:
Expand Down

0 comments on commit 11f3f0e

Please sign in to comment.