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); } }
/// <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)); }
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)); } }
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; }
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; }
/// <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); } }
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; } }
/// <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)); }
/// <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)); }
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))); }
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); }
// 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)); } }
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)); } }
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)); } }