internal SessionRequestPacket(RawEQPacket rawPacket)
        {
            this._clientIPE = rawPacket.ClientIPE;
            this._data = rawPacket.RawPacketData;
            this._SentCRC = rawPacket.SentCRC;
            this._OpCode = rawPacket.OpCode;

            GCHandle pinnedBytes = GCHandle.Alloc(GetPayload(), GCHandleType.Pinned);
            _sessionRequest = (SessionRequest)Marshal.PtrToStructure(pinnedBytes.AddrOfPinnedObject(), typeof(SessionRequest));
            pinnedBytes.Free();
        }
 internal EQRawApplicationPacket(RawEQPacket rawPacket)
     : base(rawPacket.ClientIPE, rawPacket.RawPacketData)
 {
     _OpCode = (AppOpCode)rawPacket.RawOpCode;
 }
Esempio n. 3
0
        // Process the different protocol packet types
        private void ProcessRecvPacket(RawEQPacket packet, Client client)
        {
            if (packet.RawOpCode > 0x00ff)      // Check for application level packet
            {
                //_log.Debug("OPCode above 0x00ff.");
                packet.RawOpCode = (ushort)IPAddress.NetworkToHostOrder((short)packet.RawOpCode);   // orig code says opcode byte order is backwards in this case
                ApplicationPacketReceived(new EQRawApplicationPacket(packet), client);  // Handled by specialized server type
                return;
            }

            int subPacketLen = 0, processed = 0;

            switch (packet.OpCode)
            {
                case ProtocolOpCode.None:
                    _log.Error("Protocol OpCode found not set during packet processing... please fix.");
                    break;
                case ProtocolOpCode.SessionRequest:
                    // Check for existing client - may be getting blitzed w/ session requests
                    if (client.SessionId != 0 && client.ConnectionState == ConnectionState.Established)
                    {
                        _log.Warn("Recv a sessionRequest for an existing open client.");
                        break;
                    }

                    bool add = (client.SessionId == 0);   // handles case of existing clients that aren't connected (no need to re-add)

                    EQPacket<SessionRequest> sessReqPacket = new EQPacket<SessionRequest>(packet);
                    lock (client.syncRoot)
                    {
                        client.SessionId = (UInt32)IPAddress.NetworkToHostOrder((int)sessReqPacket.PacketStruct.SessionId);
                        client.MaxLength = (UInt32)IPAddress.NetworkToHostOrder((int)sessReqPacket.PacketStruct.MaxLength);
                        client.Key = 0x11223344;
                        client.ConnectionState = ConnectionState.Established;
                        //_log.Debug(string.Format("Received Session Request: session {0} maxlength {1}", client.SessionId, client.MaxLength));
                        PreSendSessionResponse(client);
                    }

                    if (add)
                    {
                        _clientListLock.EnterWriteLock();
                        try
                        {
                            _clients.Add(client.IPEndPoint.ToString(), client);
                            _log.InfoFormat("New client connecting from {0}", client.IPEndPoint.ToString());
                        }
                        finally
                        {
                            _clientListLock.ExitWriteLock();
                        }
                    }

                    break;
                case ProtocolOpCode.SessionResponse:
                    _log.Warn("Received unhandled SessionResponse OPCode");
                    break;
                case ProtocolOpCode.Combined:

                    while (processed < packet.GetPayload().Length)
                    {
                        subPacketLen = Buffer.GetByte(packet.GetPayload(), processed);
                        //_log.Debug("Extracting combined packet of length " + subPacketLen);
                        byte[] embBytes = new byte[subPacketLen];
                        Buffer.BlockCopy(packet.GetPayload(), processed + 1, embBytes, 0, subPacketLen);
                        RawEQPacket embPacket = new RawEQPacket(client.IPEndPoint, embBytes);
                        ProcessRecvPacket(embPacket, client);
                        processed += subPacketLen + 1;
                    }
                    break;
                case ProtocolOpCode.SessionDisconnect:
                    lock (client.syncRoot)
                    {
                        switch (client.ConnectionState)
                        {
                            case ConnectionState.Established:
                                _log.Debug("Received client initiated disconnect");
                                lock (client.syncRoot)
                                    client.ConnectionState = ConnectionState.Closed;
                                    //client.SendDisconnect(ConnectionState.Closed);
                                break;
                            case ConnectionState.Closing:
                                _log.Debug("Received disconnect during a pending close");
                                lock (client.syncRoot)
                                    client.SendDisconnect(ConnectionState.Closed);
                                break;
                            case ConnectionState.Closed:
                            case ConnectionState.Disconnecting:     // This is never sent back... handling a different way
                                _log.Debug("Received expected disconnect");
                                lock (client.syncRoot)
                                    client.ConnectionState = ConnectionState.Closed;
                                break;
                        }
                    }
                    break;
                case ProtocolOpCode.KeepAlive:
                    lock (client.syncRoot)
                        client.NonSequencedQueue.Enqueue(new RawEQPacket(client.IPEndPoint, packet.RawPacketData));

                    _log.Debug("Received and replied to a KeepAlive");
                    break;
                case ProtocolOpCode.SessionStatRequest:
                    EQPacket<SessionStats> statsPacket = new EQPacket<SessionStats>(packet);
                    //_log.DebugFormat("Received Stats: {0} packets recv, {1} packets sent, Deltas: local {2}, ({3} <- {4} -> {5}) remote {6}",
                    //    RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.PacketsRecieved), RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.PacketsRecieved), RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.LastLocalDelta),
                    //    RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.LowDelta), RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.AverageDelta),
                    //    RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.HighDelta), RawEQPacket.NetToHostOrder(statsPacket.PacketStruct.LastRemoteDelta));

                    lock (client.syncRoot)
                        client.SendSessionStats(statsPacket);
                    break;
                case ProtocolOpCode.SessionStatResponse:
                    _log.Debug("Received SessionStatResponse OPCode, ignoring");
                    break;
                case ProtocolOpCode.Packet:
                    ushort seqNum = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(packet.GetPayload(), 0));   // get seq num
                    //_log.Debug(string.Format("Received Data Packet: session {0} sequence {1}", client.SessionId, seqNum));

                    // TODO: figure out the locking strategy here
                    // determine the packet sequence
                    if (seqNum > client.NextInSeq)
                    {
                        _log.DebugFormat("Recv future data packet - expected {0} but got {1}", client.NextInSeq, seqNum);
                        lock (client.syncRoot)
                        {
                            client.DataPackets.Remove(seqNum);
                            client.DataPackets.Add(seqNum, packet);     // shove into the deferred packet list
                        }
                    }
                    else if (seqNum < client.NextInSeq)
                    {
                        //_log.DebugFormat("Recv duplicate data packet - expected {0} but got {1}", client.NextInSeq, seqNum);
                        client.SendOutOfOrderAck(seqNum);
                    }
                    else
                    {
                        // Received packet w/ expected seq
                        lock (client.syncRoot)
                        {
                            client.DataPackets.Remove(seqNum);  // Remove if it was previously queued as a future packet
                            client.SetNextAckToSend(seqNum);    // sequenced packets must be ack'd
                        }

                        // check for embedded OP_AppCombined (0x19)
                        ProtocolOpCode embOp = (ProtocolOpCode)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(packet.GetPayload(), 2));
                        if (embOp == ProtocolOpCode.AppCombined)
                        {
                            //_log.Debug("Found and extracted an embedded packet in a data packet");
                            byte[] embBytes = new byte[packet.GetPayload().Length - 4]; // snip the data packet sequence num & AppCombined OpCode
                            Buffer.BlockCopy(packet.GetPayload(), 4, embBytes, 0, packet.GetPayload().Length - 4);
                            RawEQPacket embPacket = new RawEQPacket(ProtocolOpCode.AppCombined, embBytes, client.IPEndPoint);
                            ProcessRecvPacket(embPacket, client);
                        }
                        else
                        {
                            // Needs to be handled by specialized server, let's get us an app packet going
                            byte[] appBytes = new byte[packet.GetPayload().Length - 2]; // snip the data packet sequence num
                            Buffer.BlockCopy(packet.GetPayload(), 2, appBytes, 0, packet.GetPayload().Length - 2);
                            ApplicationPacketReceived(new EQRawApplicationPacket(client.IPEndPoint, appBytes), client);
                        }
                    }
                    break;
                case ProtocolOpCode.Fragment:
                    ushort fragSeqNum = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(packet.GetPayload(), 0));

                    if (fragSeqNum > client.NextInSeq)
                    {
                        _log.DebugFormat("Recv future fragment - expected {0} but got {1}", client.NextInSeq, fragSeqNum);
                        lock (client.syncRoot)
                            client.DataPackets.Add(fragSeqNum, packet);     // shove into the deferred data packet list
                    }
                    else if (fragSeqNum < client.NextInSeq)
                    {
                        //_log.DebugFormat("Recv duplicate data fragment - expected {0} but got {1}", client.NextInSeq, fragSeqNum);
                        client.SendOutOfOrderAck(fragSeqNum);
                    }
                    else
                    {
                        // Received packet w/ expected seq
                        BasePacket bigPacket = null;
                        lock (client.syncRoot)
                        {
                            client.DataPackets.Remove(fragSeqNum);  // Remove if it was previously queued as a future packet
                            client.SetNextAckToSend(fragSeqNum);

                            if (client.OversizedBuffer != null)
                            {
                                // copy this round's fragment into the oversized buffer
                                Buffer.BlockCopy(packet.GetPayload(), 2, client.OversizedBuffer, client.OversizedOffset, packet.GetPayload().Length - 2);
                                client.OversizedOffset += packet.GetPayload().Length - 2;
                                //_log.DebugFormat("Recv fragment - seq {0} now at {1}", fragSeqNum, client.OversizedBuffer.Length / client.OversizedOffset);

                                if (client.OversizedOffset == client.OversizedBuffer.Length)
                                {
                                    // I totally don't get this first comparison (shouldn't we be looking in the oversized buffer), but ok...
                                    if (Buffer.GetByte(packet.GetPayload(), 2) == 0x00 && Buffer.GetByte(packet.GetPayload(), 3) == 0x19)
                                        bigPacket = new RawEQPacket(packet.ClientIPE, client.OversizedBuffer);
                                    else
                                        bigPacket = new EQRawApplicationPacket(client.IPEndPoint, client.OversizedBuffer);

                                    client.OversizedBuffer = null;
                                    client.OversizedOffset = 0;
                                    //_log.Debug("Completed combined oversized packet.");
                                }
                            }
                            else
                            {
                                uint oversizedLen = (uint)IPAddress.NetworkToHostOrder((int)BitConverter.ToUInt32(packet.GetPayload(), 2));
                                client.OversizedBuffer = new byte[oversizedLen];    // initialize the oversized packet buffer
                                Buffer.BlockCopy(packet.GetPayload(), 6, client.OversizedBuffer, 0, packet.GetPayload().Length - 6);
                                client.OversizedOffset = packet.GetPayload().Length - 6;
                                //_log.DebugFormat("Recv initial fragment packet - total size: {0} fragment len: {1}", oversizedLen, packet.GetPayload().Length - 6);
                            }
                        }

                        if (bigPacket is RawEQPacket)
                            ProcessRecvPacket(bigPacket as RawEQPacket, client);
                        else if(bigPacket is EQRawApplicationPacket)
                            ApplicationPacketReceived(bigPacket as EQRawApplicationPacket, client);
                    }
                    break;
                case ProtocolOpCode.OutOfOrderAck:
                    _log.Debug("Received OutOfOrderAck OPCode");
                    break;
                case ProtocolOpCode.Ack:
                    ushort ackSeqNum = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(packet.GetPayload(), 0));   // get seq num
                    lock (client.syncRoot)
                        client.AckPackets(ackSeqNum);
                    break;
                case ProtocolOpCode.AppCombined:
                    //_log.Debug("Processing App Combined packet: " + BitConverter.ToString(packet.RawPacketData));
                    processed = 0;
                    EQRawApplicationPacket appPacket = null;

                    while (processed < packet.GetPayload().Length)
                    {
                        appPacket = null;
                        subPacketLen = Buffer.GetByte(packet.GetPayload(), processed);

                        if (subPacketLen != 0xff)
                        {
                            //_log.Debug("Extracting App Combined packet of length " + subPacketLen);
                            byte[] appBytes = new byte[subPacketLen];
                            Buffer.BlockCopy(packet.GetPayload(), processed + 1, appBytes, 0, subPacketLen);
                            appPacket = new EQRawApplicationPacket(client.IPEndPoint, appBytes);
                            processed += (subPacketLen + 1);
                        }
                        else
                        {
                            subPacketLen = IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(packet.GetPayload(), processed + 1));
                            //_log.Debug("Extracting App Combined packet of length " + subPacketLen);
                            byte[] appBytes = new byte[subPacketLen];
                            Buffer.BlockCopy(packet.GetPayload(), processed + 3, appBytes, 0, subPacketLen);
                            appPacket = new EQRawApplicationPacket(client.IPEndPoint, appBytes);
                            processed += (subPacketLen + 3);
                        }

                        ApplicationPacketReceived(appPacket, client);
                    }
                    break;
                case ProtocolOpCode.OutOfSession:
                    _log.Debug("Received OutOfSession OPCode, ignoring");
                    break;
                default:
                    _log.Warn("Received Unknown Protocol OPCode: " + (ushort)packet.OpCode);
                    break;
            }
        }
Esempio n. 4
0
        private void EnqueueSendPacket(RawEQPacket packet)
        {
            lock (((ICollection)_sendQueue).SyncRoot)
                _sendQueue.Enqueue(packet);

            _writerWaitHandle.Set();  // Signal writer proc
        }
Esempio n. 5
0
 /// <summary>Implemented by derived class to perform any necessary packet decompression and/or decryption.</summary>
 internal virtual void PreProcessOutPacket(ref RawEQPacket packet)
 {
 }
Esempio n. 6
0
 internal override void PreProcessOutPacket(ref RawEQPacket packet)
 {
     // compress the packet
     byte[] compBuffer = new byte[COMPRESSION_BUFFER_SIZE];
     int compLen = EQRawApplicationPacket.Deflate(packet.RawPacketData, ref compBuffer);
     Array.Resize<byte>(ref compBuffer, compLen);
     packet = new RawEQPacket(packet.ClientIPE, compBuffer);
 }
Esempio n. 7
0
        public void SendSequencedPacket(BasePacket appPacket, ProtocolOpCode opCode)
        {
            // Wrap in a raw packet and throw on sequenced queue
            ushort nextOutSeq_no = (ushort)IPAddress.HostToNetworkOrder((short)_nextOutSeq);
            RawEQPacket packet = new RawEQPacket(opCode, nextOutSeq_no, appPacket.RawPacketData, appPacket.ClientIPE);
            _nextOutSeq++;

            lock (((ICollection)_seqQueue).SyncRoot)
                _seqQueue.Enqueue(packet);
        }
Esempio n. 8
0
 public void SendDisconnect(ConnectionState connState)
 {
     _connState = connState;
     uint session_no = (uint)IPAddress.HostToNetworkOrder((int)_sessionId);
     RawEQPacket discPacket = new RawEQPacket(ProtocolOpCode.SessionDisconnect, BitConverter.GetBytes(session_no), _ipe);
     _log.DebugFormat("Sending Disconnect for session {0}", _sessionId);
     _nonSeqQueue.Enqueue(discPacket);
 }
Esempio n. 9
0
        public void SendAck(ushort seqNum)
        {
            _lastAckSent = seqNum;
            ushort seq_no = (ushort)IPAddress.HostToNetworkOrder((short)seqNum);

            RawEQPacket ackPacket = new RawEQPacket(ProtocolOpCode.Ack, BitConverter.GetBytes(seq_no), _ipe);
            //_log.Debug(string.Format("Sending Ack with sequence: {0}", seqNum));
            _nonSeqQueue.Enqueue(ackPacket);
        }