Example #1
0
        /// <summary>
        /// Adds a new connection to the list
        /// </summary>
        /// <param name="conn">Connection to add</param>
        /// <returns>UDP_OK or error code</returns>
        public int NewConnection(Connection conn)
        {
            if (conn == null)
            {
                return(UdpConsts.UDP_FAIL);
            }

            m_Parent.DebugDump("Adding connection entry for " + conn.RemoteEP.ToString() + ".");

            lock (List.SyncRoot)
            {
                List.Add(conn);
            }

            //Send the event
            m_Parent.ConnectionStateChanged(conn, true, "");

            return(UdpConsts.UDP_OK);
        }
Example #2
0
        /// <summary>
        /// Processes a raw command packet that has been received and identified as being
        /// sent to this connection.
        /// </summary>
        /// <param name="command_packet">Command packet data</param>
        public void ProcessCommandPacket(string command_packet)
        {
            try
            {
                int pcmd = 0;

                Command new_cmd = new Command();
                new_cmd.OPCode      = command_packet.Substring(pcmd, 2);
                pcmd               += 2;
                new_cmd.SequenceNum = Util.BytesToUint(command_packet.Substring(pcmd, 4));
                pcmd               += 4;
                new_cmd.Flags       = (byte)command_packet[pcmd];
                pcmd++;
                new_cmd.NumFields = Util.BytesToShort(command_packet.Substring(pcmd, 2));
                pcmd += 2;
                new_cmd.FieldSizes = new short[new_cmd.NumFields];
                for (short i = 0; i < new_cmd.NumFields; i++)
                {
                    new_cmd.FieldSizes[i] = Util.BytesToShort(command_packet.Substring(pcmd, 2));
                    pcmd += 2;
                }

                //Is a reliable packet? Send an acknowledgement back
                if ((new_cmd.Flags & UdpConsts.FLAGS_RELIABLE) > 0)
                {
                    m_Parent.DebugDump("Got a reliable packet (" + new_cmd.SequenceNum.ToString() + ") - sent acknowledgement to sender.");
                    SendUnreliableCommand(0, UdpConsts.OPCODE_RELIABLEACK, new string[] { new_cmd.SequenceNum.ToString() });

                    //Repeat reliable packet - sender must not have received our acknowledgement
                    if (LastReceivedPacketR == new_cmd.SequenceNum)
                    {
                        m_Parent.DebugDump("Repeated reliable packet - not processed.");
                        return;
                    }

                    //Update last received reliable command number
                    LastReceivedPacketR = new_cmd.SequenceNum;
                }
                else
                {
                    LastReceivedPacket = new_cmd.SequenceNum; //Update unreliable command number

                    if ((new_cmd.Flags & UdpConsts.FLAGS_SEQUENCED) > 0)
                    {
                        //If this sequenced packet has arrived too late (a newer one got there first) then don't process it
                        if (LastReceivedPacketSeq > new_cmd.SequenceNum)
                        {
                            m_Parent.DebugDump("Unreliable sequenced packet arrived out of order - ignored.");
                            return;
                        }

                        //Update the last sequenced packet number if we should
                        LastReceivedPacketSeq = new_cmd.SequenceNum;
                    }
                }

                //Encryption check
                if ((new_cmd.Flags & UdpConsts.FLAGS_ENCRYPTED) > 0)
                {
                    if (EncryptionKey != "")
                    {
                        if (Util.XORCrypt(command_packet.Substring(pcmd, 2), EncryptionKey) != UdpConsts.ENCRYPT_CHECK_STRING)
                        {
                            //!!BAD ENCRYPTION KEY
                            m_Parent.DebugDump("Received an encrypted packet but the stored encryption key failed to decrypt it!");
                            return;
                        }
                    }
                }
                pcmd += 2;

                //Populate the AllFields property of the command
                new_cmd.AllFields = command_packet.Substring(pcmd);

                if ((new_cmd.Flags & UdpConsts.FLAGS_RELIABLE) > 0)
                {
                    //Is this reliable packet a compound piece?
                    if ((new_cmd.Flags & UdpConsts.FLAGS_COMPOUNDPIECE) > 0)
                    {
                        //Assume this is the first piece of the split command
                        if (CompoundCommand == null)
                        {
                            m_Parent.DebugDump("Got first part of a compound command, stored.");
                            CompoundCommand            = new Command();
                            CompoundCommand.AllFields  = new_cmd.AllFields;
                            CompoundCommand.FieldSizes = new_cmd.FieldSizes;
                            CompoundCommand.Flags      = new_cmd.Flags;

                            //Remove the compound piece flag (will be treated as a single packet)
                            CompoundCommand.Flags &= (byte)(~UdpConsts.FLAGS_COMPOUNDPIECE);

                            CompoundCommand.NumFields   = new_cmd.NumFields;
                            CompoundCommand.SequenceNum = new_cmd.SequenceNum;
                            CompoundCommand.OPCode      = new_cmd.OPCode;
                            return;
                        }
                        else
                        {
                            //Additional pieces have FLAGS_COMPOUNDPIECE set also....

                            m_Parent.DebugDump("Got an additional compound piece.");
                            //Is not the first nor last part so just addon the fields
                            CompoundCommand.AllFields += new_cmd.AllFields;
                            return;
                        }
                    }

                    //The last compound piece has FLAGS_COMPOUNDEND set.
                    if ((new_cmd.Flags & UdpConsts.FLAGS_COMPOUNDEND) > 0)
                    {
                        m_Parent.DebugDump("Got last compound piece - sending to command processing.");

                        //Add the fields on
                        CompoundCommand.AllFields += new_cmd.AllFields;

                        //Swap the incomplete part with the whole command
                        new_cmd         = CompoundCommand;
                        CompoundCommand = null;
                    }
                }

                new_cmd.Initialize();

                //If the packet is encrypted decrypt the fields now...
                if ((new_cmd.Flags & UdpConsts.FLAGS_ENCRYPTED) > 0)
                {
                    new_cmd.AllFields = "";
                    //Decrypt the fields
                    for (int i = 0; i < new_cmd.NumFields; i++)
                    {
                        new_cmd.Fields[i] = Util.XORCrypt(new_cmd.Fields[i], EncryptionKey);

                        //Rebuild the allfields property with the decrypted field data
                        new_cmd.AllFields += new_cmd.Fields[i];
                    }
                }

                //Send to command processing
                ProcessCompletedCommand(new_cmd);
            }
            catch
            {
                m_Parent.DebugDump("Exception whilst parsing input from " + RemoteEP.ToString() + " as command, probably not a command. Ignoring.");
            }
        }