diff options
author | Casey Deccio <casey@deccio.net> | 2016-07-29 22:53:34 +0300 |
---|---|---|
committer | Casey Deccio <casey@deccio.net> | 2016-07-29 22:53:34 +0300 |
commit | c61308ab7952bd9cbf37889a3ca2b2faac4f5557 (patch) | |
tree | 0bc5124714cb7b48ff63a90fe6bbd406270f4bc9 | |
parent | daf8c6d19c7be12440ed3b99e9440f6dce663902 (diff) |
Support odd ports (i.e., other than port 53)
-rw-r--r-- | dnsviz/analysis/online.py | 65 | ||||
-rw-r--r-- | dnsviz/commands/probe.py | 12 | ||||
-rw-r--r-- | dnsviz/query.py | 12 | ||||
-rw-r--r-- | dnsviz/resolver.py | 7 |
4 files changed, 61 insertions, 35 deletions
diff --git a/dnsviz/analysis/online.py b/dnsviz/analysis/online.py index af03d18..4dbf221 100644 --- a/dnsviz/analysis/online.py +++ b/dnsviz/analysis/online.py @@ -963,10 +963,10 @@ class Analyst(object): qname_only = True analysis_type = ANALYSIS_TYPE_AUTHORITATIVE - clone_attrnames = ['dlv_domain', 'try_ipv4', 'try_ipv6', 'client_ipv4', 'client_ipv6', 'logger', 'ceiling', 'edns_diagnostics', 'follow_ns', 'explicit_delegations', 'explicit_only', 'analysis_cache', 'cache_level', 'analysis_cache_lock', 'transport_manager', 'th_factories', 'resolver'] + clone_attrnames = ['dlv_domain', 'try_ipv4', 'try_ipv6', 'client_ipv4', 'client_ipv6', 'logger', 'ceiling', 'edns_diagnostics', 'follow_ns', 'explicit_delegations', 'odd_ports', 'explicit_only', 'analysis_cache', 'cache_level', 'analysis_cache_lock', 'transport_manager', 'th_factories', 'resolver'] def __init__(self, name, dlv_domain=None, try_ipv4=True, try_ipv6=True, client_ipv4=None, client_ipv6=None, logger=_logger, ceiling=None, edns_diagnostics=False, - follow_ns=False, follow_mx=False, trace=None, explicit_delegations=None, extra_rdtypes=None, explicit_only=False, analysis_cache=None, cache_level=None, analysis_cache_lock=None, th_factories=None, transport_manager=None, resolver=None): + follow_ns=False, follow_mx=False, trace=None, explicit_delegations=None, odd_ports=None, extra_rdtypes=None, explicit_only=False, analysis_cache=None, cache_level=None, analysis_cache_lock=None, th_factories=None, transport_manager=None, resolver=None): if transport_manager is None: self.transport_manager = transport.DNSQueryTransportManager() @@ -988,11 +988,16 @@ class Analyst(object): else: self.explicit_delegations = explicit_delegations + if odd_ports is None: + self.odd_ports = {} + else: + self.odd_ports = odd_ports + if resolver is None: hints = util.get_root_hints() for key in self.explicit_delegations: hints[key] = self.explicit_delegations[key] - resolver = Resolver.FullResolver(hints, transport_manager=self.transport_manager) + resolver = Resolver.FullResolver(hints, odd_ports=self.odd_ports, transport_manager=self.transport_manager) self.resolver = resolver self.ceiling = ceiling @@ -1591,6 +1596,8 @@ class Analyst(object): else: servers = name_obj.zone.get_responsive_auth_or_designated_servers() + odd_ports = dict([(s, self.odd_ports[(n, s)]) for n, s in self.odd_ports if n == name_obj.zone.name]) + servers = self._filter_servers(servers) exclude_no_answer = set() queries = {} @@ -1605,29 +1612,29 @@ class Analyst(object): # EDNS diagnostic queries if self.edns_diagnostics: self.logger.debug('Preparing EDNS diagnostic queries %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(dns.rdatatype.SOA))) - queries[(name_obj.name, -(dns.rdatatype.SOA+100))] = self.edns_version_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) - queries[(name_obj.name, -(dns.rdatatype.SOA+101))] = self.edns_opt_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) - queries[(name_obj.name, -(dns.rdatatype.SOA+102))] = self.edns_flag_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, -(dns.rdatatype.SOA+100))] = self.edns_version_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) + queries[(name_obj.name, -(dns.rdatatype.SOA+101))] = self.edns_opt_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) + queries[(name_obj.name, -(dns.rdatatype.SOA+102))] = self.edns_flag_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # negative queries for all zones self._set_negative_queries(name_obj) if name_obj.nxdomain_name is not None: self.logger.debug('Preparing query %s/%s (NXDOMAIN)...' % (fmt.humanize_name(name_obj.nxdomain_name), dns.rdatatype.to_text(name_obj.nxdomain_rdtype))) - queries[(name_obj.nxdomain_name, name_obj.nxdomain_rdtype)] = self.diagnostic_query(name_obj.nxdomain_name, name_obj.nxdomain_rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.nxdomain_name, name_obj.nxdomain_rdtype)] = self.diagnostic_query(name_obj.nxdomain_name, name_obj.nxdomain_rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) if name_obj.nxrrset_name is not None: self.logger.debug('Preparing query %s/%s (No data)...' % (fmt.humanize_name(name_obj.nxrrset_name), dns.rdatatype.to_text(name_obj.nxrrset_rdtype))) - queries[(name_obj.nxrrset_name, name_obj.nxrrset_rdtype)] = self.diagnostic_query(name_obj.nxrrset_name, name_obj.nxrrset_rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.nxrrset_name, name_obj.nxrrset_rdtype)] = self.diagnostic_query(name_obj.nxrrset_name, name_obj.nxrrset_rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # if the name is SLD or lower, then ask MX and TXT if self._is_sld_or_lower(name_obj.name): self.logger.debug('Preparing query %s/MX...' % fmt.humanize_name(name_obj.name)) # note that we use a PMTU diagnostic query here, to simultaneously test PMTU - queries[(name_obj.name, dns.rdatatype.MX)] = self.pmtu_diagnostic_query(name_obj.name, dns.rdatatype.MX, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, dns.rdatatype.MX)] = self.pmtu_diagnostic_query(name_obj.name, dns.rdatatype.MX, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # we also do a query with small UDP payload to elicit and test a truncated response - queries[(name_obj.name, -dns.rdatatype.MX)] = self.truncation_diagnostic_query(name_obj.name, dns.rdatatype.MX, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, -dns.rdatatype.MX)] = self.truncation_diagnostic_query(name_obj.name, dns.rdatatype.MX, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) self.logger.debug('Preparing query %s/TXT...' % fmt.humanize_name(name_obj.name)) - queries[(name_obj.name, dns.rdatatype.TXT)] = self.diagnostic_query(name_obj.name, dns.rdatatype.TXT, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, dns.rdatatype.TXT)] = self.diagnostic_query(name_obj.name, dns.rdatatype.TXT, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # for zones and for (non-zone) names which have DNSKEYs referenced if name_obj.is_zone() or self._force_dnskey_query(name_obj.name): @@ -1636,21 +1643,21 @@ class Analyst(object): if servers: if self._ask_non_delegation_queries(name_obj.name) and not self.explicit_only: self.logger.debug('Preparing query %s/SOA...' % fmt.humanize_name(name_obj.name)) - queries[(name_obj.name, dns.rdatatype.SOA)] = self.diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, dns.rdatatype.SOA)] = self.diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) if name_obj.is_zone(): # for zones we also use a TCP diagnostic query here, to simultaneously test TCP connectivity - queries[(name_obj.name, -dns.rdatatype.SOA)] = self.tcp_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, -dns.rdatatype.SOA)] = self.tcp_diagnostic_query(name_obj.name, dns.rdatatype.SOA, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) else: # for non-zones we don't need to keey the (UDP) SOA query, if there is no positive response exclude_no_answer.add((name_obj.name, dns.rdatatype.SOA)) self.logger.debug('Preparing query %s/DNSKEY...' % fmt.humanize_name(name_obj.name)) # note that we use a PMTU diagnostic query here, to simultaneously test PMTU - queries[(name_obj.name, dns.rdatatype.DNSKEY)] = self.pmtu_diagnostic_query(name_obj.name, dns.rdatatype.DNSKEY, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, dns.rdatatype.DNSKEY)] = self.pmtu_diagnostic_query(name_obj.name, dns.rdatatype.DNSKEY, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # we also do a query with small UDP payload to elicit and test a truncated response - queries[(name_obj.name, -dns.rdatatype.DNSKEY)] = self.truncation_diagnostic_query(name_obj.name, dns.rdatatype.DNSKEY, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, -dns.rdatatype.DNSKEY)] = self.truncation_diagnostic_query(name_obj.name, dns.rdatatype.DNSKEY, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # query for DS/DLV if name_obj.parent is not None: @@ -1669,7 +1676,7 @@ class Analyst(object): parent_servers = self._filter_servers(parent_servers) self.logger.debug('Preparing query %s/DS...' % fmt.humanize_name(name_obj.name)) - queries[(name_obj.name, dns.rdatatype.DS)] = self.diagnostic_query(name_obj.name, dns.rdatatype.DS, dns.rdataclass.IN, parent_servers, name_obj.parent_name(), self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, dns.rdatatype.DS)] = self.diagnostic_query(name_obj.name, dns.rdatatype.DS, dns.rdataclass.IN, parent_servers, name_obj.parent_name(), self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) if name_obj.dlv_parent is not None and self.dlv_domain != self.name: dlv_servers = name_obj.dlv_parent.get_responsive_auth_or_designated_servers() @@ -1677,7 +1684,7 @@ class Analyst(object): dlv_name = name_obj.dlv_name if dlv_servers: self.logger.debug('Preparing query %s/DLV...' % fmt.humanize_name(dlv_name)) - queries[(dlv_name, dns.rdatatype.DLV)] = self.diagnostic_query(dlv_name, dns.rdatatype.DLV, dns.rdataclass.IN, dlv_servers, name_obj.dlv_parent_name(), self.client_ipv4, self.client_ipv6) + queries[(dlv_name, dns.rdatatype.DLV)] = self.diagnostic_query(dlv_name, dns.rdatatype.DLV, dns.rdataclass.IN, dlv_servers, name_obj.dlv_parent_name(), self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) exclude_no_answer.add((dlv_name, dns.rdatatype.DLV)) # get rid of any queries already asked @@ -1690,14 +1697,14 @@ class Analyst(object): for rdtype in self._rdtypes_to_query(name_obj.name): if (name_obj.name, rdtype) not in all_queries: self.logger.debug('Preparing query %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(rdtype))) - queries[(name_obj.name, rdtype)] = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, rdtype)] = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # if no default queries were identified (e.g., empty non-terminal in # in-addr.arpa space), then add a backup. if not (queries or name_obj.queries): rdtype = dns.rdatatype.A self.logger.debug('Preparing query %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(rdtype))) - queries[(name_obj.name, rdtype)] = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6) + queries[(name_obj.name, rdtype)] = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, servers, bailiwick, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) # actually execute the queries, then store the results self.logger.debug('Executing queries...') @@ -1719,6 +1726,8 @@ class Analyst(object): parent_auth_servers = name_obj.parent.get_auth_or_designated_servers() parent_auth_servers = set(self._filter_servers(parent_auth_servers)) + odd_ports = dict([(s, self.odd_ports[(n, s)]) for n, s in self.odd_ports if n == name_obj.zone.name]) + if not parent_auth_servers: return False @@ -1743,7 +1752,7 @@ class Analyst(object): name_obj.referral_rdtype = rdtype self.logger.debug('Querying %s/%s (referral)...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(rdtype))) - query = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, parent_auth_servers, name_obj.parent_name(), self.client_ipv4, self.client_ipv6) + query = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, parent_auth_servers, name_obj.parent_name(), self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) query.execute(tm=self.transport_manager, th_factories=self.th_factories) referral_queries[rdtype] = query @@ -1778,7 +1787,7 @@ class Analyst(object): is_nxdomain = query.is_nxdomain_all() is_valid = query.is_valid_complete_response_any() - # (referral type is NS) + # (referral type is NS) if name_obj.referral_rdtype == dns.rdatatype.NS: # If there was a secondary type, the fact that only NS was queried # for indicates that there was no error and no NXDOMAIN response. @@ -1798,7 +1807,7 @@ class Analyst(object): name_obj.referral_rdtype = None del referral_queries[dns.rdatatype.NS] - # (referral type is secondary type) + # (referral type is secondary type) else: # don't remove either record if there's an NXDOMAIN/YXDOMAIN mismatch if referral_queries[dns.rdatatype.NS].is_nxdomain_all() and \ @@ -1861,7 +1870,7 @@ class Analyst(object): servers = self._filter_servers(servers, no_raise=True) if servers: self.logger.debug('Querying %s/NS (auth)...' % fmt.humanize_name(name_obj.name)) - queries.append(self.diagnostic_query(name_obj.name, dns.rdatatype.NS, dns.rdataclass.IN, servers, name_obj.name, self.client_ipv4, self.client_ipv6)) + queries.append(self.diagnostic_query(name_obj.name, dns.rdatatype.NS, dns.rdataclass.IN, servers, name_obj.name, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports)) # secondary query if secondary_rdtype is not None and self._ask_non_delegation_queries(name_obj.name): @@ -1870,7 +1879,7 @@ class Analyst(object): servers = self._filter_servers(servers, no_raise=True) if servers: self.logger.debug('Querying %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(secondary_rdtype))) - queries.append(self.diagnostic_query(name_obj.name, secondary_rdtype, dns.rdataclass.IN, servers, name_obj.name, self.client_ipv4, self.client_ipv6)) + queries.append(self.diagnostic_query(name_obj.name, secondary_rdtype, dns.rdataclass.IN, servers, name_obj.name, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports)) # actually execute the queries, then store the results Q.ExecutableDNSQuery.execute_queries(*queries, tm=self.transport_manager, th_factories=self.th_factories) @@ -2211,6 +2220,8 @@ class RecursiveAnalyst(Analyst): if not servers: raise NoNameservers('No resolvers available to query!') + odd_ports = dict([(s, self.odd_ports[(n, s)]) for n, s in self.odd_ports if n == name_obj.zone.name]) + # make common query first to prime the cache # for root and TLD, use type NS @@ -2228,7 +2239,7 @@ class RecursiveAnalyst(Analyst): rdtype = dns.rdatatype.A self.logger.debug('Querying %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(rdtype))) - query = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, servers, None, self.client_ipv4, self.client_ipv6) + query = self.diagnostic_query(name_obj.name, rdtype, dns.rdataclass.IN, servers, None, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) query.execute(tm=self.transport_manager, th_factories=self.th_factories) self._add_query(name_obj, query, True) @@ -2250,7 +2261,7 @@ class RecursiveAnalyst(Analyst): # make DS queries (these won't be included in the above mix # because there is no parent on the name_obj) self.logger.debug('Querying %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(dns.rdatatype.DS))) - query = self.diagnostic_query(name_obj.name, dns.rdatatype.DS, dns.rdataclass.IN, servers, None, self.client_ipv4, self.client_ipv6) + query = self.diagnostic_query(name_obj.name, dns.rdatatype.DS, dns.rdataclass.IN, servers, None, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) query.execute(tm=self.transport_manager, th_factories=self.th_factories) self._add_query(name_obj, query) @@ -2259,7 +2270,7 @@ class RecursiveAnalyst(Analyst): # ensure these weren't already queried for (e.g., as part of extra_rdtypes) if (name_obj.name, dns.rdatatype.NS) not in name_obj.queries: self.logger.debug('Querying %s/%s...' % (fmt.humanize_name(name_obj.name), dns.rdatatype.to_text(dns.rdatatype.NS))) - query = self.diagnostic_query(name_obj.name, dns.rdatatype.NS, dns.rdataclass.IN, servers, None, self.client_ipv4, self.client_ipv6) + query = self.diagnostic_query(name_obj.name, dns.rdatatype.NS, dns.rdataclass.IN, servers, None, self.client_ipv4, self.client_ipv6, odd_ports=odd_ports) query.execute(tm=self.transport_manager, th_factories=self.th_factories) self._add_query(name_obj, query, True) diff --git a/dnsviz/commands/probe.py b/dnsviz/commands/probe.py index aa527a9..1ed8dc3 100644 --- a/dnsviz/commands/probe.py +++ b/dnsviz/commands/probe.py @@ -64,6 +64,7 @@ tm = None full_resolver = None stub_resolver = None explicit_delegations = None +odd_ports = None A_ROOT_IPV4 = IPAddr('198.41.0.4') A_ROOT_IPV6 = IPAddr('2001:503:ba3e::2:30') @@ -95,7 +96,7 @@ def _init_resolver(): hints = get_root_hints() for key in explicit_delegations: hints[key] = explicit_delegations[key] - full_resolver = FullResolver(hints, transport_manager=tm) + full_resolver = FullResolver(hints, odd_ports=odd_ports, transport_manager=tm) def _init_interrupt_handler(): signal.signal(signal.SIGINT, _raise_eof) @@ -113,7 +114,7 @@ def _analyze(args): else: c = name try: - a = cls(name, dlv_domain=dlv_domain, try_ipv4=try_ipv4, try_ipv6=try_ipv6, client_ipv4=client_ipv4, client_ipv6=client_ipv6, ceiling=c, edns_diagnostics=edns_diagnostics, explicit_delegations=explicit_delegations, extra_rdtypes=extra_rdtypes, explicit_only=explicit_only, analysis_cache=cache, cache_level=cache_level, analysis_cache_lock=cache_lock, transport_manager=tm, th_factories=th_factories, resolver=full_resolver) + a = cls(name, dlv_domain=dlv_domain, try_ipv4=try_ipv4, try_ipv6=try_ipv6, client_ipv4=client_ipv4, client_ipv6=client_ipv6, ceiling=c, edns_diagnostics=edns_diagnostics, explicit_delegations=explicit_delegations, odd_ports=odd_ports, extra_rdtypes=extra_rdtypes, explicit_only=explicit_only, analysis_cache=cache, cache_level=cache_level, analysis_cache_lock=cache_lock, transport_manager=tm, th_factories=th_factories, resolver=full_resolver) return a.analyze() # re-raise a KeyboardInterrupt, as this means we've been interrupted except KeyboardInterrupt: @@ -340,6 +341,9 @@ def name_addr_mappings_from_string(domain, mappings): if isinstance(a, DNSAnswer): found_answer = True explicit_delegations[(name, rdtype)] = dns.rrset.from_text_list(name, 0, dns.rdataclass.IN, rdtype, [r.address for r in a.rrset]) + if port != 53: + for r in a.rrset: + odd_ports[(domain, IPAddr(r.address))] = port # negative responses elif isinstance(a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)): pass @@ -383,6 +387,8 @@ def name_addr_mappings_from_string(domain, mappings): if (name, a_rdtype) not in explicit_delegations: explicit_delegations[(name, a_rdtype)] = dns.rrset.RRset(name, dns.rdataclass.IN, a_rdtype) explicit_delegations[(name, a_rdtype)].add(rdtype_cls(dns.rdataclass.IN, a_rdtype, addr)) + if port != 53: + odd_ports[(domain, IPAddr(addr))] = port def usage(err=None): if err is not None: @@ -419,6 +425,7 @@ def main(argv): global full_resolver global stub_resolver global explicit_delegations + global odd_ports try: try: @@ -432,6 +439,7 @@ def main(argv): # get all the -x options explicit_delegations = {} + odd_ports = {} client_ipv4 = None client_ipv6 = None for opt, arg in opts: diff --git a/dnsviz/query.py b/dnsviz/query.py index db9fe1a..0f44afc 100644 --- a/dnsviz/query.py +++ b/dnsviz/query.py @@ -723,7 +723,7 @@ class DNSQueryHandler: def get_query_transport_meta(self): return transport.DNSQueryTransportMeta(self.request.to_wire(), self._server, self.params['tcp'], self.get_timeout(), \ - self.query.port, src=self._client, sport=self.params['sport']) + self.query.odd_ports.get(self._server, self.query.port), src=self._client, sport=self.params['sport']) def get_remaining_lifetime(self): if self._expiration is None: @@ -1208,7 +1208,7 @@ class ExecutableDNSQuery(DNSQuery): default_th_factory = transport.DNSQueryTransportHandlerDNSPrivateFactory() def __init__(self, qname, rdtype, rdclass, servers, bailiwick, - client_ipv4, client_ipv6, port, + client_ipv4, client_ipv6, port, odd_ports, flags, edns, edns_max_udp_payload, edns_flags, edns_options, tcp, response_handlers, query_timeout, max_attempts, lifetime): @@ -1222,11 +1222,15 @@ class ExecutableDNSQuery(DNSQuery): servers = set([servers]) if not servers: raise ValueError("At least one server must be specified for an ExecutableDNSQuery") + self.servers = servers self.bailiwick = bailiwick self.client_ipv4 = client_ipv4 self.client_ipv6 = client_ipv6 self.port = port + if odd_ports is None: + odd_ports = {} + self.odd_ports = odd_ports self.response_handlers = response_handlers self.query_timeout = query_timeout @@ -1487,7 +1491,7 @@ class DNSQueryFactory(object): response_handlers = [] def __new__(cls, qname, rdtype, rdclass, servers, bailiwick=None, - client_ipv4=None, client_ipv6=None, port=53, + client_ipv4=None, client_ipv6=None, port=53, odd_ports=None, query_timeout=None, max_attempts=None, lifetime=None, executable=True): @@ -1500,7 +1504,7 @@ class DNSQueryFactory(object): if executable: return ExecutableDNSQuery(qname, rdtype, rdclass, servers, bailiwick, - client_ipv4, client_ipv6, port, + client_ipv4, client_ipv6, port, odd_ports, cls.flags, cls.edns, cls.edns_max_udp_payload, cls.edns_flags, cls.edns_options, cls.tcp, cls.response_handlers, query_timeout, max_attempts, lifetime) diff --git a/dnsviz/resolver.py b/dnsviz/resolver.py index f0642f6..fa44ae7 100644 --- a/dnsviz/resolver.py +++ b/dnsviz/resolver.py @@ -290,12 +290,15 @@ class FullResolver: MIN_TTL = 60 MAX_CHAIN = 20 - def __init__(self, hints=util.get_root_hints(), query_cls=(query.QuickDNSSECQuery, query.RobustDNSSECQuery), client_ipv4=None, client_ipv6=None, transport_manager=None, th_factories=None): + def __init__(self, hints=util.get_root_hints(), query_cls=(query.QuickDNSSECQuery, query.RobustDNSSECQuery), client_ipv4=None, client_ipv6=None, odd_ports=None, transport_manager=None, th_factories=None): self._hints = hints self._query_cls = query_cls self._client_ipv4 = client_ipv4 self._client_ipv6 = client_ipv6 + if odd_ports is None: + odd_ports = {} + self._odd_ports = odd_ports self._transport_manager = transport_manager self._th_factories = th_factories @@ -528,7 +531,7 @@ class FullResolver: ns_names[ns_name].add(IPAddr(rdata.address)) for server in ns_names[ns_name]: - query = query_cls(qname, rdtype, rdclass, (server,), bailiwick, self._client_ipv4, self._client_ipv6) + query = query_cls(qname, rdtype, rdclass, (server,), bailiwick, self._client_ipv4, self._client_ipv6, self._odd_ports.get((bailiwick, server), 53)) query.execute(tm=self._transport_manager, th_factories=self._th_factories) is_referral = False |