Example #1
0
        /// <summary>
        /// Processes received UDP packet.
        /// </summary>
        /// <param name="e">UDP packet.</param>
        private void ProcessUdpPacket(UDP_e_PacketReceived e)
        {
            try
            {
                if (m_IsDisposed)
                {
                    return;
                }

                DnsServerResponse     serverResponse = ParseQuery(e.Buffer);
                DNS_ClientTransaction transaction    = null;
                // Pass response to transaction.
                if (m_pTransactions.TryGetValue(serverResponse.ID, out transaction))
                {
                    if (transaction.State == DNS_ClientTransactionState.Active)
                    {
                        // Cache query.
                        if (m_UseDnsCache && serverResponse.ResponseCode == DNS_RCode.NO_ERROR)
                        {
                            DnsCache.AddToCache(transaction.QName, (int)transaction.QType, serverResponse);
                        }

                        transaction.ProcessResponse(serverResponse);
                    }
                }
                // No such transaction or transaction has timed out before answer received.
                //else{
                //}
            }
            catch
            {
                // We don't care about receiving errors here, skip them.
            }
        }
        /// <summary>
        /// Processes DNS server response through this transaction.
        /// </summary>
        /// <param name="response">DNS server response.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null reference.</exception>
        internal void ProcessResponse(DnsServerResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            try
            {
                lock (m_pLock)
                {
                    // Late arriving response or retransmitted response, just skip it.
                    if (m_pResponse != null)
                    {
                        return;
                    }

                    m_pResponse = response;
                }

                SetState(DNS_ClientTransactionState.Completed);
            }
            finally
            {
                if (this.State == DNS_ClientTransactionState.Completed)
                {
                    Dispose();
                }
            }
        }
Example #3
0
        /// <summary>
        /// Cleans up any resource being used.
        /// </summary>
        public void Dispose()
        {
            lock (m_pLock)
            {
                if (this.State == DNS_ClientTransactionState.Disposed)
                {
                    return;
                }

                SetState(DNS_ClientTransactionState.Disposed);

                if (m_pTimeoutTimer != null)
                {
                    m_pTimeoutTimer.Dispose();
                    m_pTimeoutTimer = null;
                }

                m_pOwner = null;

                m_pResponse = null;

                this.StateChanged = null;
                this.Timeout      = null;
            }
        }
Example #4
0
        /// <summary>
        /// Queries server with specified query.
        /// </summary>
        /// <param name="queryText">Query text. It depends on queryType.</param>
        /// <param name="queryType">Query type.</param>
        /// <param name="timeout">Query timeout in milli seconds.</param>
        /// <returns>Returns DSN server response.</returns>
        public DnsServerResponse Query(string queryText, DNS_QType queryType, int timeout)
        {
            DnsServerResponse retVal = null;
            ManualResetEvent  wait   = new ManualResetEvent(false);

            DNS_ClientTransaction transaction = CreateTransaction(queryType, queryText, timeout);

            transaction.Timeout += delegate(object s, EventArgs e)
            {
                wait.Set();
            };
            transaction.StateChanged += delegate(object s1, EventArgs <DNS_ClientTransaction> e1)
            {
                if (transaction.State == DNS_ClientTransactionState.Completed || transaction.State == DNS_ClientTransactionState.Disposed)
                {
                    retVal = transaction.Response;

                    wait.Set();
                }
            };
            transaction.Start();

            // Wait transaction to complete.
            wait.WaitOne();

            return(retVal);
        }
Example #5
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="response">DNS server response.</param>
            /// <param name="expires">Time when cache entry expires.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null reference.</exception>
            public CacheEntry(DnsServerResponse response,DateTime expires)
            {
                if(response == null){
                    throw new ArgumentNullException("response");
                }

                m_pResponse = response;
                m_Expires   = expires;
            }
Example #6
0
        /// <summary>
        /// Starts DNS transaction processing.
        /// </summary>
        /// <exception cref="InvalidOperationException">Is raised when this method is called in invalid transaction state.</exception>
        public void Start()
        {
            if (this.State != DNS_ClientTransactionState.WaitingForStart)
            {
                throw new InvalidOperationException("DNS_ClientTransaction.Start may be called only in 'WaitingForStart' transaction state.");
            }

            SetState(DNS_ClientTransactionState.Active);

            // Move processing to thread pool.
            ThreadPool.QueueUserWorkItem(delegate(object state){
                try{
                    // Use DNS cache if allowed.
                    if (Dns_Client.UseDnsCache)
                    {
                        DnsServerResponse response = m_pOwner.Cache.GetFromCache(m_QName, (int)m_QType);
                        if (response != null)
                        {
                            m_pResponse = response;

                            SetState(DNS_ClientTransactionState.Completed);
                            Dispose();

                            return;
                        }
                    }

                    byte[] buffer = new byte[1400];
                    int count     = CreateQuery(buffer, m_ID, m_QName, m_QType, 1);

                    // Send parallel query to DNS server(s).
                    foreach (string server in Dns_Client.DnsServers)
                    {
                        if (Net_Utils.IsIPAddress(server))
                        {
                            IPAddress ip = IPAddress.Parse(server);
                            m_pOwner.Send(ip, buffer, count);
                        }
                    }

                    m_pTimeoutTimer.Start();
                }
                catch {
                    // Check if we have bad unicode qname.
                    try{
                        System.Globalization.IdnMapping ldn = new System.Globalization.IdnMapping();
                        ldn.GetAscii(m_QName);
                    }
                    catch {
                        m_pResponse = new DnsServerResponse(true, m_ID, DNS_RCode.NAME_ERROR, new List <DNS_rr>(), new List <DNS_rr>(), new List <DNS_rr>());
                    }

                    SetState(DNS_ClientTransactionState.Completed);
                }
            });
        }
Example #7
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="response">DNS server response.</param>
            /// <param name="expires">Time when cache entry expires.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null reference.</exception>
            public CacheEntry(DnsServerResponse response, DateTime expires)
            {
                if (response == null)
                {
                    throw new ArgumentNullException("response");
                }

                m_pResponse = response;
                m_Expires   = expires;
            }
Example #8
0
        /// <summary>
        /// Resolves host name to IP addresses.
        /// </summary>
        /// <param name="host">Host name or IP address.</param>
        /// <returns>Return specified host IP addresses.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>host</b> is null.</exception>
        public static IPAddress[] Resolve(string host)
        {
            if (host == null)
            {
                throw new ArgumentNullException("host");
            }

            // If hostName_IP is IP
            try
            {
                return(new IPAddress[] { IPAddress.Parse(host) });
            }
            catch
            {
            }

            // This is probably NetBios name
            if (host.IndexOf(".") == -1)
            {
                return(System.Net.Dns.GetHostEntry(host).AddressList);
            }
            else
            {
                // hostName_IP must be host name, try to resolve it's IP
                using (Dns_Client dns = new Dns_Client())
                {
                    DnsServerResponse resp = dns.Query(host, DNS_QType.A);
                    if (resp.ResponseCode == DNS_RCode.NO_ERROR)
                    {
                        DNS_rr_A[]  records = resp.GetARecords();
                        IPAddress[] retVal  = new IPAddress[records.Length];
                        for (int i = 0; i < records.Length; i++)
                        {
                            retVal[i] = records[i].IP;
                        }

                        return(retVal);
                    }
                    else
                    {
                        throw new Exception(resp.ResponseCode.ToString());
                    }
                }
            }
        }
        /// <summary>
        /// Adds dns records to cache. If old entry exists, it is replaced.
        /// </summary>
        /// <param name="qname">Query name.</param>
        /// <param name="qtype">Query type.</param>
        /// <param name="response">DNS server response.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>qname</b> or <b>response</b> is null reference.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        public void AddToCache(string qname, int qtype, DnsServerResponse response)
        {
            if (qname == null)
            {
                throw new ArgumentNullException("qname");
            }
            if (qname == string.Empty)
            {
                throw new ArgumentException("Argument 'qname' value must be specified.", "qname");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            lock (m_pCache)
            {
                // Remove old cache entry, if any.
                if (m_pCache.ContainsKey(qname + qtype))
                {
                    m_pCache.Remove(qname + qtype);
                }

                if (response.ResponseCode == DNS_RCode.NO_ERROR)
                {
                    int ttl = m_MaxCacheTtl;
                    // Search smallest DNS record TTL and use it.
                    foreach (DNS_rr rr in response.AllAnswers)
                    {
                        if (rr.TTL < ttl)
                        {
                            ttl = rr.TTL;
                        }
                    }

                    m_pCache.Add(qname + qtype, new CacheEntry(response, DateTime.Now.AddSeconds(ttl)));
                }
                else
                {
                    m_pCache.Add(qname + qtype, new CacheEntry(response, DateTime.Now.AddSeconds(m_MaxNegativeCacheTtl)));
                }
            }
        }
Example #10
0
        /// <summary>
        /// Cleans up any resource being used.
        /// </summary>
        public void Dispose()
        {
            lock(m_pLock){
                if(this.State == DNS_ClientTransactionState.Disposed){
                    return;
                }

                SetState(DNS_ClientTransactionState.Disposed);

                m_pTimeoutTimer.Dispose();
                m_pTimeoutTimer = null;

                m_pOwner = null;

                m_pResponse = null;

                this.StateChanged = null;
                this.Timeout = null;
            }
        }
Example #11
0
        /// <summary>
        /// Adds dns records to cache. If old entry exists, it is replaced.
        /// </summary>
        /// <param name="qname"></param>
        /// <param name="qtype"></param>
        /// <param name="answers"></param>
        public static void AddToCache(string qname, int qtype, DnsServerResponse answers)
        {
            if (answers == null)
            {
                return;
            }

            try{
                lock (m_pCache){
                    // Remove old cache entry, if any.
                    if (m_pCache.Contains(qname + qtype))
                    {
                        m_pCache.Remove(qname + qtype);
                    }
                    m_pCache.Add(qname + qtype, new DnsCacheEntry(answers, DateTime.Now));
                }
            }
            catch {
            }
        }
Example #12
0
        /// <summary>
        /// Gets specified host IP addresses(A and AAAA).
        /// </summary>
        /// <param name="host">Host name.</param>
        /// <returns>Returns specified host IP addresses.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>host</b> is null reference.</exception>
        public IPAddress[] GetHostAddresses(string host)
        {
            if (host == null)
            {
                throw new ArgumentNullException("host");
            }

            List <IPAddress> retVal = new List <IPAddress>();

            // This is probably NetBios name
            if (host.IndexOf(".") == -1)
            {
                return(System.Net.Dns.GetHostEntry(host).AddressList);
            }
            else
            {
                DnsServerResponse response = Query(host, DNS_QType.A);
                if (response.ResponseCode != DNS_RCode.NO_ERROR)
                {
                    throw new DNS_ClientException(response.ResponseCode);
                }

                foreach (DNS_rr_A record in response.GetARecords())
                {
                    retVal.Add(record.IP);
                }

                response = Query(host, DNS_QType.AAAA);
                if (response.ResponseCode != DNS_RCode.NO_ERROR)
                {
                    throw new DNS_ClientException(response.ResponseCode);
                }

                foreach (DNS_rr_AAAA record in response.GetAAAARecords())
                {
                    retVal.Add(record.IP);
                }
            }

            return(retVal.ToArray());
        }
Example #13
0
        /// <summary>
        /// Processes DNS server response through this transaction.
        /// </summary>
        /// <param name="response">DNS server response.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null reference.</exception>
        internal void ProcessResponse(DnsServerResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            try
            {
                lock (m_pLock)
                {
                    if (this.State != DNS_ClientTransactionState.Active)
                    {
                        return;
                    }
                    m_ResponseCount++;

                    // Late arriving response or retransmitted response, just skip it.
                    if (m_pResponse != null)
                    {
                        return;
                    }
                    // If server refused to complete query and we more active queries to other servers, skip that response.
                    if (response.ResponseCode == DNS_RCode.REFUSED && m_ResponseCount < Dns_Client.DnsServers.Length)
                    {
                        return;
                    }

                    m_pResponse = response;

                    SetState(DNS_ClientTransactionState.Completed);
                }
            }
            finally
            {
                if (this.State == DNS_ClientTransactionState.Completed)
                {
                    Dispose();
                }
            }
        }
Example #14
0
        /// <summary>
        /// Processes DNS server response through this transaction.
        /// </summary>
        /// <param name="response">DNS server response.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null reference.</exception>
        internal void ProcessResponse(DnsServerResponse response)
        {
            if(response == null){
                throw new ArgumentNullException("response");
            }
                        
            try{
                lock(m_pLock){
                    if(this.State != DNS_ClientTransactionState.Active){
                        return;
                    }
                    m_ResponseCount++;

                    // Late arriving response or retransmitted response, just skip it.
                    if(m_pResponse != null){
                        return;
                    }
                    // If server refused to complete query and we more active queries to other servers, skip that response.
                    if(response.ResponseCode == DNS_RCode.REFUSED && m_ResponseCount < Dns_Client.DnsServers.Length){
                        return;
                    }

                    m_pResponse = response;

                    SetState(DNS_ClientTransactionState.Completed);
                } 
            }
            finally{
                if(this.State == DNS_ClientTransactionState.Completed){
                    Dispose();
                }                
            }
        }
Example #15
0
        /// <summary>
        /// Starts DNS transaction processing.
        /// </summary>
        /// <exception cref="InvalidOperationException">Is raised when this method is called in invalid transaction state.</exception>
        public void Start()
        {   
            if(this.State != DNS_ClientTransactionState.WaitingForStart){
                throw new InvalidOperationException("DNS_ClientTransaction.Start may be called only in 'WaitingForStart' transaction state.");
            }

            SetState(DNS_ClientTransactionState.Active);

            // Move processing to thread pool.
            ThreadPool.QueueUserWorkItem(delegate(object state){
                try{
                    // Use DNS cache if allowed.
			        if(Dns_Client.UseDnsCache){ 
	                    DnsServerResponse response = m_pOwner.Cache.GetFromCache(m_QName,(int)m_QType);
				        if(response != null){
					        m_pResponse = response;

                            SetState(DNS_ClientTransactionState.Completed);
                            Dispose();

                            return;
				        }
			        }   

                    byte[] buffer = new byte[1400];
                    int count = CreateQuery(buffer,m_ID,m_QName,m_QType,1);
  
                    // Send parallel query to DNS server(s).
                    foreach(string server in Dns_Client.DnsServers){
                        if(Net_Utils.IsIPAddress(server)){
                            IPAddress ip = IPAddress.Parse(server);
                            m_pOwner.Send(ip,buffer,count);
                        }
                    }

                    m_pTimeoutTimer.Start();
                }
                catch{
                    Dispose();
                }
            });
        }
Example #16
0
		/// <summary>
		/// Default constructor.
		/// </summary>
		/// <param name="answers">Dns answers.</param>
		/// <param name="addTime">Entry add time.</param>
		public DnsCacheEntry(DnsServerResponse answers,DateTime addTime)
		{
			m_pResponse = answers;
			m_Time      = addTime;
		}
Example #17
0
		/// <summary>
		/// Adds dns records to cache. If old entry exists, it is replaced.
		/// </summary>
		/// <param name="qname">Query name.</param>
		/// <param name="qtype">Query type.</param>
		/// <param name="response">DNS server response.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>qname</b> or <b>response</b> is null reference.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
		public void AddToCache(string qname,int qtype,DnsServerResponse response)
		{
            if(qname == null){
                throw new ArgumentNullException("qname");
            }
            if(qname == string.Empty){
                throw new ArgumentException("Argument 'qname' value must be specified.","qname");
            }
			if(response == null){
				throw new ArgumentNullException("response");
			}

	        lock(m_pCache){
			    // Remove old cache entry, if any.
				if(m_pCache.ContainsKey(qname + qtype)){
				    m_pCache.Remove(qname + qtype);
			    }

                if(response.ResponseCode == DNS_RCode.NO_ERROR){
                    int ttl = m_MaxCacheTtl;
                    // Search smallest DNS record TTL and use it.
                    foreach(DNS_rr rr in response.AllAnswers){
                        if(rr.TTL < ttl){
                            ttl = rr.TTL;
                        }
                    }

                    m_pCache.Add(qname + qtype,new CacheEntry(response,DateTime.Now.AddSeconds(ttl)));
                }
                else{
                    m_pCache.Add(qname + qtype,new CacheEntry(response,DateTime.Now.AddSeconds(m_MaxNegativeCacheTtl)));
                }
			}
		}
Example #18
0
            /// <summary>
            /// Gets A and AAAA records from DNS server additional responses section.
            /// </summary>
            /// <param name="name">Host name.</param>
            /// <param name="response">DNS server response.</param>
            /// <returns>Returns A and AAAA records from DNS server additional responses section.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>name</b> or <b>response</b> is null reference.</exception>
            private IPAddress[] Get_A_or_AAAA_FromResponse(string name,DnsServerResponse response)
            {
                if(name == null){
                    throw new ArgumentNullException("name");
                }
                if(response == null){
                    throw new ArgumentNullException("response");
                }

                List<IPAddress> aList = new List<IPAddress>();
                List<IPAddress> aaaaList = new List<IPAddress>();

                foreach(DNS_rr rr in response.AdditionalAnswers){
                    if(string.Equals(name,rr.Name,StringComparison.InvariantCultureIgnoreCase)){
                        if(rr is DNS_rr_A){
                            aList.Add(((DNS_rr_A)rr).IP);
                        }
                        else if(rr is DNS_rr_AAAA){
                            aaaaList.Add(((DNS_rr_AAAA)rr).IP);
                        }
                    }
                }

                // We list IPv4 first and then IPv6 addresses.
                aList.AddRange(aaaaList);

                return aList.ToArray();
            }
Example #19
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="answers">Dns answers.</param>
 /// <param name="addTime">Entry add time.</param>
 public DnsCacheEntry(DnsServerResponse answers, DateTime addTime)
 {
     m_pResponse = answers;
     m_Time      = addTime;
 }
Example #20
0
		/// <summary>
		/// Adds dns records to cache. If old entry exists, it is replaced.
		/// </summary>
		/// <param name="qname"></param>
		/// <param name="qtype"></param>
		/// <param name="answers"></param>
		public static void AddToCache(string qname,int qtype,DnsServerResponse answers)
		{
			if(answers == null){
				return;
			}

			try{
				lock(m_pCache){
					// Remove old cache entry, if any.
					if(m_pCache.Contains(qname + qtype)){
						m_pCache.Remove(qname + qtype);
					}
					m_pCache.Add(qname + qtype,new DnsCacheEntry(answers,DateTime.Now));
				}
			}
			catch{
			}
		}