public void EndAuthenticateAsServer(IAsyncResult ar) { try { SIPConnection sipTLSConnection = (SIPConnection)ar.AsyncState; SslStream sslStream = (SslStream)sipTLSConnection.SIPStream; sslStream.EndAuthenticateAsServer(ar); // Set timeouts for the read and write to 5 seconds. sslStream.ReadTimeout = 5000; sslStream.WriteTimeout = 5000; m_connectedSockets.Add(sipTLSConnection.RemoteEndPoint.ToString(), sipTLSConnection); sipTLSConnection.SIPSocketDisconnected += SIPTLSSocketDisconnected; sipTLSConnection.SIPMessageReceived += SIPTLSMessageReceived; //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; sipTLSConnection.SIPStream.BeginRead(sipTLSConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), sipTLSConnection); } catch (Exception excp) { logger.LogError("Exception SIPTLSChannel EndAuthenticateAsServer. " + excp); //throw excp; } }
public void ReceiveCallback(IAsyncResult ar) { SIPConnection sipTLSConnection = (SIPConnection)ar.AsyncState; if (sipTLSConnection != null && sipTLSConnection.SIPStream != null && sipTLSConnection.SIPStream.CanRead) { try { int bytesRead = sipTLSConnection.SIPStream.EndRead(ar); if (sipTLSConnection.SocketReadCompleted(bytesRead)) { sipTLSConnection.SIPStream.BeginRead(sipTLSConnection.SocketBuffer, sipTLSConnection.SocketBufferEndPosition, MaxSIPTCPMessageSize - sipTLSConnection.SocketBufferEndPosition, new AsyncCallback(ReceiveCallback), sipTLSConnection); } } catch (SocketException sockExcp) // Occurs if the remote end gets disconnected. { logger.LogWarning("SocketException SIPTLSChannel ReceiveCallback. " + sockExcp); } catch (Exception excp) { logger.LogWarning("Exception SIPTLSChannel ReceiveCallback. " + excp); SIPTLSSocketDisconnected(sipTLSConnection.RemoteEndPoint); } } }
private void AcceptConnections(string threadName) { try { Thread.CurrentThread.Name = threadName; logger.LogDebug("SIPTLSChannel socket on " + m_localSIPEndPoint + " accept connections thread started."); while (!Closed) { try { TcpClient tcpClient = m_tlsServerListener.AcceptTcpClient(); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; logger.LogDebug("SIP TLS Channel connection accepted from " + remoteEndPoint + "."); SslStream sslStream = new SslStream(tcpClient.GetStream(), false); SIPConnection sipTLSConnection = new SIPConnection(this, tcpClient, sslStream, remoteEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Listener); sslStream.BeginAuthenticateAsServer(m_serverCertificate, EndAuthenticateAsServer, sipTLSConnection); //sslStream.AuthenticateAsServer(m_serverCertificate, false, SslProtocols.Tls, false); //// Display the properties and settings for the authenticated stream. ////DisplaySecurityLevel(sslStream); ////DisplaySecurityServices(sslStream); ////DisplayCertificateInformation(sslStream); ////DisplayStreamProperties(sslStream); //// Set timeouts for the read and write to 5 seconds. //sslStream.ReadTimeout = 5000; //sslStream.WriteTimeout = 5000; ////SIPConnection sipTLSConnection = new SIPConnection(this, sslStream, remoteEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Listener); //m_connectedSockets.Add(remoteEndPoint.ToString(), sipTLSConnection); //sipTLSConnection.SIPSocketDisconnected += SIPTLSSocketDisconnected; //sipTLSConnection.SIPMessageReceived += SIPTLSMessageReceived; ////byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; //sipTLSConnection.SIPStream.BeginRead(sipTLSConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), sipTLSConnection); } catch (Exception e) { logger.LogError("SIPTLSChannel Accept Connection Exception. " + e); //sslStream.Close(); //tcpClient.Close(); } } logger.LogDebug("SIPTLSChannel socket on " + m_localSIPEndPoint + " listening halted."); } catch (Exception excp) { logger.LogError("Exception SIPTLSChannel Listen. " + excp); //throw excp; } }
private void EndConnect(IAsyncResult ar) { object[] stateObj = (object[])ar.AsyncState; TcpClient tcpClient = (TcpClient)stateObj[0]; IPEndPoint dstEndPoint = (IPEndPoint)stateObj[1]; byte[] buffer = (byte[])stateObj[2]; string serverCN = (string)stateObj[3]; try { m_connectingSockets.Remove(dstEndPoint.ToString()); tcpClient.EndConnect(ar); SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); //DisplayCertificateInformation(sslStream); SIPConnection callerConnection = new SIPConnection(this, tcpClient, sslStream, dstEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Caller); sslStream.BeginAuthenticateAsClient(serverCN, EndAuthenticateAsClient, new object[] { tcpClient, dstEndPoint, buffer, callerConnection }); //sslStream.AuthenticateAsClient(serverCN); //if (tcpClient != null && tcpClient.Connected) //{ // SIPConnection callerConnection = new SIPConnection(this, sslStream, dstEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Caller); // m_connectedSockets.Add(dstEndPoint.ToString(), callerConnection); // callerConnection.SIPSocketDisconnected += SIPTLSSocketDisconnected; // callerConnection.SIPMessageReceived += SIPTLSMessageReceived; // //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; // callerConnection.SIPStream.BeginRead(callerConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), callerConnection); // logger.LogDebug("Established TLS connection to " + dstEndPoint + "."); // callerConnection.SIPStream.BeginWrite(buffer, 0, buffer.Length, EndSend, callerConnection); //} //else //{ // logger.LogWarning("Could not establish TLS connection to " + dstEndPoint + "."); //} } catch (Exception excp) { logger.LogError("Exception SIPTLSChannel EndConnect. " + excp); if (tcpClient != null) { try { tcpClient.Close(); } catch (Exception closeExcp) { logger.LogWarning("Exception SIPTLSChannel EndConnect Close TCP Client. " + closeExcp); } } } }
private void AcceptConnections(string threadName) { try { Thread.CurrentThread.Name = threadName; logger.Debug("SIPTCPChannel socket on " + m_localSIPEndPoint + " accept connections thread started."); while (!Closed) { try { TcpClient tcpClient = m_tcpServerListener.AcceptTcpClient(); if (!Closed) { tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); tcpClient.LingerState = new LingerOption(false, 0); //clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //IPEndPoint remoteEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint; IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; logger.Debug("SIP TCP Channel connection accepted from " + remoteEndPoint + "."); //SIPTCPConnection sipTCPClient = new SIPTCPConnection(this, clientSocket, remoteEndPoint, SIPTCPConnectionsEnum.Listener); SIPConnection sipTCPConnection = new SIPConnection(this, tcpClient, tcpClient.GetStream(), remoteEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Listener); //SIPConnection sipTCPClient = new SIPConnection(this, tcpClient.Client, remoteEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Listener); lock (m_connectedSockets) { m_connectedSockets.Add(remoteEndPoint.ToString(), sipTCPConnection); } sipTCPConnection.SIPSocketDisconnected += SIPTCPSocketDisconnected; sipTCPConnection.SIPMessageReceived += SIPTCPMessageReceived; // clientSocket.BeginReceive(sipTCPClient.SocketBuffer, 0, SIPTCPConnection.MaxSIPTCPMessageSize, SocketFlags.None, new AsyncCallback(sipTCPClient.ReceiveCallback), null); //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; sipTCPConnection.SIPStream.BeginRead(sipTCPConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), sipTCPConnection); } } catch (Exception acceptExcp) { // This exception gets thrown if the remote end disconnects during the socket accept. logger.Warn("Exception SIPTCPChannel accepting socket (" + acceptExcp.GetType() + "). " + acceptExcp.Message); } } logger.Debug("SIPTCPChannel socket on " + m_localSIPEndPoint + " listening halted."); } catch (Exception excp) { logger.Error("Exception SIPTCPChannel Listen. " + excp.Message); //throw excp; } }
private void EndSend(IAsyncResult ar) { try { SIPConnection sipConnection = (SIPConnection)ar.AsyncState; sipConnection.SIPStream.EndWrite(ar); } catch (Exception excp) { logger.Error("Exception EndSend. " + excp); } }
private void EndSend(IAsyncResult ar) { try { SIPConnection sipConnection = (SIPConnection)ar.AsyncState; sipConnection.SIPStream.EndWrite(ar); OnSendComplete(EventArgs.Empty); } catch (Exception excp) { logger.LogError("Exception EndSend. " + excp); } }
private void EndSend(IAsyncResult ar) { try { SIPConnection sipTCPConnection = (SIPConnection)ar.AsyncState; sipTCPConnection.SIPStream.EndWrite(ar); //logger.Debug("EndSend on TCP " + SIPChannelEndPoint.ToString() + "."); } catch (Exception excp) { logger.Error("Exception EndSend. " + excp.Message); } }
public void Connect(IPEndPoint remoteEndPoint) { m_isConnecting = true; m_remoteEndPoint = remoteEndPoint; m_sipConnection = new SIPConnection(this, m_socket, m_remoteEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Caller); m_sipConnection.SIPSocketDisconnected += SIPSocketDisconnected; m_sipConnection.SIPMessageReceived += SIPTCPMessageReceived; m_socketConnectionArgs = new SocketAsyncEventArgs(); m_socketConnectionArgs.RemoteEndPoint = m_remoteEndPoint; m_socketConnectionArgs.Completed += SocketConnect_Completed; m_socket.ConnectAsync(m_socketConnectionArgs); //if (!m_socket.ConnectAsync(m_socketConnectionArgs)) //{ // throw new ApplicationException("Asynchronous socket connect operation unexpectedly returned synchronously."); //} }
private void EndAuthenticateAsClient(IAsyncResult ar) { try { object[] stateObj = (object[])ar.AsyncState; TcpClient tcpClient = (TcpClient)stateObj[0]; IPEndPoint dstEndPoint = (IPEndPoint)stateObj[1]; byte[] buffer = (byte[])stateObj[2]; SIPConnection callerConnection = (SIPConnection)stateObj[3]; SslStream sslStream = (SslStream)callerConnection.SIPStream; sslStream.EndAuthenticateAsClient(ar); if (tcpClient != null && tcpClient.Connected) { //SIPConnection callerConnection = new SIPConnection(this, sslStream, dstEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Caller); m_connectedSockets.Add(callerConnection.RemoteEndPoint.ToString(), callerConnection); callerConnection.SIPSocketDisconnected += SIPTLSSocketDisconnected; callerConnection.SIPMessageReceived += SIPTLSMessageReceived; //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; callerConnection.SIPStream.BeginRead(callerConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), callerConnection); logger.LogDebug("Established TLS connection to " + callerConnection.RemoteEndPoint + "."); callerConnection.SIPStream.BeginWrite(buffer, 0, buffer.Length, EndSend, callerConnection); } else { logger.LogWarning("Could not establish TLS connection to " + callerConnection.RemoteEndPoint + "."); } } catch (Exception excp) { logger.LogError("Exception SIPTLSChannel EndAuthenticateAsClient. " + excp); } }
/// <summary> /// Processes the receive buffer after a read from the connected socket. /// </summary> /// <param name="bytesRead">The number of bytes that were read into the receive buffer.</param> /// <returns>True if the receive was processed correctly, false if the socket returned 0 bytes or was disconnected.</returns> public bool SocketReadCompleted(int bytesRead) { try { if (bytesRead > 0) { SocketBufferEndPosition += bytesRead; int bytesSkipped = 0; // Attempt to extract a SIP message from the receive buffer. byte[] sipMsgBuffer = SIPConnection.ProcessReceive(SocketBuffer, 0, SocketBufferEndPosition, out bytesSkipped); while (sipMsgBuffer != null) { // A SIP message is available. if (SIPMessageReceived != null) { LastTransmission = DateTime.Now; SIPMessageReceived(m_owningChannel, new SIPEndPoint(SIPProtocolsEnum.tcp, RemoteEndPoint), sipMsgBuffer); } SocketBufferEndPosition -= (sipMsgBuffer.Length + bytesSkipped); if (SocketBufferEndPosition == 0) { //Array.Clear(SocketBuffer, 0, SocketBuffer.Length); break; } else { // Do a left shift on the receive array. Array.Copy(SocketBuffer, sipMsgBuffer.Length + bytesSkipped, SocketBuffer, 0, SocketBufferEndPosition); //Array.Clear(SocketBuffer, SocketBufferEndPosition, SocketBuffer.Length - SocketBufferEndPosition); // Try and extract another SIP message from the receive buffer. sipMsgBuffer = SIPConnection.ProcessReceive(SocketBuffer, 0, SocketBufferEndPosition, out bytesSkipped); } } return(true); } else { //logger.Debug("SIP " + ConnectionProtocol + " socket to " + RemoteEndPoint + " was disconnected, closing."); //SIPStream.Close(); Close(); SIPSocketDisconnected(RemoteEndPoint); return(false); } } catch (ObjectDisposedException) { // Will occur if the owning channel closed the connection. SIPSocketDisconnected(RemoteEndPoint); return(false); } catch (SocketException) { // Will occur if the owning channel closed the connection. SIPSocketDisconnected(RemoteEndPoint); return(false); } catch (Exception excp) { logger.Error("Exception SIPConnection SocketReadCompleted. " + excp.Message); throw; } }
private void EndConnect(IAsyncResult ar) { try { object[] stateObj = (object[])ar.AsyncState; TcpClient tcpClient = (TcpClient)stateObj[0]; IPEndPoint dstEndPoint = (IPEndPoint)stateObj[1]; byte[] buffer = (byte[])stateObj[2]; string serverCN = (string)stateObj[3]; m_connectingSockets.Remove(dstEndPoint.ToString()); SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); //DisplayCertificateInformation(sslStream); sslStream.AuthenticateAsClient(serverCN); tcpClient.EndConnect(ar); if (tcpClient != null && tcpClient.Connected) { SIPConnection callerConnection = new SIPConnection(this, sslStream, dstEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Caller); m_connectedSockets.Add(dstEndPoint.ToString(), callerConnection); callerConnection.SIPSocketDisconnected += SIPTLSSocketDisconnected; callerConnection.SIPMessageReceived += SIPTLSMessageReceived; //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; callerConnection.SIPStream.BeginRead(callerConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), callerConnection); logger.Debug("Established TLS connection to " + dstEndPoint + "."); callerConnection.SIPStream.BeginWrite(buffer, 0, buffer.Length, EndSend, callerConnection); } else { logger.Warn("Could not establish TLS connection to " + dstEndPoint + "."); } } catch (Exception excp) { logger.Error("Exception SIPTLSChannel EndConnect. " + excp.Message); } }
private void AcceptConnections(string threadName) { try { Thread.CurrentThread.Name = threadName; //m_sipConn.Listen(MAX_TCP_CONNECTIONS); m_tlsServerListener.Start(MAX_TLS_CONNECTIONS); logger.Debug("SIPTLSChannel socket on " + m_localSIPEndPoint + " listening started."); while (!Closed) { try { TcpClient tcpClient = m_tlsServerListener.AcceptTcpClient(); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; logger.Debug("SIP TLS Channel connection accepted from " + remoteEndPoint + "."); SslStream sslStream = new SslStream(tcpClient.GetStream(), false); sslStream.AuthenticateAsServer(m_serverCertificate, false, SslProtocols.Tls, false); // Display the properties and settings for the authenticated stream. //DisplaySecurityLevel(sslStream); //DisplaySecurityServices(sslStream); //DisplayCertificateInformation(sslStream); //DisplayStreamProperties(sslStream); // Set timeouts for the read and write to 5 seconds. sslStream.ReadTimeout = 5000; sslStream.WriteTimeout = 5000; SIPConnection sipTLSConnection = new SIPConnection(this, sslStream, remoteEndPoint, SIPProtocolsEnum.tls, SIPConnectionsEnum.Listener); m_connectedSockets.Add(remoteEndPoint.ToString(), sipTLSConnection); sipTLSConnection.SIPSocketDisconnected += SIPTLSSocketDisconnected; sipTLSConnection.SIPMessageReceived += SIPTLSMessageReceived; //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; sipTLSConnection.SIPStream.BeginRead(sipTLSConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), sipTLSConnection); } catch (Exception e) { logger.Error("SIPTLSChannel AuthenticationException. " + e.Message); //sslStream.Close(); //tcpClient.Close(); } } logger.Debug("SIPTLSChannel socket on " + m_localSIPEndPoint + " listening halted."); } catch (Exception excp) { logger.Error("Exception SIPTLSChannel Listen. " + excp.Message); //throw excp; } }
public void TestSocketReadWithTwoMessagesAndBytesToSkipTest() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); string testReceive = @" SUBSCRIBE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP 10.1.1.5:62647;branch=z9hG4bKa58b912c426f415daa887289efda50cd;rport To: <sip:[email protected]> From: <sip:[email protected]>;tag=1902440575 Call-ID: 1b569032-d1e4-4869-be9f-67d4ba8a4e3a CSeq: 3 SUBSCRIBE Contact: <sip:10.1.1.5:62647;transport=tcp> Max-Forwards: 70 Expires: 600 Content-Length: 15 Content-Type: text/text Event: dialog includesdp=true SUBSCRIBE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP 10.1.1.5:62647;branch=z9hG4bKa58b912c426f415daa887289efda50cd;rport To: <sip:[email protected]> From: <sip:[email protected]>;tag=1902440575 Call-ID: 1b569032-d1e4-4869-be9f-67d4ba8a4e3a CSeq: 3 SUBSCRIBE SUBSCRIBE sip:[email protected]"; byte[] testReceiveBytes = UTF8Encoding.UTF8.GetBytes(testReceive); SIPConnection testConnection = new SIPConnection(null, (Stream)null, new IPEndPoint(IPAddress.Loopback, 0), SIPProtocolsEnum.tcp, SIPConnectionsEnum.Caller); int sipMessages = 0; testConnection.SIPMessageReceived += (chan, ep, buffer) => { sipMessages++; }; Array.Copy(testReceiveBytes, testConnection.SocketBuffer, testReceiveBytes.Length); bool result = testConnection.SocketReadCompleted(testReceiveBytes.Length); string remainingBytes = Encoding.UTF8.GetString(testConnection.SocketBuffer, 0, testConnection.SocketBufferEndPosition); Console.WriteLine("SocketBufferEndPosition=" + testConnection.SocketBufferEndPosition + "."); Console.WriteLine("SocketBuffer=" + remainingBytes + "."); Assert.IsTrue(result, "The result from processing the socket read should have been true."); Assert.IsTrue(sipMessages == 2, "The number of SIP messages parsed was incorrect."); Assert.IsTrue(testConnection.SocketBufferEndPosition == 26, "The receive buffer end position was incorrect."); Assert.IsTrue(remainingBytes == "SUBSCRIBE sip:[email protected]", "The leftover bytes in the socket buffer were incorrect."); }
public override void Send(IPEndPoint dstEndPoint, byte[] buffer, string serverCertificateName) { try { if (buffer == null) { throw new ApplicationException("An empty buffer was specified to Send in SIPTLSChannel."); } else if (LocalTCPSockets.Contains(dstEndPoint.ToString())) { logger.LogError("SIPTLSChannel blocked Send to " + dstEndPoint.ToString() + " as it was identified as a locally hosted TCP socket.\r\n" + Encoding.UTF8.GetString(buffer)); throw new ApplicationException("A Send call was made in SIPTLSChannel to send to another local TCP socket."); } else { bool sent = false; bool existingConnection = false; // Lookup a client socket that is connected to the destination. //m_sipConn(buffer, buffer.Length, destinationEndPoint); if (m_connectedSockets.ContainsKey(dstEndPoint.ToString())) { existingConnection = true; SIPConnection sipTLSClient = m_connectedSockets[dstEndPoint.ToString()]; try { lock (m_writeLock) { if (sipTLSClient.SIPStream != null && sipTLSClient.SIPStream.CanWrite) { //sipTLSClient.SIPStream.Write(buffer, 0, buffer.Length); sipTLSClient.SIPStream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(EndSend), sipTLSClient); sent = true; sipTLSClient.LastTransmission = DateTime.Now; } else { logger.LogWarning("A SIPTLSChannel write operation to " + dstEndPoint + " was dropped as the stream was null or could not be written to."); } } } catch (SocketException) { logger.LogWarning("Could not send to TLS socket " + dstEndPoint + ", closing and removing."); sipTLSClient.SIPStream.Close(); m_connectedSockets.Remove(dstEndPoint.ToString()); } } if (!sent && !existingConnection) { if (serverCertificateName.IsNullOrBlank()) { throw new ApplicationException("The SIP TLS Channel must be provided with the name of the expected server certificate, please use alternative method."); } if (!m_connectingSockets.Contains(dstEndPoint.ToString())) { logger.LogDebug("Attempting to establish TLS connection to " + dstEndPoint + "."); TcpClient tcpClient = new TcpClient(); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); tcpClient.Client.Bind(m_localSIPEndPoint.GetIPEndPoint()); m_connectingSockets.Add(dstEndPoint.ToString()); tcpClient.BeginConnect(dstEndPoint.Address, dstEndPoint.Port, EndConnect, new object[] { tcpClient, dstEndPoint, buffer, serverCertificateName }); } else { logger.LogWarning("Could not send SIP packet to TLS " + dstEndPoint + " and another connection was already in progress so dropping message."); } } } } catch (Exception excp) { logger.LogError("Exception (" + excp.GetType().ToString() + ") SIPTLSChannel Send (sendto=>" + dstEndPoint + "). " + excp); throw excp; } }
private void AcceptConnections(string threadName) { try { Thread.CurrentThread.Name = threadName; logger.Debug("SIPTCPChannel socket on " + m_localSIPEndPoint + " accept connections thread started."); while (!Closed) { try { TcpClient tcpClient = m_tcpServerListener.AcceptTcpClient(); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //IPEndPoint remoteEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint; IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; logger.Debug("SIP TCP Channel connection accepted from " + remoteEndPoint + "."); //SIPTCPConnection sipTCPClient = new SIPTCPConnection(this, clientSocket, remoteEndPoint, SIPTCPConnectionsEnum.Listener); SIPConnection sipTCPConnection = new SIPConnection(this, tcpClient.GetStream(), remoteEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Listener); //SIPConnection sipTCPClient = new SIPConnection(this, tcpClient.Client, remoteEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Listener); lock (m_connectedSockets) { m_connectedSockets.Add(remoteEndPoint.ToString(), sipTCPConnection); } sipTCPConnection.SIPSocketDisconnected += SIPTCPSocketDisconnected; sipTCPConnection.SIPMessageReceived += SIPTCPMessageReceived; // clientSocket.BeginReceive(sipTCPClient.SocketBuffer, 0, SIPTCPConnection.MaxSIPTCPMessageSize, SocketFlags.None, new AsyncCallback(sipTCPClient.ReceiveCallback), null); //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; sipTCPConnection.SIPStream.BeginRead(sipTCPConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), sipTCPConnection); } catch (Exception acceptExcp) { // This exception gets thrown if the remote end disconnects during the socket accept. logger.Warn("Exception SIPTCPChannel accepting socket (" + acceptExcp.GetType() + "). " + acceptExcp.Message); } } logger.Debug("SIPTCPChannel socket on " + m_localSIPEndPoint + " listening halted."); } catch (Exception excp) { logger.Error("Exception SIPTCPChannel Listen. " + excp.Message); //throw excp; } }
private void EndConnect(IAsyncResult ar) { bool connected = false; IPEndPoint dstEndPoint = null; try { object[] stateObj = (object[])ar.AsyncState; TcpClient tcpClient = (TcpClient)stateObj[0]; dstEndPoint = (IPEndPoint)stateObj[1]; byte[] buffer = (byte[])stateObj[2]; m_connectingSockets.Remove(dstEndPoint.ToString()); tcpClient.EndConnect(ar); if (tcpClient != null && tcpClient.Connected) { logger.Debug("Established TCP connection to " + dstEndPoint + "."); connected = true; m_connectionFailureStrikes.Remove(dstEndPoint.ToString()); m_connectionFailures.Remove(dstEndPoint.ToString()); SIPConnection callerConnection = new SIPConnection(this, tcpClient.GetStream(), dstEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Caller); m_connectedSockets.Add(dstEndPoint.ToString(), callerConnection); callerConnection.SIPSocketDisconnected += SIPTCPSocketDisconnected; callerConnection.SIPMessageReceived += SIPTCPMessageReceived; //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; callerConnection.SIPStream.BeginRead(callerConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), callerConnection); callerConnection.SIPStream.BeginWrite(buffer, 0, buffer.Length, EndSend, callerConnection); } else { logger.Warn("Could not establish TCP connection to " + dstEndPoint + "."); } } catch (SocketException sockExcp) { logger.Warn("SocketException SIPTCPChannel EndConnect. " + sockExcp.Message); } catch (Exception excp) { logger.Error("Exception SIPTCPChannel EndConnect (" + excp.GetType() + "). " + excp.Message); } finally { if (!connected && dstEndPoint != null) { if (m_connectionFailureStrikes.ContainsKey(dstEndPoint.ToString())) { m_connectionFailureStrikes[dstEndPoint.ToString()] = m_connectionFailureStrikes[dstEndPoint.ToString()] + 1; } else { m_connectionFailureStrikes.Add(dstEndPoint.ToString(), 1); } if (m_connectionFailureStrikes[dstEndPoint.ToString()] >= CONNECTION_ATTEMPTS_ALLOWED) { if (!m_connectionFailures.ContainsKey(dstEndPoint.ToString())) { m_connectionFailures.Add(dstEndPoint.ToString(), DateTime.Now); } m_connectionFailureStrikes.Remove(dstEndPoint.ToString()); } } } }
public override void Send(IPEndPoint dstEndPoint, byte[] buffer) { try { if (buffer == null) { throw new ApplicationException("An empty buffer was specified to Send in SIPTCPChannel."); } else if (LocalTCPSockets.Contains(dstEndPoint.ToString())) { logger.Error("SIPTCPChannel blocked Send to " + dstEndPoint.ToString() + " as it was identified as a locally hosted TCP socket.\r\n" + Encoding.UTF8.GetString(buffer)); throw new ApplicationException("A Send call was made in SIPTCPChannel to send to another local TCP socket."); } else { bool sent = false; // Lookup a client socket that is connected to the destination. //m_sipConn(buffer, buffer.Length, destinationEndPoint); if (m_connectedSockets.ContainsKey(dstEndPoint.ToString())) { SIPConnection sipTCPClient = m_connectedSockets[dstEndPoint.ToString()]; try { lock (m_writeLock) { //logger.Warn("TCP channel BeginWrite from " + SIPChannelEndPoint.ToString() + " to " + sipTCPClient.RemoteEndPoint + ": " + Encoding.ASCII.GetString(buffer, 0, 32) + "."); sipTCPClient.SIPStream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(EndSend), sipTCPClient); //logger.Warn("TCP channel BeginWrite complete from " + SIPChannelEndPoint.ToString() + " to " + sipTCPClient.RemoteEndPoint + "."); //sipTCPClient.SIPStream.Flush(); sent = true; sipTCPClient.LastTransmission = DateTime.Now; } } catch (SocketException) { logger.Warn("Could not send to TCP socket " + dstEndPoint + ", closing and removing."); sipTCPClient.SIPStream.Close(); m_connectedSockets.Remove(dstEndPoint.ToString()); } } if (!sent) { if (m_connectionFailures.ContainsKey(dstEndPoint.ToString()) && m_connectionFailures[dstEndPoint.ToString()] < DateTime.Now.AddSeconds(FAILED_CONNECTION_DONTUSE_INTERVAL * -1)) { m_connectionFailures.Remove(dstEndPoint.ToString()); } if (m_connectionFailures.ContainsKey(dstEndPoint.ToString())) { throw new ApplicationException("TCP connection attempt to " + dstEndPoint.ToString() + " was not attempted, too many failures."); } else if (!m_connectingSockets.Contains(dstEndPoint.ToString())) { logger.Debug("Attempting to establish TCP connection to " + dstEndPoint + "."); TcpClient tcpClient = new TcpClient(); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); tcpClient.Client.Bind(m_localSIPEndPoint.GetIPEndPoint()); m_connectingSockets.Add(dstEndPoint.ToString()); tcpClient.BeginConnect(dstEndPoint.Address, dstEndPoint.Port, EndConnect, new object[] { tcpClient, dstEndPoint, buffer }); } else { //logger.Warn("Could not send SIP packet to TCP " + dstEndPoint + " and another connection was already in progress so dropping message."); } } } } catch (ApplicationException appExcp) { logger.Warn("ApplicationException SIPTCPChannel Send (sendto=>" + dstEndPoint + "). " + appExcp.Message); throw; } catch (Exception excp) { logger.Error("Exception (" + excp.GetType().ToString() + ") SIPTCPChannel Send (sendto=>" + dstEndPoint + "). " + excp.Message); throw; } }
public void TestSocketReadSingleMessageTest() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); string testReceive = @"SUBSCRIBE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP 10.1.1.5:62647;branch=z9hG4bKa58b912c426f415daa887289efda50cd;rport To: <sip:[email protected]> From: <sip:[email protected]>;tag=1902440575 Call-ID: 1b569032-d1e4-4869-be9f-67d4ba8a4e3a CSeq: 3 SUBSCRIBE Contact: <sip:10.1.1.5:62647;transport=tcp> Max-Forwards: 70 Expires: 600 Content-Length: 15 Content-Type: text/text Event: dialog includesdp=true"; byte[] testReceiveBytes = UTF8Encoding.UTF8.GetBytes(testReceive); SIPConnection testConnection = new SIPConnection(null, (Stream)null, null, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Caller); Array.Copy(testReceiveBytes, testConnection.SocketBuffer, testReceiveBytes.Length); bool result = testConnection.SocketReadCompleted(testReceiveBytes.Length); Assert.IsTrue(result, "The result of processing the receive should have been true."); Assert.IsTrue(testConnection.SocketBufferEndPosition == 0, "The receive buffer end position should have been 0."); }
/// <summary> /// Periodically checks the established connections and closes any that have not had a transmission for a specified /// period or where the number of connections allowed per IP address has been exceeded. Only relevant for connection /// oriented channels such as TCP and TLS. /// </summary> protected void PruneConnections(string threadName) { try { Thread.CurrentThread.Name = threadName; Thread.Sleep(INITIALPRUNE_CONNECTIONS_DELAY); while (!Closed) { bool checkComplete = false; while (!checkComplete) { try { SIPConnection inactiveConnection = null; Dictionary <string, SIPConnection> connections = GetConnectionsList(); lock (connections) { var inactiveConnectionKey = (from connection in connections where connection.Value.LastTransmission < DateTime.Now.AddMinutes(PRUNE_NOTRANSMISSION_MINUTES * -1) select connection.Key).FirstOrDefault(); if (inactiveConnectionKey != null) { inactiveConnection = connections[inactiveConnectionKey]; connections.Remove(inactiveConnectionKey); } } if (inactiveConnection != null) { logger.Debug("Pruning inactive connection on " + SIPChannelContactURI + " to remote end point " + inactiveConnection.RemoteEndPoint.ToString() + "."); inactiveConnection.Close(); } else { checkComplete = true; } } catch (SocketException) { // Will be thrown if the socket is already closed. } catch (Exception pruneExcp) { logger.Error("Exception PruneConnections (pruning). " + pruneExcp.Message); checkComplete = true; } } Thread.Sleep(PRUNE_CONNECTIONS_INTERVAL); checkComplete = false; } logger.Debug("SIPChannel socket on " + m_localSIPEndPoint.ToString() + " pruning connections halted."); } catch (Exception excp) { logger.Error("Exception SIPChannel PruneConnections. " + excp.Message); } }
private void EndConnect(IAsyncResult ar) { bool connected = false; IPEndPoint dstEndPoint = null; try { object[] stateObj = (object[])ar.AsyncState; TcpClient tcpClient = (TcpClient)stateObj[0]; dstEndPoint = (IPEndPoint)stateObj[1]; byte[] buffer = (byte[])stateObj[2]; m_connectingSockets.Remove(dstEndPoint.ToString()); tcpClient.EndConnect(ar); if (tcpClient != null && tcpClient.Connected) { logger.Debug("Established TCP connection to " + dstEndPoint + "."); connected = true; m_connectionFailureStrikes.Remove(dstEndPoint.ToString()); m_connectionFailures.Remove(dstEndPoint.ToString()); SIPConnection callerConnection = new SIPConnection(this, tcpClient, tcpClient.GetStream(), dstEndPoint, SIPProtocolsEnum.tcp, SIPConnectionsEnum.Caller); m_connectedSockets.Add(dstEndPoint.ToString(), callerConnection); callerConnection.SIPSocketDisconnected += SIPTCPSocketDisconnected; callerConnection.SIPMessageReceived += SIPTCPMessageReceived; //byte[] receiveBuffer = new byte[MaxSIPTCPMessageSize]; callerConnection.SIPStream.BeginRead(callerConnection.SocketBuffer, 0, MaxSIPTCPMessageSize, new AsyncCallback(ReceiveCallback), callerConnection); callerConnection.SIPStream.BeginWrite(buffer, 0, buffer.Length, EndSend, callerConnection); } else { logger.Warn("Could not establish TCP connection to " + dstEndPoint + "."); } } catch (SocketException sockExcp) { logger.Warn("SocketException SIPTCPChannel EndConnect. " + sockExcp.Message); } catch (Exception excp) { logger.Error("Exception SIPTCPChannel EndConnect (" + excp.GetType() + "). " + excp.Message); } finally { if (!connected && dstEndPoint != null) { if (m_connectionFailureStrikes.ContainsKey(dstEndPoint.ToString())) { m_connectionFailureStrikes[dstEndPoint.ToString()] = m_connectionFailureStrikes[dstEndPoint.ToString()] + 1; } else { m_connectionFailureStrikes.Add(dstEndPoint.ToString(), 1); } if (m_connectionFailureStrikes[dstEndPoint.ToString()] >= CONNECTION_ATTEMPTS_ALLOWED) { if (!m_connectionFailures.ContainsKey(dstEndPoint.ToString())) { m_connectionFailures.Add(dstEndPoint.ToString(), DateTime.Now); } m_connectionFailureStrikes.Remove(dstEndPoint.ToString()); } } } }