@@ -430,13 +430,13 @@ def add_question_or_all_cache(
430430 for cached_entry in cached_entries :
431431 self .add_answer_at_time (cached_entry , now )
432432
433- def _pack (self , format_ : Union [bytes , str ], value : Any ) -> None :
433+ def _pack (self , format_ : Union [bytes , str ], size : int , value : Any ) -> None :
434434 self .data .append (struct .pack (format_ , value ))
435- self .size += struct . calcsize ( format_ )
435+ self .size += size
436436
437437 def _write_byte (self , value : int ) -> None :
438438 """Writes a single byte to the packet"""
439- self ._pack (b'!c' , bytes ((value ,)))
439+ self ._pack (b'!c' , 1 , bytes ((value ,)))
440440
441441 def _insert_short_at_start (self , value : int ) -> None :
442442 """Inserts an unsigned short at the start of the packet"""
@@ -448,11 +448,11 @@ def _replace_short(self, index: int, value: int) -> None:
448448
449449 def write_short (self , value : int ) -> None :
450450 """Writes an unsigned short to the packet"""
451- self ._pack (b'!H' , value )
451+ self ._pack (b'!H' , 2 , value )
452452
453453 def _write_int (self , value : Union [float , int ]) -> None :
454454 """Writes an unsigned integer to the packet"""
455- self ._pack (b'!I' , int (value ))
455+ self ._pack (b'!I' , 4 , int (value ))
456456
457457 def write_string (self , value : bytes ) -> None :
458458 """Writes a string to the packet"""
@@ -491,38 +491,29 @@ def write_name(self, name: str) -> None:
491491 """
492492
493493 # split name into each label
494- parts = name .split ('.' )
495- if not parts [- 1 ]:
496- parts .pop ()
497-
498- # construct each suffix
499- name_suffices = ['.' .join (parts [i :]) for i in range (len (parts ))]
500-
501- # look for an existing name or suffix
502- for count , sub_name in enumerate (name_suffices ):
503- if sub_name in self .names :
504- break
505- else :
506- count = len (name_suffices )
507-
508- # note the new names we are saving into the packet
509- name_length = len (name .encode ('utf-8' ))
510- for suffix in name_suffices [:count ]:
511- self .names [suffix ] = self .size + name_length - len (suffix .encode ('utf-8' )) - 1
512-
513- # write the new names out.
514- for part in parts [:count ]:
515- self ._write_utf (part )
516-
517- # if we wrote part of the name, create a pointer to the rest
518- if count != len (name_suffices ):
519- # Found substring in packet, create pointer
520- index = self .names [name_suffices [count ]]
521- self ._write_byte ((index >> 8 ) | 0xC0 )
522- self ._write_byte (index & 0xFF )
523- else :
524- # this is the end of a name
525- self ._write_byte (0 )
494+ name_length = None
495+ if name .endswith ('.' ):
496+ name = name [: len (name ) - 1 ]
497+ labels = name .split ('.' )
498+ # Write each new label or a pointer to the existing
499+ # on in the packet
500+ start_size = self .size
501+ for count in range (len (labels )):
502+ label = name if count == 0 else '.' .join (labels [count :])
503+ index = self .names .get (label )
504+ if index :
505+ # If part of the name already exists in the packet,
506+ # create a pointer to it
507+ self ._write_byte ((index >> 8 ) | 0xC0 )
508+ self ._write_byte (index & 0xFF )
509+ return
510+ if name_length is None :
511+ name_length = len (name .encode ('utf-8' ))
512+ self .names [label ] = start_size + name_length - len (label .encode ('utf-8' ))
513+ self ._write_utf (labels [count ])
514+
515+ # this is the end of a name
516+ self ._write_byte (0 )
526517
527518 def _write_question (self , question : DNSQuestion ) -> bool :
528519 """Writes a question to the packet"""
0 commit comments