private DNSResponse GetResponse(DNSRequest request, List<IPEndPoint> dnsServers, int timeout) { request.header.ID = m_Unique; request.header.RD = m_Recursion; DNSResponse response = null; if (m_TransportType == TransportType.Udp) { response = UdpRequest(request, dnsServers, timeout); } if (m_TransportType == TransportType.Tcp) { response = TcpRequest(request, dnsServers, timeout); } if (response == null) { response = new DNSResponse(); response.Error = "Unknown TransportType"; } Question question = request.Questions[0]; string questionKey = question.QClass + "-" + question.QType + "-" + question.QName; AddToCache(response, questionKey); return response; }
/// <summary> /// Do Query on specified DNS servers /// </summary> /// <param name="name">Name to query</param> /// <param name="qtype">Question type</param> /// <param name="timeout">Timeout for lookup in seconds.</param> /// <param name="qclass">Class type</param> /// <returns>Response of the query</returns> public DNSResponse Query(string name, DNSQType qtype, QClass qclass, int timeout) { Question question = new Question(name, qtype, qclass); DNSResponse response = SearchInCache(question); if (response != null) return response; DNSRequest request = new DNSRequest(); request.AddQuestion(question); return GetResponse(request, m_DnsServers, timeout); }
public DNSResponse Query(string name, DNSQType qtype, int timeout, List<IPEndPoint> dnsServers) { Question question = new Question(name, qtype, QClass.IN); DNSResponse response = SearchInCache(question); if (response != null) return response; DNSRequest request = new DNSRequest(); request.AddQuestion(question); return GetResponse(request, dnsServers, timeout); }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <param name="timeout">Timeout for lookup in seconds.</param> /// <returns></returns> private DNSResponse TcpRequest(DNSRequest request, List<IPEndPoint> dnsServers, int timeout) { //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); //sw.Start(); byte[] responseMessage = new byte[512]; for (int intAttempts = 0; intAttempts < m_Retries; intAttempts++) { for (int intDnsServer = 0; intDnsServer < dnsServers.Count; intDnsServer++) { TcpClient tcpClient = new TcpClient(); tcpClient.ReceiveTimeout = timeout * 1000; try { IAsyncResult result = tcpClient.BeginConnect(dnsServers[intDnsServer].Address, dnsServers[intDnsServer].Port, null, null); bool success = result.AsyncWaitHandle.WaitOne(timeout * 1000, true); if (!success || !tcpClient.Connected) { tcpClient.Close(); Verbose(string.Format(";; Connection to nameserver {0} failed", (intDnsServer + 1))); continue; } BufferedStream bs = new BufferedStream(tcpClient.GetStream()); byte[] data = request.Data; bs.WriteByte((byte)((data.Length >> 8) & 0xff)); bs.WriteByte((byte)(data.Length & 0xff)); bs.Write(data, 0, data.Length); bs.Flush(); DNSResponse TransferResponse = new DNSResponse(); int intSoa = 0; int intMessageSize = 0; //Debug.WriteLine("Sending "+ (request.Length+2) + " bytes in "+ sw.ElapsedMilliseconds+" mS"); while (true) { int intLength = bs.ReadByte() << 8 | bs.ReadByte(); if (intLength <= 0) { tcpClient.Close(); Verbose(string.Format(";; Connection to nameserver {0} failed", (intDnsServer + 1))); throw new SocketException(); // next try } intMessageSize += intLength; data = new byte[intLength]; bs.Read(data, 0, intLength); DNSResponse response = new DNSResponse(dnsServers[intDnsServer], data); //Debug.WriteLine("Received "+ (intLength+2)+" bytes in "+sw.ElapsedMilliseconds +" mS"); if (response.header.RCODE != RCode.NOERROR) return response; if (response.Questions[0].QType != DNSQType.AXFR) { //AddToCache(response); return response; } // Zone transfer!! if (TransferResponse.Questions.Count == 0) TransferResponse.Questions.AddRange(response.Questions); TransferResponse.Answers.AddRange(response.Answers); TransferResponse.Authorities.AddRange(response.Authorities); TransferResponse.Additionals.AddRange(response.Additionals); if (response.Answers[0].Type == DNSType.SOA) intSoa++; if (intSoa == 2) { TransferResponse.header.QDCOUNT = (ushort)TransferResponse.Questions.Count; TransferResponse.header.ANCOUNT = (ushort)TransferResponse.Answers.Count; TransferResponse.header.NSCOUNT = (ushort)TransferResponse.Authorities.Count; TransferResponse.header.ARCOUNT = (ushort)TransferResponse.Additionals.Count; TransferResponse.MessageSize = intMessageSize; return TransferResponse; } } } // try catch (SocketException) { continue; // next try } finally { m_Unique++; // close the socket tcpClient.Close(); } } } DNSResponse responseTimeout = new DNSResponse(); responseTimeout.Timedout = true; return responseTimeout; }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <param name="timeout">Timeout for lookup in seconds.</param> /// <returns></returns> private DNSResponse UdpRequest(DNSRequest request, List<IPEndPoint> dnsServers, int timeout) { // RFC1035 max. size of a UDP datagram is 512 bytes byte[] responseMessage = new byte[512]; IPEndPoint activeDNSServer = GetActiveDNSServer(); //for (int intAttempts = 0; intAttempts < m_Retries; intAttempts++) //{ // for (int intDnsServer = 0; intDnsServer < dnsServers.Count; intDnsServer++) // { string requestStr = request.Questions[0].QType + " " + request.Questions[0].QName; logger.Debug("Resolver sending UDP DNS request to " + activeDNSServer + " for " + requestStr + "."); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout * 1000); try { socket.SendTo(request.Data, activeDNSServer); int intReceived = socket.Receive(responseMessage); ResetTimeoutCount(activeDNSServer); byte[] data = new byte[intReceived]; Array.Copy(responseMessage, data, intReceived); DNSResponse response = new DNSResponse(activeDNSServer, data); //AddToCache(response); //logger.Debug("Success in UdpRequest for " + requestStr + "."); return response; } catch (SocketException sockExcp) { //logger.Debug("SocketException UdpRequest for " + requestStr + ". " + sockExcp.Message); IncrementTimeoutCount(activeDNSServer); logger.Warn("Resolver connection to nameserver " + activeDNSServer + " failed. " + sockExcp.Message); //continue; // next try } catch (Exception excp) { logger.Error("Exception Resolver UdpRequest for " + requestStr + ". " + excp.Message); } finally { m_Unique++; // close the socket socket.Close(); } // } //} logger.Warn("Resolver UDP request timed out for " + requestStr + "."); DNSResponse responseTimeout = new DNSResponse(); responseTimeout.Timedout = true; return responseTimeout; }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <param name="timeout">Timeout for lookup in seconds.</param> /// <returns></returns> private DNSResponse TcpRequest(DNSRequest request, List <IPEndPoint> dnsServers, int timeout) { byte[] responseMessage = new byte[512]; IPEndPoint activeDNSServer = GetActiveDNSServer(); if (dnsServers == null) { dnsServers = new List <IPEndPoint>(); } if (dnsServers.Count == 0) { dnsServers.Add(activeDNSServer); } ResetAllTimeoutCountIfNecessary(); string requestStr = request.Questions[0].QType + " " + request.Questions[0].QName; for (int nAttempts = 0; nAttempts < m_Retries && !m_stop; nAttempts++) { for (int nDnsServer = 0; nDnsServer < dnsServers.Count && !m_stop; nDnsServer++) { if (dnsServers[nDnsServer].Address.IsIPv6LinkLocal) { continue; } if (GetTimeoutCount(dnsServers[nDnsServer]) >= SWITCH_ACTIVE_TIMEOUT_COUNT) { Logger.Logger.Debug("Resolver not sending TCP DNS request to " + dnsServers[nDnsServer] + " because of maximum count of request timeouts reached"); continue; } string requestStrWithDns = "for '" + requestStr + "' on dns-server '" + dnsServers[nDnsServer] + "'"; Logger.Logger.Debug("Resolver sending TCP DNS request " + requestStrWithDns); TcpClient tcpClient = new TcpClient(); tcpClient.ReceiveTimeout = timeout * 1000; try { IAsyncResult result = tcpClient.BeginConnect(dnsServers[nDnsServer].Address, dnsServers[nDnsServer].Port, null, null); bool success = result.AsyncWaitHandle.WaitOne(timeout * 1000, true); if (!success || !tcpClient.Connected) { tcpClient.Close(); Verbose(string.Format(";; Connection to nameserver {0} failed", (nDnsServer + 1))); continue; } BufferedStream bs = new BufferedStream(tcpClient.GetStream()); byte[] data = request.Data; bs.WriteByte((byte)((data.Length >> 8) & 0xff)); bs.WriteByte((byte)(data.Length & 0xff)); bs.Write(data, 0, data.Length); bs.Flush(); DNSResponse TransferResponse = new DNSResponse(); int intSoa = 0; int intMessageSize = 0; //Debug.WriteLine("Sending "+ (request.Length+2) + " bytes in "+ sw.ElapsedMilliseconds+" mS"); while (true) { int intLength = bs.ReadByte() << 8 | bs.ReadByte(); if (intLength <= 0) { tcpClient.Close(); Verbose(string.Format(";; Connection to nameserver {0} failed", (nDnsServer + 1))); throw new SocketException(); // next try } intMessageSize += intLength; data = new byte[intLength]; bs.Read(data, 0, intLength); DNSResponse response = new DNSResponse(m_DnsServers[nDnsServer], data); if (response.header.RCODE != RCode.NOERROR) { Logger.Logger.Debug("Error " + response.header.RCODE + " in Resolver TcpRequest " + requestStrWithDns); return(response); } else { Logger.Logger.Info("Success in TcpRequest " + requestStrWithDns); } if (response.Questions[0].QType != QType.AXFR) { return(response); } // Zone transfer!! if (TransferResponse.Questions.Count == 0) { TransferResponse.Questions.AddRange(response.Questions); } TransferResponse.Answers.AddRange(response.Answers); TransferResponse.Authorities.AddRange(response.Authorities); TransferResponse.Additionals.AddRange(response.Additionals); if (response.Answers[0].Type == DnsType.SOA) { intSoa++; } if (intSoa == 2) { TransferResponse.header.QDCOUNT = (ushort)TransferResponse.Questions.Count; TransferResponse.header.ANCOUNT = (ushort)TransferResponse.Answers.Count; TransferResponse.header.NSCOUNT = (ushort)TransferResponse.Authorities.Count; TransferResponse.header.ARCOUNT = (ushort)TransferResponse.Additionals.Count; TransferResponse.MessageSize = intMessageSize; return(TransferResponse); } } } // try catch (SocketException sockExcp) { IncrementTimeoutCount(dnsServers[nDnsServer]); Logger.Logger.Warn( "SocketExcpetion(" + sockExcp.ErrorCode + ") Resolver TcpRequest connection to nameserver " + dnsServers[nDnsServer] + " failed. ->" + sockExcp); continue; // next try } catch (Exception excp) { Logger.Logger.Error("Exception Resolver UdpRequest " + requestStrWithDns + ". ->" + excp); } finally { m_Unique++; // close the socket tcpClient.Close(); } } } Logger.Logger.Warn("Resolver TCP request timed out for " + requestStr + "."); DNSResponse responseTimeout = new DNSResponse(); responseTimeout.Timedout = true; responseTimeout.Error = "Timeout Error"; return(responseTimeout); }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <param name="timeout">Timeout for lookup in seconds.</param> /// <returns></returns> private DNSResponse UdpRequest(DNSRequest request, List <IPEndPoint> dnsServers, int timeout) { // RFC1035 max. size of a UDP datagram is 512 bytes byte[] responseMessage = new byte[512]; IPEndPoint activeDNSServer = GetActiveDNSServer(); if (dnsServers == null) { dnsServers = new List <IPEndPoint>(); } if (dnsServers.Count == 0) { dnsServers.Add(activeDNSServer); } ResetAllTimeoutCountIfNecessary(); string requestStr = request.Questions[0].QType + " " + request.Questions[0].QName; for (int nAttempts = 0; nAttempts < m_Retries && !m_stop; nAttempts++) { for (int nDnsServer = 0; nDnsServer < dnsServers.Count && !m_stop; nDnsServer++) { if (dnsServers[nDnsServer].Address.IsIPv6LinkLocal) { continue; } if (GetTimeoutCount(dnsServers[nDnsServer]) >= SWITCH_ACTIVE_TIMEOUT_COUNT) { Logger.Logger.Debug("Resolver not sending UDP DNS request to " + dnsServers[nDnsServer] + " because of maximum count of request timeouts reached"); continue; } string requestStrWithDns = "for '" + requestStr + "' on dns-server '" + dnsServers[nDnsServer] + "'"; Logger.Logger.Debug("Resolver sending UDP DNS request " + requestStrWithDns); Socket socket = new Socket(dnsServers[nDnsServer].AddressFamily, SocketType.Dgram, ProtocolType.Udp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout * 1000); try { socket.SendTo(request.Data, dnsServers[nDnsServer]); int nReceived = socket.Receive(responseMessage); ResetTimeoutCount(dnsServers[nDnsServer]); byte[] data = new byte[nReceived]; Array.Copy(responseMessage, data, nReceived); DNSResponse response = new DNSResponse(dnsServers[nDnsServer], data); if (response.header.RCODE == RCode.NOERROR) { Logger.Logger.Info("Success in UdpRequest " + requestStrWithDns); return(response); } else { Logger.Logger.Debug("Error " + response.header.RCODE + " in Resolver UdpRequest " + requestStrWithDns); } } catch (SocketException sockExcp) { IncrementTimeoutCount(dnsServers[nDnsServer]); Logger.Logger.Warn( "SocketExcpetion(" + sockExcp.ErrorCode + ") Resolver UdpRequest connection to nameserver " + dnsServers[nDnsServer] + " failed. ->" + sockExcp); continue; // next try } catch (Exception excp) { Logger.Logger.Error("Exception Resolver UdpRequest " + requestStrWithDns + ". ->" + excp); } finally { m_Unique++; // close the socket socket.Close(); } } } Logger.Logger.Warn("Resolver UDP request timed out for " + requestStr + "."); DNSResponse responseTimeout = new DNSResponse(); responseTimeout.Timedout = true; responseTimeout.Error = "Timeout Error"; return(responseTimeout); }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <param name="timeout">Timeout for lookup in seconds.</param> /// <returns></returns> private DNSResponse TcpRequest(DNSRequest request, List <IPEndPoint> dnsServers, int timeout) { //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); //sw.Start(); byte[] responseMessage = new byte[512]; for (int intAttempts = 0; intAttempts < m_Retries; intAttempts++) { for (int intDnsServer = 0; intDnsServer < dnsServers.Count; intDnsServer++) { TcpClient tcpClient = new TcpClient(); tcpClient.ReceiveTimeout = timeout * 1000; try { IAsyncResult result = tcpClient.BeginConnect(dnsServers[intDnsServer].Address, dnsServers[intDnsServer].Port, null, null); bool success = result.AsyncWaitHandle.WaitOne(timeout * 1000, true); if (!success || !tcpClient.Connected) { tcpClient.Close(); Verbose(string.Format(";; Connection to nameserver {0} failed", (intDnsServer + 1))); continue; } BufferedStream bs = new BufferedStream(tcpClient.GetStream()); byte[] data = request.Data; bs.WriteByte((byte)((data.Length >> 8) & 0xff)); bs.WriteByte((byte)(data.Length & 0xff)); bs.Write(data, 0, data.Length); bs.Flush(); DNSResponse TransferResponse = new DNSResponse(); int intSoa = 0; int intMessageSize = 0; //Debug.WriteLine("Sending "+ (request.Length+2) + " bytes in "+ sw.ElapsedMilliseconds+" mS"); while (true) { int intLength = bs.ReadByte() << 8 | bs.ReadByte(); if (intLength <= 0) { tcpClient.Close(); Verbose(string.Format(";; Connection to nameserver {0} failed", (intDnsServer + 1))); throw new SocketException(); // next try } intMessageSize += intLength; data = new byte[intLength]; bs.Read(data, 0, intLength); DNSResponse response = new DNSResponse(dnsServers[intDnsServer], data); //Debug.WriteLine("Received "+ (intLength+2)+" bytes in "+sw.ElapsedMilliseconds +" mS"); if (response.header.RCODE != RCode.NOERROR) { return(response); } if (response.Questions[0].QType != DNSQType.AXFR) { //AddToCache(response); return(response); } // Zone transfer!! if (TransferResponse.Questions.Count == 0) { TransferResponse.Questions.AddRange(response.Questions); } TransferResponse.Answers.AddRange(response.Answers); TransferResponse.Authorities.AddRange(response.Authorities); TransferResponse.Additionals.AddRange(response.Additionals); if (response.Answers[0].Type == DNSType.SOA) { intSoa++; } if (intSoa == 2) { TransferResponse.header.QDCOUNT = (ushort)TransferResponse.Questions.Count; TransferResponse.header.ANCOUNT = (ushort)TransferResponse.Answers.Count; TransferResponse.header.NSCOUNT = (ushort)TransferResponse.Authorities.Count; TransferResponse.header.ARCOUNT = (ushort)TransferResponse.Additionals.Count; TransferResponse.MessageSize = intMessageSize; return(TransferResponse); } } } // try catch (SocketException) { continue; // next try } finally { m_Unique++; // close the socket tcpClient.Close(); } } } DNSResponse responseTimeout = new DNSResponse(); responseTimeout.Timedout = true; return(responseTimeout); }