具体来说,在authority.FileAuthority类下的_lookup调用中会发生什么,以及它如何返回结果?这是Names的未记录区域之一。
答案 0 :(得分:0)
以下是Twisted Names 11.1的authority.py文件中的FileAuthority._lookup调用的注释版本。此方法负责同步搜索已从BIND区域文件,Python区域文件等编制索引的DNS信息。
def _lookup(self, name, cls, type, timeout = None):
"""Return a list of results.
name: Queried host name.
cls: An enum of the query class. See dns.py:
IN, CS, CH, HS = range(1, 5)
QUERY_CLASSES = {
IN: 'IN',
CS: 'CS',
CH: 'CH',
HS: 'HS',
ANY: 'ANY'
}
type: The type of record to search for (or ANY/255 for any and all).
See dns.py:
(A, NS, MD, MF, CNAME, SOA, MB, MG, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT,
RP, AFSDB) = range(1, 19)
AAAA = 28
SRV = 33
NAPTR = 35
A6 = 38
DNAME = 39
SPF = 99
QUERY_TYPES = {
A: 'A',
NS: 'NS',
MD: 'MD',
MF: 'MF',
CNAME: 'CNAME',
SOA: 'SOA',
MB: 'MB',
MG: 'MG',
MR: 'MR',
NULL: 'NULL',
WKS: 'WKS',
PTR: 'PTR',
HINFO: 'HINFO',
MINFO: 'MINFO',
MX: 'MX',
TXT: 'TXT',
RP: 'RP',
AFSDB: 'AFSDB',
# 19 through 27? Eh, I'll get to 'em.
AAAA: 'AAAA',
SRV: 'SRV',
NAPTR: 'NAPTR',
A6: 'A6',
DNAME: 'DNAME',
SPF: 'SPF'
}
timeout: The retention time for this record, in seconds.
"""
cnames = []
results = []
authority = []
additional = []
default_ttl = max(self.soa[1].minimum, self.soa[1].expire)
# Do records search. Get a list of classes like Record_A and Record_MX
# back. These are defined in dns.py .
domain_records = self.records.get(name.lower())
# Structure the results so as to present them the way that DNS records
# usually come back.
if domain_records:
# Loop through all of the results.
for record in domain_records:
if record.ttl is not None:
ttl = record.ttl
else:
ttl = default_ttl
# If we're looking at a [subdomain?] NS record, note it.
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)
)
# Was the record what was requested, or did we want everything?
elif record.TYPE == type or type == dns.ALL_RECORDS:
results.append(
dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
)
# If we're looking at a CNAME record, note it.
if record.TYPE == dns.CNAME:
cnames.append(
dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)
)
# If no requested records were found, use the CNAME records (if any).
if not results:
results = cnames
# Go through any NS, CNAME, or MX records found, and find the IPs
# for those hosts.
#
# NOTE: The "additional" list doesn't appear to be populated.
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)
)
# Not found. Return an SOA record with the name that was requested
# (the normal response that you'll see at the console).
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)
)
# We return a tuple of individual result lists. Each of the records
# is an instance of RRHeader, which wraps the Record_* classes in
# dns.py for returning as a result (Resource Record).
#
# The first item in the tuple refers to the "ANSWER SECTION" in the
# DiG output, and the third item refers to the "ADDITIONAL
# SECTION". As "authority" was an empty list in the example, no
# output relates to it. It will have NS records if any are present,
# or contain an SOA record for what was requested if nothing was
# found.
#
#;; QUESTION SECTION:
#;example-domain.com. IN ANY
#
#;; ANSWER SECTION:
#example-domain.com. 3600 IN SOA ns1.example-domain.com. root.example-domain.com. 2003010601 3600 3600 3600 3600
#example-domain.com. 3600 IN A 127.9.9.9
#example-domain.com. 3600 IN NS ns1.example-domain.com.
#example-domain.com. 3600 IN MX 0 mail.example-domain.com.
#
#;; ADDITIONAL SECTION:
#mail.example-domain.com. 3600 IN A 123.0.16.43
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)))