private void ProcessConnectRsAck(StandardConnectRsAckPacket packet) { TcpConnectionHolder conn = null; try { conn = _tcpConnections.GetRemoteConnection(packet.ConnectionId); try { conn.Connection.Open(); conn.StopTimerToOpen(); } catch (Exception e) { Logger.Error("Error starting connection [" + conn.Connection.ConnectionId + "] : " + e.Message); if (conn != null) { conn.Connection.Close(); } } } catch (ConnectionException e) { Logger.Error("Dropping connect rs ack packet [" + packet + "], failed to get a connection : " + e.Message); } }
private void ProcessDataPacket(StandardTcpDataPacket packet) { try { TcpConnectionHolder conn = _tcpConnections.GetRemoteConnection(packet.ConnectionId); // If the connect response ack packet was lost, its possible that this connection is not open, we need to open it now if (!conn.Connection.Established) { Logger.Debug("Outgoing Connection [" + conn.Connection.ConnectionId + "] received data, means our connect rs ack was lost, auto opening"); conn.Connection.Open(); } // Lock receiving while we process this packet (we will still be able to send) // Now TcpConnection doesn't have to be threadsafe, but each connection // can process data independently at full speed. lock (conn.ReceiveLock) { // now process the dataPacket; conn.Connection.ProcessDataPacket(packet); } } catch (ConnectionException e) { Logger.Error("Dropping data packet [" + packet + "], failed to get a connection : " + e.Message); } }
internal TcpConnectionHolder[] GetActiveConnectionList() { lock (_connectionLock) { TcpConnectionHolder[] list = new TcpConnectionHolder[_localOpenConnectionList.Count]; _localOpenConnectionList.Values.CopyTo(list, 0); return(list); } }
private void ProcessDisconnectPacket(StandardDisconnectPacket packet) { // immediately acknowlege that we got it (with remote connection id as the connection id) SendData(new StandardDisconnectAckPacket(packet.ConnectionId)); // if we are not disconnecting, start the process. try { // do we have it in our list? TcpConnectionHolder connectionHolder = _tcpConnections.GetRemoteConnection(packet.ConnectionId); // this method will send the disconnectRs packet connectionHolder.Connection.ProcessDisconnect(packet); } catch (Exception e) { Logger.Error("Failed to close connection [remote id = " + packet.ConnectionId + "] : " + e.Message); } }
internal TcpConnectionHolder Remove(byte localConnectionId) { TcpConnectionHolder holder = null; lock (_connectionLock) { if (_localOpenConnectionList.TryGetValue(localConnectionId, out holder)) { _localOpenConnectionList.Remove(localConnectionId); if (_remoteLocalIdMap.ContainsKey(holder.Connection.RemoteConnectionId)) { _remoteLocalIdMap.Remove(holder.Connection.RemoteConnectionId); } Logger.Debug("Removed connection " + localConnectionId + " to from lists."); } } return(holder); }
private void ProcessAckPacket(StandardAckPacket packet) { try { TcpConnectionHolder conn = _tcpConnections.GetRemoteConnection(packet.ConnectionId); // Lock sending while we process this packet (we will still be able to receive) // Now TcpConnection doesn't have to be threadsafe, but each connection // can process acks independently at full speed. lock (conn.SendLock) { // now process the ackPacket; conn.Connection.ProcessAck(packet); } } catch (ConnectionException e) { Logger.Error("Dropping ack packet [" + packet + "], failed to get a connection : " + e.Message); } }
internal TcpConnectionHolder[] GetActiveConnectionList() { lock (_connectionLock) { TcpConnectionHolder[] list = new TcpConnectionHolder[_localOpenConnectionList.Count]; _localOpenConnectionList.Values.CopyTo(list, 0); return list; } }
private void ProcessNamedConnectionRequest(StandardNamedConnectRqPacket packet) { StandardNamedConnectRsPacket response = new StandardNamedConnectRsPacket { ConnectionId = packet.ConnectionId }; // By default the conn id going back is the conn id of the request // this will change if the connection is a success, then it will be our conn id. lock (_receiveConnectLock) { // If this connection exists if (_tcpConnections.IsRemoteConnection(packet.ConnectionId)) { Logger.Debug("Request for connection id [" + packet.ConnectionId + "] already established, resending response"); TcpConnectionHolder tcpConnectionHolder = _tcpConnections.GetRemoteConnection(packet.ConnectionId); response.RemoteConnectionId = tcpConnectionHolder.Connection.ConnectionId; response.ProtocolId = tcpConnectionHolder.Connection.ProtocolId; response.Sequence = tcpConnectionHolder.Connection.NextSeqToSend; // we can respond that we are already established here response.Success = true; } else { lock (_listeningNamedTCPEndPoints) { if (_listeningNamedTCPEndPoints.ContainsKey(packet.ConnectionName)) { byte localConnectionId = GetNextConnectionId(); Logger.Debug("Found a listener for " + packet.ConnectionName + " connecting local conn [" + localConnectionId + "] to remote conn [" + packet.ConnectionId + "]"); byte agreedProtocolId = packet.ProtocolId; if (packet.ProtocolId > MaxSupportedProtocolId) { Logger.Debug("They wanted protocol " + packet.ProtocolId + ", but I only support up to " + MaxSupportedProtocolId + ", so I propose it."); agreedProtocolId = MaxSupportedProtocolId; } Logger.Debug("I have agreed to protocol " + agreedProtocolId); response.ProtocolId = agreedProtocolId; response.Sequence = (ushort)(_rand.Next(ushort.MaxValue)); ITcpTransportLayer connection = null; switch (agreedProtocolId) { case (2): { connection = new TcpTransportLayerSlidingWindow(this, localConnectionId, packet.ConnectionId, response.Sequence, packet.Sequence); break; } default: { Logger.Error("Failed to agree on a tcp protocol, I don't support " + agreedProtocolId); break; } } if (connection != null) { // only add the connection if response.Success = _listeningNamedTCPEndPoints[packet.ConnectionName].ConnectCallback(connection.Socket); if (response.Success) { // set it up to tie up loose ends when the connection dies connection.ConnectionClose += ConnectionOnConnectionClose; _tcpConnections.Add(connection); response.RemoteConnectionId = localConnectionId; } } else { response.Success = false; } } else { Logger.Warn("No listener for " + packet.ConnectionName); response.Success = false; } } } } Logger.Debug("Sending connection response : " + response); SendData(response); if (response.Success) { // This sends a positive response, we would like to get an Ack of this connection response // which will open this connection, but should that ack not arrive, let set a timer to automatically // open this connection after 10 seconds // we know that the sender will retry the connection should it not receive our response. _tcpConnections.GetLocalOpenConnection(response.RemoteConnectionId).StartTimerToOpen(); } }