def _rr_line(self, section): """Process one line from the text format answer, authority, or additional data sections. """ deleting = None # Name token = self.tok.get(want_leading = True) if token[0] != dnspython.tokenizer.WHITESPACE: self.last_name = dnspython.name.from_text(token[1], None) name = self.last_name token = self.tok.get() if token[0] != dnspython.tokenizer.IDENTIFIER: raise dnspython.exception.SyntaxError # TTL try: ttl = int(token[1], 0) token = self.tok.get() if token[0] != dnspython.tokenizer.IDENTIFIER: raise dnspython.exception.SyntaxError except dnspython.exception.SyntaxError: raise dnspython.exception.SyntaxError except: ttl = 0 # Class try: rdclass = dnspython.rdataclass.from_text(token[1]) token = self.tok.get() if token[0] != dnspython.tokenizer.IDENTIFIER: raise dnspython.exception.SyntaxError if rdclass == dnspython.rdataclass.ANY or rdclass == dnspython.rdataclass.NONE: deleting = rdclass rdclass = self.zone_rdclass except dnspython.exception.SyntaxError: raise dnspython.exception.SyntaxError except: rdclass = dnspython.rdataclass.IN # Type rdtype = dnspython.rdatatype.from_text(token[1]) token = self.tok.get() if token[0] != dnspython.tokenizer.EOL and token[0] != dnspython.tokenizer.EOF: self.tok.unget(token) rd = dnspython.rdata.from_text(rdclass, rdtype, self.tok, None) covers = rd.covers() else: rd = None covers = dnspython.rdatatype.NONE rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, self.updating) if not rd is None: rrset.add(rd, ttl)
def _get_section(self, section, count): """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 dnspython.rrset.RRset objects @param count: the number of records to read @type count: int""" if self.updating or self.one_rr_per_rrset: force_unique = True else: force_unique = False seen_opt = False for i in xrange(0, count): rr_start = self.current (name, used) = dnspython.name.from_wire(self.wire, self.current) absolute_name = name if not self.message.origin is None: name = name.relativize(self.message.origin) self.current = self.current + used (rdtype, rdclass, ttl, rdlen) = \ struct.unpack('!HHIH', self.wire[self.current:self.current + 10]) self.current = self.current + 10 if rdtype == dnspython.rdatatype.OPT: if not section is self.message.additional or seen_opt: raise BadEDNS self.message.payload = rdclass self.message.ednsflags = ttl self.message.edns = (ttl & 0xff0000) >> 16 self.message.options = [] current = self.current optslen = rdlen while optslen > 0: (otype, olen) = \ struct.unpack('!HH', self.wire[current:current + 4]) current = current + 4 opt = dnspython.ednspython.option_from_wire(otype, self.wire, current, olen) self.message.options.append(opt) current = current + olen optslen = optslen - 4 - olen seen_opt = True elif rdtype == dnspython.rdatatype.TSIG: if not (section is self.message.additional and i == (count - 1)): raise BadTSIG if self.message.keyring is None: raise UnknownTSIGKey, 'got signed message without keyring' secret = self.message.keyring.get(absolute_name) if secret is None: raise UnknownTSIGKey, "key '%s' unknown" % name self.message.tsig_ctx = \ dnspython.tsig.validate(self.wire, absolute_name, secret, int(time.time()), self.message.request_mac, rr_start, self.current, rdlen, self.message.tsig_ctx, self.message.multi, self.message.first) self.message.had_tsig = True else: if ttl < 0: ttl = 0 if self.updating and \ (rdclass == dnspython.rdataclass.ANY or rdclass == dnspython.rdataclass.NONE): deleting = rdclass rdclass = self.zone_rdclass else: deleting = None if deleting == dnspython.rdataclass.ANY or \ (deleting == dnspython.rdataclass.NONE and \ section == self.message.answer): covers = dnspython.rdatatype.NONE rd = None else: rd = dnspython.rdata.from_wire(rdclass, rdtype, self.wire, self.current, rdlen, self.message.origin) covers = rd.covers() if self.message.xfr and rdtype == dnspython.rdatatype.SOA: force_unique = True rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, force_unique) if not rd is None: rrset.add(rd, ttl) self.current = self.current + rdlen