public static SIPDNSLookupResult DNSNameRecordLookup(string host, int port, bool async, SIPURI uri, SIPDNSLookupResult lookupResult = null, bool?preferIPv6 = null, int recursionLevel = 0) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS Name record lookup requested for " + host + ".", null)); SIPDNSLookupResult result = lookupResult ?? new SIPDNSLookupResult(uri); result.LookupError = null; if (UseANYLookups) { DNSResponse aRecordResponse = DNSManager.Lookup(host, QType.ANY, DNS_A_RECORD_LOOKUP_TIMEOUT, null, true, async); if (aRecordResponse == null && async) { result.Pending = true; } else if (aRecordResponse == null) { } else if (aRecordResponse.Timedout) { result.ATimedoutAt = DateTime.Now; } else if (!string.IsNullOrWhiteSpace(aRecordResponse.Error)) { result.LookupError = aRecordResponse.Error; } else if ((aRecordResponse.RecordsAAAA == null || aRecordResponse.RecordsAAAA.Length == 0) && (aRecordResponse.RecordsA == null || aRecordResponse.RecordsA.Length == 0) && (aRecordResponse.RecordsCNAME == null || aRecordResponse.RecordsCNAME.Length == 0)) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no CNAME, A or AAAA records found for " + host + ".", null)); result.LookupError = "No CNAME, A or AAAA records found for " + host + "."; } else { if (preferIPv6 == null) { preferIPv6 = SIPDNSManager.PreferIPv6NameResolution; } foreach (RecordCNAME aRecord in aRecordResponse.RecordsCNAME) { //CNAME could be another CNAME or A/AAAA Record -> max 3 levels recursive name resolution if (recursionLevel < 3) { SIPDNSLookupResult resultCName = DNSNameRecordLookup(aRecord.CNAME, port, async, uri, lookupResult, preferIPv6, recursionLevel + 1); if (resultCName != null) { foreach (SIPDNSLookupEndPoint ep in resultCName.EndPointResults) { result.AddLookupResult(ep); } } } } if (preferIPv6 == true) { SIPURI sipURI = result.URI; foreach (RecordAAAA aRecord in aRecordResponse.RecordsAAAA) { SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL); result.AddLookupResult(sipLookupEndPoint); SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS AAAA record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null)); } foreach (RecordA aRecord in aRecordResponse.RecordsA) { SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL); result.AddLookupResult(sipLookupEndPoint); SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null)); } } else { SIPURI sipURI = result.URI; foreach (RecordA aRecord in aRecordResponse.RecordsA) { SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL); result.AddLookupResult(sipLookupEndPoint); SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS A record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null)); } foreach (RecordAAAA aRecord in aRecordResponse.RecordsAAAA) { SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(aRecord.Address, port)), aRecord.RR.TTL); result.AddLookupResult(sipLookupEndPoint); SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS AAAA record found for " + host + ", result " + sipLookupEndPoint.LookupEndPoint.ToString() + ".", null)); } } } } if (result.LookupError != null || result.EndPointResults == null || result.EndPointResults.Count == 0) { if (preferIPv6 == true) { result = DNSAAAARecordLookup(host, port, async, uri, lookupResult); } else { result = DNSARecordLookup(host, port, async, uri, lookupResult); } } return(result); }
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 { lock (m_queuedLookups) { if (m_queuedLookups.Count > 0) { lookupRequest = m_queuedLookups.Dequeue(); 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 + "."); //dnsEntry = new DNSEntry(hostname); //dnsEntry.LastLookup = DateTime.Now; //IPHostEntry ipHostEntry = Dns.GetHostEntry(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); } if (dnsResponse == null) { logger.LogWarning("DNSManager resolution error for " + lookupRequest.QueryType + " " + lookupRequest.Hostname + " no response was returned. Time taken=" + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##") + "ms."); } else if (dnsResponse.Error != null) { logger.LogWarning("DNSManager resolution error for " + lookupRequest.QueryType + " " + lookupRequest.Hostname + ". " + dnsResponse.Error + ". Time taken=" + DateTime.Now.Subtract(startLookupTime).TotalMilliseconds.ToString("0.##") + "ms."); } 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(); } } } lock (m_inProgressLookups) { m_inProgressLookups.Remove(lookupRequest); } } 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."); } }
public static DNSResponse Lookup(string hostname, QType queryType, int timeout, List <IPEndPoint> dnsServers, bool useCache, bool async) { if (hostname == null || hostname.Trim().Length == 0) { return(null); } DNSResponse ipAddressResult = MatchIPAddress(hostname); if (ipAddressResult != null) { return(ipAddressResult); } else if (useCache) { DNSResponse cacheResult = m_resolver.QueryCache(hostname.Trim().ToLower(), queryType); if (cacheResult != null) { return(cacheResult); } } if (async) { //logger.LogDebug("DNS lookup cache miss for async lookup to " + queryType.ToString() + " " + hostname + "."); QueueLookup(new LookupRequest(hostname.Trim().ToLower(), queryType, timeout, dnsServers, null)); return(null); } else { ManualResetEvent completeEvent = new ManualResetEvent(false); QueueLookup(new LookupRequest(hostname.Trim().ToLower(), queryType, timeout, dnsServers, completeEvent)); if (completeEvent.WaitOne(timeout * 1000 * 2, false)) { //logger.LogDebug("Complete event fired for DNS lookup on " + queryType.ToString() + " " + hostname + "."); // Completed event was fired, the DNS entry will now be in cache. DNSResponse result = m_resolver.QueryCache(hostname, queryType); if (result != null) { return(result); } else { //logger.LogDebug("DNS lookup cache miss for " + queryType.ToString() + " " + hostname + "."); // Timeout. DNSResponse timeoutResponse = new DNSResponse(); timeoutResponse.Timedout = true; return(timeoutResponse); } } else { // If this block gets called it's because the DNS resolver class did not return within twice the timeout period it // was asked to do so in. If this happens a lot further investigation into the DNS resolver class is warranted. logger.LogError("DNSManager timed out waiting for the DNS resolver to complete the lookup for " + queryType.ToString() + " " + hostname + "."); // Timeout. DNSResponse timeoutResponse = new DNSResponse(); timeoutResponse.Timedout = true; return(timeoutResponse); } } }
public static void DNSSRVRecordLookup(SIPSchemesEnum scheme, SIPProtocolsEnum protocol, string host, bool async, ref SIPDNSLookupResult lookupResult) { SIPServicesEnum reqdNAPTRService = SIPServicesEnum.none; if (scheme == SIPSchemesEnum.sip && protocol == SIPProtocolsEnum.udp) { reqdNAPTRService = SIPServicesEnum.sipudp; } else if (scheme == SIPSchemesEnum.sip && protocol == SIPProtocolsEnum.tcp) { reqdNAPTRService = SIPServicesEnum.siptcp; } else if (scheme == SIPSchemesEnum.sips && protocol == SIPProtocolsEnum.tcp) { reqdNAPTRService = SIPServicesEnum.sipstcp; } else if (scheme == SIPSchemesEnum.sip && protocol == SIPProtocolsEnum.tls) { reqdNAPTRService = SIPServicesEnum.siptls; } // If there are NAPTR records available see if there is a matching one for the SIP scheme and protocol required. SIPDNSServiceResult naptrService = null; if (lookupResult.SIPNAPTRResults != null && lookupResult.SIPNAPTRResults.Count > 0) { if (reqdNAPTRService != SIPServicesEnum.none && lookupResult.SIPNAPTRResults.ContainsKey(reqdNAPTRService)) { naptrService = lookupResult.SIPNAPTRResults[reqdNAPTRService]; } } // Construct the SRV target to lookup depending on whether an NAPTR record was available or not. string srvLookup = null; if (naptrService != null) { srvLookup = naptrService.Data; } else { srvLookup = "_" + scheme.ToString() + "._" + protocol.ToString() + "." + host; } SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup requested for " + srvLookup + ".", null)); DNSResponse srvRecordResponse = DNSManager.Lookup(srvLookup, DNSQType.SRV, DNS_LOOKUP_TIMEOUT, null, true, async); if (srvRecordResponse == null && async) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup pending for " + srvLookup + ".", null)); lookupResult.Pending = true; } else if (srvRecordResponse.Timedout) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup timed out for " + srvLookup + ".", null)); lookupResult.SRVTimedoutAt = DateTime.Now; } else if (srvRecordResponse.Error != null) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup for " + srvLookup + " returned error of " + lookupResult.LookupError + ".", null)); } else if (srvRecordResponse.Error == null && srvRecordResponse.RecordSRV != null && srvRecordResponse.RecordSRV.Length > 0) { foreach (RecordSRV srvRecord in srvRecordResponse.RecordSRV) { SIPDNSServiceResult sipSRVResult = new SIPDNSServiceResult(reqdNAPTRService, srvRecord.Priority, srvRecord.Weight, srvRecord.RR.TTL, srvRecord.Target, srvRecord.Port, DateTime.Now); lookupResult.AddSRVResult(sipSRVResult); SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record found for " + srvLookup + ", result " + srvRecord.Target + " " + srvRecord.Port + ".", null)); } } else { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no SRV records found for " + srvLookup + ".", null)); } }
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.Logger.Debug("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.Logger.Warn("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.Logger.Warn("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 < GetDnsSuffixes().Length&& bDnsErr && UseDNSSuffixes && !m_close; iSuffix++) { string host = lookupRequest.Hostname; if (!host.EndsWith(".")) { host += "."; } host += 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.Logger.Warn("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.Logger.Warn("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.Logger.Debug( $"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.Logger.Warn("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.Logger.Debug( $"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.Logger.Warn("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.Logger.Debug("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.Logger.Debug( " no SRV resource records found for " + lookupRequest.Hostname + "."); } else { foreach (RecordSRV srvRecord in dnsResponse.RecordSRV) { Logger.Logger.Debug(" result: priority=" + srvRecord.PRIORITY + ", weight=" + srvRecord.WEIGHT + ", port=" + srvRecord.PORT + ", target=" + srvRecord.TARGET + "."); } } } else { Logger.Logger.Debug("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.Logger.Error("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.Logger.Error("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.Logger.Error("Exception DNSManager ProcessLookups. ->" + excp.Message); } finally { if (m_close) { m_lookupARE.Set(); } //logger.LogDebug("DNSManager thread shutdown."); } }
public static void DNSSRVRecordLookup(SIPSchemesEnum scheme, SIPProtocolsEnum protocol, string host, bool async, ref SIPDNSLookupResult lookupResult) { SIPServicesEnum reqdNAPTRService = SIPServicesEnum.none; if (scheme == SIPSchemesEnum.sip && protocol == SIPProtocolsEnum.udp) { reqdNAPTRService = SIPServicesEnum.sipudp; } else if (scheme == SIPSchemesEnum.sip && protocol == SIPProtocolsEnum.tcp) { reqdNAPTRService = SIPServicesEnum.siptcp; } else if (scheme == SIPSchemesEnum.sips && protocol == SIPProtocolsEnum.tcp) { reqdNAPTRService = SIPServicesEnum.sipstcp; } //rj2 2018-10-17: this looks wrong, but the www says: if sips then protocol is _tcp not _tls else if (scheme == SIPSchemesEnum.sips && protocol == SIPProtocolsEnum.tls) { reqdNAPTRService = SIPServicesEnum.sipstcp; } else if (scheme == SIPSchemesEnum.sip && protocol == SIPProtocolsEnum.tls) { reqdNAPTRService = SIPServicesEnum.siptls; } // If there are NAPTR records available see if there is a matching one for the SIP scheme and protocol required. // this works best (only works) if protocol in sip-uri matches sip-service of NAPTRRecord SIPDNSServiceResult naptrService = null; if (lookupResult.SIPNAPTRResults != null && lookupResult.SIPNAPTRResults.Count > 0) { if (reqdNAPTRService != SIPServicesEnum.none && lookupResult.SIPNAPTRResults.ContainsKey(reqdNAPTRService)) { naptrService = lookupResult.SIPNAPTRResults[reqdNAPTRService]; } } // Construct the SRV target to lookup depending on whether an NAPTR record was available or not. string srvLookup = null; if (naptrService != null) { srvLookup = naptrService.Data; } else { if (scheme == SIPSchemesEnum.sips) { srvLookup = SIPDNSConstants.SRV_SIPS_TCP_QUERY_PREFIX + host; } else { srvLookup = "_" + scheme.ToString() + "._" + protocol.ToString() + "." + host; } } SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup requested for " + srvLookup + ".", null)); DNSResponse srvRecordResponse = DNSManager.Lookup(srvLookup, QType.SRV, DNS_LOOKUP_TIMEOUT, null, true, async); if (srvRecordResponse == null && async) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup pending for " + srvLookup + ".", null)); lookupResult.Pending = true; } else if (srvRecordResponse.Timedout) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup timed out for " + srvLookup + ".", null)); lookupResult.SRVTimedoutAt = DateTime.Now; } else if (!string.IsNullOrWhiteSpace(srvRecordResponse.Error)) { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record lookup for " + srvLookup + " returned error of " + lookupResult.LookupError + ".", null)); } else if (string.IsNullOrWhiteSpace(srvRecordResponse.Error) && srvRecordResponse.RecordSRV != null && srvRecordResponse.RecordSRV.Length > 0) { foreach (RecordSRV srvRecord in srvRecordResponse.RecordSRV) { SIPDNSServiceResult sipSRVResult = new SIPDNSServiceResult(reqdNAPTRService, srvRecord.PRIORITY, srvRecord.WEIGHT, srvRecord.RR.TTL, srvRecord.TARGET, srvRecord.PORT, DateTime.Now); lookupResult.AddSRVResult(sipSRVResult); SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS SRV record found for " + srvLookup + ", result " + srvRecord.TARGET + " " + srvRecord.PORT + ".", null)); } } else { SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS no SRV records found for " + srvLookup + ".", null)); } }