home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1628 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  20.5 KB  |  710 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import cStringIO
  5. import random
  6. import struct
  7. import sys
  8. import time
  9. import dns.exception as dns
  10. import dns.flags as dns
  11. import dns.name as dns
  12. import dns.opcode as dns
  13. import dns.rcode as dns
  14. import dns.rdata as dns
  15. import dns.rdataclass as dns
  16. import dns.rdatatype as dns
  17. import dns.rrset as dns
  18. import dns.renderer as dns
  19. import dns.tsig as dns
  20.  
  21. class ShortHeader(dns.exception.FormError):
  22.     pass
  23.  
  24.  
  25. class TrailingJunk(dns.exception.FormError):
  26.     pass
  27.  
  28.  
  29. class UnknownHeaderField(dns.exception.DNSException):
  30.     pass
  31.  
  32.  
  33. class BadEDNS(dns.exception.FormError):
  34.     pass
  35.  
  36.  
  37. class BadTSIG(dns.exception.FormError):
  38.     pass
  39.  
  40.  
  41. class UnknownTSIGKey(dns.exception.DNSException):
  42.     pass
  43.  
  44.  
  45. class Message(object):
  46.     
  47.     def __init__(self, id = None):
  48.         if id is None:
  49.             self.id = random.randint(0, 65535)
  50.         else:
  51.             self.id = id
  52.         self.flags = 0
  53.         self.question = []
  54.         self.answer = []
  55.         self.authority = []
  56.         self.additional = []
  57.         self.edns = -1
  58.         self.ednsflags = 0
  59.         self.payload = 0
  60.         self.request_payload = 0
  61.         self.keyring = None
  62.         self.keyname = None
  63.         self.request_mac = ''
  64.         self.other_data = ''
  65.         self.tsig_error = 0
  66.         self.fudge = 300
  67.         self.original_id = self.id
  68.         self.mac = ''
  69.         self.xfr = False
  70.         self.origin = None
  71.         self.tsig_ctx = None
  72.         self.had_tsig = False
  73.         self.multi = False
  74.         self.first = True
  75.         self.index = { }
  76.  
  77.     
  78.     def __repr__(self):
  79.         return '<DNS message, ID ' + `self.id` + '>'
  80.  
  81.     
  82.     def __str__(self):
  83.         return self.to_text()
  84.  
  85.     
  86.     def to_text(self, origin = None, relativize = True, **kw):
  87.         s = cStringIO.StringIO()
  88.         print >>s, 'id %d' % self.id
  89.         print >>s, 'opcode %s' % dns.opcode.to_text(dns.opcode.from_flags(self.flags))
  90.         rc = dns.rcode.from_flags(self.flags, self.ednsflags)
  91.         print >>s, 'rcode %s' % dns.rcode.to_text(rc)
  92.         print >>s, 'flags %s' % dns.flags.to_text(self.flags)
  93.         if self.edns >= 0:
  94.             print >>s, 'edns %s' % self.edns
  95.             if self.ednsflags != 0:
  96.                 print >>s, 'eflags %s' % dns.flags.edns_to_text(self.ednsflags)
  97.             
  98.             print >>s, 'payload', self.payload
  99.         
  100.         is_update = dns.opcode.is_update(self.flags)
  101.         if is_update:
  102.             print >>s, ';ZONE'
  103.         else:
  104.             print >>s, ';QUESTION'
  105.         for rrset in self.question:
  106.             print >>s, rrset.to_text(origin, relativize, **kw)
  107.         
  108.         if is_update:
  109.             print >>s, ';PREREQ'
  110.         else:
  111.             print >>s, ';ANSWER'
  112.         for rrset in self.answer:
  113.             print >>s, rrset.to_text(origin, relativize, **kw)
  114.         
  115.         if is_update:
  116.             print >>s, ';UPDATE'
  117.         else:
  118.             print >>s, ';AUTHORITY'
  119.         for rrset in self.authority:
  120.             print >>s, rrset.to_text(origin, relativize, **kw)
  121.         
  122.         print >>s, ';ADDITIONAL'
  123.         for rrset in self.additional:
  124.             print >>s, rrset.to_text(origin, relativize, **kw)
  125.         
  126.         return s.getvalue()[:-1]
  127.  
  128.     
  129.     def __eq__(self, other):
  130.         if not isinstance(other, Message):
  131.             return False
  132.         if self.id != other.id:
  133.             return False
  134.         if self.flags != other.flags:
  135.             return False
  136.         for n in self.question:
  137.             if n not in other.question:
  138.                 return False
  139.         
  140.         for n in other.question:
  141.             if n not in self.question:
  142.                 return False
  143.         
  144.         for n in self.answer:
  145.             if n not in other.answer:
  146.                 return False
  147.         
  148.         for n in other.answer:
  149.             if n not in self.answer:
  150.                 return False
  151.         
  152.         for n in self.authority:
  153.             if n not in other.authority:
  154.                 return False
  155.         
  156.         for n in other.authority:
  157.             if n not in self.authority:
  158.                 return False
  159.         
  160.         return True
  161.  
  162.     
  163.     def __ne__(self, other):
  164.         return not self.__eq__(other)
  165.  
  166.     
  167.     def is_response(self, other):
  168.         if other.flags & dns.flags.QR == 0 and self.id != other.id or dns.opcode.from_flags(self.flags) != dns.opcode.from_flags(other.flags):
  169.             return False
  170.         if dns.rcode.from_flags(other.flags, other.ednsflags) != dns.rcode.NOERROR:
  171.             return True
  172.         if dns.opcode.is_update(self.flags):
  173.             return True
  174.         for n in self.question:
  175.             if n not in other.question:
  176.                 return False
  177.         
  178.         for n in other.question:
  179.             if n not in self.question:
  180.                 return False
  181.         
  182.         return True
  183.  
  184.     
  185.     def section_number(self, section):
  186.         if section is self.question:
  187.             return 0
  188.         if section is self.answer:
  189.             return 1
  190.         if section is self.authority:
  191.             return 2
  192.         if section is self.additional:
  193.             return 3
  194.         raise ValueError, 'unknown section'
  195.  
  196.     
  197.     def find_rrset(self, section, name, rdclass, rdtype, covers = dns.rdatatype.NONE, deleting = None, create = False, force_unique = False):
  198.         key = (self.section_number(section), name, rdclass, rdtype, covers, deleting)
  199.         if not force_unique:
  200.             if self.index is not None:
  201.                 rrset = self.index.get(key)
  202.                 if rrset is not None:
  203.                     return rrset
  204.             else:
  205.                 for rrset in section:
  206.                     if rrset.match(name, rdclass, rdtype, covers, deleting):
  207.                         return rrset
  208.                 
  209.         
  210.         if not create:
  211.             raise KeyError
  212.         create
  213.         rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting)
  214.         section.append(rrset)
  215.         if self.index is not None:
  216.             self.index[key] = rrset
  217.         
  218.         return rrset
  219.  
  220.     
  221.     def get_rrset(self, section, name, rdclass, rdtype, covers = dns.rdatatype.NONE, deleting = None, create = False, force_unique = False):
  222.         
  223.         try:
  224.             rrset = self.find_rrset(section, name, rdclass, rdtype, covers, deleting, create, force_unique)
  225.         except KeyError:
  226.             rrset = None
  227.  
  228.         return rrset
  229.  
  230.     
  231.     def to_wire(self, origin = None, max_size = 0, **kw):
  232.         if max_size == 0:
  233.             if self.request_payload != 0:
  234.                 max_size = self.request_payload
  235.             else:
  236.                 max_size = 65535
  237.         
  238.         if max_size < 512:
  239.             max_size = 512
  240.         elif max_size > 65535:
  241.             max_size = 65535
  242.         
  243.         r = dns.renderer.Renderer(self.id, self.flags, max_size, origin)
  244.         for rrset in self.question:
  245.             r.add_question(rrset.name, rrset.rdtype, rrset.rdclass)
  246.         
  247.         for rrset in self.answer:
  248.             r.add_rrset(dns.renderer.ANSWER, rrset, **kw)
  249.         
  250.         for rrset in self.authority:
  251.             r.add_rrset(dns.renderer.AUTHORITY, rrset, **kw)
  252.         
  253.         if self.edns >= 0:
  254.             r.add_edns(self.edns, self.ednsflags, self.payload)
  255.         
  256.         for rrset in self.additional:
  257.             r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw)
  258.         
  259.         r.write_header()
  260.         if self.keyname is not None:
  261.             r.add_tsig(self.keyname, self.keyring[self.keyname], self.fudge, self.original_id, self.tsig_error, self.other_data, self.request_mac)
  262.             self.mac = r.mac
  263.         
  264.         return r.get_wire()
  265.  
  266.     
  267.     def use_tsig(self, keyring, keyname = None, fudge = 300, original_id = None, tsig_error = 0, other_data = ''):
  268.         self.keyring = keyring
  269.         if keyname is None:
  270.             self.keyname = self.keyring.keys()[0]
  271.         elif isinstance(keyname, (str, unicode)):
  272.             keyname = dns.name.from_text(keyname)
  273.         
  274.         self.keyname = keyname
  275.         self.fudge = fudge
  276.         if original_id is None:
  277.             self.original_id = self.id
  278.         else:
  279.             self.original_id = original_id
  280.         self.tsig_error = tsig_error
  281.         self.other_data = other_data
  282.  
  283.     
  284.     def use_edns(self, edns = 0, ednsflags = 0, payload = 1280, request_payload = None):
  285.         if edns is None or edns is False:
  286.             edns = -1
  287.         
  288.         if edns is True:
  289.             edns = 0
  290.         
  291.         if request_payload is None:
  292.             request_payload = payload
  293.         
  294.         if edns < 0:
  295.             ednsflags = 0
  296.             payload = 0
  297.             request_payload = 0
  298.         
  299.         self.edns = edns
  300.         self.ednsflags = ednsflags
  301.         self.payload = payload
  302.         self.request_payload = request_payload
  303.  
  304.     
  305.     def want_dnssec(self, wanted = True):
  306.         if wanted:
  307.             if self.edns < 0:
  308.                 self.use_edns()
  309.             
  310.             self.ednsflags |= dns.flags.DO
  311.         elif self.edns >= 0:
  312.             self.ednsflags &= ~(dns.flags.DO)
  313.         
  314.  
  315.     
  316.     def rcode(self):
  317.         return dns.rcode.from_flags(self.flags, self.ednsflags)
  318.  
  319.     
  320.     def set_rcode(self, rcode):
  321.         (value, evalue) = dns.rcode.to_flags(rcode)
  322.         self.flags &= 65520
  323.         self.flags |= value
  324.         self.ednsflags &= 0xFF000000L
  325.         self.ednsflags |= evalue
  326.  
  327.     
  328.     def opcode(self):
  329.         return dns.opcode.from_flags(self.flags)
  330.  
  331.     
  332.     def set_opcode(self, opcode):
  333.         self.flags &= 34815
  334.         self.flags |= dns.opcode.to_flags(opcode)
  335.  
  336.  
  337.  
  338. class _WireReader(object):
  339.     
  340.     def __init__(self, wire, message, question_only = False):
  341.         self.wire = wire
  342.         self.message = message
  343.         self.current = 0
  344.         self.updating = False
  345.         self.zone_rdclass = dns.rdataclass.IN
  346.         self.question_only = question_only
  347.  
  348.     
  349.     def _get_question(self, qcount):
  350.         if self.updating and qcount > 1:
  351.             raise dns.exception.FormError
  352.         qcount > 1
  353.         for i in xrange(0, qcount):
  354.             (qname, used) = dns.name.from_wire(self.wire, self.current)
  355.             if self.message.origin is not None:
  356.                 qname = qname.relativize(self.message.origin)
  357.             
  358.             self.current = self.current + used
  359.             (rdtype, rdclass) = struct.unpack('!HH', self.wire[self.current:self.current + 4])
  360.             self.current = self.current + 4
  361.             self.message.find_rrset(self.message.question, qname, rdclass, rdtype, create = True, force_unique = True)
  362.             if self.updating:
  363.                 self.zone_rdclass = rdclass
  364.                 continue
  365.         
  366.  
  367.     
  368.     def _get_section(self, section, count):
  369.         if self.updating:
  370.             force_unique = True
  371.         else:
  372.             force_unique = False
  373.         seen_opt = False
  374.         for i in xrange(0, count):
  375.             rr_start = self.current
  376.             (name, used) = dns.name.from_wire(self.wire, self.current)
  377.             if self.message.origin is not None:
  378.                 name = name.relativize(self.message.origin)
  379.             
  380.             self.current = self.current + used
  381.             (rdtype, rdclass, ttl, rdlen) = struct.unpack('!HHIH', self.wire[self.current:self.current + 10])
  382.             self.current = self.current + 10
  383.             if rdtype == dns.rdatatype.OPT:
  384.                 if section is not self.message.additional or seen_opt:
  385.                     raise BadEDNS
  386.                 seen_opt
  387.                 self.message.payload = rdclass
  388.                 self.message.ednsflags = ttl
  389.                 self.message.edns = (ttl & 16711680) >> 16
  390.                 seen_opt = True
  391.             elif rdtype == dns.rdatatype.TSIG:
  392.                 if not section is self.message.additional and i == count - 1:
  393.                     raise BadTSIG
  394.                 i == count - 1
  395.                 if self.message.keyring is None:
  396.                     raise UnknownTSIGKey, 'got signed message without keyring'
  397.                 self.message.keyring is None
  398.                 secret = self.message.keyring.get(name)
  399.                 if secret is None:
  400.                     raise UnknownTSIGKey, "key '%s' unknown" % name
  401.                 secret is None
  402.                 self.message.tsig_ctx = dns.tsig.validate(self.wire, name, secret, int(time.time()), self.message.request_mac, rr_start, self.current, rdlen, self.message.tsig_ctx, self.message.multi, self.message.first)
  403.                 self.message.had_tsig = True
  404.             elif ttl < 0:
  405.                 ttl = 0
  406.             
  407.             if self.updating:
  408.                 if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
  409.                     deleting = rdclass
  410.                     rdclass = self.zone_rdclass
  411.                 else:
  412.                     deleting = None
  413.             if deleting == dns.rdataclass.ANY:
  414.                 covers = dns.rdatatype.NONE
  415.                 rd = None
  416.             else:
  417.                 rd = dns.rdata.from_wire(rdclass, rdtype, self.wire, self.current, rdlen, self.message.origin)
  418.                 covers = rd.covers()
  419.             if self.message.xfr and rdtype == dns.rdatatype.SOA:
  420.                 force_unique = True
  421.             
  422.             rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, force_unique)
  423.             if rd is not None:
  424.                 rrset.add(rd, ttl)
  425.             
  426.             self.current = self.current + rdlen
  427.         
  428.  
  429.     
  430.     def read(self):
  431.         l = len(self.wire)
  432.         if l < 12:
  433.             raise ShortHeader
  434.         l < 12
  435.         (self.message.id, self.message.flags, qcount, ancount, aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12])
  436.         self.current = 12
  437.         if dns.opcode.is_update(self.message.flags):
  438.             self.updating = True
  439.         
  440.         self._get_question(qcount)
  441.         if self.question_only:
  442.             return None
  443.         self._get_section(self.message.answer, ancount)
  444.         self._get_section(self.message.authority, aucount)
  445.         self._get_section(self.message.additional, adcount)
  446.         if self.current != l:
  447.             raise TrailingJunk
  448.         self.current != l
  449.         if self.message.multi and self.message.tsig_ctx and not (self.message.had_tsig):
  450.             self.message.tsig_ctx.update(self.wire)
  451.         
  452.  
  453.  
  454.  
  455. def from_wire(wire, keyring = None, request_mac = '', xfr = False, origin = None, tsig_ctx = None, multi = False, first = True, question_only = False):
  456.     m = Message(id = 0)
  457.     m.keyring = keyring
  458.     m.request_mac = request_mac
  459.     m.xfr = xfr
  460.     m.origin = origin
  461.     m.tsig_ctx = tsig_ctx
  462.     m.multi = multi
  463.     m.first = first
  464.     reader = _WireReader(wire, m, question_only)
  465.     reader.read()
  466.     return m
  467.  
  468.  
  469. class _TextReader(object):
  470.     
  471.     def __init__(self, text, message):
  472.         self.message = message
  473.         self.tok = dns.tokenizer.Tokenizer(text)
  474.         self.last_name = None
  475.         self.zone_rdclass = dns.rdataclass.IN
  476.         self.updating = False
  477.  
  478.     
  479.     def _header_line(self, section):
  480.         (ttype, what) = self.tok.get()
  481.         if what == 'id':
  482.             self.message.id = self.tok.get_int()
  483.         elif what == 'flags':
  484.             while True:
  485.                 token = self.tok.get()
  486.                 if token[0] != dns.tokenizer.IDENTIFIER:
  487.                     self.tok.unget(token)
  488.                     break
  489.                 
  490.                 self.message.flags = self.message.flags | dns.flags.from_text(token[1])
  491.             if dns.opcode.is_update(self.message.flags):
  492.                 self.updating = True
  493.             
  494.         elif what == 'edns':
  495.             self.message.edns = self.tok.get_int()
  496.             self.message.ednsflags = self.message.ednsflags | self.message.edns << 16
  497.         elif what == 'eflags':
  498.             if self.message.edns < 0:
  499.                 self.message.edns = 0
  500.             
  501.             while True:
  502.                 token = self.tok.get()
  503.                 if token[0] != dns.tokenizer.IDENTIFIER:
  504.                     self.tok.unget(token)
  505.                     break
  506.                 
  507.                 self.message.ednsflags = self.message.ednsflags | dns.flags.edns_from_text(token[1])
  508.         elif what == 'payload':
  509.             self.message.payload = self.tok.get_int()
  510.             if self.message.edns < 0:
  511.                 self.message.edns = 0
  512.             
  513.         elif what == 'opcode':
  514.             text = self.tok.get_string()
  515.             self.message.flags = self.message.flags | dns.opcode.to_flags(dns.opcode.from_text(text))
  516.         elif what == 'rcode':
  517.             text = self.tok.get_string()
  518.             self.message.set_rcode(dns.rcode.from_text(text))
  519.         else:
  520.             raise UnknownHeaderField
  521.         (what == 'id').tok.get_eol()
  522.  
  523.     
  524.     def _question_line(self, section):
  525.         token = self.tok.get(want_leading = True)
  526.         if token[0] != dns.tokenizer.WHITESPACE:
  527.             self.last_name = dns.name.from_text(token[1], None)
  528.         
  529.         name = self.last_name
  530.         token = self.tok.get()
  531.         if token[0] != dns.tokenizer.IDENTIFIER:
  532.             raise dns.exception.SyntaxError
  533.         token[0] != dns.tokenizer.IDENTIFIER
  534.         
  535.         try:
  536.             rdclass = dns.rdataclass.from_text(token[1])
  537.             token = self.tok.get()
  538.             if token[0] != dns.tokenizer.IDENTIFIER:
  539.                 raise dns.exception.SyntaxError
  540.             token[0] != dns.tokenizer.IDENTIFIER
  541.         except dns.exception.SyntaxError:
  542.             raise dns.exception.SyntaxError
  543.         except:
  544.             rdclass = dns.rdataclass.IN
  545.  
  546.         rdtype = dns.rdatatype.from_text(token[1])
  547.         self.message.find_rrset(self.message.question, name, rdclass, rdtype, create = True, force_unique = True)
  548.         if self.updating:
  549.             self.zone_rdclass = rdclass
  550.         
  551.         self.tok.get_eol()
  552.  
  553.     
  554.     def _rr_line(self, section):
  555.         deleting = None
  556.         token = self.tok.get(want_leading = True)
  557.         if token[0] != dns.tokenizer.WHITESPACE:
  558.             self.last_name = dns.name.from_text(token[1], None)
  559.         
  560.         name = self.last_name
  561.         token = self.tok.get()
  562.         if token[0] != dns.tokenizer.IDENTIFIER:
  563.             raise dns.exception.SyntaxError
  564.         token[0] != dns.tokenizer.IDENTIFIER
  565.         
  566.         try:
  567.             ttl = int(token[1], 0)
  568.             token = self.tok.get()
  569.             if token[0] != dns.tokenizer.IDENTIFIER:
  570.                 raise dns.exception.SyntaxError
  571.             token[0] != dns.tokenizer.IDENTIFIER
  572.         except dns.exception.SyntaxError:
  573.             raise dns.exception.SyntaxError
  574.         except:
  575.             ttl = 0
  576.  
  577.         
  578.         try:
  579.             rdclass = dns.rdataclass.from_text(token[1])
  580.             token = self.tok.get()
  581.             if token[0] != dns.tokenizer.IDENTIFIER:
  582.                 raise dns.exception.SyntaxError
  583.             token[0] != dns.tokenizer.IDENTIFIER
  584.             if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
  585.                 deleting = rdclass
  586.                 rdclass = self.zone_rdclass
  587.         except dns.exception.SyntaxError:
  588.             raise dns.exception.SyntaxError
  589.         except:
  590.             rdclass = dns.rdataclass.IN
  591.  
  592.         rdtype = dns.rdatatype.from_text(token[1])
  593.         token = self.tok.get()
  594.         if token[0] != dns.tokenizer.EOL and token[0] != dns.tokenizer.EOF:
  595.             self.tok.unget(token)
  596.             rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
  597.             covers = rd.covers()
  598.         else:
  599.             rd = None
  600.             covers = dns.rdatatype.NONE
  601.         rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, self.updating)
  602.         if rd is not None:
  603.             rrset.add(rd, ttl)
  604.         
  605.  
  606.     
  607.     def read(self):
  608.         line_method = self._header_line
  609.         section = None
  610.         while None:
  611.             token = self.tok.get(True, True)
  612.             if token[0] == dns.tokenizer.EOL or token[0] == dns.tokenizer.EOF:
  613.                 break
  614.             
  615.             if token[0] == dns.tokenizer.COMMENT:
  616.                 u = token[1].upper()
  617.                 if u == 'HEADER':
  618.                     line_method = self._header_line
  619.                 elif u == 'QUESTION' or u == 'ZONE':
  620.                     line_method = self._question_line
  621.                     section = self.message.question
  622.                 elif u == 'ANSWER' or u == 'PREREQ':
  623.                     line_method = self._rr_line
  624.                     section = self.message.answer
  625.                 elif u == 'AUTHORITY' or u == 'UPDATE':
  626.                     line_method = self._rr_line
  627.                     section = self.message.authority
  628.                 elif u == 'ADDITIONAL':
  629.                     line_method = self._rr_line
  630.                     section = self.message.additional
  631.                 
  632.                 self.tok.get_eol()
  633.                 continue
  634.             
  635.             line_method(section)
  636.             continue
  637.             return None
  638.  
  639.  
  640.  
  641. def from_text(text):
  642.     m = Message()
  643.     reader = _TextReader(text, m)
  644.     reader.read()
  645.     return m
  646.  
  647.  
  648. def from_file(f):
  649.     if sys.hexversion >= 33751040:
  650.         str_type = basestring
  651.         opts = 'rU'
  652.     else:
  653.         str_type = str
  654.         opts = 'r'
  655.     if isinstance(f, str_type):
  656.         f = file(f, opts)
  657.         want_close = True
  658.     else:
  659.         want_close = False
  660.     
  661.     try:
  662.         m = from_text(f)
  663.     finally:
  664.         if want_close:
  665.             f.close()
  666.         
  667.  
  668.     return m
  669.  
  670.  
  671. def make_query(qname, rdtype, rdclass = dns.rdataclass.IN, use_edns = None, want_dnssec = False):
  672.     if isinstance(qname, (str, unicode)):
  673.         qname = dns.name.from_text(qname)
  674.     
  675.     if isinstance(rdtype, str):
  676.         rdtype = dns.rdatatype.from_text(rdtype)
  677.     
  678.     if isinstance(rdclass, str):
  679.         rdclass = dns.rdataclass.from_text(rdclass)
  680.     
  681.     m = Message()
  682.     m.flags |= dns.flags.RD
  683.     m.find_rrset(m.question, qname, rdclass, rdtype, create = True, force_unique = True)
  684.     m.use_edns(use_edns)
  685.     m.want_dnssec(want_dnssec)
  686.     return m
  687.  
  688.  
  689. def make_response(query, recursion_available = False, our_payload = 8192):
  690.     if query.flags & dns.flags.QR:
  691.         raise dns.exception.FormError, 'specified query message is not a query'
  692.     query.flags & dns.flags.QR
  693.     response = dns.message.Message(query.id)
  694.     response.flags = dns.flags.QR | query.flags & dns.flags.RD
  695.     if recursion_available:
  696.         response.flags |= dns.flags.RA
  697.     
  698.     response.set_opcode(query.opcode())
  699.     response.question = list(query.question)
  700.     if query.edns >= 0:
  701.         response.use_edns(0, 0, our_payload, query.payload)
  702.     
  703.     if query.keyname is not None:
  704.         response.keyname = query.keyname
  705.         response.keyring = query.keyring
  706.         response.request_mac = query.mac
  707.     
  708.     return response
  709.  
  710.