示例#1
0
        /// <summary>
        /// Attempts a lookup from DNS.
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="startQuery"></param>
        /// <param name="preferIPv6"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        private static async Task <SIPEndPoint> SIPLookupAsync(
            SIPURI uri,
            QueryType startQuery,
            bool preferIPv6,
            CancellationToken ct)
        {
            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 && !ct.IsCancellationRequested)
            {
                switch (queryType)
                {
                case QueryType.SRV:

                    try
                    {
                        var srvProtocol = SIPServices.GetSRVProtocolForSIPURI(uri);
                        var srvResult   = await _lookupClient.ResolveServiceAsync(uri.MAddrOrHostAddress, uri.Scheme.ToString(), srvProtocol.ToString()).ConfigureAwait(false);

                        (var srvHost, var srvPort) = GetHostAndPortFromSrvResult(srvResult);
                        if (srvHost != null)
                        {
                            host = srvHost;
                            port = srvPort != 0 ? srvPort : port;

                            logger.LogDebug($"SIP DNS SRV for {uri} resolved to {host} and port {port}.");
                        }
                    }
                    catch (Exception srvExcp)
                    {
                        logger.LogWarning(srvExcp, $"SIPDNS exception on SRV lookup. {srvExcp.Message}.");
                    }
                    queryType = preferIPv6 ? QueryType.AAAA : QueryType.A;

                    break;

                case QueryType.AAAA:

                    try
                    {
                        var aaaaResult = await _lookupClient.QueryAsync(host, UseANYLookups?QueryType.ANY : QueryType.AAAA, QueryClass.IN, ct).ConfigureAwait(false);

                        if (aaaaResult?.Answers?.Count > 0)
                        {
                            result = GetFromLookupResult(uri.Protocol, aaaaResult.Answers.AddressRecords().OrderByDescending(x => x.RecordType).First(), port);
                            isDone = true;
                        }
                        else
                        {
                            queryType = QueryType.A;
                        }
                    }
                    catch (Exception srvExcp)
                    {
                        logger.LogWarning(srvExcp, $"SIPDNS exception on AAAA lookup. {srvExcp.Message}.");
                        queryType = QueryType.A;
                    }

                    break;

                default:
                    // A record lookup.
                    try
                    {
                        var aResult = await _lookupClient.QueryAsync(host, QueryType.A, QueryClass.IN, ct).ConfigureAwait(false);

                        if (aResult != null)
                        {
                            if (aResult.Answers?.Count > 0)
                            {
                                result = GetFromLookupResult(uri.Protocol, aResult.Answers.AddressRecords().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;
                            }
                        }
                    }
                    catch (Exception srvExcp)
                    {
                        logger.LogWarning(srvExcp, $"SIPDNS exception on A lookup. {srvExcp.Message}.");
                        result = SIPEndPoint.Empty;
                    }

                    isDone = true;
                    break;
                }
            }

            return(result);
        }