3 @Wy @sdZddlmZddlmZddlZddlZddlZddl Zddl Zddl Zddl Zddl ZddlZddlZddlZddlZddlZddlZddlZddlZddlmZmZmZGdddejjZGd d d ejjZGd d d ejjZGd ddejjZ GdddejjZ!GdddejjZ"Gddde#Z$Gddde#Z%d(ddZ&Gddde#Z'ddZ(d d!Z)ej*j+ddddddfd"d#Z,d)d&d'Z-dS)*z DNS Messages)absolute_import)StringION)longxrange string_typesc@seZdZdZdS) ShortHeaderz2The DNS packet passed to from_wire() is too short.N)__name__ __module__ __qualname____doc__r r /usr/lib/python3.6/message.pyr*src@seZdZdZdS) TrailingJunkzEThe DNS packet passed to from_wire() has extra junk at the end of it.N)r r r r r r r rr/src@seZdZdZdS)UnknownHeaderFieldzVThe header field name was not recognized when converting from text into a message.N)r r r r r r r rr4src@seZdZdZdS)BadEDNSzVOPT record occurred somewhere other than the start of the additional data section.N)r r r r r r r rr:src@seZdZdZdS)BadTSIGzWA TSIG record occurred somewhere other than the end of the additional data section.N)r r r r r r r rr@src@seZdZdZdS)UnknownTSIGKeyz(A TSIG with an unknown key was received.N)r r r r r r r rrFsrc@seZdZdZd-ddZddZddZd.d d Zd d ZddZ ddZ ddZ e j jdddfddZe j jdddfddZd/ddZddddde jjfddZd0d!d"Zd1d#d$Zd%d&Zd'd(Zd)d*Zd+d,ZdS)2Messagea, A DNS message. @ivar id: The query id; the default is a randomly chosen id. @type id: int @ivar flags: The DNS flags of the message. @see: RFC 1035 for an explanation of these flags. @type flags: int @ivar question: The question section. @type question: list of dns.rrset.RRset objects @ivar answer: The answer section. @type answer: list of dns.rrset.RRset objects @ivar authority: The authority section. @type authority: list of dns.rrset.RRset objects @ivar additional: The additional data section. @type additional: list of dns.rrset.RRset objects @ivar edns: The EDNS level to use. The default is -1, no Edns. @type edns: int @ivar ednsflags: The EDNS flags @type ednsflags: long @ivar payload: The EDNS payload size. The default is 0. @type payload: int @ivar options: The EDNS options @type options: list of dns.edns.Option objects @ivar request_payload: The associated request's EDNS payload size. @type request_payload: int @ivar keyring: The TSIG keyring to use. The default is None. @type keyring: dict @ivar keyname: The TSIG keyname to use. The default is None. @type keyname: dns.name.Name object @ivar keyalgorithm: The TSIG algorithm to use; defaults to dns.tsig.default_algorithm. Constants for TSIG algorithms are defined in dns.tsig, and the currently implemented algorithms are HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and HMAC_SHA512. @type keyalgorithm: string @ivar request_mac: The TSIG MAC of the request message associated with this message; used when validating TSIG signatures. @see: RFC 2845 for more information on TSIG fields. @type request_mac: string @ivar fudge: TSIG time fudge; default is 300 seconds. @type fudge: int @ivar original_id: TSIG original id; defaults to the message's id @type original_id: int @ivar tsig_error: TSIG error code; default is 0. @type tsig_error: int @ivar other_data: TSIG other data. @type other_data: string @ivar mac: The TSIG MAC for this message. @type mac: string @ivar xfr: Is the message being used to contain the results of a DNS zone transfer? The default is False. @type xfr: bool @ivar origin: The origin of the zone in messages which are used for zone transfers or for DNS dynamic updates. The default is None. @type origin: dns.name.Name object @ivar tsig_ctx: The TSIG signature context associated with this message. The default is None. @type tsig_ctx: hmac.HMAC object @ivar had_tsig: Did the message decoded from wire format have a TSIG signature? @type had_tsig: bool @ivar multi: Is this message part of a multi-message sequence? The default is false. This variable is used when validating TSIG signatures on messages which are part of a zone transfer. @type multi: bool @ivar first: Is this message standalone, or the first of a multi message sequence? This variable is used when validating TSIG signatures on messages which are part of a zone transfer. @type first: bool @ivar index: An index of rrsets in the message. The index key is (section, name, rdclass, rdtype, covers, deleting). Indexing can be disabled by setting the index to None. @type index: dict NcCs|dkrtjj|_n||_d|_g|_g|_g|_g|_d|_ d|_ d|_ g|_ d|_ d|_d|_tjj|_d|_d|_d|_d|_|j|_d|_d|_d|_d|_d|_d|_d|_i|_dS)Nrri,FT) dnsZentropyZ random_16idflagsquestionanswer authority additionaledns ednsflagspayloadoptionsrequest_payloadkeyringkeynametsigdefault_algorithm keyalgorithm request_mac other_data tsig_errorfudge original_idmacxfrorigintsig_ctxhad_tsigmultifirstindex)selfrr r r__init__s: zMessage.__init__cCsdt|jdS)Nz)reprr)r5r r r__repr__szMessage.__repr__cCs|jS)N)to_text)r5r r r__str__szMessage.__str__TcKst}|jd|j|jdtjjtjj|jtjj|j|j }|jdtjj||jdtjj|j|j dkr|jd|j |j dkr|jdtjj |j |jd|j tjj |j}|r|jd n |jd x.|jD]$}|j|j||f||jd qW|r,|jd n |jd x0|jD]&}|j|j||f||jd q>W|rz|jdn |jdx0|jD]&}|j|j||f||jd qW|jdx0|jD]&}|j|j||f||jd qW|jddS)zConvert the message to text. The I{origin}, I{relativize}, and any other keyword arguments are passed to the rrset to_wire() method. @rtype: string zid %d z opcode %s z rcode %s z flags %s rzedns %s z eflags %s z payload %d z;ZONE z ;QUESTION  z;PREREQ z;ANSWER z;UPDATE z ;AUTHORITY z ;ADDITIONAL Nrr)rwriterropcoder: from_flagsrrcoderrZ edns_to_textr is_updaterrrrgetvalue)r5r/ relativizekwsZrcrArrsetr r rr:sJ              zMessage.to_textcCst|tsdS|j|jkrdS|j|jkr.dSx|jD]}||jkr6dSq6Wx|jD]}||jkrTdSqTWx|jD]}||jkrrdSqrWx|jD]}||jkrdSqWx|jD]}||jkrdSqWx|jD]}||jkrdSqWdS)zTwo messages are equal if they have the same content in the header, question, answer, and authority sections. @rtype: boolFT) isinstancerrrrrr)r5othernr r r__eq__s2               zMessage.__eq__cCs |j| S)z0Are two messages not equal? @rtype: bool)rJ)r5rHr r r__ne__szMessage.__ne__cCs|jtjj@dks:|j|jks:tjj|jtjj|jkr>dStjj|j|jtjjkr\dStjj |jrndSx|j D]}||j krvdSqvWx|j D]}||j krdSqWdS)z1Is other a response to self? @rtype: boolrFT) rrQRrr>r?r@rZNOERRORrAr)r5rHrIr r r is_responses"       zMessage.is_responsecCsD||jkrdS||jkrdS||jkr*dS||jkr8dStddS)Nrrzunknown section)rrrr ValueError)r5sectionr r rsection_number-s    zMessage.section_numberFc Cs|j||||||f} |sb|jdk r>|jj| } | dk rb| Sn$x"|D]} | j|||||rD| SqDW|sjttjj|||||} |j| |jdk r| |j| <| S)aFind the RRset with the given attributes in the specified section. @param section: the section of the message to look in, e.g. self.answer. @type section: list of dns.rrset.RRset objects @param name: the name of the RRset @type name: dns.name.Name object @param rdclass: the class of the RRset @type rdclass: int @param rdtype: the type of the RRset @type rdtype: int @param covers: the covers value of the RRset @type covers: int @param deleting: the deleting value of the RRset @type deleting: int @param create: If True, create the RRset if it is not found. The created RRset is appended to I{section}. @type create: bool @param force_unique: If True and create is also True, create a new RRset regardless of whether a matching RRset exists already. @type force_unique: bool @raises KeyError: the RRset was not found and create was False @rtype: dns.rrset.RRset objectN) rRr4getmatchKeyErrorrrFZRRsetappend) r5rQnamerdclassrdtypecoversdeletingcreate force_uniquekeyrFr r r find_rrset9s"      zMessage.find_rrsetc Cs:y|j||||||||} Wntk r4d} YnX| S)aGet the RRset with the given attributes in the specified section. If the RRset is not found, None is returned. @param section: the section of the message to look in, e.g. self.answer. @type section: list of dns.rrset.RRset objects @param name: the name of the RRset @type name: dns.name.Name object @param rdclass: the class of the RRset @type rdclass: int @param rdtype: the type of the RRset @type rdtype: int @param covers: the covers value of the RRset @type covers: int @param deleting: the deleting value of the RRset @type deleting: int @param create: If True, create the RRset if it is not found. The created RRset is appended to I{section}. @type create: bool @param force_unique: If True and create is also True, create a new RRset regardless of whether a matching RRset exists already. @type force_unique: bool @rtype: dns.rrset.RRset object or NoneN)r_rU) r5rQrWrXrYrZr[r\r]rFr r r get_rrsetgs  zMessage.get_rrsetrc KsR|dkr|jdkr|j}nd}|dkr,d}n |dkr8d}tjj|j|j||}x"|jD]}|j|j|j |j qVWx"|j D]}|j tjj |f|qzWx"|jD]}|j tjj|f|qW|jdkr|j|j|j|j|jx"|jD]}|j tjj|f|qW|j|jdk rJ|j|j|j|j|j|j|j|j|j|j |j!|_!|j"S)a7Return a string containing the message in DNS compressed wire format. Additional keyword arguments are passed to the rrset to_wire() method. @param origin: The origin to be appended to any relative names. @type origin: dns.name.Name object @param max_size: The maximum size of the wire format output; default is 0, which means 'the message's request payload, if nonzero, or 65536'. @type max_size: int @raises dns.exception.TooBig: max_size was exceeded @rtype: string riiN)#r"rZrendererZRendererrrrZ add_questionrWrYrXrZ add_rrsetANSWERr AUTHORITYrZadd_ednsrr r!r ADDITIONALZ write_headerr$Zadd_tsigr#r+r,r*r)r(r'r-Zget_wire)r5r/Zmax_sizerDrrFr r rto_wires6        zMessage.to_wirei,rcCst||_|dkr$t|jjd|_nt|tr:tjj|}||_||_ ||_ |dkr^|j |_ n||_ ||_ ||_dS)awWhen sending, a TSIG signature using the specified keyring and keyname should be added. @param keyring: The TSIG keyring to use; defaults to None. @type keyring: dict @param keyname: The name of the TSIG key to use; defaults to None. The key must be defined in the keyring. If a keyring is specified but a keyname is not, then the key used will be the first key in the keyring. Note that the order of keys in a dictionary is not defined, so applications should supply a keyname when a keyring is used, unless they know the keyring contains only one key. @type keyname: dns.name.Name or string @param fudge: TSIG time fudge; default is 300 seconds. @type fudge: int @param original_id: TSIG original id; defaults to the message's id @type original_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 algorithm: The TSIG algorithm to use; defaults to dns.tsig.default_algorithm Nr)r#listkeysr$rGrrrW from_textr'r+rr,r*r))r5r#r$r+r,r*r) algorithmr r ruse_tsigs   zMessage.use_tsigcCs|dks|dkrd}|dkr d}|dkr,|}|dkrFd}d}d}g}n$|tdM}||d>O}|dkrjg}||_||_||_||_||_dS) a_Configure EDNS behavior. @param edns: The EDNS level to use. Specifying None, False, or -1 means 'do not use EDNS', and in this case the other parameters are ignored. Specifying True is equivalent to specifying 0, i.e. 'use EDNS0'. @type edns: int or bool or None @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 request_payload: The EDNS payload size to use when sending this message. If not specified, defaults to the value of payload. @type request_payload: int or None @param options: The EDNS options @type options: None or list of dns.edns.Option objects @see: RFC 2671 NFrTrl~r)rrrr r!r")r5rrr r"r!r r ruse_ednss(  zMessage.use_ednscCsL|r*|jdkr|j|jtjjO_n|jdkrH|jtjjM_dS)a Enable or disable 'DNSSEC desired' flag in requests. @param wanted: Is DNSSEC desired? If True, EDNS is enabled if required, and then the DO bit is set. If False, the DO bit is cleared if EDNS is enabled. @type wanted: bool rN)rrmrrrZDO)r5Zwantedr r r want_dnssecs   zMessage.want_dnsseccCstjj|j|jS)z.Return the rcode. @rtype: int )rr@r?rr)r5r r rr@sz Message.rcodecCsjtjj|\}}|jdM_|j|O_|jtdM_|j|O_|jdkrf|jdkrfd|_dS)zPSet the rcode. @param rcode: the rcode @type rcode: int iirN)rr@to_flagsrrrr)r5r@valueZevaluer r r set_rcode"szMessage.set_rcodecCstjj|jS)z/Return the opcode. @rtype: int )rr>r?r)r5r r rr>/szMessage.opcodecCs(|jdM_|jtjj|O_dS)zTSet the opcode. @param opcode: the opcode @type opcode: int iN)rrr>ro)r5r>r r r set_opcode5szMessage.set_opcode)N)NT)Nr)rrrkNN)T)r r r r r6r9r;r:rJrKrMrRr rdatatypeNONEr_r`rer%r&rjrmrnr@rqr>rrr r r rrKs0K  7  -  ! .) *  rc@s2eZdZdZd ddZddZddZd d Zd S) _WireReaderaWire format reader. @ivar wire: the wire-format message. @type wire: string @ivar message: The message object being built @type message: dns.message.Message object @ivar current: When building a message object from wire format, this variable contains the offset from the beginning of wire of the next octet to be read. @type current: int @ivar updating: Is the message a dynamic update? @type updating: bool @ivar one_rr_per_rrset: Put each RR into its own RRset? @type one_rr_per_rrset: bool @ivar ignore_trailing: Ignore trailing junk at end of request? @type ignore_trailing: bool @ivar zone_rdclass: The class of the zone in messages which are DNS dynamic updates. @type zone_rdclass: int FcCs@tjj||_||_d|_d|_tjj|_ ||_ ||_ ||_ dS)NrF) rZwiredataZ maybe_wrapwiremessagecurrentupdating rdataclassIN zone_rdclass question_onlyone_rr_per_rrsetignore_trailing)r5rvrwr}r~rr r rr6Us z_WireReader.__init__c Cs|jr|dkrtjjxtd|D]}tjj|j|j\}}|j j dk rV|j |j j }|j||_t j d|j|j|jd\}}|jd|_|j j|j j|||ddd|jr"||_q"WdS)zRead the next I{qcount} records from the wire data and add them to the question section. @param qcount: the number of questions in the message @type qcount: intrrNz!HHT)r\r])ryr exception FormErrorrrW from_wirervrxrwr/rCstructunpackr_rr|)r5qcountiqnameusedrYrXr r r _get_question`s   z_WireReader._get_questionc CsH|js |jrd}nd}d}x&td|D]}|j}tjj|j|j\}}|} |jj dk rh|j |jj }|j||_t j d|j|j|jd\} } } } |jd|_| tj jkrn||jjk s|rt| |j_| |j_| d@d?|j_g|j_|j}| }xj|dkrdt j d |j||d \}}|d }tjj||j||}|jjj|||}|d |}qWd}n| tj jkrH||jjko||d kst|jjdkrtd |jjj| }|dkrtd || |j_tjj|j|j| \|j_|j_ tjj!|j| |t"t#j#|jj$||j| |jj%|jj&|jj' |j_%d|j_(n| dkrVd} |jr| tj)j*ksz| tj)j+kr| }|j,} nd}|tj)j*ks|tj)j+kr||jj-krtj j+}d}n&tj.j| | |j|j| |jj }|j/}|jj0r| tj j1krd}|jj2||| | ||d|}|dk r4|j3|| |j| |_q(WdS)a/Read the next I{count} records from the wire data and add them to the specified section. @param section: the section of the message to which to add records @type section: list of dns.rrset.RRset objects @param count: the number of records to read @type count: intTFrNz!HHIH irlz!HHrrz"got signed message without keyringzkey '%s' unknown)4ryr~rrxrrWrrvrwr/rCrrrsOPTrrr rrr!Zoption_from_wirerVZTSIGrr#rrSr$r%Zget_algorithm_and_macr'r-Zvalidateinttimer(r0r2r3r1rzANYrtr|rrdatarZr.ZSOAr_add)r5rQcountr]Zseen_optrZrr_startrWrZ absolute_namerYrXttlZrdlenrxZoptslenZotypeZolenoptZsecretr[rZrdrFr r r _get_sectionxs                 z_WireReader._get_sectioncCst|j}|dkrttjd|jdd\|j_|j_}}}}d|_t j j |jjr\d|_ |j ||jrpdS|j|jj||j|jj||j|jj||j r|j|krt|jjr|jjr|jj r|jjj|jdS)zNRead a wire format DNS message and build a dns.message.Message object. z!HHHHHHNT)lenrvrrrrwrrrxrr>rAryrr}rrrrrrr2r0r1update)r5lrZancountZaucountZadcountr r rreads$ *  z_WireReader.readN)FFF)r r r r r6rrrr r r rru>s  crurFTc CsPtdd} || _|| _|| _|| _|| _|| _|| _t|| || | } | j | S)a)Convert a DNS wire format message into a message object. @param keyring: The keyring to use if the message is signed. @type keyring: dict @param request_mac: If the message is a response to a TSIG-signed request, I{request_mac} should be set to the MAC of that request. @type request_mac: string @param xfr: Is this message part of a zone transfer? @type xfr: bool @param origin: If the message is part of a zone transfer, I{origin} should be the origin name of the zone. @type origin: dns.name.Name object @param tsig_ctx: The ongoing TSIG context, used when validating zone transfers. @type tsig_ctx: hmac.HMAC object @param multi: Is this message part of a multiple message sequence? @type multi: bool @param first: Is this message standalone, or the first of a multi message sequence? @type first: bool @param question_only: Read only up to the end of the question section? @type question_only: bool @param one_rr_per_rrset: Put each RR into its own RRset @type one_rr_per_rrset: bool @param ignore_trailing: Ignore trailing junk at end of request? @type ignore_trailing: bool @raises ShortHeader: The message is less than 12 octets long. @raises TrailingJunk: There were octets in the message past the end of the proper DNS message. @raises BadEDNS: An OPT record was in the wrong section, or occurred more than once. @raises BadTSIG: A TSIG record was not the last record of the additional data section. @rtype: dns.message.Message objectr)r) rr#r(r.r/r0r2r3rur) rvr#r(r.r/r0r2r3r}r~rmreaderr r rrs(  rc@s8eZdZdZddZddZddZdd Zd d Zd S) _TextReaderaText format reader. @ivar tok: the tokenizer @type tok: dns.tokenizer.Tokenizer object @ivar message: The message object being built @type message: dns.message.Message object @ivar updating: Is the message a dynamic update? @type updating: bool @ivar zone_rdclass: The class of the zone in messages which are DNS dynamic updates. @type zone_rdclass: int @ivar last_name: The most recently read name when building a message object from text format. @type last_name: dns.name.Name object cCs.||_tjj||_d|_tjj|_d|_ dS)NF) rwrZ tokenizer Tokenizertok last_namerzr{r|ry)r5textrwr r rr6>s  z_TextReader.__init__cCs|jj}|j}|dkr*|jj|j_n|dkrx>|jj}|jsT|jj|P|jjt jj |jB|j_q4Wt j j |jjrd|_ n&|dkr|jj|j_|jj|jjd>B|j_n|dkr|jjdkrd|j_x|jj}|js|jj|P|jjt jj|jB|j_qWn|dkrN|jj|j_|jjdkrd|j_nd|d kr|jj}|jjt j jt j j |B|j_n.|d kr|jj}|jjt jj |nt|jjd S) z5Process one line from the text format header section.rrTrrlZeflagsrr r>r@N)rrSrpZget_intrwr is_identifierungetrrrhr>rAryrrZedns_from_textr Z get_stringrorqr@rget_eol)r5rQtokenZwhatrr r r _header_lineEsR               z_TextReader._header_linecCs|jjdd}|js(tjj|jd|_|j}|jj}|jsHtj j y,tj j|j}|jj}|jsrtj j Wn:tj j k rtj j Ynt k rtj j }YnXtjj|j}|jj|jj|||ddd|jr||_|jjdS)z7Process one line from the text format question section.T) want_leadingN)r\r])rrS is_whitespacerrWrhrprrr SyntaxErrorrz Exceptionr{rsrwr_rryr|r)r5rQrrWrXrYr r r_question_liness.    z_TextReader._question_linec Csd}|jjdd}|js,tjj|jd|_|j}|jj}|jsLtj j y*t |jd}|jj}|jsttj j Wn6tj j k rtj j Ynt k rd}YnXyPtj j|j}|jj}|jstj j |tj jks|tj jkr|}|j}Wn>tj j k r tj j Ynt k r<tj j}YnXtjj|j}|jj}|js|jj|tjj|||jd}|j} n d}tjj} |jj||||| |d|j} |dk r| j||dS)zfProcess one line from the text format answer, authority, or additional data sections. NT)rr)rrSrrrWrhrprrrrrrrzrrtr|r{rs is_eol_or_eofrrrZrwr_ryr) r5rQr[rrWrrXrYrrZrFr r r_rr_linesT                z_TextReader._rr_linecCs|j}d}x|jjdd}|jr$P|jr|jj}|dkrF|j}nv|dksV|dkrf|j}|jj }nV|dksv|dkr|j }|jj }n6|dks|d kr|j }|jj }n|d kr|j }|jj }|jjq |jj|||q WdS) zNRead a text format DNS message and build a dns.message.Message object.NTZHEADERZQUESTIONZZONEraZPREREQrbZUPDATErc)rrrSrZ is_commentrpupperrrwrrrrrrr)r5Z line_methodrQrur r rrs4      z_TextReader.readN) r r r r r6rrrrr r r rr,s .5rcCst}t||}|j|S)zConvert the text format message into a message object. @param text: The text format message. @type text: string @raises UnknownHeaderField: @raises dns.exception.SyntaxError: @rtype: dns.message.Message object)rrr)rrrr r rrhs  rhc CsFt}d}t||r"t||}d}nd}z t|}Wd|r@|jX|S)aRead the next text format message from the specified file. @param f: file or string. If I{f} is a string, it is treated as the name of a file to open. @raises UnknownHeaderField: @raises dns.exception.SyntaxError: @rtype: dns.message.Message objectZrUTFN)rrGopenrhclose)fZstr_typeZoptsZ want_closerr r r from_files     rc Cst|trtjj|}t|tr,tjj|}t|trBtjj|}t} | jtjj O_| j | j |||dddi} |dk r|| d<|dkrd}|dk r|| d<|dkrd}|dk r|| d<|dkrd}|dk r|| d<|dkrd}|| d <| j f| | j || S) aVMake a query message. The query name, type, and class may all be specified either as objects of the appropriate type, or as strings. The query will have a randomly chosen query id, and its DNS flags will be set to dns.flags.RD. @param qname: The query name. @type qname: dns.name.Name object or string @param rdtype: The desired rdata type. @type rdtype: int @param rdclass: The desired rdata class; the default is class IN. @type rdclass: int @param use_edns: The EDNS level to use; the default is None (no EDNS). See the description of dns.message.Message.use_edns() for the possible values for use_edns and their meanings. @type use_edns: int or bool or None @param want_dnssec: Should the query indicate that DNSSEC is desired? @type want_dnssec: bool @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 request_payload: The EDNS payload size to use when sending this message. If not specified, defaults to the value of payload. @type request_payload: int or None @param options: The EDNS options @type options: None or list of dns.edns.Option objects @see: RFC 2671 @rtype: dns.message.Message objectT)r\r]Nrrr r"r!r)rGrrrWrhrsrzrrRDr_rrmrn) rrYrXrmrnrr r"r!rkwargsr r r make_querys>$        r ,cCs|jtjj@rtjjdtjj|j}tjj|jtjj@B|_|rV|jtjj O_|j |j t |j |_ |jdkr|jdd||j|jr|j|j|j|ddd|j|j|_|S)a Make a message which is a response for the specified query. The message returned is really a response skeleton; it has all of the infrastructure required of a response, but none of the content. The response's question section is a shallow copy of the query's question section, so the query's question RRsets should not be changed. @param query: the query to respond to @type query: dns.message.Message object @param recursion_available: should RA be set in the response? @type recursion_available: bool @param our_payload: payload size to advertise in EDNS responses; default is 8192. @type our_payload: int @param fudge: TSIG time fudge; default is 300 seconds. @type fudge: int @rtype: dns.message.Message objectz&specified query message is not a queryrNr)rrrLrrrwrrrZRArrr>rfrrrmr r1rjr#r$r'r-r()ZqueryZrecursion_availableZ our_payloadr+Zresponser r r make_response\s   r) NrFNNFTFFF)Frr).r Z __future__riorrrZdns.ednsrZ dns.exceptionZ dns.flagsZdns.nameZ dns.opcodeZ dns.entropyZ dns.rcodeZ dns.rdataZdns.rdataclassZ dns.rdatatypeZ dns.rrsetZ dns.rendererZdns.tsigZ dns.wiredataZ_compatrrrrrrrZ DNSExceptionrrrrobjectrrurrrhrrzr{rrr r r rsX  v7 5:F