/// <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); }
/// <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> /// Creates new DNS client transaction. /// </summary> /// <param name="queryType">Query type.</param> /// <param name="queryText">Query text. It depends on queryType.</param> /// <param name="timeout">Transaction timeout in milliseconds. DNS default value is 2000, value 0 means no timeout - this is not suggested.</param> /// <returns>Returns DNS client transaction.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>queryText</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <remarks>Creates asynchronous(non-blocking) DNS transaction. Call <see cref="DNS_ClientTransaction.Start"/> to start transaction. /// It is allowd to create multiple conccurent transactions.</remarks> public DNS_ClientTransaction CreateTransaction(DNS_QType queryType,string queryText,int timeout) { if(queryType == DNS_QType.PTR){ IPAddress ip = null; if(!IPAddress.TryParse(queryText,out ip)){ throw new ArgumentException("Argument 'queryText' value must be IP address if queryType == DNS_QType.PTR.","queryText"); } } if(queryText == null){ throw new ArgumentNullException("queryText"); } if(queryText == string.Empty){ throw new ArgumentException("Argument 'queryText' value may not be \"\".","queryText"); } if(queryType == DNS_QType.PTR){ string ip = queryText; // See if IP is ok. IPAddress ipA = IPAddress.Parse(ip); queryText = ""; // IPv6 if(ipA.AddressFamily == AddressFamily.InterNetworkV6){ // 4321:0:1:2:3:4:567:89ab // would be // b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.IP6.ARPA char[] ipChars = ip.Replace(":","").ToCharArray(); for(int i=ipChars.Length - 1;i>-1;i--){ queryText += ipChars[i] + "."; } queryText += "IP6.ARPA"; } // IPv4 else{ // 213.35.221.186 // would be // 186.221.35.213.in-addr.arpa string[] ipParts = ip.Split('.'); //--- Reverse IP ---------- for(int i=3;i>-1;i--){ queryText += ipParts[i] + "."; } queryText += "in-addr.arpa"; } } DNS_ClientTransaction retVal = new DNS_ClientTransaction(this,new Random().Next(0xFFFF),queryType,queryText,timeout); retVal.StateChanged += delegate(object s1,EventArgs<DNS_ClientTransaction> e1){ if(retVal.State == DNS_ClientTransactionState.Completed){ m_pTransactions.Remove(e1.Value.ID); } }; m_pTransactions.Add(retVal.ID,retVal); return retVal; }
/// <summary> /// Creates new DNS client transaction. /// </summary> /// <param name="queryType">Query type.</param> /// <param name="queryText">Query text. It depends on queryType.</param> /// <param name="timeout">Transaction timeout in milliseconds. DNS default value is 2000, value 0 means no timeout - this is not suggested.</param> /// <returns>Returns DNS client transaction.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>queryText</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <remarks>Creates asynchronous(non-blocking) DNS transaction. Call <see cref="DNS_ClientTransaction.Start"/> to start transaction. /// It is allowd to create multiple conccurent transactions.</remarks> public DNS_ClientTransaction CreateTransaction(DNS_QType queryType, string queryText, int timeout) { if (queryType == DNS_QType.PTR) { IPAddress ip = null; if (!IPAddress.TryParse(queryText, out ip)) { throw new ArgumentException("Argument 'queryText' value must be IP address if queryType == DNS_QType.PTR.", "queryText"); } } if (queryText == null) { throw new ArgumentNullException("queryText"); } if (queryText == string.Empty) { throw new ArgumentException("Argument 'queryText' value may not be \"\".", "queryText"); } if (queryType == DNS_QType.PTR) { string ip = queryText; // See if IP is ok. IPAddress ipA = IPAddress.Parse(ip); queryText = ""; // IPv6 if (ipA.AddressFamily == AddressFamily.InterNetworkV6) { // 4321:0:1:2:3:4:567:89ab // would be // b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.IP6.ARPA char[] ipChars = ip.Replace(":", "").ToCharArray(); for (int i = ipChars.Length - 1; i > -1; i--) { queryText += ipChars[i] + "."; } queryText += "IP6.ARPA"; } // IPv4 else { // 213.35.221.186 // would be // 186.221.35.213.in-addr.arpa string[] ipParts = ip.Split('.'); //--- Reverse IP ---------- for (int i = 3; i > -1; i--) { queryText += ipParts[i] + "."; } queryText += "in-addr.arpa"; } } DNS_ClientTransaction retVal = new DNS_ClientTransaction(this, new Random().Next(0xFFFF), queryType, queryText, timeout); retVal.StateChanged += delegate(object s1, EventArgs <DNS_ClientTransaction> e1) { if (retVal.State == DNS_ClientTransactionState.Completed) { m_pTransactions.Remove(e1.Value.ID); } }; m_pTransactions.Add(retVal.ID, retVal); return(retVal); }