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