/// <summary> /// Sends query to server. /// </summary> /// <param name="timeout">Query timeout in milli seconds.</param> /// <param name="qname">Query text.</param> /// <param name="qtype">Query type.</param> /// <param name="qclass">Query class.</param> /// <returns>Returns DNS server response.</returns> private DnsServerResponse QueryServer(int timeout, string qname, QTYPE qtype, int qclass) { if (m_DnsServers == null || m_DnsServers.Length == 0) { throw new Exception("Dns server isn't specified !"); } // See if query is in cache if (m_UseDnsCache) { DnsServerResponse resopnse = DnsCache.GetFromCache(qname, (int)qtype); if (resopnse != null) { return(resopnse); } } int queryID = Dns_Client.ID; byte[] query = CreateQuery(queryID, qname, qtype, qclass); // Create transcation and start processing it. using (DnsTransaction transaction = new DnsTransaction(this, queryID, qname, (int)qtype, timeout, query)){ ManualResetEvent wait = new ManualResetEvent(false); transaction.Timeout += delegate(object s, EventArgs e){ wait.Set(); }; transaction.Completed += delegate(object s, EventArgs e){ wait.Set(); }; m_pTransactions.Add(transaction.ID, transaction); // Start transaction processing and wait transaction to complete. transaction.Start(); wait.WaitOne(); // DNS server response received. if (transaction.Response != null) { return(transaction.Response); } // No server response - timeout. else { throw new Exception("Timeout - no response from DNS server."); } } }
/// <summary> /// Sends query to server. /// </summary> /// <param name="timeout">Query timeout in milli seconds.</param> /// <param name="qname">Query text.</param> /// <param name="qtype">Query type.</param> /// <param name="qclass">Query class.</param> /// <returns></returns> private DnsServerResponse QueryServer(int timeout, string qname, QTYPE qtype, int qclass) { if (m_DnsServers == null || m_DnsServers.Length == 0) { throw new Exception("Dns server isn't specified !"); } // See if query is in cache if (m_UseDnsCache) { DnsServerResponse resopnse = DnsCache.GetFromCache(qname, (int)qtype); if (resopnse != null) { return(resopnse); } } int queryID = Dns_Client.ID; byte[] query = CreateQuery(queryID, qname, qtype, qclass); // Create sending UDP socket. Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); udpClient.SendTimeout = 500; // Send parallel query to all dns servers and get first answer. DateTime startTime = DateTime.Now; while (startTime.AddMilliseconds(timeout) > DateTime.Now) { foreach (IPAddress dnsServer in m_DnsServers) { try{ udpClient.SendTo(query, new IPEndPoint(dnsServer, 53)); } catch { } } // Wait 10 ms response to arrive, if no response, retransmit query. if (udpClient.Poll(10, SelectMode.SelectRead)) { try{ byte[] retVal = new byte[1024]; int countRecieved = udpClient.Receive(retVal); // If reply is ok, return it DnsServerResponse serverResponse = ParseQuery(retVal, queryID); // Cache query if (m_UseDnsCache && serverResponse.ResponseCode == RCODE.NO_ERROR) { DnsCache.AddToCache(qname, (int)qtype, serverResponse); } return(serverResponse); } catch { } } } udpClient.Close(); // If we reach so far, we probably won't get connection to dsn server return(new DnsServerResponse(false, RCODE.SERVER_FAILURE, new List <DNS_rr_base>(), new List <DNS_rr_base>(), new List <DNS_rr_base>())); }