3 bW.@shdZddlmZddlZddlZddlZddlZddlZddl m Z dZ dZ dZ dZGdd d eZdS) z*Help for building DNS wire format messages)BytesION)longc@steZdZdZdddZddZd d Zejj fd d Z d dZ ddZ dddZ ejjfddZddZddZdS)RendereraiHelper 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() @ivar output: where rendering is written @type output: BytesIO object @ivar id: the message id @type id: int @ivar flags: the message flags @type flags: int @ivar max_size: the maximum size of the message @type max_size: int @ivar origin: the origin to use when rendering relative names @type origin: dns.name.Name object @ivar compress: the compression table @type compress: dict @ivar section: the section currently being rendered @type section: int (dns.renderer.QUESTION, dns.renderer.ANSWER, dns.renderer.AUTHORITY, or dns.renderer.ADDITIONAL) @ivar counts: list of the number of RRs in each section @type counts: int list of length 4 @ivar mac: the MAC of the rendered message (if TSIG was used) @type mac: string NrcCsht|_|dkr tjdd|_n||_||_||_||_i|_t |_ ddddg|_ |jj dd|_ dS)aInitialize a new renderer. @param id: the message id @type id: int @param flags: the DNS message flags @type flags: int @param max_size: the maximum message size; the default is 65535. If rendering results in a message greater than I{max_size}, then L{dns.exception.TooBig} will be raised. @type max_size: int @param origin: the origin to use when rendering relative names @type origin: dns.name.Name or None. Nri s )routputrandomZrandintidflagsmax_sizeorigincompressQUESTIONsectioncountswritemac)selfrrrrr/usr/lib/python3.6/renderer.py__init__Ns zRenderer.__init__cCs^|jj||jjg}x(|jjD]\}}||kr&|j|q&Wx|D] }|j|=qJWdS)zTruncate the output buffer at offset I{where}, and remove any compression table entries that pointed beyond the truncation point. @param where: the offset @type where: int N)r seektruncateritemsappend)rwhereZkeys_to_deletekvrrr _rollbackks   zRenderer._rollbackcCs&|j|kr"|j|krtjj||_dS)aZSet the renderer's current section. Sections must be rendered order: QUESTION, ANSWER, AUTHORITY, ADDITIONAL. Sections may be empty. @param section: the section @type section: int @raises dns.exception.FormError: an attempt was made to set a section value less than the current section. N)rdns exceptionZ FormError)rrrrr _set_section}s  zRenderer._set_sectioncCsz|jt|jj}|j|j|j|j|jjtj d|||jj}||j krd|j |t j j|jtd7<dS)aAdd a question to the message. @param qname: the question name @type qname: dns.name.Name @param rdtype: the question rdata type @type rdtype: int @param rdclass: the question rdata class @type rdclass: int z!HHrN)r&rr tellto_wirerrrstructpackrr#r$r%TooBigr)rZqnameZrdtypeZrdclassbeforeafterrrr add_questions     zRenderer.add_questioncKsh|j||jj}|j|j|j|jf|}|jj}||jkrR|j|tj j |j ||7<dS)aAdd the rrset to the specified section. Any keyword arguments are passed on to the rdataset's to_wire() routine. @param section: the section @type section: int @param rrset: the rrset @type rrset: dns.rrset.RRset object N) r&r r'r(rrrr#r$r%r+r)rrZrrsetkwr,nr-rrr add_rrsets     zRenderer.add_rrsetcKsj|j||jj}|j||j|j|jf|}|jj}||jkrT|j|tj j |j ||7<dS)aAdd 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. @param section: the section @type section: int @param name: the owner name @type name: dns.name.Name object @param rdataset: the rdataset @type rdataset: dns.rdataset.Rdataset object N) r&r r'r(rrrr#r$r%r+r)rrnameZrdatasetr/r,r0r-rrr add_rdatasets     zRenderer.add_rdatasetc Csf|tdM}||d>O}|jt|jj}|jjtjddtj j ||d|dk r(|jj}x|D]z}tjd|j d}|jj||jj} |j |j|jj} |jj | dtjd| | }|jj||jj ddqfW|jj} |jj |dtjd| |}|jj||jj dd|jj} | |jkrP|j|tjj|jtd 7<dS) aAdd an EDNS OPT record to the message. @param edns: The EDNS level to use. @type edns: int @param ednsflags: EDNS flag values. @type ednsflags: int @param payload: The EDNS sender's payload field, which is the maximum size of UDP datagram the sender can handle. @type payload: int @param options: The EDNS options list @type options: list of dns.edns.Option instances @see: RFC 2671 l~z!BHHIHrNz!HHrz!Hr)rr& ADDITIONALr r'rr)r*r$ rdatatypeOPTZotyper(rrr#r%r+r) rZednsZ ednsflagsZpayloadZoptionsr,ZlstartoptZstuffstartendZlendr-rrradd_ednss8                  zRenderer.add_ednsc  Cs2|jt|jj} |jj} tjj| ||tt j ||||||d \} |_ } |j |j|j |j |jjtjdtjjtjjdd|jj} |jj| |jj}||jkr|j| tjj|jj| d|jjtjd|| |jtd7<|jjd|jjtjd|jt|jjdddS) aAdd a TSIG signature to the message. @param keyname: the TSIG key name @type keyname: dns.name.Name object @param secret: the secret to use @type secret: string @param fudge: TSIG time fudge @type fudge: int @param id: the message id to encode in the tsig signature @type id: int @param tsig_error: TSIG error code; default is 0. @type tsig_error: int @param other_data: TSIG other data. @type other_data: string @param request_mac: This message is a response to the request which had the specified MAC. @type request_mac: string @param algorithm: the TSIG algorithm to use @type algorithm: dns.name.Name object ) algorithmz!HHIHrrz!Hr N)r&r5r r'getvaluer$tsigZsigninttimerr(rrrr)r*r6ZTSIG rdataclassANYrr#r%r+rr)rZkeynameZsecretZfudgerZ tsig_errorZ other_dataZ request_macr<r,sZ tsig_rdataZctxZ rdata_startr-rrradd_tsigs8          zRenderer.add_tsigc CsX|jjd|jjtjd|j|j|jd|jd|jd|jd|jjdddS)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. rz!HHHHHHrrrN)r rrr)r*rrr)rrrr write_header5s  zRenderer.write_headercCs |jjS)z@Return the wire format message. @rtype: string )r r>)rrrrget_wireCszRenderer.get_wire)NrrN)N)__name__ __module__ __qualname____doc__rr#r&r$rBINr.r1r3r;r?Zdefault_algorithmrErFrGrrrrr"s*  04r)rKiorr)r rAZ dns.exceptionr$Zdns.tsigZ_compatrrZANSWERZ AUTHORITYr5objectrrrrrs