/// <summary> /// Attempts a lookup from cache. /// </summary> /// <param name="uri"></param> /// <param name="startQuery"></param> /// <param name="preferIPv6"></param> /// <returns></returns> private static SIPEndPoint SIPLookupFromCache( SIPURI uri, QueryType startQuery, bool preferIPv6) { SIPEndPoint result = null; QueryType queryType = startQuery; string host = uri.MAddrOrHostAddress; int port = SIPConstants.GetDefaultPort(uri.Protocol); if (ushort.TryParse(uri.HostPort, out var uriPort)) { port = uriPort; } bool isDone = false; while (!isDone) { switch (queryType) { case QueryType.SRV: var srvProtocol = SIPServices.GetSRVProtocolForSIPURI(uri); string serviceHost = DnsQueryExtensions.ConcatServiceName(uri.MAddrOrHostAddress, uri.Scheme.ToString(), srvProtocol.ToString()); var srvResult = _lookupClient.QueryCache(serviceHost, QueryType.SRV); (var srvHost, var srvPort) = GetHostAndPortFromSrvResult(srvResult); if (srvHost != null) { host = srvHost; port = srvPort != 0 ? srvPort : port; } queryType = preferIPv6 ? QueryType.AAAA : QueryType.A; break; case QueryType.AAAA: var aaaaResult = _lookupClient.QueryCache(host, UseANYLookups ? QueryType.ANY : QueryType.AAAA, QueryClass.IN); if (aaaaResult?.Answers?.Count > 0) { result = GetFromLookupResult(uri.Protocol, aaaaResult.Answers.OrderByDescending(x => x.RecordType).First(), port); isDone = true; } else { queryType = QueryType.A; } break; default: // A record lookup. var aResult = _lookupClient.QueryCache(host, QueryType.A, QueryClass.IN); if (aResult != null) { if (aResult.Answers?.Count > 0) { result = GetFromLookupResult(uri.Protocol, aResult.Answers.First(), port); } else { // We got a result back but it was empty indicating an unresolvable host or // some other DNS error condition. result = SIPEndPoint.Empty; } } isDone = true; break; } } return(result); }