Ejemplo n.º 1
0
 public DnsResponse Get(DnsRequest request)
 {
     ushort requestID = request.RequestID;
     DnsResponse response = null;
     try
     {
         using (DnsClient client = new DnsClient(m_serverIP))
         {
             if (m_timeout != null)
             {
                 client.Timeout = m_timeout.Value;
             }
             response = client.Resolve(request);
         }
     }
     finally
     {
         if (response != null)
         {
             response.RequestID = requestID;
         }            
         request.RequestID = requestID;
     }
     return response;
 }
Ejemplo n.º 2
0
        DnsResponse ProcessRequest(DnsRequest request)
        {
            DnsStandard.RecordType questionType = request.Question.Type;
            DnsResponse response = new DnsResponse(request);
            response.Header.IsAuthoritativeAnswer = true;
            
            switch (response.Question.Type)
            {
                default:
                    throw new DnsServerException(DnsStandard.ResponseCode.NotImplemented);

                case DnsStandard.RecordType.ANAME:
                    ProcessANAMEQuestion(response);
                    break;
                case DnsStandard.RecordType.NS:
                    ProcessNSQuestion(response);
                    break;
                case DnsStandard.RecordType.MX:
                    ProcessMXQuestion(response);
                    break;
                case DnsStandard.RecordType.SOA:
                    ProcessSOAQuestion(response);
                    break;
                case DnsStandard.RecordType.CERT:
                    ProcessCERTQuestion(response);
                    break;
                case DnsStandard.RecordType.CNAME:
                    ProcessCNAMEQuestion(response);
                    break;                    
            }
            
            return response;
        }
Ejemplo n.º 3
0
 public DnsRequest ReceiveRequest()
 {
     DnsBuffer responseBuffer = this.ReceiveBuffer();
     DnsRequest request = new DnsRequest(responseBuffer.CreateReader());
     Assert.True(!string.IsNullOrEmpty(request.Question.Domain));
     return request;
 }
Ejemplo n.º 4
0
        DnsResponse CreateResponse(DnsRequest request, IEnumerable<DnsResourceRecord> matches)
        {
            DnsStandard.RecordType questionType = request.Question.Type;
            DnsResponse response = new DnsResponse(request);
            int matchCount = 0;
            foreach (DnsResourceRecord record in matches)
            {
                if (record.Type == questionType)
                {
                    ++matchCount;
                    switch (record.Type)
                    {
                        default:
                            response.AnswerRecords.Add(record);
                            break;

                        case DnsStandard.RecordType.NS:
                        case DnsStandard.RecordType.SOA:
                            response.AnswerRecords.Add(record);
                            break;
                    }
                }
            }
            
            if (matchCount == 0)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.NameError);
            }
            
            return response;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Convenience method resolving and returning SOA RRs.
        /// </summary>
        /// <param name="domain">
        /// The domain name to resolve.
        /// </param>
        /// <returns>
        /// An enumeration of SOA Records. See <see cref="SOARecord"/>
        /// </returns>
        public IEnumerable <SOARecord> ResolveSOA(string domain)
        {
            DnsResponse response = this.Resolve(DnsRequest.CreateSOA(domain));

            if (response != null)
            {
                if (response.HasNameServerRecords)
                {
                    return(response.NameServerRecords.SOA);
                }

                if (response.HasAnswerRecords)
                {
                    return(response.AnswerRecords.SOA);
                }
            }

            return(null);
        }
        public DnsResponse Get(DnsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException();
            }

            DnsQuestion question = request.Question;
            if (question == null || question.Class != DnsStandard.Class.IN)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.NotImplemented);
            }
            
            DnsResponse response = this.ProcessRequest(request); 
            //
            // Usually need some post-processing on the response
            //   
            return this.ProcessResponse(response);    
        }
Ejemplo n.º 7
0
 public DnsResponse Get(DnsRequest request)
 {
     if (request == null)
     {
         throw new ArgumentNullException();
     }
     
     DnsQuestion question = request.Question;
     if (question == null || question.Class != DnsStandard.Class.IN)
     {
         return null;
     }
     
     IEnumerable<DnsResourceRecord> matches = m_records[request.Question.Domain];
     if (matches == null)
     {
         return null;
     }
     
     return this.CreateResponse(request, matches);
 }
Ejemplo n.º 8
0
        public DnsResponse ProcessRequest(DnsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException();
            }
            
            this.Received.SafeInvoke(request);
            
            DnsResponse response = null;
            try
            {
                this.Validate(request);

                response = m_store.Get(request);
                if (response == null || !response.IsSuccess)
                {
                    throw new DnsServerException(DnsStandard.ResponseCode.NameError);
                }
                
                this.FixupTTL(response);
            }
            catch (DnsProtocolException)
            {
                response = this.ProcessError(request, DnsStandard.ResponseCode.FormatError);
            }
            catch (DnsServerException serverEx)
            {
                response = this.ProcessError(request, serverEx.ResponseCode);
            }
            catch(Exception ex)
            {
                this.HandleException(ex);
                response = this.ProcessError(request, DnsStandard.ResponseCode.ServerFailure);
            }
            
            this.Responding.SafeInvoke(response);
            
            return response;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Handle the DNS query.
        /// </summary>        
        public DnsResponse Get(DnsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request"); 
            }

            DnsQuestion question = request.Question;
            if (question == null || question.Class != DnsStandard.Class.IN)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.NotImplemented);
            }

            /* Don't handle NS and SOA record recursilvey since these are retrieved from the primary
             * DNS servers and are cached. So, we would always end up retrieving the cached values 
             * from the primary DNS servers. */
            if (request.Question.Type != DnsStandard.RecordType.ANAME &&
                request.Question.Type != DnsStandard.RecordType.CERT &&
                request.Question.Type != DnsStandard.RecordType.CNAME &&
                request.Question.Type != DnsStandard.RecordType.MX)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.NotImplemented);
            }

            DnsResponse response = ProcessRequest(request);

            return response; 
        }        
Ejemplo n.º 10
0
        static IEnumerable<SRVRecord> RequestSrv(DnsClient client, string domain)
        {
            var dnsRequest = new DnsRequest(DnsStandard.RecordType.SRV, domain);
            var response = client.Resolve(dnsRequest);
            if (response == null || !response.HasAnswerRecords)
            {
                return null;
            }

            return response.AnswerRecords.SRV
                .OrderBy(r => r.Priority)
                .OrderByDescending(r => r.Weight);
        }
Ejemplo n.º 11
0
 public DnsResponse Get(DnsRequest request)
 {
     long requestNumber = System.Threading.Interlocked.Increment(ref m_requestCount);
     if (this.SuccessInterval <= 0 || (requestNumber % this.SuccessInterval) != 0)
     {
         if (this.ThrowDnsException)
         {
             throw new DnsServerException(ErrorCode);
         }
         
         throw new InvalidOperationException();
     }
     
     return m_innerStore.Get(request);
 }
Ejemplo n.º 12
0
        protected void Validate(DnsRequest request)
        {
            request.Validate();
            if (request.Header.QuestionCount < 1)
            {
                throw new DnsProtocolException(DnsProtocolError.InvalidQuestionCount);
            }

            if (request.Header.QuestionCount > this.Settings.MaxQuestionCount)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.Refused);
            }
        }
Ejemplo n.º 13
0
 void SerializeRequest(DnsRequest request)
 {
     m_requestBuffer.Clear();
     request.Serialize(m_requestBuffer);
 }
Ejemplo n.º 14
0
 public void Send(DnsRequest request)
 {
     DnsBuffer requestBuffer = new DnsBuffer();
     request.Serialize(requestBuffer);
     this.SendBuffer(requestBuffer);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// overrides base resolve method to provide cache funcationality at time of resolution
        /// </summary>
        /// <param name="request"></param>
        /// <returns>DnsResponse containing the results either pulled from cache or manually resolved</returns>
        public override DnsResponse Resolve(DnsRequest request)
        {
            //----------------------------------------------------------------------------------------------------
            //---check to see if the item is in the cache
            DnsResponse dr = m_cache.Get(request);
            if (dr != null)
            {
                return dr;
            }

            //----------------------------------------------------------------------------------------------------
            //---item as not found in cache, try to get it from the base class
            dr = base.Resolve(request);
            if (dr != null)
            {
                //----------------------------------------------------------------------------------------------------
                //---if found store in the cache for future use
                //---Potential for negative caching here 
                m_cache.Put(dr);
            }
            
            return dr;
        }
Ejemplo n.º 16
0
        DnsResponse ProcessRequest(DnsRequest request)
        {
            IEnumerable<IPAddress> nameServers = GetNameServers(request.Question.Domain);
            
            if (nameServers == null)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.NameError); 
            }

            bool useUdp = request.Question.Type == DnsStandard.RecordType.CERT ? false : true;

            int count = 0; 
            DnsResponse response = null; 
            foreach (IPAddress nameserver in nameServers)
            {                 
                DnsClient client = null;
                try
                {
                    if (m_doCache)
                    {
                        client = new DnsClientWithCache(new IPEndPoint(nameserver, m_dnsResolutionPort));
                    }
                    else
                    {
                        client = new DnsClient(new IPEndPoint(nameserver, m_dnsResolutionPort));
                    }

                    client.Timeout = Timeout;
                    client.UseUDPFirst = useUdp;
                    DnsRequest newRequest = new DnsRequest(new DnsQuestion(request.Question));
                    response = client.Resolve(newRequest);

                    if (response != null)
                    {
                        // Clone the response before returning it since the response may be cached
                        // and we don't want the cached response to be modified.
                        response = response.Clone();
                        
                        // updates the TTL of records to reflect the elapsed time since the 
                        // record was cached. 
                        response.UpdateRecordsTTL(); 
                        break;
                    }
                }
                catch (DnsException)
                {
                    continue; 
                }
                finally
                {
                    if (client != null)
                    {
                        client.Dispose();
                    }
                }

                count++;
                if (count > m_maxNameServersToAttempt)
                {
                    break; 
                }
            }

            if (response == null)
            {
                throw new DnsServerException(DnsStandard.ResponseCode.ServerFailure); 
            }

            response.RequestID = request.RequestID;            

            return response; 
        }        
Ejemplo n.º 17
0
        /// <summary>
        /// Resolves a DNS Request and returns a DnsResponse response instance.
        /// </summary>
        /// <param name="request">
        /// The DNS Request to resolve. See <see cref="DnsRequest"/>
        /// </param>
        /// <returns>
        /// A DNS Response instance representing the response. See <see cref="DnsResponse"/>
        /// </returns>
        /// <exception cref="DnsException">Thrown for network failure (e.g. max retries exceeded) or badly formed responses.</exception>
        public virtual DnsResponse Resolve(DnsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            
            request.Validate();
               
            request.RequestID = this.NextID();
            this.SerializeRequest(request);

            bool useUDPFirst = this.UseUDPFirst;
            int attempt = 0;
            int maxAttempts = this.m_maxRetries + 1;
            while (attempt < maxAttempts)
            {
                attempt++;
                try
                {
                    if (useUDPFirst)
                    {
                        this.ExecuteUDP();
                    }
                    else
                    {
                        this.ExecuteTCP();
                    }
                    
                    DnsResponse response = this.DeserializeResponse();
                    response.Validate();

                    if (request.RequestID != response.RequestID || !response.Question.Equals(request.Question))
                    {
                        // Hmm. Not a response to any query we'd sent. 
                        // Could be a spoof, a server misbehaving, or some other socket (UDP) oddity (delayed message etc)
                        // If this is TCP, then this should not happen and we will hit max attempts and stop
                        // Ignore and retry
                        continue;
                    }
                    
                    if (response.IsNameError)
                    {
                        return response;
                    }
                    
                    if (!response.IsSuccess)
                    {
                        throw new DnsServerException(response.Header.ResponseCode);
                    }
                    
                    if (!response.Header.IsTruncated)
                    {
                        return response;
                    }
                    
                    useUDPFirst = false;
                }
                catch(DnsServerException se)
                {
                    //
                    // Server failures deserve a retry
                    //
                    if (se.ResponseCode != DnsStandard.ResponseCode.ServerFailure)
                    {
                        throw;
                    }
                }
                catch(DnsProtocolException pe)
                {
                    //
                    // Random failures also deserve a retry
                    //
                    if (pe.Error != DnsProtocolError.Failed)
                    {
                        throw;
                    }
                }
                catch(DnsException)
                {
                    throw;
                }
                catch(Exception error)
                {
                    //
                    // Typically, a socket exception or network error...
                    //
                    if (attempt >= maxAttempts)
                    {
                        throw;
                    }
                    
                    this.NotifyError(error);
                }
                
                this.CloseUdpSocket();
                
                if (m_postFailurePause != null)
                {
                    System.Threading.Thread.Sleep(m_postFailurePause.Value);
                }            
            }

            throw new DnsProtocolException(DnsProtocolError.MaxAttemptsReached, Server.Address);
        }
Ejemplo n.º 18
0
 void OnTcpRequest(DnsRequest request)
 {
     if (m_logger.IsTraceEnabled)
     {
         m_logger.Debug(this.Summarize("TCP", request));
     }
     else if (m_logger.IsDebugEnabled)
     {
         m_logger.Info("TCP Request {0} {1}", request.Question.Domain, request.Question.Type);
     }
 }
Ejemplo n.º 19
0
 DnsResponse ProcessError(DnsRequest request, DnsStandard.ResponseCode code)
 {
     DnsResponse errorResponse = new DnsResponse(request);
     errorResponse.Header.ResponseCode = code;
     return errorResponse;
 }
Ejemplo n.º 20
0
 string Summarize(string type, DnsRequest request)
 {
     using (StringWriter writer = new StringWriter())
     {
         writer.WriteLine();
         writer.Write(type);
         writer.WriteLine(" Request");
         DnsRecordPrinter printer = new DnsRecordPrinter(writer);
         printer.Print(request);
         return writer.ToString();
     }
 }
Ejemplo n.º 21
0
        private void Resolve(DnsRequest request)
        {
            DnsResponse matches = m_client.Resolve(request);

            Assert.NotNull(matches);
            Assert.True(matches.HasAnswerRecords, string.Format("{0}:{1}", request.Question.Type, request.Question.Domain));
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Initialize a response to the given request
 /// </summary>
 public void Init(DnsRequest request)
 {
     if (request == null)
     {
         throw new ArgumentNullException();
     }
     
     this.RequestID = request.RequestID;
     this.Header.IsRecursionDesired = request.Header.IsRecursionDesired;
     this.Header.IsRequest = false;
     this.Question = request.Question;
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Resolves a DNS Request and returns a DnsResponse response instance.
        /// </summary>
        /// <param name="request">
        /// The DNS Request to resolve. See <see cref="DnsRequest"/>
        /// </param>
        /// <returns>
        /// A DNS Response instance representing the response. See <see cref="DnsResponse"/>
        /// </returns>
        /// <exception cref="DnsException">Thrown for network failure (e.g. max retries exceeded) or badly formed responses.</exception>
        public virtual DnsResponse Resolve(DnsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Validate();

            request.RequestID = this.NextID();
            this.SerializeRequest(request);

            bool useUDPFirst = this.UseUDPFirst;
            int  attempt     = 0;
            int  maxAttempts = this.m_maxRetries + 1;

            while (attempt < maxAttempts)
            {
                attempt++;
                try
                {
                    if (useUDPFirst)
                    {
                        this.ExecuteUDP();
                    }
                    else
                    {
                        this.ExecuteTCP();
                    }

                    DnsResponse response = this.DeserializeResponse();
                    response.Validate();

                    if (request.RequestID != response.RequestID || !response.Question.Equals(request.Question))
                    {
                        // Hmm. Not a response to any query we'd sent.
                        // Could be a spoof, a server misbehaving, or some other socket (UDP) oddity (delayed message etc)
                        // If this is TCP, then this should not happen and we will hit max attempts and stop
                        // Ignore and retry
                        continue;
                    }

                    if (response.IsNameError)
                    {
                        return(response);
                    }

                    if (!response.IsSuccess)
                    {
                        throw new DnsServerException(response.Header.ResponseCode);
                    }

                    if (!response.Header.IsTruncated)
                    {
                        return(response);
                    }

                    useUDPFirst = false;
                }
                catch (DnsServerException se)
                {
                    //
                    // Server failures deserve a retry
                    //
                    if (se.ResponseCode != DnsStandard.ResponseCode.ServerFailure)
                    {
                        throw;
                    }
                }
                catch (DnsProtocolException pe)
                {
                    //
                    // Random failures also deserve a retry
                    //
                    if (pe.Error != DnsProtocolError.Failed)
                    {
                        throw;
                    }
                }
                catch (DnsException)
                {
                    throw;
                }
                catch (Exception error)
                {
                    //
                    // Typically, a socket exception or network error...
                    //
                    if (attempt >= maxAttempts)
                    {
                        throw;
                    }

                    this.NotifyError(error);
                }

                this.CloseUdpSocket();

                if (m_postFailurePause != null)
                {
                    System.Threading.Thread.Sleep(m_postFailurePause.Value);
                }
            }

            throw new DnsProtocolException(DnsProtocolError.MaxAttemptsReached, Server.Address);
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Construct a response to a request
 /// </summary>
 /// <param name="request"></param>
 public DnsResponse(DnsRequest request)
     : base()
 {
     this.Init(request);
 }        
Ejemplo n.º 25
0
 void SerializeRequest(DnsRequest request)
 {
     m_requestBuffer.Clear();
     request.Serialize(m_requestBuffer);
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Construct a response to a request
 /// </summary>
 /// <param name="request"></param>
 public DnsResponse(DnsRequest request)
     : base()
 {
     this.Init(request);
 }