Пример #1
0
 internal ResolutionResult(int nestingLevel, DnsClient.Request request, DnsClient.Response response, NameServerCollection authorities)
 {
     this.NestingLevel = nestingLevel;
     this.Request      = request;
     this.Response     = response;
     _Authorities      = authorities;
 }
Пример #2
0
 internal ResolutionResult(int nestingLevel, DnsClient.Request request, DnsClient.Response response, NameServerCollection authorities)
 {
     this.NestingLevel = nestingLevel;
       this.Request = request;
       this.Response = response;
       _Authorities = authorities;
 }
Пример #3
0
 public virtual void Reset()
 {
     CurrentResult     = null;
     IsCompleted       = false;
     _IterationCount   = 0;
     StoredAuthorities = null;
 }
Пример #4
0
        //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);
        }
Пример #5
0
 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));
     }
 }
Пример #6
0
            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);
            }
Пример #7
0
            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));
            }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
 protected virtual void OnResolutionStart(NameServerCollection authorities)
 {
     // "Starting resolution of '{0}' with a '{1}' authority name server."
     LogMessageCreate(Logging.LogMessageText.REQUEST.ResolutionStart(Resolver.Domain, authorities));
 }
Пример #12
0
        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;
        }
Пример #13
0
        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;
        }
Пример #14
0
 protected virtual void OnResolutionStart(NameServerCollection authorities)
 {
     // "Starting resolution of '{0}' with a '{1}' authority name server."
       LogMessageCreate(Logging.LogMessageText.REQUEST.ResolutionStart(Resolver.Domain, authorities));
 }
Пример #15
0
 protected virtual void OnResolutionContinue(NameServerCollection authorities)
 {
     // "Continuing resolution of '{0}' with a '{1}' authority."
       LogMessageCreate(Logging.LogMessageText.REQUEST.INFO.ContinuingResultion(Resolver.Domain, authorities));
 }
Пример #16
0
 public static LogMessage NextAuthoritiesReceived(DnsDomain server, DnsDomain name, NameServerCollection nextAuthorities)
 {
     return Create(Resources.LogMessages.NextAuthoritiesReceived,
     new object[] { server, name, nextAuthorities.Count });
 }
Пример #17
0
 protected virtual void OnAuthoritySelected(NameServerCollection authorities)
 {
     // "Name server '{0}' has been selected."
     LogMessageCreate(Logging.LogMessageText.REQUEST.INFO.AuthoritySelected(authorities));
 }
Пример #18
0
 public static LogMessage AuthoritySelected(NameServerCollection authorities)
 {
     return(Create(Resources.LogMessages.AuthoritySelected, new object[] { authorities.Selected.Name }));
 }
Пример #19
0
 public static LogMessage StartingResultion(DnsDomain name, NameServerCollection authorities)
 {
     return Create(Resources.LogMessages.StartingResultion, new object[] { name, authorities.ZoneName });
 }
Пример #20
0
 public static LogMessage ContinuingResultion(DnsDomain domain, NameServerCollection authorities)
 {
     return Create(Resources.LogMessages.ContinuingResultion, new object[] { domain, authorities.ZoneName });
 }
Пример #21
0
 public static LogMessage AuthoritySelected(NameServerCollection authorities)
 {
     return Create(Resources.LogMessages.AuthoritySelected, new object[] { authorities.Selected.Name });
 }
Пример #22
0
        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
            });
        }
Пример #23
0
 protected virtual void OnResolutionContinue(NameServerCollection authorities)
 {
     // "Continuing resolution of '{0}' with a '{1}' authority."
     LogMessageCreate(Logging.LogMessageText.REQUEST.INFO.ContinuingResultion(Resolver.Domain, authorities));
 }
Пример #24
0
 private NameServerCollection FindAuthorities(DnsDomain sname)
 {
     // NS RRs from Authority Section, resolved by Additional address RRs.
     return(NameServerCollection.Find(
                sname, Response.AuthorityRecords, Response.AdditionalRecords));
 }
Пример #25
0
 protected virtual void OnAuthoritySelected(NameServerCollection authorities)
 {
     // "Name server '{0}' has been selected."
       LogMessageCreate(Logging.LogMessageText.REQUEST.INFO.AuthoritySelected(authorities));
 }
Пример #26
0
 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));
       }
 }
Пример #27
0
 internal AddressResolutionResult(int nestingLevel, DnsClient.Request request, DnsClient.Response response, NameServerCollection authorities)
     : base(nestingLevel, request, response, authorities)
 {
 }
Пример #28
0
 public static LogMessage StartingResultion(DnsDomain name, NameServerCollection authorities)
 {
     return(Create(Resources.LogMessages.StartingResultion, new object[] { name, authorities.ZoneName }));
 }
Пример #29
0
 public static LogMessage ContinuingResultion(DnsDomain domain, NameServerCollection authorities)
 {
     return(Create(Resources.LogMessages.ContinuingResultion, new object[] { domain, authorities.ZoneName }));
 }
Пример #30
0
 internal AddressResolutionResult(int nestingLevel, DnsClient.Request request, DnsClient.Response response, NameServerCollection authorities)
     : base(nestingLevel, request, response, authorities)
 {
 }
Пример #31
0
 public static LogMessage NextAuthoritiesReceived(DnsDomain server, DnsDomain name, NameServerCollection nextAuthorities)
 {
     return(Create(Resources.LogMessages.NextAuthoritiesReceived,
                   new object[] { server, name, nextAuthorities.Count }));
 }