Example #1
0
    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)
Example #2
0
    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