public void TestNotAuthorityWhenPTRIsUnknown() { // We can't be authorities for PTR records we don't recognize var zone = new DNSZone(start_of_authority, relays); Assert.That(zone.IsAuthorityFor(new Domain("1.0.168.192.in-addr.arpa")), Is.False); }
public void TestNotAuthorityWithoutDelegation() { // Ensure that we are not considered authoritative for things clearly // outside of our zone var zone = new DNSZone(start_of_authority, relays); Assert.That(zone.IsAuthorityFor(new Domain("bogus.com")), Is.False); }
public void TestAuthorityWithoutDelegation() { // Ensure that we are considered authoritative for things that // are in our zone (without involvement by subzones) var zone = new DNSZone(start_of_authority, relays); Assert.That(zone.IsAuthorityFor(new Domain("www.example.com")), Is.True); }
public void TestAuthorityWithDelegation() { // Ensures that we're not an authority for things that are subzones var zone = new DNSZone(start_of_authority, relays); var subzone = new DNSRecord( new Domain("foo.example.com"), AddressClass.INTERNET, 42, new NSResource(new Domain("ns.foo.example.com"))); zone.Add(subzone); Assert.That(zone.IsAuthorityFor(new Domain("www.foo.example.com")), Is.False); }
public void TestAuthorityWhenPTRIsKnownV6() { // We should be an authority for a PTR record that we know about var zone = new DNSZone(start_of_authority, relays); var ptr = new DNSRecord( new Domain("b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa"), AddressClass.INTERNET, 42, new PTRResource(new Domain("www.example.com"))); zone.Add(ptr); Assert.That(zone.IsAuthorityFor(new Domain("b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa")), Is.True); }
public void TestAuthorityWhenEqualToDelegation() { // Ensure that we are an authority for the subzone's address itself (which can // occur if, say, there's a CNAME pointing to it) var zone = new DNSZone(start_of_authority, relays); var subzone = new DNSRecord( new Domain("foo.example.com"), AddressClass.INTERNET, 42, new NSResource(new Domain("ns.foo.example.com"))); zone.Add(subzone); Assert.That(zone.IsAuthorityFor(new Domain("foo.example.com")), Is.True); }
/** * Resolves the given query, returning a QueryResult that contains * everything we found while doing the resolution. */ public QueryResult Execute(Domain domain, ResourceRecordType rtype, AddressClass addr_class, bool recursive) { logger.Trace("Executing query on {0} for type {1} with recursion {2}", domain, rtype, recursive); if (zone.IsAuthorityFor(domain)) { var records = zone.Query(domain, rtype, addr_class).ToList(); // It is possible that there is a CNAME that we should be aware of - in that case, check // it and see if we can find one. if (records.Count == 0) { var cname_records = zone.Query(domain, ResourceRecordType.CANONICAL_NAME, addr_class).ToArray(); if (cname_records.Length != 0) { logger.Trace("Authoritative for CNAMEs, re-executing"); // In this case, try again with the alias var alias = ((CNAMEResource)cname_records[0].Resource).Alias; var alias_results = Execute(alias, rtype, addr_class, recursive); // The RFC directs us to return any intermediate CNAMEs, which we do alias_results.Answers.InsertRange(0, cname_records); return(alias_results); } } var result = new QueryResult(); result.IsAuthority = true; result.FoundAnswer = true; result.Answers = new List <DNSRecord>(); result.Authority = new List <DNSRecord>(); result.Additional = new List <DNSRecord>(); result.Answers.AddRange(records); result.Authority.Add(zone.StartOfAuthority); return(result); } else { var owning_subzone = zone.FindSubZone(domain); if (owning_subzone != null) { logger.Trace("Subzone {0} is authoritative", owning_subzone); // We can punt on the computation to our subzone delgation var subzone_nameservers = zone.Query(owning_subzone, ResourceRecordType.NAME_SERVER, addr_class); var subzone_nameserver_addr_records = subzone_nameservers .SelectMany(ns => zone.Query(ns.Name, ResourceRecordType.HOST_ADDRESS, addr_class)); var subzone_nameserver_addrs = subzone_nameserver_addr_records.Select( record => new IPEndPoint(((AResource)record.Resource).Address, 53) ).ToArray(); IEnumerable <DNSRecord> response = null; try { var info = resolver.Resolve(domain, ResourceRecordType.HOST_ADDRESS, addr_class, subzone_nameserver_addrs); response = info.aliases.Concat(info.answers).ToList(); } catch (ResolverException err) { logger.Trace("Could not resolve from subzone: {0}", err); response = new DNSRecord[] { }; } var result = new QueryResult(); result.IsAuthority = false; result.FoundAnswer = response.Count() > 0; result.Answers = new List <DNSRecord>(response); result.Authority = new List <DNSRecord>(subzone_nameservers); result.Additional = new List <DNSRecord>(subzone_nameserver_addr_records); return(result); } else if (recursive) { // We'll have to go outside our zone and use the general-purpose resolver ResolverResult response; logger.Trace("No authoritative server is local, executing recursive resolver"); try { response = resolver.Resolve(domain, rtype, addr_class, zone.Relays); } catch (ResolverException err) { logger.Trace("Could not resolve: {0}", err); response = new ResolverResult(); response.answers = new List <DNSRecord>(); response.aliases = new List <DNSRecord>(); response.referrals = new List <DNSRecord>(); response.referral_additional = new List <DNSRecord>(); } var result = new QueryResult(); result.IsAuthority = false; result.FoundAnswer = response.answers.Count() > 0; result.Answers = response.aliases.Concat(response.answers).ToList(); result.Authority = response.referrals.ToList(); result.Additional = response.referral_additional.ToList(); return(result); } else { var cached_responses = cache.Query(domain, AddressClass.INTERNET, rtype); if (cached_responses.Count > 0) { logger.Trace("Non-recursive search found {0} cached results", cached_responses.Count); var cached_result = new QueryResult(); cached_result.IsAuthority = false; cached_result.FoundAnswer = true; cached_result.Answers = cached_responses.ToList(); cached_result.Additional = new List <DNSRecord>(); cached_result.Authority = new List <DNSRecord>(); return(cached_result); } // If we can't recurse, and our cache knows nothing, then punt onto the forwarder logger.Trace("Executing limited-case non-recursive resolver"); var question = new DNSQuestion(domain, rtype, AddressClass.INTERNET); foreach (var forwarder in zone.Relays) { try { var forward_result = ResolverUtils.SendQuery(forwarder, question, false); // If the server doesn't like our request, then pass it to something else if (forward_result.ResponseType != ResponseType.NO_ERROR && forward_result.ResponseType != ResponseType.NAME_ERROR) { continue; } var forward_return = new QueryResult(); forward_return.FoundAnswer = forward_result.ResponseType == ResponseType.NO_ERROR; forward_return.IsAuthority = false; forward_return.Answers = forward_result.Answers.ToList(); forward_return.Additional = forward_result.AdditionalRecords.ToList(); forward_return.Authority = forward_result.AuthoritativeAnswers.ToList(); return(forward_return); } catch (SocketException err) { // We can safely punt onto the next forwarder if one bails logger.Trace("Could not request from {0}: {1}", forwarder, err); } } // We can't do anything else here, so there is no such host, as far as we knot var result = new QueryResult(); result.FoundAnswer = false; result.IsAuthority = false; result.Answers = new List <DNSRecord>(); result.Authority = new List <DNSRecord>(); result.Additional = new List <DNSRecord>(); return(result); } } }