public BasicTcpPacket getPacket(byte[] bytes) { BasicTcpPacket packet; switch (bytes[BasicTcpPacket.PKT_POS_TYPE]) { case BasicTcpPacket.PKT_TYPE_DISCONNECT: packet = new StandardDisconnectPacket(); break; case BasicTcpPacket.PKT_TYPE_DISCONNECT_ACK: packet = new StandardDisconnectAckPacket(); break; case BasicTcpPacket.PKT_TYPE_DISCONNECT_RS: packet = new StandardDisconnectRsPacket(); break; case BasicTcpPacket.PKT_TYPE_CONNECT_RS_ACK: packet = new StandardConnectRsAckPacket(); break; case BasicTcpPacket.PKT_TYPE_CONNECT_NAME_RS: packet = new StandardNamedConnectRsPacket(); break; case BasicTcpPacket.PKT_TYPE_CONNECT_NAME_RQ: packet = new StandardNamedConnectRqPacket(); break; case BasicTcpPacket.PKT_TYPE_DATA: packet = new StandardTcpDataPacket(); break; case BasicTcpPacket.PKT_TYPE_ACK: packet = new StandardAckPacket(); break; case BasicTcpPacket.PKT_TYPE_NOP: packet = new StandardTcpNopPacket(); break; default: throw new UnknownPacketException("Failed to determine packet type"); } packet.ProcessPacket(bytes); return(packet); }
public void ProcessConnectRs(StandardNamedConnectRsPacket packet) { Logger.Debug("Processing Connect Response " + packet); // In a connection response, ConnectionId is set to the same as the connection request ConnectionId if (_connectEvents.ContainsKey(packet.ConnectionId)) { _connectResults[packet.ConnectionId] = packet; _connectEvents[packet.ConnectionId].Set(); _connectEvents.Remove(packet.ConnectionId); } else { // we know nothing about this (probably timed out), close this connection Logger.Error("Got a Connect Response with an Id we don't have [" + packet.ConnectionId + "]"); //CloseConnection(packet.ConnectionId, packet.Sequence); } }
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(); } }