feat: speed up decoding incoming packets (#1256) · python-zeroconf/python-zeroconf@ac081cf
@@ -89,6 +89,7 @@ class DNSIncoming:
8989'num_additionals',
9090'valid',
9191'now',
92+'_now_float',
9293'scope_id',
9394'source',
9495 )
@@ -116,6 +117,7 @@ def __init__(
116117self.valid = False
117118self._did_read_others = False
118119self.now = now or current_time_millis()
120+self._now_float = self.now
119121self.source = source
120122self.scope_id = scope_id
121123try:
@@ -226,11 +228,13 @@ def _read_questions(self) -> None:
226228question = DNSQuestion(name, type_, class_)
227229self.questions.append(question)
228230229-def _read_character_string(self) -> bytes:
231+def _read_character_string(self) -> str:
230232"""Reads a character string from the packet"""
231233length = self.data[self.offset]
232234self.offset += 1
233-return self._read_string(length)
235+info = self.data[self.offset : self.offset + length].decode('utf-8', 'replace')
236+self.offset += length
237+return info
234238235239def _read_string(self, length: _int) -> bytes:
236240"""Reads a string of a given length from the packet"""
@@ -273,7 +277,7 @@ def _read_record(
273277"""Read known records types and skip unknown ones."""
274278if type_ == _TYPE_A:
275279dns_address = DNSAddress(domain, type_, class_, ttl, self._read_string(4))
276-dns_address.created = self.now
280+dns_address.created = self._now_float
277281return dns_address
278282if type_ in (_TYPE_CNAME, _TYPE_PTR):
279283return DNSPointer(domain, type_, class_, ttl, self._read_name(), self.now)
@@ -299,13 +303,13 @@ def _read_record(
299303type_,
300304class_,
301305ttl,
302-self._read_character_string().decode('utf-8', 'replace'),
303-self._read_character_string().decode('utf-8', 'replace'),
306+self._read_character_string(),
307+self._read_character_string(),
304308self.now,
305309 )
306310if type_ == _TYPE_AAAA:
307311dns_address = DNSAddress(domain, type_, class_, ttl, self._read_string(16))
308-dns_address.created = self.now
312+dns_address.created = self._now_float
309313dns_address.scope_id = self.scope_id
310314return dns_address
311315if type_ == _TYPE_NSEC:
@@ -377,7 +381,7 @@ def _decode_labels_at_offset(self, off: _int, labels: List[str], seen_pointers:
377381# We have a DNS compression pointer
378382link_data = self.data[off + 1]
379383link = (length & 0x3F) * 256 + link_data
380-lint_int = int(link)
384+link_py_int = link
381385if link > self._data_len:
382386raise IncomingDecodeError(
383387f"DNS compression pointer at {off} points to {link} beyond packet from {self.source}"
@@ -386,16 +390,16 @@ def _decode_labels_at_offset(self, off: _int, labels: List[str], seen_pointers:
386390raise IncomingDecodeError(
387391f"DNS compression pointer at {off} points to itself from {self.source}"
388392 )
389-if lint_int in seen_pointers:
393+if link_py_int in seen_pointers:
390394raise IncomingDecodeError(
391395f"DNS compression pointer at {off} was seen again from {self.source}"
392396 )
393-linked_labels = self.name_cache.get(lint_int)
397+linked_labels = self.name_cache.get(link_py_int)
394398if not linked_labels:
395399linked_labels = []
396-seen_pointers.add(lint_int)
400+seen_pointers.add(link_py_int)
397401self._decode_labels_at_offset(link, linked_labels, seen_pointers)
398-self.name_cache[lint_int] = linked_labels
402+self.name_cache[link_py_int] = linked_labels
399403labels.extend(linked_labels)
400404if len(labels) > MAX_DNS_LABELS:
401405raise IncomingDecodeError(