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; }
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; }
/// <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); }
/// <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); }
/// <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); }
/// <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> /// 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); } } }
/// <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); }
/// <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.",""))); } }
public void Send(DnsResponse response) { DnsBuffer buffer = new DnsBuffer(); response.Serialize(buffer); this.SendBuffer(buffer); }
/// <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))); } } }
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; }
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); } }
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 { } }
DnsResponse ProcessError(DnsRequest request, DnsStandard.ResponseCode code) { DnsResponse errorResponse = new DnsResponse(request); errorResponse.Header.ResponseCode = code; return errorResponse; }
/// <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); } } }
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); } } }
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); } }
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); } }