示例#1
0
        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;
        }
示例#2
0
        /// <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);
        }
示例#3
0
        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);
        }
示例#4
0
        /// <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;
        }
示例#5
0
        /// <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;
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// <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);
        }