internal ResolutionResult(int nestingLevel, DnsClient.Request request, DnsClient.Response response, NameServerCollection authorities) { this.NestingLevel = nestingLevel; this.Request = request; this.Response = response; _Authorities = authorities; }
public virtual void Reset() { CurrentResult = null; IsCompleted = false; _IterationCount = 0; StoredAuthorities = null; }
//protected virtual void OnResolutionCompleted(DnsClient.DNS.QTYPE question, DnsClient.Response response) //{ // IEnumerable<DnsClient.DNS.RR> requested = response.AnswerRecords.OfQuestion(question); // if (requested.Any()) // { // // The requested record type was found. // LogMessageCreate(Logging.LogMessageText.RESPONSE.ResolutionSucceded(Resolver.Domain, Question, requested)); // } // else // { // // The requested record type was NOT found. // if (question == DnsClient.DNS.QTYPE.ANY) // { // // The question is ANY, so the result is acceptable. // LogMessageCreate(Logging.LogMessageText.RESPONSE.AnyResolutionSucceded(response.AnswerRecords)); // } // else // { // // maybe CNAME // } // } //} #endregion #region private private Results.ResolutionResult Request(NameServerCollection authorities, out bool isCompleted) { // perform name server request DnsClient.Request request; IPAddress address = authorities.Selected.GetFirstAddress(Resolver.Options.IPVersion); DnsClient.Response response = Resolver.LookUp(address, Question, out request); Results.ResolutionResult result = new Results.ResolutionResult(this.NestingLevel, request, response, authorities); // "Request took {0}ms." LogMessageCreate(Logging.LogMessageText.RESPONSE.INFO.RequestDuration(result.Duration.TotalMilliseconds)); if (response.Header.AA) { // authoritative response isCompleted = true; } else { // [RFC 1035] // Name Error - Meaningful only for responses from an authoritative name server, // this code signifies that the domain name referenced in the query does not exist. // stop if the response was any other than NoError or NameError isCompleted = !( response.Header.RCODE == DnsClient.DNS.RCODE.NoError || response.Header.RCODE == DnsClient.DNS.RCODE.NameError); } return(result); }
protected virtual void OnNextAuthorities(NameServer ns, NameServerCollection authorities) { foreach (IGrouping <int, NameServer> nsg in authorities.Groupings) { LogMessageCreate(Logging.LogMessageText.RESPONSE.INFO.NextAuthoritiesReceived( ns.Name, nsg.First().Zone, authorities)); } }
public static LogMessage ResolutionStart(DnsDomain name, NameServerCollection authorities) { if (authorities.ZoneName.Equals(DnsDomain.Root)) { // "Starting resolution of '{0}' with a root name server." return REQUEST.INFO.StartingResultion(name); } // "Starting resolution of '{0}' with a '{1}' authority name server." return REQUEST.INFO.StartingResultion(name, authorities); }
public static LogMessage ResolutionStart(DnsDomain name, NameServerCollection authorities) { if (authorities.ZoneName.Equals(DnsDomain.Root)) { // "Starting resolution of '{0}' with a root name server." return(REQUEST.INFO.StartingResultion(name)); } // "Starting resolution of '{0}' with a '{1}' authority name server." return(REQUEST.INFO.StartingResultion(name, authorities)); }
private Iterators.CNameIterator CreateCNameIterator(DnsDomain cname, NameServerCollection authorities) { // TODO // apply authorties Iterators.CNameIterator iterator = new CNameIterator(this, (DnsDomain)cname); if (LogMessageCreated != null) { iterator.LogMessageCreated += new DnsClient.Logging.LogMessageEventHandler(OnSubIteratorLogMessage); } return(iterator); }
private NameServerCollection GetResultAuthorities(Results.ResolutionResult result) { // get authority records from existing result NameServerCollection authorities = NameServerCollection.Create( result.Response.AuthorityRecords, result.Response.AdditionalRecords); // save top level name server cache if (!RootCacheState) { RootServers.Cache.Set(authorities.ZoneName, authorities); RootCacheState = true; } return(authorities); }
private NameServerCollection GetStartAuthorities() { NameServerCollection authorities = null; // initial state: // get cached top level name servers or root hints if (Resolver.Options.UseRootCache) { authorities = RootServers.Cache.Get(Resolver.Domain); } if (authorities == null) { // either RootCache disabled or not found in cache authorities = RootServers.RootHints; RootCacheState = false; } return(authorities); }
protected virtual void OnResolutionStart(NameServerCollection authorities) { // "Starting resolution of '{0}' with a '{1}' authority name server." LogMessageCreate(Logging.LogMessageText.REQUEST.ResolutionStart(Resolver.Domain, authorities)); }
private Results.ResolutionResult Request(NameServerCollection authorities, out bool isCompleted) { // perform name server request DnsClient.Request request; IPAddress address = authorities.Selected.GetFirstAddress(Resolver.Options.IPVersion); DnsClient.Response response = Resolver.LookUp(address, Question, out request); Results.ResolutionResult result = new Results.ResolutionResult(this.NestingLevel, request, response, authorities); // "Request took {0}ms." LogMessageCreate(Logging.LogMessageText.RESPONSE.INFO.RequestDuration(result.Duration.TotalMilliseconds)); if (response.Header.AA) { // authoritative response isCompleted = true; } else { // [RFC 1035] // Name Error - Meaningful only for responses from an authoritative name server, // this code signifies that the domain name referenced in the query does not exist. // stop if the response was any other than NoError or NameError isCompleted = !( response.Header.RCODE == DnsClient.DNS.RCODE.NoError || response.Header.RCODE == DnsClient.DNS.RCODE.NameError); } return result; }
private Iterators.CNameIterator CreateCNameIterator(DnsDomain cname, NameServerCollection authorities) { // TODO // apply authorties Iterators.CNameIterator iterator = new CNameIterator(this, (DnsDomain)cname); if (LogMessageCreated != null) { iterator.LogMessageCreated += new DnsClient.Logging.LogMessageEventHandler(OnSubIteratorLogMessage); } return iterator; }
protected virtual void OnResolutionContinue(NameServerCollection authorities) { // "Continuing resolution of '{0}' with a '{1}' authority." LogMessageCreate(Logging.LogMessageText.REQUEST.INFO.ContinuingResultion(Resolver.Domain, authorities)); }
public static LogMessage NextAuthoritiesReceived(DnsDomain server, DnsDomain name, NameServerCollection nextAuthorities) { return Create(Resources.LogMessages.NextAuthoritiesReceived, new object[] { server, name, nextAuthorities.Count }); }
protected virtual void OnAuthoritySelected(NameServerCollection authorities) { // "Name server '{0}' has been selected." LogMessageCreate(Logging.LogMessageText.REQUEST.INFO.AuthoritySelected(authorities)); }
public static LogMessage AuthoritySelected(NameServerCollection authorities) { return(Create(Resources.LogMessages.AuthoritySelected, new object[] { authorities.Selected.Name })); }
public static LogMessage StartingResultion(DnsDomain name, NameServerCollection authorities) { return Create(Resources.LogMessages.StartingResultion, new object[] { name, authorities.ZoneName }); }
public static LogMessage ContinuingResultion(DnsDomain domain, NameServerCollection authorities) { return Create(Resources.LogMessages.ContinuingResultion, new object[] { domain, authorities.ZoneName }); }
public static LogMessage AuthoritySelected(NameServerCollection authorities) { return Create(Resources.LogMessages.AuthoritySelected, new object[] { authorities.Selected.Name }); }
public QueryResult Process() { // [RFC 1034], 5.3.3. Algorithm // // 4. Analyze the response, either: // // a. if the response answers the question or contains a name // error, cache the data as well as returning it back to // the client. // // b. if the response contains a better delegation to other // servers, cache the delegation information, and go to // step 2. // // c. if the response shows a CNAME and that is not the // answer itself, cache the CNAME, change the SNAME to the // canonical name in the CNAME RR and go to step 1. // // d. if the response shows a servers failure or other // bizarre contents, delete the server from the SLIST and // go back to step 3. // // Step 4 involves analyzing responses. The resolver should be highly // paranoid in its parsing of responses. // Verify the question section matches the query. if (Response.Questions.Count == 1) { DnsClient.DNS.Question q = Response.Questions.First(); if (!this.SNAME.Equals(q.QNAME) || this.STYPE != q.QTYPE) { throw new QueryException(QueryState.MissingQuestion); } } else { throw new QueryException(QueryState.MissingQuestion); } // Check for unhandled RCODE. if (!(Response.Header.RCODE == DnsClient.DNS.RCODE.NoError || Response.Header.RCODE == DnsClient.DNS.RCODE.NameError)) { return(new QueryResult { State = QueryState.UnexpectedRCode }); } // RCODE.NoError or RCODE.NameError if (!Response.Header.AA) { // Non-Authoritative Answer NameServerCollection nextAuthorities = FindAuthorities(SNAME); if (nextAuthorities.Any()) { // Referral response: authorities is not empty. // Check for relevant answer RRs matching STYPE within additional RRs IEnumerable <DnsClient.DNS.RR> additional = Response.AdditionalRecords.Where( rr => SNAME.Equals(rr.Base.NAME)).OfQuestion(STYPE); if (additional.Any()) { // Found answer RRs matching the query. return(new QueryResult { Answers = additional, State = QueryState.NonAuthoritativeAnswer }); } return(new QueryResult { NextAuthorities = nextAuthorities, State = QueryState.NextAuthorities }); } return(new QueryResult { State = QueryState.MissingAuthorities }); } // Authoritative Answer // Process CNAMEs unless the question is CNAME. // Even on RCODE.NameError CNAMEs need to be applied // (cf.: [RFC 2308], 2.1 - Name Error). bool cnamed = false; DnsDomain canonical = SNAME; if (STYPE != DnsClient.DNS.QTYPE.CNAME) { // resolve internal CNAME chain cnamed = FindCanonical(ref canonical); } if (Response.Header.RCODE == DnsClient.DNS.RCODE.NameError) { // RCODE.NameError // [RFC 2308], 2.1 - Name Error // // Name errors (NXDOMAIN) are indicated by the presence of "Name Error" // in the RCODE field. In this case the domain referred to by the QNAME // does not exist. Note: the answer section may have SIG and CNAME RRs // and the authority section may have SOA, NXT [RFC2065] and SIG RRsets. // // It is possible to distinguish between a referral and a NXDOMAIN // response by the presense of NXDOMAIN in the RCODE regardless of the // presence of NS or SOA records in the authority section. return(new QueryResult { CanonicalName = cnamed ? canonical : null, SOA = Response.AuthorityRecords.FirstOrDefault < DnsClient.DNS.Records.SOA>(), State = QueryState.NxDomain }); } // Authoritative RCODE.NoError // Check for relevant answer RRs matching the canonical name and STYPE. IEnumerable <DnsClient.DNS.RR> answers = Response.AnswerRecords.Where( rr => canonical.Equals(rr.Base.NAME)).OfQuestion(STYPE); if (answers.Any()) { // Found answer RRs matching the query. return(new QueryResult { CanonicalName = cnamed ? canonical : null, Answers = answers, State = QueryState.AuthoritativeAnswer }); } // NoData or referral CNAME response // [RFC 2308], 2.2 - No Data // // It is possible to distinguish between a NODATA and a referral // response by the presence of a SOA record in the authority section or // the absence of NS records in the authority section. DnsClient.DNS.Records.SOA soa = Response.AuthorityRecords.FirstOrDefault < DnsClient.DNS.Records.SOA>(); NameServerCollection authorities = FindAuthorities(canonical); if (!object.ReferenceEquals(null, soa) || authorities.Any()) { // NODATA // Do not treat as referral (cf.: [RFC 2308], 2.2 - No Data) return(new QueryResult { SOA = soa, CanonicalName = cnamed ? canonical : null, State = QueryState.NoData }); } // Referral response: authorities is not empty. if (cnamed) { // referral CNAME return(new QueryResult { CanonicalName = canonical, NextAuthorities = FindAuthorities(canonical), State = QueryState.FollowCName }); } return(new QueryResult { State = QueryState.EmptyResponse }); }
private NameServerCollection FindAuthorities(DnsDomain sname) { // NS RRs from Authority Section, resolved by Additional address RRs. return(NameServerCollection.Find( sname, Response.AuthorityRecords, Response.AdditionalRecords)); }
protected virtual void OnNextAuthorities(NameServer ns, NameServerCollection authorities) { foreach (IGrouping<int, NameServer> nsg in authorities.Groupings) { LogMessageCreate(Logging.LogMessageText.RESPONSE.INFO.NextAuthoritiesReceived( ns.Name, nsg.First().Zone, authorities)); } }
internal AddressResolutionResult(int nestingLevel, DnsClient.Request request, DnsClient.Response response, NameServerCollection authorities) : base(nestingLevel, request, response, authorities) { }
public static LogMessage StartingResultion(DnsDomain name, NameServerCollection authorities) { return(Create(Resources.LogMessages.StartingResultion, new object[] { name, authorities.ZoneName })); }
public static LogMessage ContinuingResultion(DnsDomain domain, NameServerCollection authorities) { return(Create(Resources.LogMessages.ContinuingResultion, new object[] { domain, authorities.ZoneName })); }
public static LogMessage NextAuthoritiesReceived(DnsDomain server, DnsDomain name, NameServerCollection nextAuthorities) { return(Create(Resources.LogMessages.NextAuthoritiesReceived, new object[] { server, name, nextAuthorities.Count })); }