Skip to content

Commit f4665fc

Browse files
authored
Reduce dns protocol attributes and add slots (#987)
1 parent 4398538 commit f4665fc

1 file changed

Lines changed: 42 additions & 11 deletions

File tree

zeroconf/_protocol.py

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,30 @@ class DNSIncoming(DNSMessage, QuietLogger):
8787

8888
"""Object representation of an incoming DNS packet"""
8989

90+
__slots__ = (
91+
'offset',
92+
'data',
93+
'data_len',
94+
'name_cache',
95+
'questions',
96+
'_answers',
97+
'id',
98+
'num_questions',
99+
'num_answers',
100+
'num_authorities',
101+
'num_additionals',
102+
'valid',
103+
'now',
104+
'scope_id',
105+
)
106+
90107
def __init__(self, data: bytes, scope_id: Optional[int] = None, now: Optional[float] = None) -> None:
91108
"""Constructor from string holding bytes of packet"""
92109
super().__init__(0)
93110
self.offset = 0
94111
self.data = data
95112
self.data_len = len(data)
96113
self.name_cache: Dict[int, List[str]] = {}
97-
self.seen_pointers: Set[int] = set()
98114
self.questions: List[DNSQuestion] = []
99115
self._answers: List[DNSRecord] = []
100116
self.id = 0
@@ -162,10 +178,9 @@ def read_header(self) -> None:
162178

163179
def read_questions(self) -> None:
164180
"""Reads questions section of packet"""
165-
for _ in range(self.num_questions):
166-
name = self.read_name()
167-
type_, class_ = self.unpack(b'!HH', 4)
168-
self.questions.append(DNSQuestion(name, type_, class_))
181+
self.questions = [
182+
DNSQuestion(self.read_name(), *self.unpack(b'!HH', 4)) for _ in range(self.num_questions)
183+
]
169184

170185
def read_character_string(self) -> bytes:
171186
"""Reads a character string from the packet"""
@@ -278,14 +293,14 @@ def read_bitmap(self, end: int) -> List[int]:
278293
def read_name(self) -> str:
279294
"""Reads a domain name from the packet."""
280295
labels: List[str] = []
281-
self.seen_pointers.clear()
282-
self.offset = self._decode_labels_at_offset(self.offset, labels)
296+
seen_pointers: Set[int] = set()
297+
self.offset = self._decode_labels_at_offset(self.offset, labels, seen_pointers)
283298
name = ".".join(labels) + "."
284299
if len(name) > MAX_NAME_LENGTH:
285300
raise IncomingDecodeError(f"DNS name {name} exceeds maximum length of {MAX_NAME_LENGTH}")
286301
return name
287302

288-
def _decode_labels_at_offset(self, off: int, labels: List[str]) -> int:
303+
def _decode_labels_at_offset(self, off: int, labels: List[str], seen_pointers: Set[int]) -> int:
289304
# This is a tight loop that is called frequently, small optimizations can make a difference.
290305
while off < self.data_len:
291306
length = self.data[off]
@@ -307,12 +322,12 @@ def _decode_labels_at_offset(self, off: int, labels: List[str]) -> int:
307322
raise IncomingDecodeError(f"DNS compression pointer at {off} points to {link} beyond packet")
308323
if link == off:
309324
raise IncomingDecodeError(f"DNS compression pointer at {off} points to itself")
310-
if link in self.seen_pointers:
325+
if link in seen_pointers:
311326
raise IncomingDecodeError(f"DNS compression pointer at {off} was seen again")
312-
self.seen_pointers.add(link)
327+
seen_pointers.add(link)
313328
linked_labels = self.name_cache.get(link, [])
314329
if not linked_labels:
315-
self._decode_labels_at_offset(link, linked_labels)
330+
self._decode_labels_at_offset(link, linked_labels, seen_pointers)
316331
self.name_cache[link] = linked_labels
317332
labels.extend(linked_labels)
318333
if len(labels) > MAX_DNS_LABELS:
@@ -326,6 +341,22 @@ class DNSOutgoing(DNSMessage):
326341

327342
"""Object representation of an outgoing packet"""
328343

344+
__slots__ = (
345+
'finished',
346+
'id',
347+
'multicast',
348+
'packets_data',
349+
'names',
350+
'data',
351+
'size',
352+
'allow_long',
353+
'state',
354+
'questions',
355+
'answers',
356+
'authorities',
357+
'additionals',
358+
)
359+
329360
def __init__(self, flags: int, multicast: bool = True, id_: int = 0) -> None:
330361
super().__init__(flags)
331362
self.finished = False

0 commit comments

Comments
 (0)