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; }
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; }
public DnsRequest ReceiveRequest() { DnsBuffer responseBuffer = this.ReceiveBuffer(); DnsRequest request = new DnsRequest(responseBuffer.CreateReader()); Assert.True(!string.IsNullOrEmpty(request.Question.Domain)); return request; }
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 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); }
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); }
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; }
/// <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; }
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); }
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); }
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); } }
void SerializeRequest(DnsRequest request) { m_requestBuffer.Clear(); request.Serialize(m_requestBuffer); }
public void Send(DnsRequest request) { DnsBuffer requestBuffer = new DnsBuffer(); request.Serialize(requestBuffer); this.SendBuffer(requestBuffer); }
/// <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; }
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; }
/// <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); }
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); } }
DnsResponse ProcessError(DnsRequest request, DnsStandard.ResponseCode code) { DnsResponse errorResponse = new DnsResponse(request); errorResponse.Header.ResponseCode = code; return errorResponse; }
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(); } }
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)); }
/// <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; }
/// <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> /// Construct a response to a request /// </summary> /// <param name="request"></param> public DnsResponse(DnsRequest request) : base() { this.Init(request); }