Beispiel #1
0
 public SIPEndPoint ToSIPEndPoint()
 {
     if (IPSocket.TryParseIPEndPoint(Host, out var ipEndPoint))
     {
         if (ipEndPoint.Port != 0)
         {
             return(new SIPEndPoint(Protocol, ipEndPoint));
         }
         else
         {
             if (Protocol == SIPProtocolsEnum.tls)
             {
                 ipEndPoint.Port = m_defaultSIPTLSPort;
                 return(new SIPEndPoint(Protocol, ipEndPoint));
             }
             else
             {
                 ipEndPoint.Port = m_defaultSIPPort;
                 return(new SIPEndPoint(Protocol, ipEndPoint));
             }
         }
     }
     else
     {
         return(null);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Reverses ToString().
        /// </summary>
        /// <param name="serialisedSIPEndPoint">The serialised SIP end point MUST be in the form protocol:socket and protocol must
        /// be exactly 3 characters. Valid examples are udp:10.0.0.1:5060, invalid example is 10.0.0.1:5060.</param>
        private static SIPEndPoint ParseSerialisedSIPEndPoint(string serialisedSIPEndPoint)
        {
            if (!IPSocket.TryParseIPEndPoint(serialisedSIPEndPoint.Substring(4), out var endPoint))
            {
                throw new ApplicationException($"Could not parse SIPURI host {serialisedSIPEndPoint.Substring(4)} as an IP end point.");
            }

            return(new SIPEndPoint(SIPProtocolsType.GetProtocolType(serialisedSIPEndPoint.Substring(0, 3)), endPoint));
        }
Beispiel #3
0
 public static Task <SIPEndPoint> ResolveSIPUri(SIPURI uri, bool preferIPv6)
 {
     if (IPSocket.TryParseIPEndPoint(uri.Host, out var ipEndPoint))
     {
         return(Task.FromResult(new SIPEndPoint(uri.Protocol, ipEndPoint)));
     }
     else
     {
         return(Task.FromResult <SIPEndPoint>(null));
     }
 }
Beispiel #4
0
        public SIPEndPoint(SIPURI sipURI)
        {
            Protocol = sipURI.Protocol;

            if (!IPSocket.TryParseIPEndPoint(sipURI.Host, out var endPoint))
            {
                throw new ApplicationException($"Could not parse SIPURI host {sipURI.Host} as an IP end point.");
            }

            Address = endPoint.Address;
            Port    = (endPoint.Port == 0) ? (Protocol == SIPProtocolsEnum.tls) ? m_defaultSIPTLSPort : m_defaultSIPPort : endPoint.Port;
        }
Beispiel #5
0
        public SIPEndPoint(SIPURI sipURI)
        {
            Protocol = sipURI.Protocol;

            if (!IPSocket.TryParseIPEndPoint(sipURI.Host, out var endPoint))
            {
                throw new ApplicationException($"Could not parse SIPURI host {sipURI.Host} as an IP end point.");
            }

            Address = endPoint.Address;
            Port    = (endPoint.Port == 0) ? SIPConstants.GetDefaultPort(Protocol) : endPoint.Port;
        }
Beispiel #6
0
        /// <summary>
        /// Checks whether the host string corresponds to a socket address that this SIP channel is listening on.
        /// </summary>
        /// <param name="host">The host string to check.</param>
        /// <returns>True if the host is a socket this channel is listening on. False if not.</returns>
        internal bool IsChannelSocket(string host)
        {
            if (IPSocket.TryParseIPEndPoint(host, out var ep))
            {
                if (ListeningIPAddress != IPAddress.Any)
                {
                    return(ep.Address.Equals(ListeningIPAddress) && ep.Port == ListeningEndPoint.Port);
                }
                else
                {
                    return(ep.Port == ListeningEndPoint.Port && LocalIPAddresses.Any(x => x.Equals(ep.Address)));
                }
            }

            return(false);
        }
 public SIPEndPoint ToSIPEndPoint()
 {
     if (IPSocket.TryParseIPEndPoint(Host, out var ipEndPoint))
     {
         if (ipEndPoint.Port != 0)
         {
             return(new SIPEndPoint(Protocol, ipEndPoint));
         }
         else
         {
             ipEndPoint.Port = SIPConstants.GetDefaultPort(Protocol);
             return(new SIPEndPoint(Protocol, ipEndPoint));
         }
     }
     else
     {
         return(null);
     }
 }
Beispiel #8
0
        public SIPResponse GetOkResponse(SIPRequest sipRequest, SIPEndPoint localSIPEndPoint, string contentType, string messageBody)
        {
            try
            {
                SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, null, sipRequest.LocalSIPEndPoint);

                SIPHeader requestHeader = sipRequest.Header;
                okResponse.Header = new SIPHeader(new SIPContactHeader(null, new SIPURI(sipRequest.URI.Scheme, localSIPEndPoint)), requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId);

                if (m_contactIPAddress != null)
                {
                    if (IPSocket.TryParseIPEndPoint(okResponse.Header.Contact.First().ContactURI.Host, out var contactEP))
                    {
                        contactEP.Address = m_contactIPAddress;
                        okResponse.Header.Contact.First().ContactURI.Host = contactEP.ToString();
                    }
                    else
                    {
                        throw new ApplicationException($"Could not parse IP end point from {okResponse.Header.Contact.First().ContactURI.Host} when parsing OK response.");
                    }
                }

                okResponse.Header.To.ToTag     = m_localTag;
                okResponse.Header.CSeqMethod   = requestHeader.CSeqMethod;
                okResponse.Header.Vias         = requestHeader.Vias;
                okResponse.Header.Server       = m_sipServerAgent;
                okResponse.Header.MaxForwards  = Int32.MinValue;
                okResponse.Header.RecordRoutes = requestHeader.RecordRoutes;
                okResponse.Body = messageBody;
                okResponse.Header.ContentType   = contentType;
                okResponse.Header.ContentLength = (messageBody != null) ? messageBody.Length : 0;

                return(okResponse);
            }
            catch (Exception excp)
            {
                logger.LogError("Exception GetOkResponse. " + excp.Message);
                throw excp;
            }
        }
Beispiel #9
0
        /// <summary>
        /// Reverses The SIPEndPoint.ToString() method.
        /// </summary>
        /// <param name="serialisedSIPEndPoint">The serialised SIP end point MUST be in the form protocol:socket[;connid=abcd].
        /// Valid examples are udp:10.0.0.1:5060 and ws:10.0.0.1:5060;connid=abcd. An invalid example is 10.0.0.1:5060.</param>
        private static SIPEndPoint ParseSerialisedSIPEndPoint(string serialisedSIPEndPoint)
        {
            string connectionID = null;
            string endPointStr  = null;
            string protcolStr   = serialisedSIPEndPoint.Substring(0, serialisedSIPEndPoint.IndexOf(':'));

            if (serialisedSIPEndPoint.Contains(";"))
            {
                endPointStr  = serialisedSIPEndPoint.Slice(':', ';');
                connectionID = serialisedSIPEndPoint.Substring(serialisedSIPEndPoint.IndexOf(';'));
            }
            else
            {
                endPointStr = serialisedSIPEndPoint.Substring(serialisedSIPEndPoint.IndexOf(':') + 1);
            }

            if (!IPSocket.TryParseIPEndPoint(endPointStr, out var endPoint))
            {
                throw new ApplicationException($"Could not parse SIPEndPoint host {endPointStr} as an IP end point.");
            }

            return(new SIPEndPoint(SIPProtocolsType.GetProtocolType(protcolStr), endPoint, connectionID));
        }
Beispiel #10
0
        /// <summary>
        /// Reverses The SIPEndPoint.ToString() method.
        /// </summary>
        /// <param name="serialisedSIPEndPoint">The serialised SIP end point MUST be in the form protocol:socket[;connid=abcd].
        /// Valid examples are udp:10.0.0.1:5060 and ws:10.0.0.1:5060;connid=abcd. An invalid example is 10.0.0.1:5060.</param>
        private static SIPEndPoint ParseSerialisedSIPEndPoint(string serialisedSIPEndPoint)
        {
            string channelID    = null;
            string connectionID = null;
            string endPointStr  = null;
            string protcolStr   = serialisedSIPEndPoint.Substring(0, serialisedSIPEndPoint.IndexOf(':'));

            if (serialisedSIPEndPoint.Contains(";"))
            {
                endPointStr = serialisedSIPEndPoint.Slice(':', ';');
                var paramsStr = serialisedSIPEndPoint.Substring(serialisedSIPEndPoint.IndexOf(';') + 1)?.Trim();

                var endPointParams = new SIPParameters(paramsStr, ';');

                if (endPointParams.Has(CHANNELID_ATTRIBUTE_NAME))
                {
                    channelID = endPointParams.Get(CHANNELID_ATTRIBUTE_NAME);
                }

                if (endPointParams.Has(CONNECTIONID_ATTRIBUTE_NAME))
                {
                    connectionID = endPointParams.Get(CONNECTIONID_ATTRIBUTE_NAME);
                }
            }
            else
            {
                endPointStr = serialisedSIPEndPoint.Substring(serialisedSIPEndPoint.IndexOf(':') + 1);
            }

            if (!IPSocket.TryParseIPEndPoint(endPointStr, out var endPoint))
            {
                throw new ApplicationException($"Could not parse SIPEndPoint host {endPointStr} as an IP end point.");
            }

            return(new SIPEndPoint(SIPProtocolsType.GetProtocolType(protcolStr), endPoint, channelID, connectionID));
        }
Beispiel #11
0
 public static SIPDNSLookupResult Resolve(SIPURI sipURI, bool async, bool?preferIPv6)
 {
     // This assumes the input SIP URI has an IP address as the host!
     IPSocket.TryParseIPEndPoint(sipURI.Host, out var ipEndPoint);
     return(new SIPDNSLookupResult(sipURI, new SIPEndPoint(ipEndPoint)));
 }
Beispiel #12
0
        public static STUNUri ParseSTUNUri(string uri)
        {
            STUNUri stunUri = new STUNUri();

            if (String.IsNullOrEmpty(uri))
            {
                throw new ApplicationException("A STUN URI cannot be parsed from an empty string.");
            }
            else
            {
                uri = uri.Trim();

                // If the scheme is included it needs to be within the first 5 characters.
                if (uri.Length > SCHEME_MAX_LENGTH + 2)
                {
                    string schemeStr = uri.Substring(0, SCHEME_MAX_LENGTH + 1);
                    int    colonPosn = schemeStr.IndexOf(SCHEME_ADDR_SEPARATOR);

                    if (colonPosn == -1)
                    {
                        // No scheme has been specified, use default.
                        stunUri.Scheme = DefaultSTUNScheme;
                    }
                    else
                    {
                        if (!Enum.TryParse <STUNSchemesEnum>(schemeStr.Substring(0, colonPosn), true,
                                                             out stunUri.Scheme))
                        {
                            stunUri.Scheme = DefaultSTUNScheme;
                        }

                        uri = uri.Substring(colonPosn + 1);
                    }
                }

                if (uri.IndexOf(':') != -1)
                {
                    stunUri.ExplicitPort = true;

                    if (IPSocket.TryParseIPEndPoint(uri, out var ipEndPoint))
                    {
                        if (ipEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                        {
                            stunUri.Host = $"[{ipEndPoint.Address}]";
                        }
                        else
                        {
                            stunUri.Host = ipEndPoint.Address.ToString();
                        }

                        stunUri.Port = ipEndPoint.Port;
                    }
                    else
                    {
                        stunUri.Host = uri.Substring(0, uri.LastIndexOf(':'));
                        if (!Int32.TryParse(uri.Substring(uri.LastIndexOf(':') + 1), out stunUri.Port))
                        {
                            stunUri.Port = STUNConstants.GetPortForScheme(stunUri.Scheme);
                        }
                    }
                }
                else
                {
                    stunUri.Host = uri?.Trim();
                    stunUri.Port = STUNConstants.GetPortForScheme(stunUri.Scheme);
                }
            }

            return(stunUri);
        }
Beispiel #13
0
        // TODO: Remove this nasty code duplication with ResolveSIPService!
        public static async Task <SIPDNSLookupResult> ResolveAsync(SIPURI sipURI, bool?preferIPv6 = null)
        {
            try
            {
                if (sipURI == null)
                {
                    throw new ArgumentNullException("sipURI", "Cannot resolve SIP service on a null URI.");
                }

                if (IPSocket.TryParseIPEndPoint(sipURI.MAddrOrHost, out var ipEndPoint))
                {
                    // Target is an IP address, no DNS lookup required.
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, ipEndPoint), 0);
                    SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                    result.AddLookupResult(sipLookupEndPoint);
                    return(result);
                }
                else
                {
                    string host = sipURI.MAddrOrHostAddress;
                    //int port = IPSocket.ParsePortFromSocket(host);
                    int port = sipURI.Protocol != SIPProtocolsEnum.tls ? m_defaultSIPPort : m_defaultSIPSPort;
                    if (preferIPv6 == null)
                    {
                        preferIPv6 = SIPDNSManager.PreferIPv6NameResolution;
                    }
                    bool explicitPort = false;

                    try
                    {
                        //Parse returns true if sipURI.Host can be parsed as an ipaddress
                        bool parseresult = SIPSorcery.Sys.IPSocket.Parse(sipURI.MAddrOrHost, out host, out port);
                        explicitPort = port >= 0;
                        if (!explicitPort)
                        {
                            //port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                            port = sipURI.Protocol != SIPProtocolsEnum.tls ? m_defaultSIPPort : m_defaultSIPSPort;
                        }
                        if (parseresult == true)
                        {
                            IPAddress            hostIP            = IPAddress.Parse(host);
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(hostIP, port)), 0);
                            SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                            result.AddLookupResult(sipLookupEndPoint);
                            return(result);
                        }
                    }
                    catch (Exception ex)
                    {
                        SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + ex, null));

                        //rj2: if there is a parsing exception, then fallback to original sipsorcery parsing mechanism
                        port         = IPSocket.ParsePortFromSocket(sipURI.Host);
                        explicitPort = port > 0;

                        //if(Regex.Match(host, @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$").Success)
                        if (SIPSorcery.Sys.IPSocket.IsIPAddress(host))
                        {
                            // Target is an IP address, no DNS lookup required.
                            IPAddress            hostIP            = IPAddress.Parse(host);
                            SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, new IPEndPoint(hostIP, port)), 0);
                            SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                            result.AddLookupResult(sipLookupEndPoint);
                            return(result);
                        }
                    }

                    if (!explicitPort)
                    {
                        //port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                        port = sipURI.Protocol != SIPProtocolsEnum.tls ? m_defaultSIPPort : m_defaultSIPSPort;
                    }

                    if (host.Contains(".") == false || IPSocket.ParseHostFromSocket(host).EndsWith(MDNS_TLD))
                    {
                        string hostOnly = IPSocket.ParseHostFromSocket(host);

                        // If host is not fully qualified then assume there's no point using NAPTR or SRV record look ups and go straight to A's.
                        if (hostOnly.ToLower() == System.Net.Dns.GetHostName()?.ToLower())
                        {
                            // The lookup is for the current machine.
                            var addressList = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList;

                            if (addressList?.Length == 0)
                            {
                                return(new SIPDNSLookupResult(sipURI, $"Failed to resolve local machine hostname."));
                            }
                            else
                            {
                                // Preference for IPv4 IP address for local host name lookup.
                                IPAddress   firstAddress = addressList.Where(x => x.AddressFamily == (preferIPv6 == true ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork)).FirstOrDefault() ?? addressList.FirstOrDefault();
                                SIPEndPoint resultEp     = new SIPEndPoint(sipURI.Protocol, new IPEndPoint(firstAddress, port));
                                return(new SIPDNSLookupResult(sipURI, resultEp));
                            }
                        }
                        else
                        {
                            return(await Task.Run(() => DNSNameRecordLookup(hostOnly, port, false, sipURI, null, preferIPv6)).ConfigureAwait(false));
                        }
                    }
                    else if (explicitPort)
                    {
                        // If target is a hostname with an explicit port then SIP lookup rules state to use DNS lookup for A or AAAA record.
                        host = host.Substring(0, host.LastIndexOf(':'));
                        return(await Task.Run(() => DNSNameRecordLookup(host, port, false, sipURI, null, preferIPv6)).ConfigureAwait(false));
                    }
                    else
                    {
                        // Target is a hostname with no explicit port, use the whole NAPTR->SRV->A lookup procedure.
                        SIPDNSLookupResult sipLookupResult = new SIPDNSLookupResult(sipURI);

                        // Do without the NAPTR lookup for the time being. Very few organisations appear to use them and it can cost up to 2.5s to get a failed resolution.
                        //rj2: uncomment this section for telekom 1TR118 lookup
                        SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS full lookup requested for " + sipURI.ToString() + ".", null));
                        DNSNAPTRRecordLookup(host, false, ref sipLookupResult);
                        if (sipLookupResult.Pending)
                        {
                            if (!m_inProgressSIPServiceLookups.Contains(sipURI.ToString()))
                            {
                                m_inProgressSIPServiceLookups.Add(sipURI.ToString());
                                //ThreadPool.QueueUserWorkItem(delegate { ResolveSIPService(sipURI, false); });
                                System.Threading.ThreadPool.QueueUserWorkItem((obj) => ResolveSIPService(sipURI, false, preferIPv6));
                            }
                            return(sipLookupResult);
                        }

                        return(await Task.Run(() =>
                        {
                            DNSSRVRecordLookup(sipURI.Scheme, sipURI.Protocol, host, false, ref sipLookupResult);
                            if (sipLookupResult.Pending)
                            {
                                //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is pending.");
                                return sipLookupResult;
                            }
                            else
                            {
                                //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is final.");

                                // Add some custom logic to cope with sips SRV records using _sips._tcp (e.g. free.call.ciscospark.com).
                                // By default only _sips._tls SRV records are checked for. THis block adds an additional check for _sips._tcp SRV records.
                                //if ((sipLookupResult.SIPSRVResults == null || sipLookupResult.SIPSRVResults.Count == 0) && sipURI.Scheme == SIPSchemesEnum.sips)
                                //{
                                //    DNSSRVRecordLookup(sipURI.Scheme, SIPProtocolsEnum.tcp, host, async, ref sipLookupResult);
                                //    SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                                //    int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                                //    return DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI);
                                //}
                                //else
                                //{
                                //   SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                                //   int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                                //   return DNSARecordLookup(nextSRVRecord, host, lookupPort, false, sipLookupResult.URI);
                                //}

                                // The SRV record can indicate the SIP server is using a non-standard port.
                                SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                                int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;

                                return DNSNameRecordLookup(host, lookupPort, false, sipLookupResult.URI, ref sipLookupResult, preferIPv6);
                            }
                        }).ConfigureAwait(false));
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + excp.Message);
                m_inProgressSIPServiceLookups.Remove(sipURI.ToString());
                return(new SIPDNSLookupResult(sipURI, excp.Message));
            }
        }
Beispiel #14
0
        public static SIPDNSLookupResult ResolveSIPService(SIPURI sipURI, bool async)
        {
            try
            {
                if (sipURI == null)
                {
                    throw new ArgumentNullException("sipURI", "Cannot resolve SIP service on a null URI.");
                }

                if (IPSocket.TryParseIPEndPoint(sipURI.Host, out var ipEndPoint))
                {
                    // Target is an IP address, no DNS lookup required.
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, ipEndPoint), 0);
                    SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                    result.AddLookupResult(sipLookupEndPoint);
                    return(result);
                }
                else
                {
                    string host         = sipURI.Host;
                    int    port         = IPSocket.ParsePortFromSocket(sipURI.Host);
                    bool   explicitPort = (port != 0);

                    if (!explicitPort)
                    {
                        port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                    }

                    if (host.Contains(".") == false)
                    {
                        string hostOnly = IPSocket.ParseHostFromSocket(host);

                        // If host is not fully qualified then assume there's no point using NAPTR or SRV record look ups and go straight to A's.
                        if (hostOnly.ToLower() == System.Net.Dns.GetHostName()?.ToLower())
                        {
                            // The lookup is for the current machine.
                            var addressList = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList;

                            if (addressList?.Length == 0)
                            {
                                return(new SIPDNSLookupResult(sipURI, $"Failed to resolve local machine hostname."));
                            }
                            else
                            {
                                // Preference for IPv4 IP address for local host anem lookup.
                                IPAddress   firstAddress = addressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault() ?? addressList.FirstOrDefault();
                                SIPEndPoint resultEp     = new SIPEndPoint(sipURI.Protocol, new IPEndPoint(firstAddress, port));
                                return(new SIPDNSLookupResult(sipURI, resultEp));
                            }
                        }
                        else
                        {
                            return(DNSARecordLookup(hostOnly, port, async, sipURI));
                        }
                    }
                    else if (explicitPort)
                    {
                        // If target is a hostname with an explicit port then SIP lookup rules state to use DNS lookup for A or AAAA record.
                        host = host.Substring(0, host.LastIndexOf(':'));
                        return(DNSARecordLookup(host, port, async, sipURI));
                    }
                    else
                    {
                        // Target is a hostname with no explicit port, use the whole NAPTR->SRV->A lookup procedure.
                        SIPDNSLookupResult sipLookupResult = new SIPDNSLookupResult(sipURI);

                        // Do without the NAPTR lookup for the time being. Very few organisations appear to use them and it can cost up to 2.5s to get a failed resolution.

                        /*SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS full lookup requested for " + sipURI.ToString() + ".", null));
                         * DNSNAPTRRecordLookup(host, async, ref sipLookupResult);
                         * if (sipLookupResult.Pending)
                         * {
                         *  if (!m_inProgressSIPServiceLookups.Contains(sipURI.ToString()))
                         *  {
                         *      m_inProgressSIPServiceLookups.Add(sipURI.ToString());
                         *      ThreadPool.QueueUserWorkItem(delegate { ResolveSIPService(sipURI, false); });
                         *  }
                         *  return sipLookupResult;
                         * }*/

                        DNSSRVRecordLookup(sipURI.Scheme, sipURI.Protocol, host, async, ref sipLookupResult);
                        if (sipLookupResult.Pending)
                        {
                            //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is pending.");
                            return(sipLookupResult);
                        }
                        else
                        {
                            //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is final.");

                            // Add some custom logic to cope with sips SRV records using _sips._tcp (e.g. free.call.ciscospark.com).
                            // By default only _sips._tls SRV records are checked for. THis block adds an additional check for _sips._tcp SRV records.
                            //if ((sipLookupResult.SIPSRVResults == null || sipLookupResult.SIPSRVResults.Count == 0) && sipURI.Scheme == SIPSchemesEnum.sips)
                            //{
                            //    DNSSRVRecordLookup(sipURI.Scheme, SIPProtocolsEnum.tcp, host, async, ref sipLookupResult);
                            //    SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                            //    int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                            //    return DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI);
                            //}
                            //else
                            //{
                            SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                            int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                            return(DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI));
                            //}
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + excp.Message);
                m_inProgressSIPServiceLookups.Remove(sipURI.ToString());
                return(new SIPDNSLookupResult(sipURI, excp.Message));
            }
        }
Beispiel #15
0
        public static SIPDNSLookupResult ResolveSIPService(SIPURI sipURI, bool async)
        {
            try
            {
                if (sipURI == null)
                {
                    throw new ArgumentNullException("sipURI", "Cannot resolve SIP service on a null URI.");
                }

                if (IPSocket.TryParseIPEndPoint(sipURI.Host, out var ipEndPoint))
                {
                    // Target is an IP address, no DNS lookup required.
                    //IPAddress hostIP = IPAddress.Parse(host);
                    SIPDNSLookupEndPoint sipLookupEndPoint = new SIPDNSLookupEndPoint(new SIPEndPoint(sipURI.Protocol, ipEndPoint), 0);
                    SIPDNSLookupResult   result            = new SIPDNSLookupResult(sipURI);
                    result.AddLookupResult(sipLookupEndPoint);
                    return(result);
                }
                else
                {
                    string host         = sipURI.Host;
                    int    port         = IPSocket.ParsePortFromSocket(sipURI.Host);
                    bool   explicitPort = (port != 0);

                    if (!explicitPort)
                    {
                        port = (sipURI.Scheme == SIPSchemesEnum.sip) ? m_defaultSIPPort : m_defaultSIPSPort;
                    }

                    if (explicitPort)
                    {
                        host = host.Substring(0, host.LastIndexOf(':'));
                        // Target is a hostname with an explicit port, DNS lookup for A or AAAA record.
                        return(DNSARecordLookup(host, port, async, sipURI));
                    }
                    else
                    {
                        // Target is a hostname with no explicit port, use the whole NAPTR->SRV->A lookup procedure.
                        SIPDNSLookupResult sipLookupResult = new SIPDNSLookupResult(sipURI);

                        // Do without the NAPTR lookup for the time being. Very few organisations appear to use them and it can cost up to 2.5s to get a failed resolution.

                        /*SIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Unknown, SIPMonitorEventTypesEnum.DNS, "SIP DNS full lookup requested for " + sipURI.ToString() + ".", null));
                         * DNSNAPTRRecordLookup(host, async, ref sipLookupResult);
                         * if (sipLookupResult.Pending)
                         * {
                         *  if (!m_inProgressSIPServiceLookups.Contains(sipURI.ToString()))
                         *  {
                         *      m_inProgressSIPServiceLookups.Add(sipURI.ToString());
                         *      ThreadPool.QueueUserWorkItem(delegate { ResolveSIPService(sipURI, false); });
                         *  }
                         *  return sipLookupResult;
                         * }*/

                        DNSSRVRecordLookup(sipURI.Scheme, sipURI.Protocol, host, async, ref sipLookupResult);
                        if (sipLookupResult.Pending)
                        {
                            //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is pending.");
                            return(sipLookupResult);
                        }
                        else
                        {
                            //logger.LogDebug("SIPDNSManager SRV lookup for " + host + " is final.");

                            // Add some custom logic to cope with sips SRV records using _sips._tcp (e.g. free.call.ciscospark.com).
                            // By default only _sips._tls SRV records are checked for. THis block adds an additional check for _sips._tcp SRV records.
                            //if ((sipLookupResult.SIPSRVResults == null || sipLookupResult.SIPSRVResults.Count == 0) && sipURI.Scheme == SIPSchemesEnum.sips)
                            //{
                            //    DNSSRVRecordLookup(sipURI.Scheme, SIPProtocolsEnum.tcp, host, async, ref sipLookupResult);
                            //    SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                            //    int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                            //    return DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI);
                            //}
                            //else
                            //{
                            SIPDNSServiceResult nextSRVRecord = sipLookupResult.GetNextUnusedSRV();
                            int lookupPort = (nextSRVRecord != null) ? nextSRVRecord.Port : port;
                            return(DNSARecordLookup(nextSRVRecord, host, lookupPort, async, sipLookupResult.URI));
                            //}
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPDNSManager ResolveSIPService (" + sipURI.ToString() + "). " + excp.Message);
                m_inProgressSIPServiceLookups.Remove(sipURI.ToString());
                return(new SIPDNSLookupResult(sipURI, excp.Message));
            }
        }