Exemplo n.º 1
0
 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;
 }
Exemplo n.º 2
0
 public override void ProcessDisconnect(StandardDisconnectPacket packet)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 3
0
 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);
     }
 }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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();
                }
            }
        }
Exemplo n.º 6
0
 public abstract void ProcessDisconnect(StandardDisconnectPacket packet);