private void Initialise() { try { m_tlsServerListener = new TcpListener(m_localSIPEndPoint.GetIPEndPoint()); m_tlsServerListener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); m_tlsServerListener.Start(MAX_TLS_CONNECTIONS); if (m_localSIPEndPoint.Port == 0) { m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.tls, (IPEndPoint)m_tlsServerListener.Server.LocalEndPoint); } LocalTCPSockets.Add(((IPEndPoint)m_tlsServerListener.Server.LocalEndPoint).ToString()); ThreadPool.QueueUserWorkItem(delegate { AcceptConnections(ACCEPT_THREAD_NAME + m_localSIPEndPoint.Port); }); ThreadPool.QueueUserWorkItem(delegate { PruneConnections(PRUNE_THREAD_NAME + m_localSIPEndPoint.Port); }); logger.LogDebug("SIP TLS Channel listener created " + m_localSIPEndPoint.GetIPEndPoint() + "."); } catch (Exception excp) { logger.LogError("Exception SIPTLSChannel Initialise. " + excp); throw; } }
new Dictionary <string, DateTime>(); // Tracks sockets that have had a connection failure on them to avoid endless re-connect attmepts. public SIPTCPChannel(IPEndPoint endPoint) { m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.tcp, endPoint); LocalTCPSockets.Add(endPoint.ToString()); m_isReliable = true; Initialise(); }
/// <summary> /// Initialises the SIP channel's socket listener. /// </summary> private void Initialise() { try { IPEndPoint listenEndPoint = m_localSIPEndPoint.GetIPEndPoint(); m_tcpServerListener = new TcpListener(listenEndPoint); m_tcpServerListener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); m_tcpServerListener.Server.LingerState = new LingerOption(true, 0); m_tcpServerListener.Start(MAX_TCP_CONNECTIONS); if (m_localSIPEndPoint.Port == 0) { m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.tcp, listenEndPoint); } LocalTCPSockets.Add(listenEndPoint.ToString()); ThreadPool.QueueUserWorkItem(delegate { AcceptConnections(); }); ThreadPool.QueueUserWorkItem(delegate { PruneConnections(m_pruneThreadName + m_localSIPEndPoint.Port); }); logger.LogDebug("SIP TCP Channel listener created " + m_localSIPEndPoint.GetIPEndPoint() + "."); } catch (Exception excp) { logger.LogError("Exception SIPTCPChannel Initialise. " + excp.Message); throw excp; } }
/// <summary> /// Attempts to send data to the remote end point over a reliable connection. If an existing /// connection exists it will be used otherwise an attempt will be made to establish a new connection. /// </summary> /// <param name="dstEndPoint">The remote end point to send the reliable data to.</param> /// <param name="buffer">The data to send.</param> /// <param name="serverCertificateName">Optional. Only relevant for SSL streams. The common name /// that is expected for the remote SSL server.</param> public override async Task <SocketError> SendAsync(IPEndPoint dstEndPoint, byte[] buffer, string serverCertificateName) { try { if (buffer == null || buffer.Length == 0) { throw new ApplicationException("An empty buffer was specified to Send in SIPTCPChannel."); } else if (DisableLocalTCPSocketsCheck == false && LocalTCPSockets.Contains(dstEndPoint.ToString())) { logger.LogWarning($"SIPTCPChannel blocked Send to {dstEndPoint} as it was identified as a locally hosted TCP socket.\r\n" + Encoding.UTF8.GetString(buffer)); throw new ApplicationException("A Send call was blocked in SIPTCPChannel due to the destination being another local TCP socket."); } else if (m_connectionFailures.ContainsKey(dstEndPoint.ToString())) { throw new ApplicationException($"SIP TCP channel connect attempt to {dstEndPoint} failed."); } else { SIPStreamConnection sipStreamConn = null; // Lookup a client socket that is connected to the destination. If it does not exist attempt to connect a new one. if (m_connectedSockets.ContainsKey(dstEndPoint.ToString())) { sipStreamConn = m_connectedSockets[dstEndPoint.ToString()]; SendOnConnected(sipStreamConn, buffer); return(SocketError.Success); } else { await ConnectClientAsync(dstEndPoint, buffer, serverCertificateName); return(SocketError.Success); } } } catch (SocketException sockExcp) { return(sockExcp.SocketErrorCode); } catch (ApplicationException) { throw; } catch (Exception excp) { logger.LogError("Exception (" + excp.GetType().ToString() + ") SIPTCPChannel Send (sendto=>" + dstEndPoint + "). " + excp.Message); throw; } }
public SIPTLSChannel(X509Certificate2 serverCertificate, IPEndPoint endPoint) { if (serverCertificate == null) { throw new ArgumentNullException("serverCertificate", "An X509 certificate must be supplied for a SIP TLS channel."); } if (endPoint == null) { throw new ArgumentNullException("endPoint", "An IP end point must be supplied for a SIP TLS channel."); } m_localSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.tls, endPoint); LocalTCPSockets.Add(endPoint.ToString()); m_isReliable = true; m_isTLS = true; //m_certificatePath = certificateFileName; ///base.Name = "s" + Crypto.GetRandomInt(4); m_serverCertificate = serverCertificate; Initialise(); }
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.Error("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 { if (sipTLSClient.SIPStream != null && sipTLSClient.SIPStream.CanWrite) { sipTLSClient.SIPStream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(EndSend), sipTLSClient); sent = true; sipTLSClient.LastTransmission = DateTime.Now; } else { logger.Warn("A SIPTLSChannel write operation to " + dstEndPoint + " was dropped as the stream was null or could not be written to."); } } catch (SocketException) { logger.Warn("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.Debug("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.Warn("Could not send SIP packet to TLS " + dstEndPoint + " and another connection was already in progress so dropping message."); } } } } catch (Exception excp) { logger.Error("Exception (" + excp.GetType().ToString() + ") SIPTLSChannel Send (sendto=>" + dstEndPoint + "). " + excp); throw excp; } }
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; } }