self.adjust_fields = ['copy_id']
self.origin = '.'
self.message = dns.message.Message()
+ self.message.use_edns(edns = 0)
self.sections = []
def match_part(self, code, msg):
def adjust_reply(self, query):
""" Copy scripted reply and adjust to received query. """
answer = dns.message.from_text(self.message.to_text())
+ answer.use_edns(query.edns, query.ednsflags)
if 'copy_id' in self.adjust_fields:
answer.id = query.id
answer.question[0].name = query.question[0].name
except:
flags.append(code)
self.message.flags = dns.flags.from_text(' '.join(flags))
- self.message.ednsflags = dns.flags.edns_from_text(' '.join(eflags))
+ self.message.want_dnssec('DO' in eflags)
self.message.set_rcode(rcode)
def begin_section(self, section):
""" Add record to current packet section. """
rr = self.__rr_from_str(owner, args)
if self.section == 'QUESTION':
- self.message.question.append(rr)
+ self.__rr_add(self.message.question, rr)
elif self.section == 'ANSWER':
- self.message.answer.append(rr)
+ self.__rr_add(self.message.answer, rr)
elif self.section == 'AUTHORITY':
- self.message.authority.append(rr)
+ self.__rr_add(self.message.authority, rr)
elif self.section == 'ADDITIONAL':
- self.message.additional.append(rr)
+ self.__rr_add(self.message.additional, rr)
else:
raise Exception('bad section %s' % self.section)
+ def __rr_add(self, section, rr):
+ """ Merge record to existing RRSet, or append to given section. """
+ for existing_rr in section:
+ if existing_rr.match(rr.name, rr.rdclass, rr.rdtype, 0):
+ existing_rr += rr
+ return
+ section.append(rr)
+
def __rr_from_str(self, owner, args):
""" Parse RR from tokenized string. """
if not owner.endswith('.'):
if len(self.data) == 0:
raise Exception("query definition required")
msg = self.data[0].message
- msg.use_edns(edns = 1)
self.answer = ctx.resolve(msg.to_wire())
if self.answer is not None:
self.answer = dns.message.from_wire(self.answer)