Exemplo n.º 1
0
    def lookupNameservers(self, name, timeout=None):
        """ Answer NS record requests """
        name_is_self = name in [self.wildcard_domain, self.ns_domain]
        if name.endswith('.' + self.wildcard_domain) or name_is_self:
            # If we're responsible for this domain, return NS records
            payload = dns.Record_NS(name=self.ns_domain)
            answer = dns.RRHeader(name=name,
                                  type=dns.NS,
                                  payload=payload,
                                  auth=True,
                                  ttl=TTL)

            # Additional section: NS ip address
            additional_payload = dns.Record_A(address=self.my_ip)
            additional_answer = dns.RRHeader(name=name,
                                             payload=additional_payload,
                                             ttl=TTL)

            answers = [answer]
            authority = []
            additional = [additional_answer]

            return defer.succeed((answers, authority, additional))

        # fail for domains that are not handled by our server
        return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
Exemplo n.º 2
0
    def _lookup(self, name, cls, type, timeout):
        segs = name.split('.')

        print name, segs

        for i in reversed(xrange(len(segs))):
            seg = segs[i]
            try:
                nh = util.name_to_name_hash(seg)
            except ValueError:
                continue
            name2 = '.'.join(segs[i:])
            break
        else:
            raise dns.DomainError(name)

        print(nh, name2)

        result = yield self.dht.iterativeFindValue(nh)

        if isinstance(result, list):
            print result
            print 5
            raise dns.AuthoritativeDomainError(name)

        assert isinstance(result, dict), result
        print result
        pkt = packet.DomainPacket.from_binary(result[nh])

        if pkt.get_name_hash() != nh:
            print 6
            raise dns.AuthoritativeDomainError(name)
        record = pkt.get_record()
        if not self.dht.get_my_time() < record.get_end_time():
            print 7
            raise dns.AuthoritativeDomainError(name)
        if not pkt.verify_signature():
            print 8
            raise dns.AuthoritativeDomainError(name)

        zone = record.get_zone(name2)

        defer.returnValue((yield zone._lookup(name, cls, type, timeout)))
Exemplo n.º 3
0
    def _lookup(self, name, cls, type, timeout=None):
        if self._debug_level > 2:
            print('address %s (%s)' % (name, type), file=sys.stderr)

        answers = []
        additional = []
        authority = []

        if type == dns.NS:
            return self.lookupNameservers(name)
        elif type == dns.SOA:
            answer = [self._get_authority_record(name)]
            return defer.succeed(([answer], authority, additional))
        elif type == dns.A:
            result = self._localLookup(name)
            if result:
                # TTL = 1 hour
                payload = dns.Record_A(address=bytes(result))
                answer = dns.RRHeader(name=name,
                                      payload=payload,
                                      auth=True,
                                      ttl=TTL)

                answers = [answer]

                return defer.succeed((answers, authority, additional))

            else:
                if self._debug_level > 2:
                    print('Unknown %s' % name, file=sys.stderr)
                return defer.fail(
                    failure.Failure(dns.AuthoritativeDomainError(name)))
        else:
            # Types not handled by our server - respond with SOA
            authority = [self._get_authority_record(name)]
            return defer.succeed((answers, authority, additional))
Exemplo n.º 4
0
    def _lookup(self, name, cls, type, timeout=None):
        """
        Determine a response to a particular DNS query.

        @param name: The name which is being queried and for which to lookup a
            response.
        @type name: L{bytes}

        @param cls: The class which is being queried.  Only I{IN} is
            implemented here and this value is presently disregarded.
        @type cls: L{int}

        @param type: The type of records being queried.  See the types defined
            in L{twisted.names.dns}.
        @type type: L{int}

        @param timeout: All processing is done locally and a result is
            available immediately, so the timeout value is ignored.

        @return: A L{Deferred} that fires with a L{tuple} of three sets of
            response records (to comprise the I{answer}, I{authority}, and
            I{additional} sections of a DNS response) or with a L{Failure} if
            there is a problem processing the query.
        """
        cnames = []
        results = []
        authority = []
        additional = []
        default_ttl = max(self.soa[1].minimum, self.soa[1].expire)

        domain_records = self.records.get(name.lower())

        if domain_records:
            for record in domain_records:
                if record.ttl is not None:
                    ttl = record.ttl
                else:
                    ttl = default_ttl

                if (record.TYPE == dns.NS and
                        name.lower() != self.soa[0].lower()):
                    # NS record belong to a child zone: this is a referral.  As
                    # NS records are authoritative in the child zone, ours here
                    # are not.  RFC 2181, section 6.1.
                    authority.append(
                        dns.RRHeader(
                            name, record.TYPE, dns.IN, ttl, record, auth=False
                        )
                    )
                elif record.TYPE == type or type == dns.ALL_RECORDS:
                    results.append(
                        dns.RRHeader(
                            name, record.TYPE, dns.IN, ttl, record, auth=True
                        )
                    )
                if record.TYPE == dns.CNAME:
                    cnames.append(
                        dns.RRHeader(
                            name, record.TYPE, dns.IN, ttl, record, auth=True
                        )
                    )
            if not results:
                results = cnames

            # Sort of https://tools.ietf.org/html/rfc1034#section-4.3.2 .
            # See https://twistedmatrix.com/trac/ticket/6732
            additionalInformation = self._additionalRecords(
                results, authority, default_ttl)
            if cnames:
                results.extend(additionalInformation)
            else:
                additional.extend(additionalInformation)

            if not results and not authority:
                # Empty response. Include SOA record to allow clients to cache
                # this response. RFC 1034, sections 3.7 and 4.3.4, and RFC 2181
                # section 7.1.
                authority.append(
                    dns.RRHeader(
                        self.soa[0], dns.SOA, dns.IN, ttl, self.soa[1],
                        auth=True
                    )
                )
            return defer.succeed((results, authority, additional))
        else:
            if dns._isSubdomainOf(name, self.soa[0]):
                # We may be the authority and we didn't find it.
                # XXX: The QNAME may also be in a delegated child zone. See
                # #6581 and #6580
                return defer.fail(
                    failure.Failure(dns.AuthoritativeDomainError(name))
                )
            else:
                # The QNAME is not a descendant of this zone. Fail with
                # DomainError so that the next chained authority or
                # resolver will be queried.
                return defer.fail(failure.Failure(error.DomainError(name)))
    def _lookup(self, name, cls, type, timeout=None):
        cnames = []
        results = []
        authority = []
        additional = []
        default_ttl = max(self.soa[1].minimum, self.soa[1].expire)

        domain_records = self.records.get(name.lower())

        if domain_records:
            for record in domain_records:
                if record.ttl is not None:
                    ttl = record.ttl
                else:
                    ttl = default_ttl

                if record.TYPE == dns.NS and name.lower() != self.soa[0].lower(
                ):
                    # NS record belong to a child zone: this is a referral.  As
                    # NS records are authoritative in the child zone, ours here
                    # are not.  RFC 2181, section 6.1.
                    authority.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=False))
                elif record.TYPE == type or type == dns.ALL_RECORDS:
                    results.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
                if record.TYPE == dns.CNAME:
                    cnames.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
            if not results:
                results = cnames

            for record in results + authority:
                section = {
                    dns.NS: additional,
                    dns.CNAME: results,
                    dns.MX: additional
                }.get(record.type)
                if section is not None:
                    n = str(record.payload.name)
                    for rec in self.records.get(n.lower(), ()):
                        if rec.TYPE == dns.A:
                            section.append(
                                dns.RRHeader(n,
                                             dns.A,
                                             dns.IN,
                                             rec.ttl or default_ttl,
                                             rec,
                                             auth=True))

            if not results and not authority:
                # Empty response. Include SOA record to allow clients to cache
                # this response.  RFC 1034, sections 3.7 and 4.3.4, and RFC 2181
                # section 7.1.
                authority.append(
                    dns.RRHeader(self.soa[0],
                                 dns.SOA,
                                 dns.IN,
                                 ttl,
                                 self.soa[1],
                                 auth=True))
            return defer.succeed((results, authority, additional))
        else:
            if name.lower().endswith(self.soa[0].lower()):
                # We are the authority and we didn't find it.  Goodbye.
                return defer.fail(
                    failure.Failure(dns.AuthoritativeDomainError(name)))
            return defer.fail(failure.Failure(dns.DomainError(name)))
Exemplo n.º 6
0
    def _lookup(self, name, cls, type, timeout=None):
        cnames = []
        results = []
        authority = []
        additional = []
        default_ttl = max(self.soa[1].minimum, self.soa[1].expire)

        domain_records = self.records.get(name.lower())

        if domain_records:
            for record in domain_records:
                if record.ttl is not None:
                    ttl = record.ttl
                else:
                    ttl = default_ttl

                if record.TYPE == type or type == dns.ALL_RECORDS:
                    results.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
                elif record.TYPE == dns.NS and type != dns.ALL_RECORDS:
                    authority.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
                if record.TYPE == dns.CNAME:
                    cnames.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
            if not results:
                results = cnames

            for record in results + authority:
                section = {
                    dns.NS: additional,
                    dns.CNAME: results,
                    dns.MX: additional
                }.get(record.type)
                if section is not None:
                    n = str(record.payload.name)
                    for rec in self.records.get(n.lower(), ()):
                        if rec.TYPE == dns.A:
                            section.append(
                                dns.RRHeader(n,
                                             dns.A,
                                             dns.IN,
                                             rec.ttl or default_ttl,
                                             rec,
                                             auth=True))

            return defer.succeed((results, authority, additional))
        else:
            if name.lower().endswith(self.soa[0].lower()):
                # We are the authority and we didn't find it.  Goodbye.
                return defer.fail(
                    failure.Failure(dns.AuthoritativeDomainError(name)))
            return defer.fail(failure.Failure(dns.DomainError(name)))
Exemplo n.º 7
0
    def _lookup(self, name, cls, type, timeout = None):
        """
        Determine a response to a particular DNS query.

        @param name: The name which is being queried and for which to lookup a
            response.
        @type name: L{bytes}

        @param cls: The class which is being queried.  Only I{IN} is
            implemented here and this value is presently disregarded.
        @type cls: L{int}

        @param type: The type of records being queried.  See the types defined
            in L{twisted.names.dns}.
        @type type: L{int}

        @param timeout: All processing is done locally and a result is
            available immediately, so the timeout value is ignored.

        @return: A L{Deferred} that fires with a L{tuple} of three sets of
            response records (to comprise the I{answer}, I{authority}, and
            I{additional} sections of a DNS response) or with a L{Failure} if
            there is a problem processing the query.
        """
        cnames = []
        results = []
        authority = []
        additional = []

        print '%s %s' % (name, dns.QUERY_TYPES[type])

        domain_zone, zone_name = self._lookup_records(name.lower())
        if not domain_zone:
            return defer.fail(failure.Failure(error.DomainError(name)))

        domain_records = domain_zone.get(name.lower())
        if not domain_records:
            return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))

        for record in domain_records:
            ttl = record.ttl

            if record.TYPE == dns.NS and name.lower() != zone_name.lower():
                # NS record belong to a child zone: this is a referral.  As
                # NS records are authoritative in the child zone, ours here
                # are not.  RFC 2181, section 6.1.
                authority.append(
                    dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=False)
                )
            elif record.TYPE == type or type == dns.ALL_RECORDS:
                results.append(
                    dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
                )
            if record.TYPE == dns.CNAME:
                cnames.append(
                    dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
                )
            if record.TYPE == dns.SOA:
                soa = record
        if not results:
            results = cnames

        # https://tools.ietf.org/html/rfc1034#section-4.3.2 - sort of.
        # See https://twistedmatrix.com/trac/ticket/6732
        additionalInformation = self._additionalRecords(results, authority)
        if cnames:
            results.extend(additionalInformation)
        else:
            additional.extend(additionalInformation)

        if not results and not authority:
            # Empty response. Include SOA record to allow clients to cache
            # this response.  RFC 1034, sections 3.7 and 4.3.4, and RFC 2181
            # section 7.1.

            authority.append(
                dns.RRHeader(zone_name, dns.SOA, dns.IN, ttl, soa, auth=True)
                )
        return defer.succeed((results, authority, additional))
Exemplo n.º 8
0
    def _lookup(self, name, cls, type, timeout = None):
        cnames = []
        results = []
        authority = []
        additional = []
        default_ttl = max(self.soa[1].minimum, self.soa[1].expire)

        domain_records = self.records.get(name.lower())

        if domain_records:
            for record in domain_records:
                if record.ttl is not None:
                    ttl = record.ttl
                else:
                    ttl = default_ttl

                if record.TYPE == dns.NS and name.lower() != self.soa[0].lower():
                    # NS record belong to a child zone: this is a referral.  As
                    # NS records are authoritative in the child zone, ours here
                    # are not.  RFC 2181, section 6.1.
                    authority.append(
                        dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=False)
                    )
                elif record.TYPE == type or type == dns.ALL_RECORDS:
                    results.append(
                        dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
                    )
                if record.TYPE == dns.CNAME:
                    cnames.append(
                        dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
                    )
            if not results:
                results = cnames

            for record in results + authority:
                section = {dns.NS: additional, dns.CNAME: results, dns.MX: additional}.get(record.type)
                if section is not None:
                    n = str(record.payload.name)
                    for rec in self.records.get(n.lower(), ()):
                        if rec.TYPE == dns.A:
                            section.append(
                                dns.RRHeader(n, dns.A, dns.IN, rec.ttl or default_ttl, rec, auth=True)
                            )

            if not results and not authority:
                # Empty response. Include SOA record to allow clients to cache
                # this response.  RFC 1034, sections 3.7 and 4.3.4, and RFC 2181
                # section 7.1.
                authority.append(
                    dns.RRHeader(self.soa[0], dns.SOA, dns.IN, ttl, self.soa[1], auth=True)
                    )
            return defer.succeed((results, authority, additional))
        else:
            if dns._isSubdomainOf(name, self.soa[0]):
                # We may be the authority and we didn't find it.
                # XXX: The QNAME may also be a in a delegated child zone. See
                # #6581 and #6580
                return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
            else:
                # The QNAME is not a descendant of this zone. Fail with
                # DomainError so that the next chained authority or
                # resolver will be queried.
                return defer.fail(failure.Failure(error.DomainError(name)))
Exemplo n.º 9
0
    def _lookup(self, name, cls, type, timeout=None):
        cnames = []
        results = []
        authority = []
        additional = []
        default_ttl = max(self.soa[1].minimum, self.soa[1].expire)
        client_address = self.address[0]

        domain_records = self.records.get(name.lower())
        if not domain_records:
            domain_records = list()

        # search database only for CLOUDLET_DOMAIN
        if name.lower() == MemoryResolver.CLOUDLET_DOMAIN.lower():
            db_domain_records = list() + domain_records
            machine_list = self.db.search_nearby_cloudlet(client_address,
                                                          max_count=10)
            appended_ips = dict()
            for each_machine in machine_list:
                # avoid duplicated record
                if appended_ips.get(each_machine.ip_address, False) == True:
                    continue
                if each_machine.ip_address.startswith(
                        MemoryResolver.IP_FILTER):
                    new_record = dns.Record_A(address=each_machine.ip_address,
                                              ttl=default_ttl)
                    db_domain_records.append(new_record)
                    appended_ips[each_machine.ip_address] = True
        else:
            db_domain_records = domain_records

        if db_domain_records:
            for record in db_domain_records:
                if record.ttl is not None:
                    ttl = record.ttl
                else:
                    ttl = default_ttl

                if record.TYPE == dns.NS and name.lower() != self.soa[0].lower(
                ):
                    # NS record belong to a child zone: this is a referral.  As
                    # NS records are authoritative in the child zone, ours here
                    # are not.  RFC 2181, section 6.1.
                    authority.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=False))
                elif record.TYPE == type or type == dns.ALL_RECORDS:
                    results.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
                if record.TYPE == dns.CNAME:
                    cnames.append(
                        dns.RRHeader(name,
                                     record.TYPE,
                                     dns.IN,
                                     ttl,
                                     record,
                                     auth=True))
            if not results:
                results = cnames

            for record in results + authority:
                section = {
                    dns.NS: additional,
                    dns.CNAME: results,
                    dns.MX: additional
                }.get(record.type)
                if section is not None:
                    n = str(record.payload.name)
                    for rec in self.records.get(n.lower(), ()):
                        if rec.TYPE == dns.A:
                            section.append(
                                dns.RRHeader(n,
                                             dns.A,
                                             dns.IN,
                                             rec.ttl or default_ttl,
                                             rec,
                                             auth=True))

            if not results and not authority:
                # Empty response. Include SOA record to allow clients to cache
                # this response.  RFC 1034, sections 3.7 and 4.3.4, and RFC 2181
                # section 7.1.
                authority.append(
                    dns.RRHeader(self.soa[0],
                                 dns.SOA,
                                 dns.IN,
                                 ttl,
                                 self.soa[1],
                                 auth=True))
            return defer.succeed((results, authority, additional))
        else:
            if name.lower().endswith(self.soa[0].lower()):
                # We are the authority and we didn't find it.  Goodbye.
                return defer.fail(
                    failure.Failure(dns.AuthoritativeDomainError(name)))
            return defer.fail(failure.Failure(dns.DomainError(name)))