Beispiel #1
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;
            }
Beispiel #2
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;
            }
        }
Beispiel #3
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();
                }                
            }
        }
Beispiel #4
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();
                }
            });
        }
Beispiel #5
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;
		}
Beispiel #6
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{
			}
		}
Beispiel #7
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)));
                }
			}
		}
Beispiel #8
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();
            }