Exemple #1
0
 public DnsResourceRecord Receive()
 {
     DnsBuffer responseBuffer = this.ReceiveBuffer();            
     DnsResponse response = new DnsResponse(responseBuffer.CreateReader());
     Assert.True(response.AnswerRecords.Count != 0);
     return response.AnswerRecords[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;
        }
Exemple #3
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;
        }
Exemple #4
0
        /// <summary>
        /// Convenience method resolving and returning NS RRs.
        /// </summary>
        /// <param name="domain">
        /// The domain name to resolve.
        /// </param>
        /// <returns>
        /// An enumeration of NS Records. See <see cref="NSRecord"/>
        /// </returns>
        public IEnumerable <NSRecord> ResolveNS(string domain)
        {
            DnsResponse response = this.Resolve(DnsRequest.CreateNS(domain));

            if (response == null || !response.HasNameServerRecords)
            {
                return(null);
            }
            return(response.AnswerRecords.NS);
        }
Exemple #5
0
        /// <summary>
        /// Convenience method resolving and returning MX RRs.
        /// </summary>
        /// <param name="emailDomain">
        /// The domain name to resolve.
        /// </param>
        /// <returns>
        /// An enumeration of MX Records. See <see cref="MXRecord"/>
        /// </returns>
        public IEnumerable <MXRecord> ResolveMX(string emailDomain)
        {
            DnsResponse response = this.Resolve(DnsRequest.CreateMX(emailDomain));

            if (response == null || !response.HasAnswerRecords)
            {
                return(null);
            }
            return(response.AnswerRecords.MX);
        }
Exemple #6
0
        /// <summary>
        /// Convenience method resolving and returning TXT RRs.
        /// </summary>
        /// <param name="domain">
        /// The domain name to resolve.
        /// </param>
        /// <returns>
        /// An enumeration of TXT Records. See <see cref="TextRecord"/>
        /// </returns>
        public IEnumerable <TextRecord> ResolveTXT(string domain)
        {
            DnsResponse response = this.Resolve(DnsRequest.CreateTXT(domain));

            if (response == null || !response.HasAnswerRecords)
            {
                return(null);
            }
            return(response.AnswerRecords.TXT);
        }
Exemple #7
0
        /// <summary>
        /// Clone this DnsResponse.
        /// </summary>
        public DnsResponse Clone()
        {
            DnsBuffer buffer = new DnsBuffer(DnsStandard.MaxUdpMessageLength);

            this.Serialize(buffer);

            DnsResponse newResponse = new DnsResponse(buffer.CreateReader());

            newResponse.TTLOrigin = this.TTLOrigin;

            return(newResponse);
        }
Exemple #8
0
        /// <summary>
        /// Resolves all the name server names for a given domain
        /// </summary>
        /// <param name="domain"></param>
        /// <returns>An enumeration of name server names</returns>
        public IEnumerable <string> GetNameServerNames(string domain)
        {
            DnsResponse response = this.Resolve(DnsRequest.CreateNS(domain));

            if (response == null)
            {
                yield break;
            }

            IEnumerable <DnsResourceRecord> nsRecords = null;

            if (response.HasAnswerRecords)
            {
                nsRecords = response.AnswerRecords;
            }
            else if (response.HasNameServerRecords)
            {
                nsRecords = response.NameServerRecords;
            }
            if (nsRecords == null)
            {
                yield break;
            }

            string serverName = null;

            foreach (DnsResourceRecord record in nsRecords)
            {
                serverName = null;
                switch (record.Type)
                {
                default:
                    break;

                case DnsStandard.RecordType.NS:
                    serverName = ((NSRecord)record).NameServer;
                    break;

                case DnsStandard.RecordType.SOA:
                    serverName = ((SOARecord)record).DomainName;
                    break;
                }

                if (serverName != null)
                {
                    yield return(serverName);
                }
            }
        }
Exemple #9
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);
        }
Exemple #10
0
        /// <summary>
        /// Prints a DNS response.
        /// </summary>
        /// <param name="response">The response to print</param>
        public void Print(DnsResponse response)
        {
            if (response == null)
            {
                return;
            }

            this.Print("RequestID", response.RequestID);
            this.Print("Response Code", response.Header.ResponseCode);
            if (!response.IsSuccess)
            {
                return;
            }

            this.Print(response.Question);

            if (response.HasAnswerRecords)
            {
                this.Print("***ANSWERS***");
                this.Print(response.AnswerRecords);
            }
            else
            {
                this.Print("No answers");
            }

            if (response.HasNameServerRecords)
            {
                this.Print("***NAME SERVERS***");
                this.Print(response.NameServerRecords);
            }

            if (response.HasAdditionalRecords)
            {
                this.Print("***Additional***");
                this.Print(response.AdditionalRecords);
            }
        }
        /// <summary>
        /// Returns a list of dns response entries that has been loaded from the files that are part of the solution
        /// </summary>
        /// <remarks>
        /// Verifies that list has been properly loaded up. These are only A record responses.
        /// </remarks>
        protected void PopulateMockDnsARecordResponseEntries()
        {
            m_responses = new List<DnsResponse>();
            foreach (string s in MockDomainResponses)
            {
                byte[] buff;
                DnsResponse dr;

                string fileName = Path.GetFullPath(Path.Combine(m_filePath, s + ".bin"));
                using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    Dump("checking [{0}]", fileName);
                    buff = new BinaryReader(fs).ReadBytes((int)new FileInfo(fileName).Length);
                    DnsBufferReader reader = new DnsBufferReader(buff, 0, buff.Count());

                    // get a dr 
                    dr = new DnsResponse(reader);
                    m_responses.Add(dr);
                }

                // ensure that the qusetion QName matches the name of the mocked entry
                Assert.True(dr.Question.Domain.ToLower().Contains(s.ToLower().Replace("aname.","")));
            }
        }
Exemple #12
0
 public void Send(DnsResponse response)
 {
     DnsBuffer buffer = new DnsBuffer();
     response.Serialize(buffer);
     this.SendBuffer(buffer);
 }
Exemple #13
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);
        }
 /// <summary>
 /// processes a SRV Question, populated the response with any matching results pulled from the database store
 /// </summary>
 /// <param name="response">DnsResponse instance containing information about the question that will
 /// have any corresponding answer records populated upon return</param>
 protected void ProcessSRVQuestion(DnsResponse response)
 {
     using (RecordRetrievalServiceClient client = m_recordRetrievalServiceSettings.CreateRecordRetrievalClient())
     {
         client.GetSRVRecords(response.Question.Domain, response.AnswerRecords);
     }
 }
 void ProcessNSQuestion(DnsResponse response)
 {
     using (RecordRetrievalServiceClient client = m_recordRetrievalServiceSettings.CreateRecordRetrievalClient())
     {
         client.GetNSRecords(response.Question.Domain, response.AnswerRecords);
         if (!response.HasAnswerRecords)
         {
             return;
         }
         //
         // Also resolve the NS Record's actual address, to save roundtrips
         //
         foreach(NSRecord record in response.AnswerRecords.NS)
         {
             client.GetANAMERecords(record.NameServer, response.AdditionalRecords);
         }
     }
 }
 /// <summary>
 /// processes a CERT Question, populated the response with any matching results pulled from the database store
 /// </summary>
 /// <param name="response">DnsResponse instance containing information about the question that will
 /// have any corresponding answer records populated upon return</param>
 void ProcessCERTQuestion(DnsResponse response)
 {
     using (RecordRetrievalServiceClient client = m_recordRetrievalServiceSettings.CreateRecordRetrievalClient())
     {
         Certificate[] certs = client.GetCertificatesForOwner(response.Question.Domain);
         foreach (Certificate cert in certs)
         {
             response.AnswerRecords.Add(new CertRecord(new DnsX509Cert(cert.Data)));
         }
     }
 }
Exemple #17
0
 string Summarize(string type, DnsResponse response)
 {
     using(StringWriter writer = new StringWriter())
     {
         writer.WriteLine();
         writer.Write(type);
         writer.WriteLine(" Response");
         DnsRecordPrinter printer = new DnsRecordPrinter(writer);
         printer.Print(response);
         return writer.ToString();
     }
 }
 DnsResponse ProcessResponse(DnsResponse response)
 {
     if (!response.HasAnyRecords)
     {
         response = null; // This will cause the server to return a NameError
     }
     
     return response;
 }
Exemple #19
0
 void FixupTTL(DnsResponse response)
 {
     if (response.HasAnswerRecords)
     {
         this.FixupTTL(response.AnswerRecords);
     }
     if (response.HasAdditionalRecords)
     {
         this.FixupTTL(response.AdditionalRecords);
     }
     if (response.HasNameServerRecords)
     {
         this.FixupTTL(response.NameServerRecords);
     }
 }
Exemple #20
0
 void HandleRequest(IAsyncResult result)
 {
     try
     {
         using(Socket socket = m_listener.EndAcceptSocket(result))
         {
             TestTCPClient client = new TestTCPClient(socket); // Chunk sends
             DnsRequest request = client.ReceiveRequest();
             DnsResponse response = null;
             try
             {
                 response = m_store.Get(request);
                 if (response == null)
                 {
                     response = new DnsResponse(request);
                     response.Header.ResponseCode = DnsStandard.ResponseCode.NameError;
                 }
             }
             catch
             {
                 response = new DnsResponse(request);
                 response.Header.ResponseCode = DnsStandard.ResponseCode.NameError;
             }
             
             if (response != null)
             {
                 client.Send(response);
             }
         }
     }
     catch
     {
     }
 }
Exemple #21
0
 DnsResponse ProcessError(DnsRequest request, DnsStandard.ResponseCode code)
 {
     DnsResponse errorResponse = new DnsResponse(request);
     errorResponse.Header.ResponseCode = code;
     return errorResponse;
 }
Exemple #22
0
        /// <summary>
        /// Clone this DnsResponse.
        /// </summary>        
        public DnsResponse Clone()
        {
            DnsBuffer buffer = new DnsBuffer(DnsStandard.MaxUdpMessageLength);

            this.Serialize(buffer); 

            DnsResponse newResponse = new DnsResponse(buffer.CreateReader());
            newResponse.TTLOrigin = this.TTLOrigin;

            return newResponse; 
        }
 /// <summary>
 /// processes a ANAME Question, populated the response with any matching results pulled from the database store
 /// </summary>
 /// <param name="response">DnsResponse instance containing information about the question that will
 /// have any corresponding answer records populated upon return</param>
 protected void ProcessANAMEQuestion(DnsResponse response)
 {
     using (RecordRetrievalServiceClient client = m_recordRetrievalServiceSettings.CreateRecordRetrievalClient())
     {
         client.GetANAMERecords(response.Question.Domain, response.AnswerRecords);
         if (!response.HasAnswerRecords)
         {
             client.GetCNAMERecords(response.Question.Domain, response.AnswerRecords);
         }
     }            
 }
Exemple #24
0
 void Serialize(DnsResponse response)
 {
     m_buffer.Clear();
     response.Serialize(m_buffer);        
 }
 /// <summary>
 /// processes a MX Question, populated the response with any matching results pulled from the database store
 /// </summary>
 /// <param name="response">DnsResponse instance containing information about the question that will
 /// have any corresponding answer records populated upon return</param>
 protected void ProcessMXQuestion(DnsResponse response)
 {
     using (RecordRetrievalServiceClient client = m_recordRetrievalServiceSettings.CreateRecordRetrievalClient())
     {
         client.GetMXRecords(response.Question.Domain, response.AnswerRecords);
         if (!response.HasAnswerRecords)
         {
             return;
         }
         //
         // additionally return each MX record's IP address
         //
         foreach (MXRecord mxRecord in response.AnswerRecords.MX)
         {
             client.GetANAMERecords(mxRecord.Exchange, response.AdditionalRecords);
         }
     }
 }
Exemple #26
0
 protected void Serialize(DnsResponse response, DnsBuffer buffer, int maxResponse)
 {
     buffer.Clear();
     response.Serialize(buffer);
     if (buffer.Count > maxResponse)
     {
         response.Truncate();
         buffer.Clear();
         response.Serialize(buffer);
     }
 }
Exemple #27
0
 void OnTcpResponse(DnsResponse response)
 {
     if (m_logger.IsTraceEnabled)
     {
         m_logger.Debug(this.Summarize("TCP", response));
     }
     else if (m_logger.IsDebugEnabled)
     {
         m_logger.Info("TCP Response {0} {1}", response.Question.Domain, response.Header.ResponseCode);
     }
 }