@@ -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