private static void QueueLookup(LookupRequest lookupRequest) { LookupRequest inProgressLookup = (from lookup in m_inProgressLookups where lookup.Key == lookupRequest.id() select lookup.Value).FirstOrDefault(); if (inProgressLookup == null) { m_inProgressLookups.TryAdd(lookupRequest.id(), lookupRequest); m_queuedLookups.Enqueue(lookupRequest); logger.LogDebug("DNSManager lookup queued for " + lookupRequest.QueryType + " " + lookupRequest.Hostname + ", queue size=" + m_queuedLookups.Count + ", in progress=" + m_queuedLookups.Count + "."); m_lookupARE.Set(); } else { if (lookupRequest.CompleteEvent != null) { if (inProgressLookup.Duplicates == null) { inProgressLookup.Duplicates = new List <LookupRequest>() { lookupRequest }; } else { inProgressLookup.Duplicates.Add(lookupRequest); } logger.LogDebug("DNSManager duplicate lookup added for " + lookupRequest.QueryType + " " + lookupRequest.Hostname + ", queue size=" + m_queuedLookups.Count + ", in progress=" + m_queuedLookups.Count + "."); } } }
private static void ProcessLookups() { string hostname = null; try { string threadName = Thread.CurrentThread.Name; //logger.LogDebug("DNS Lookup Thread " + threadName + " started."); while (!m_close) { int lookups = 0; while (m_queuedLookups.Count > 0 && !m_close) { LookupRequest lookupRequest = LookupRequest.Empty; string queryType = null; //string hostname = null; DNSResponse dnsResponse = null; DateTime startLookupTime = DateTime.Now; try { if (m_queuedLookups.Count > 0) { if (m_queuedLookups.TryDequeue(out lookupRequest)) { hostname = lookupRequest.Hostname; queryType = lookupRequest.QueryType.ToString(); } } else { // Another thread got in ahead of this one to do the lookup. continue; } lookups++; logger.LogDebug("DNSManager thread " + threadName + " looking up " + queryType + " " + lookupRequest.Hostname + "."); if (lookupRequest.DNSServers == null) { dnsResponse = m_resolver.Query(lookupRequest.Hostname, lookupRequest.QueryType, lookupRequest.Timeout); } else { dnsResponse = m_resolver.Query(lookupRequest.Hostname, lookupRequest.QueryType, lookupRequest.Timeout, lookupRequest.DNSServers); } bool bDnsErr = false; if (dnsResponse == null) { logger.LogWarning("DNSManager resolution error for " + lookupRequest.QueryType + " " + lookupRequest.Hostname + " no response was returned. Time taken=" + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds + "ms."); bDnsErr = true; } else if (!string.IsNullOrWhiteSpace(dnsResponse.Error)) { logger.LogWarning("DNSManager resolution error for " + lookupRequest.QueryType + " " + lookupRequest.Hostname + ". " + dnsResponse.Error + ". Time taken=" + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds + "ms."); bDnsErr = true; } //rj2: use default dns suffixes for address resolution for (int iSuffix = 0; iSuffix < DNSManager.GetDnsSuffixes().Length&& bDnsErr && DNSManager.UseDNSSuffixes && !m_close; iSuffix++) { string host = lookupRequest.Hostname; if (!host.EndsWith(".")) { host += "."; } host += DNSManager.m_dnsSuffixes[iSuffix]; if (lookupRequest.DNSServers == null) { dnsResponse = m_resolver.Query(host, lookupRequest.QueryType, lookupRequest.Timeout); } else { dnsResponse = m_resolver.Query(host, lookupRequest.QueryType, lookupRequest.Timeout, lookupRequest.DNSServers); } bDnsErr = false; if (dnsResponse == null) { logger.LogWarning("DNSManager resolution error for " + lookupRequest.QueryType + " " + host + " no response was returned. Time taken=" + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds + "ms."); bDnsErr = true; } else if (!string.IsNullOrWhiteSpace(dnsResponse.Error)) { logger.LogWarning("DNSManager resolution error for " + lookupRequest.QueryType + " " + host + ". " + dnsResponse.Error + ". Time taken=" + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds + "ms."); bDnsErr = true; } } if (bDnsErr) { } else if (lookupRequest.QueryType == QType.A) { if (dnsResponse?.RecordsA.Length > 0) { logger.LogDebug($"DNSManager resolved A record for {lookupRequest.Hostname} to {dnsResponse.RecordsA[0].Address.ToString()} with TTL {dnsResponse.RecordsA[0].RR.TTL} in {DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##")}ms."); } else { logger.LogWarning("DNSManager could not resolve A record for " + lookupRequest.Hostname + " in " + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##") + "ms."); } } else if (lookupRequest.QueryType == QType.AAAA) { if (dnsResponse?.RecordsAAAA.Length > 0) { logger.LogDebug($"DNSManager resolved AAAA record for {lookupRequest.Hostname} to {dnsResponse.RecordsAAAA[0].Address.ToString()} with TTL {dnsResponse.RecordsAAAA[0].RR.TTL} in {DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##")}ms."); } else { logger.LogWarning("DNSManager could not resolve AAAA record for " + lookupRequest.Hostname + " in " + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##") + "ms."); } } else if (lookupRequest.QueryType == QType.SRV) { logger.LogDebug("DNSManager resolve time for " + lookupRequest.Hostname + " " + lookupRequest.QueryType + " " + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##") + "ms."); if (dnsResponse.RecordsRR == null || dnsResponse.RecordsRR.Length == 0) { logger.LogDebug(" no SRV resource records found for " + lookupRequest.Hostname + "."); } else { foreach (RecordSRV srvRecord in dnsResponse.RecordSRV) { logger.LogDebug(" result: priority=" + srvRecord.PRIORITY + ", weight=" + srvRecord.WEIGHT + ", port=" + srvRecord.PORT + ", target=" + srvRecord.TARGET + "."); } } } else { logger.LogDebug("DNSManager resolve time for " + lookupRequest.Hostname + " " + lookupRequest.QueryType + " " + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##") + "ms."); } } catch (Exception lookupExcp) { //dnsEntry.Unresolvable = true; dnsResponse.Error = "Exception lookup. " + lookupExcp.Message; logger.LogError("Exception DNSManager ProcessLookups Lookup (thread, " + threadName + ", hostname=" + hostname + "). " + lookupExcp.GetType().ToString() + "-" + lookupExcp.Message); } finally { try { if (dnsResponse != null) { if (lookupRequest.CompleteEvent != null) { lookupRequest.CompleteEvent.Set(); } // Mark any requests for the same hostname complete and fire the completed lookup event where required. if (lookupRequest.Duplicates != null) { foreach (LookupRequest duplicateRequest in lookupRequest.Duplicates) { duplicateRequest.CompleteEvent.Set(); } } } LookupRequest lr; m_inProgressLookups.TryRemove(lookupRequest.id(), out lr); } catch (Exception excp) { logger.LogError("Exception DNSManager ProcessLookup Adding DNS Response. " + excp.Message); } } } // No more lookups outstanding, put thread to sleep until a new lookup is required. m_lookupARE.WaitOne(); } //logger.LogDebug("Thread " + threadName + " shutdown."); } catch (Exception excp) { logger.LogError("Exception DNSManager ProcessLookups. " + excp.Message); } finally { if (m_close) { m_lookupARE.Set(); } //logger.LogDebug("DNSManager thread shutdown."); } }