protected virtual void OnSipReceivedFromTcp(SipMessageEventArgs e) { if (null != SipReceivedFromPipe) { SipReceivedFromPipe(this, e); } if (!e.Cancel && e.SipMessage.StartsWith("BYE", StringComparison.InvariantCultureIgnoreCase)) { // We should kill sound proxy REGEX.Match m = g_CallId.Match(e.SipMessage); if (m.Success && m.Groups["q"].Success) { string callId = m.Groups["q"].Value; SoundProxy sp = null; if (m_SoundProxies.TryGetValue(callId, out sp)) { m_SoundProxies.Remove(callId); sp.Dispose(); m_Settings.WriteMessageToLog( LogMessageType.Information + 1, "Destroyed sound proxy for Call-ID '" + callId + '\'' ); } } } }
protected virtual void OnRtpReceivedFromTcp(RtpMessageEventArgs e) { if (null != RtpReceivedFromPipe) { RtpReceivedFromPipe(this, e); } string callId; byte[] soundData; SoundProxy.GetSoundData(e.RtpData, e.RtpData.Length, out callId, out soundData); SoundProxy sp; if (!m_SoundProxies.TryGetValue(callId, out sp)) { m_Settings.WriteMessageToLog( LogMessageType.Error, "Failed to find sound proxy for Call-ID '" + callId + "'. Ignoring sound packet." ); } sp.SendSoundDataToServer(soundData); }
protected string CreateSoundProxyAndChangeSdpData(string sipMsg, out SoundProxy sp, out ushort length) { sp = null; length = 0; string localIp = m_Transport.LocalAddress.ToString(); System.IO.StringReader strReader = new System.IO.StringReader(sipMsg); System.Text.StringBuilder sbSipMsg = new System.Text.StringBuilder(sipMsg.Length + 16); string sipMsgLine, callId = null; bool createProxy = false, startCounting = false; while ((sipMsgLine = strReader.ReadLine()) != null) { if (sipMsgLine.StartsWith("Content-Type:", StringComparison.InvariantCultureIgnoreCase)) { createProxy = (sipMsgLine.IndexOf("application/sdp", StringComparison.InvariantCultureIgnoreCase) > 0); if (!createProxy) { return(sipMsg); } } else if (sipMsgLine.StartsWith("Call-ID:", StringComparison.InvariantCultureIgnoreCase)) { callId = sipMsgLine.Substring(8).Trim(); } else if (null != sp && sipMsgLine.StartsWith("o=", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_SdpAddressInO.Replace(sipMsgLine, "${a}" + localIp + "${z}"); } else if (null != sp && sipMsgLine.StartsWith("c=", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_SdpAddressInC.Replace(sipMsgLine, "${a}" + localIp + "${z}"); } else if (null != sp && sipMsgLine.StartsWith("m=", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_SdpPortInM.Replace(sipMsgLine, "${a}" + sp.LocalPort.ToString(CultureInfo.InvariantCulture) + "${z}"); } else if (0 == sipMsgLine.Length) { startCounting = true; } if (createProxy && null == sp && null != callId && callId.Length > 0) { sp = m_Transport.CreateSoundProxy(sipMsg, callId, false); if (null == sp) { return(sipMsg); } } sbSipMsg.Append(sipMsgLine + "\r\n"); if (startCounting && sipMsgLine.Length > 0) { length += (ushort)(sipMsgLine.Length + 2); } } return(sbSipMsg.ToString()); }
protected override void OnSipReceivedFromPipe(object sender, SipMessageEventArgs e) { base.OnSipReceivedFromPipe(sender, e); ushort sdpLength = 0; SoundProxy sp = null; string newSipMsg = CreateSoundProxyAndChangeSdpData(e.SipMessage, out sp, out sdpLength); System.IO.StringReader strReader = new System.IO.StringReader(newSipMsg); System.Text.StringBuilder sbSipMsg = new System.Text.StringBuilder(newSipMsg.Length + 16); string sipMsgLine; string localIp = m_Transport.LocalAddress.ToString(); bool request = false; while ((sipMsgLine = strReader.ReadLine()) != null) { if (0 == sbSipMsg.Length) { if (!sipMsgLine.StartsWith("SIP/2.0", StringComparison.InvariantCultureIgnoreCase)) { request = true; REGEX.Match m = g_ServerInMsgType.Match(sipMsgLine); if (m.Success && m.Groups["host"].Success && m.Groups["host"].Value.Equals(ProgramSettings.SipTunnelInternalHost, StringComparison.InvariantCulture)) { sipMsgLine = g_ServerInMsgType.Replace( sipMsgLine, String.Format( CultureInfo.InvariantCulture, "${{a}}{0}{1}${{z}}", m.Groups["acc"].Success ? m.Groups["acc"].Value + '@' : String.Empty, Settings.SipServerHost ) ); } } } else { if (sipMsgLine.StartsWith("Via:", StringComparison.InvariantCultureIgnoreCase)) { if (request) { sbSipMsg.AppendFormat( CultureInfo.InvariantCulture, "Via: SIP/2.0/{0} {1}:{2};rport;SipTunnel\n", Settings.ServerType == ConnectorType.UDP ? "UDP" : "TCP", localIp, m_Transport.LocalPort ); } } else if (sipMsgLine.StartsWith("To:", StringComparison.InvariantCultureIgnoreCase)) { REGEX.Match m = g_To.Match(sipMsgLine); if (m.Success && m.Groups["q"].Success && m.Groups["q"].Value.Equals(ProgramSettings.SipTunnelInternalHost, StringComparison.InvariantCulture)) { sipMsgLine = g_To.Replace(sipMsgLine, "${a}" + Settings.SipServerHost + "${z}"); } } else if (sipMsgLine.StartsWith("Content-Length:", StringComparison.CurrentCultureIgnoreCase)) { if (sp != null && sdpLength > 0) { sipMsgLine = "Content-Length: " + sdpLength.ToString(CultureInfo.InvariantCulture); } } else if (sipMsgLine.StartsWith("From:", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_From.Replace(sipMsgLine, "${a}${acc}@" + Settings.SipServerHost + "${z}"); } else if (sipMsgLine.StartsWith("Contact:", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_Contact.Replace(sipMsgLine, "${a}${acc}@" + localIp + ':' + m_Transport.LocalPort.ToString(CultureInfo.InvariantCulture) + "${z}"); } else if (sipMsgLine.StartsWith("User-Agent:", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine += " (via SipTunnel)"; } } sbSipMsg.AppendLine(sipMsgLine); } m_Transport.SendSipMsgToClient(sbSipMsg.ToString(), Settings.SipServerHost, Settings.SipServerPort); }
protected override void OnSipReceivedFromPipe(object sender, SipMessageEventArgs e) { base.OnSipReceivedFromPipe(sender, e); ushort sdpLength = 0; SoundProxy sp = null; string newSipMsg = CreateSoundProxyAndChangeSdpData(e.SipMessage, out sp, out sdpLength); System.IO.StringReader strReader = new System.IO.StringReader(newSipMsg); System.Text.StringBuilder sbSipMsg = new System.Text.StringBuilder(newSipMsg.Length + 16); string sipMsgLine; string localIp = Settings.ClientIp.ToString(); bool request = false; System.Net.IPEndPoint ipEp = null; while ((sipMsgLine = strReader.ReadLine()) != null) { if (0 == sbSipMsg.Length) { if (!sipMsgLine.StartsWith("SIP/2.0", StringComparison.InvariantCultureIgnoreCase)) { request = true; #if PLAT_WINDOWS || PLAT_MONO REGEX.Match m = g_ServerInMsgType.Match(sipMsgLine); if (!m.Success) { throw new SipProxyClientException("Message header is wrong format."); } if (!m.Groups["acc"].Success) { throw new SipProxyClientException("Account code not found in message header."); } if (!m_Accounts.TryGetValue(m.Groups["acc"].Value, out ipEp)) { throw new SipProxyClientException("Account for code '" + m.Groups["acc"].Value + "' not found."); } #else if (null == m_EpClientContact) { throw new SipProxyClientException("Client end point not set (contact)."); } ipEp = m_EpClientContact; #endif sipMsgLine = g_ServerInMsgType.Replace(sipMsgLine, "${a}${acc}@" + localIp + "${z}"); } } else { if (sipMsgLine.StartsWith("Via:", StringComparison.InvariantCultureIgnoreCase)) { if (request) { sbSipMsg.AppendFormat( CultureInfo.InvariantCulture, "Via: SIP/2.0/{0} {1}:{2};rport;SipTunnel\r\n", Settings.ServerType == ConnectorType.UDP ? "UDP" : "TCP", localIp, m_Transport.LocalPort ); } else { REGEX.Match m = g_Via.Match(sipMsgLine); if (!m.Success) { throw new SipProxyClientException("Via header is wrong format or is absent."); } if (m.Groups["rport"].Success && m.Groups["rport"].Value.Length > 0) { // Using sender's source address and port if (!m.Groups["stckVal"].Success) { throw new SipProxyClientException("Via header parameter 'stck' not found."); } #if PLAT_WINDOWS || PLAT_MONO int key = int.Parse(m.Groups["stckVal"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture); if (!m_Clients.ContainsKey(key)) { throw new SipProxyClientException("Failed to find client for value in 'stck'."); } ipEp = m_Clients[key]; #else if (null == m_EpClientStck) { throw new SipProxyClientException("Client end point not set (stck)."); } ipEp = m_EpClientStck; #endif } else { // Using address and port from Via header if (!m.Groups["addr"].Success || !m.Groups["port"].Success) { throw new SipProxyClientException("Address or port in Via header not found."); } ipEp = new System.Net.IPEndPoint( NET.IPAddress.Parse(m.Groups["addr"].Value), ushort.Parse(m.Groups["port"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture) ); } } } else if (sipMsgLine.StartsWith("To:", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_To.Replace(sipMsgLine, "${a}" + localIp + "${z}"); } else if (sipMsgLine.StartsWith("From:", StringComparison.InvariantCultureIgnoreCase)) { REGEX.Match m = g_From.Match(sipMsgLine); if (m.Success && m.Groups["host"].Success && m.Groups["host"].Value.Equals(ProgramSettings.SipTunnelInternalHost, StringComparison.InvariantCulture)) { sipMsgLine = g_From.Replace(sipMsgLine, "${a}${acc}@" + localIp + "${z}"); } } else if (sipMsgLine.StartsWith("Content-Length:", StringComparison.CurrentCultureIgnoreCase)) { if (sp != null && sdpLength > 0) { sipMsgLine = "Content-Length: " + sdpLength.ToString(CultureInfo.InvariantCulture); } } else if (sipMsgLine.StartsWith("Contact:", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine = g_Contact.Replace(sipMsgLine, "${a}${acc}@" + localIp + ':' + m_Transport.LocalPort.ToString(CultureInfo.InvariantCulture) + "${z}"); } else if (sipMsgLine.StartsWith("User-Agent:", StringComparison.InvariantCultureIgnoreCase)) { sipMsgLine += " (via SipTunnel)"; } } sbSipMsg.Append(sipMsgLine + "\r\n"); } m_Transport.SendSipMsgToClient(sbSipMsg.ToString(), ipEp); }
public SoundProxy CreateSoundProxy(string sipMsg, string callId, bool setServer) { if (null == sipMsg || 0 == sipMsg.Length) { return(null); } if (null == callId || 0 == callId.Length) { return(null); } SoundProxy sp = null; if (m_SoundProxies.TryGetValue(callId, out sp)) { if (!setServer) { return(sp); } if (sp.ServerSet) { return(sp); } } REGEX.Match m = g_SdpAddressInC.Match(sipMsg); if (!m.Groups["q"].Success) { return(null); } string ssHost = m.Groups["q"].Value; m = g_SdpPortInM.Match(sipMsg); if (!m.Groups["q"].Success) { return(null); } ushort ssPort = ushort.Parse(m.Groups["q"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture); if (0 == ssPort) { return(null); } if (null == sp) { if (setServer) { sp = new SoundProxy(ssHost, ssPort, callId, this); } else { sp = new SoundProxy(callId, this); } m_SoundProxies.Add(callId, sp); m_Settings.WriteMessageToLog( LogMessageType.Information + 1, string.Format( CultureInfo.CurrentUICulture, "Created sound proxy" + (setServer ? " for {1}:{2}" : string.Empty) + " with branch {0}.", callId, ssHost, ssPort ) ); } else { sp.SetServer(ssHost, ssPort); m_Settings.WriteMessageToLog( LogMessageType.Information + 1, string.Format( CultureInfo.CurrentUICulture, "Updated sound proxy for {0}:{1} with branch {2}.", ssHost, ssPort, callId ) ); } return(sp); }