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 override void ProcessDisconnect(StandardDisconnectPacket packet) { throw new NotImplementedException(); }
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); } }
public void DisconnectConnection(byte connectionId, ushort seq) { const long waitTime = 120000; // 2 minute disconnect time const int disconnectRetryTimeout = 20000; Logger.Debug("Disconnecting tcp session " + connectionId); try { var packet = new StandardDisconnectPacket(connectionId); packet.Sequence = seq; long startTime = DateTime.Now.Ticks; _disconnectEvents[connectionId] = new AutoResetEvent(false); do { // we only do this if we haven't received the ack of our disconnect if (!_disconnectAcks.ContainsKey(connectionId)) { _transport.SendData(packet); packet.ResendCount++; } else { Logger.Debug("Will not resend disconnect request, remote side has acked it already"); } var timeSpan = new TimeSpan(DateTime.Now.Ticks - startTime); if (timeSpan.TotalMilliseconds > waitTime) { Logger.Debug("Disconnect timeout : " + timeSpan.TotalMilliseconds + "ms"); break; } Logger.Debug("Waiting for disconnect response for connection id " + connectionId); } while (_disconnectEvents.ContainsKey(connectionId) && !_disconnectEvents[connectionId].WaitOne(disconnectRetryTimeout)); if(_disconnectEvents.ContainsKey(connectionId)) { // this means the disconnect wasn't acknowledged, oh well! Logger.Warn("Failed to receive a disconnect response for connection id " + connectionId + ", closing regardless."); } } catch (Exception e) { Logger.Error("Failed to send the close packet, closing connection anyway. : " + e.Message, e); } if (_disconnectEvents.ContainsKey(connectionId)) _disconnectEvents.Remove(connectionId); if (_disconnectAcks.ContainsKey(connectionId)) _disconnectAcks.Remove(connectionId); }
public override void ProcessDisconnect(StandardDisconnectPacket packet) { if (!_isDisconnecting) { _isDisconnecting = true; // Turn off our data sender, remote host won't process the data anyway // release a potentially blocked data sender ReleaseDataSender(); // clear the data retry timer if (_retryTimer.Enabled) { _retryTimer.Stop(); } if (Stats.DataPacketsReceived > 0 && packet.Sequence == (_nextDataSeqIn - 1)) { // Wait for all data to arrive (disconnect notified us of the last seq) long startTime = Environment.TickCount; int elapsedTime = 0; const int timeout = 60000; lock (_processDataLock) { #if DEBUG Logger.Debug("Waiting for all data which was sent to arrive, up until " + packet.Sequence); #endif while (elapsedTime < timeout && (_lastAckedPacket == null || _lastAckedPacket.Sequence < packet.Sequence)) { Monitor.Wait(_processDataLock, timeout - elapsedTime); elapsedTime = (int)(Environment.TickCount - startTime); } } if (_lastAckedPacket == null || _lastAckedPacket.Sequence < packet.Sequence) { Logger.Error( "Failed to receive all the sent data packets during disconnect, timeout while waiting, last acked packet is " + _lastAckedPacket + ", we wanted " + packet.Sequence); } else { Logger.Debug("We have successfully received all the data that was sent : expected " + packet.Sequence + ", got " + _lastAckedPacket.Sequence); } } else { Logger.Debug("Don't have to wait for all data to arrive, because none has been sent."); } // Mark it as disconnected _disconnected = true; // Now close upstream if (Established && !Closing && !Closed) { Logger.Debug("Closing connection after disconnect " + ConnectionId + "-" + RemoteConnectionId); Closing = true; var closer = new Thread(CompleteClose) { IsBackground = true, Name = "closer[" + ConnectionId + "-" + RemoteConnectionId + "]" }; closer.Start(); } } }
public abstract void ProcessDisconnect(StandardDisconnectPacket packet);