
    uiY#                     d    S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSr	Sr
SrSr " S S5      rg)z*Help for building DNS wire format messages    N         c                      \ rS rSrSrSS jrS rS r\R                  S 5       r
\R                  R                  4S jrS	 rS
 rSS jr\R$                  R&                  4S jr\R$                  R&                  4S jrS rS rS rSrg)Renderer$   a  Helper class for building DNS wire-format messages.

Most applications can use the higher-level L{dns.message.Message}
class and its to_wire() method to generate wire-format messages.
This class is for those applications which need finer control
over the generation of messages.

Typical use::

    r = dns.renderer.Renderer(id=1, flags=0x80, max_size=512)
    r.add_question(qname, qtype, qclass)
    r.add_rrset(dns.renderer.ANSWER, rrset_1)
    r.add_rrset(dns.renderer.ANSWER, rrset_2)
    r.add_rrset(dns.renderer.AUTHORITY, ns_rrset)
    r.add_edns(0, 0, 4096)
    r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_1)
    r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_2)
    r.write_header()
    r.add_tsig(keyname, secret, 300, 1, 0, '', request_mac)
    wire = r.get_wire()

output, an io.BytesIO, where rendering is written

id: the message id

flags: the message flags

max_size: the maximum size of the message

origin: the origin to use when rendering relative names

compress: the compression table

section: an int, the section currently being rendered

counts: list of the number of RRs in each section

mac: the MAC of the rendered message (if TSIG was used)
Nc                 "   [         R                  " 5       U l        Uc  [        R                  " SS5      U l        OXl        X l        X0l        X@l        0 U l	        [        U l        / SQU l        U R                  R                  S5        SU l        g)zInitialize a new renderer.Nr     )r   r   r   r   s                )ioBytesIOoutputrandomrandintidflagsmax_sizeorigincompressQUESTIONsectioncountswritemac)selfr   r   r   r   s        C/home/kodi/.kodi/addons/script.module.dnspython/lib/dns/renderer.py__init__Renderer.__init__M   sj     jjl:nnQ.DGG
 ",'    c                    U R                   R                  U5        U R                   R                  5         / nU R                  R	                  5        H  u  p4XA:  d  M  UR                  U5        M     U H  nU R                  U	 M     g)zTruncate the output buffer at offset *where*, and remove any
compression table entries that pointed beyond the truncation
point.
N)r   seektruncater   itemsappend)r   wherekeys_to_deletekvs        r   	_rollbackRenderer._rollback^   so     	MM'')DAz%%a( *  Aa   r   c                     U R                   U:w  a1  U R                   U:  a  [        R                  R                  eXl         gg)zSet the renderer's current section.

Sections must be rendered order: QUESTION, ANSWER, AUTHORITY,
ADDITIONAL.  Sections may be empty.

Raises dns.exception.FormError if an attempt was made to set
a section value less than the current section.
N)r   dns	exception	FormError)r   r   s     r   _set_sectionRenderer._set_sectionm   s6     <<7"||g%mm---"L #r   c              #      #    U R                   R                  5       nUv   U R                   R                  5       U R                  :  a+  U R                  U5        [        R
                  R                  eg 7fN)r   tellr   r)   r,   r-   TooBig)r   starts     r   _track_sizeRenderer._track_size|   sV       ";;-NN5!--&&& .s   A3A5c                 z   U R                  [        5        U R                  5          UR                  U R                  U R
                  U R                  5        U R                  R                  [        R                  " SX#5      5        SSS5        U R                  [        ==   S-  ss'   g! , (       d  f       N*= f)zAdd a question to the message.z!HHNr   )r/   r   r6   to_wirer   r   r   r   structpackr   )r   qnamerdtyperdclasss       r   add_questionRenderer.add_question   s{     	(#MM$++t}}dkkBKKfkk%AB   	H"  s   A"B,,
B:c                    U R                  U5        U R                  5          UR                  " U R                  U R                  U R
                  40 UD6nSSS5        U R                  U==   W-  ss'   g! , (       d  f       N&= f)zrAdd the rrset to the specified section.

Any keyword arguments are passed on to the rdataset's to_wire()
routine.
Nr/   r6   r9   r   r   r   r   )r   r   rrsetkwns        r   	add_rrsetRenderer.add_rrset   sc     	'"dkk4==$++LLA  G!     4A66
Bc                    U R                  U5        U R                  5          UR                  " X R                  U R                  U R
                  40 UD6nSSS5        U R                  U==   W-  ss'   g! , (       d  f       N&= f)zAdd the rdataset to the specified section, using the specified
name as the owner name.

Any keyword arguments are passed on to the rdataset's to_wire()
routine.
NrB   )r   r   namerdatasetrD   rE   s         r   add_rdatasetRenderer.add_rdataset   sl     	'"  {{DMM4;; '#%'A   	G!  rH   c                     US-  nX!S-  -  n[         R                  R                  R                  X#U5      nU R	                  [
        U5        g)z&Add an EDNS OPT record to the message.l   ~    N)r,   messageMessage	_make_optrF   
ADDITIONAL)r   edns	ednsflagspayloadoptionsopts         r   add_ednsRenderer.add_edns   sD     	Z	bj!	kk!!++IHz3'r   c	           
         U R                   R                  5       n	[        U[        R                  R
                  5      (       a  Un
O [        R                  R                  XU5      n
[        R                  R                  R                  XSUSXEU5      n[        R                  R                  XUS   [        [        R                  " 5       5      U5      u  pU R                  X5        g)z$Add a TSIG signature to the message.r   r   Nr   getvalue
isinstancer,   tsigKeyrP   rQ   
_make_tsigsigninttime_write_tsig)r   keynamesecretfudger   
tsig_error
other_datarequest_mac	algorithmskeyr_   _s                r   add_tsigRenderer.add_tsig   s     KK  "fchhll++C((,,w	:C{{""--g!U.12:OHHMM!$q'3tyy{3C"-/	'r   c
           
         U R                   R                  5       n
[        U[        R                  R
                  5      (       a  UnO [        R                  R                  X#U	5      n[        R                  R                  R                  X)SUSXVU5      n[        R                  R                  XUS   [        [        R                  " 5       5      XS5      u  pU R                  X5        U$ )aQ  Add a TSIG signature to the message. Unlike add_tsig(), this can be
used for a series of consecutive DNS envelopes, e.g. for a zone
transfer over TCP [RFC2845, 4.4].

For the first message in the sequence, give ctx=None. For each
subsequent message, give the ctx that was returned from the
add_multi_tsig() call for the previous message.r   r   Tr\   )r   ctxrf   rg   rh   r   ri   rj   rk   rl   rm   rn   r_   s                r   add_multi_tsigRenderer.add_multi_tsig   s     KK  "fchhll++C((,,w	:C{{""--g!U.12:OhhmmADGS5E$/d<'
r   c           
      ,   U R                  [        5        U R                  5          UR                  U R                  U R
                  U R                  5        U R                  R                  [        R                  " S[        R                  R                  [        R                  R                  SS5      5        U R                  R                  5       nUR                  U R                  5        S S S 5        U R                  R                  5       nU R                  R!                  WS-
  5        U R                  R                  [        R                  " SXC-
  5      5        U R"                  [        ==   S-  ss'   U R                  R!                  S5        U R                  R                  [        R                  " SU R"                  [           5      5        U R                  R!                  S[$        R&                  5        g ! , (       d  f       GN= f)Nz!HHIHr   r   z!Hr   
   )r/   rS   r6   r9   r   r   r   r   r:   r;   r,   	rdatatypeTSIG
rdataclassANYr3   r!   r   r   SEEK_END)r   r_   rf   rdata_startafters        r   re   Renderer._write_tsig   sT   *%OODKKDKKfkk'3==3E3E*-..*<*<aD E++**,KLL%     "q)&++dE,?@AJ1$&++dDKK
,CDEBKK(  s   C
H
Hc                    U R                   R                  S5        U R                   R                  [        R                  " SU R
                  U R                  U R                  S   U R                  S   U R                  S   U R                  S   5      5        U R                   R                  S[        R                  5        g)zWrite the DNS message header.

Writing the DNS message header is done after all sections
have been rendered, but before the optional TSIG signature
is added.
r   z!HHHHHHr   r   r   N)
r   r!   r   r:   r;   r   r   r   r   r|   r   s    r   write_headerRenderer.write_header   s     	&++i$**&*kk!ndkk!n&*kk!ndkk!nF 	G 	BKK(r   c                 6    U R                   R                  5       $ )zReturn the wire format message.)r   r]   r   s    r   get_wireRenderer.get_wire   s     {{##%%r   )	r   r   r   r   r   r   r   r   r   )Nr   r
   Nr2   )__name__
__module____qualname____firstlineno____doc__r   r)   r/   
contextlibcontextmanagerr6   r,   rz   INr?   rF   rL   rY   r_   default_algorithmrp   rt   re   r   r   __static_attributes__ r   r   r   r   $   s    &P"!# ' ' 36..2C2C #
""( ),(B(B($ "%!;!;0)")&r   r   )r   r   r   r:   r   rd   dns.exceptionr,   dns.tsigr   ANSWER	AUTHORITYrS   r   r   r   r   <module>r      sA   $ 1  	      	
	
V& V&r   