Exemple #1
0
        /// <summary>
        /// Append a CRC checksum and encrypt data in place using XTEA
        /// </summary>
        internal void EncryptSymmetric(NetBuffer buffer)
        {
            //string plain = Convert.ToBase64String(buffer.Data, 0, buffer.LengthBytes);
            int bufferLen = buffer.LengthBytes;

            // calculate number of pad bits
            int dataBits   = buffer.LengthBits;
            int bitsNeeded = dataBits + 24;             // 24 extra for crc and num-pad-bits
            int totalBits  = bitsNeeded + (64 - (bitsNeeded % 64));
            int padBits    = totalBits - bitsNeeded;

            // write to ensure zeroes in buffer (crc and num-pad-bits space)
            buffer.Write((uint)0, 24);

            if (padBits > 0)
            {
                buffer.Write((ulong)0, padBits);
            }
            int writePadBitsPosition = buffer.LengthBits - 8;

            // write crc
            ushort crc = Checksum.Adler16(buffer.Data, 0, buffer.LengthBytes);

            buffer.ResetWritePointer(dataBits);
            buffer.Write(crc);

            // write num-pad-bits in LAST byte
            buffer.ResetWritePointer(writePadBitsPosition);
            buffer.Write((byte)padBits);

            // encrypt in place
            int ptr = 0;

            bufferLen = buffer.LengthBytes;
            while (ptr < bufferLen)
            {
                m_xtea.EncryptBlock(buffer.Data, ptr, buffer.Data, ptr);
                ptr += 8;
            }

            return;
        }
Exemple #2
0
 // unsequenced packets only, returns number of bytes sent
 internal int SendSingleMessageAtOnce(NetMessage msg, NetConnection connection, IPEndPoint endpoint)
 {
     m_sendBuffer.ResetWritePointer();
     msg.Encode(connection, m_sendBuffer);
     if (connection != null)
     {
         return(ExecuteSend(m_sendBuffer, connection, connection.RemoteEndpoint));
     }
     else
     {
         return(ExecuteSend(m_sendBuffer, null, endpoint));
     }
 }
Exemple #3
0
        /// <summary>
        /// Decrypt using XTEA algo and verify CRC
        /// </summary>
        /// <returns>true for success, false for failure</returns>
        internal bool DecryptSymmetric(NetBuffer buffer)
        {
            int bufLen = buffer.LengthBytes;

            if (bufLen % 8 != 0)
            {
                if (NetBase.CurrentContext != null && NetBase.CurrentContext.Log != null)
                {
                    NetBase.CurrentContext.Log.Info("Bad buffer size in DecryptSymmetricInPlace()");
                }
                return(false);
            }

            //NetBase.CurrentContext.Log.Debug.Debug("Decrypting using key: " + Convert.ToBase64String(m_xtea.Key));

            // decrypt
            for (int i = 0; i < bufLen; i += 8)
            {
                m_xtea.DecryptBlock(buffer.Data, i, buffer.Data, i);
            }

            int numPadBits = buffer.Data[bufLen - 1];

            buffer.Data[bufLen - 1] = 0;                     // zap for correct crc calculation
            int dataBits = (bufLen * 8) - (24 + numPadBits); // include pad and crc

            buffer.ResetReadPointer(dataBits);
            ushort statedCrc = buffer.ReadUInt16();

            // zap crc to be able to compare
            buffer.ResetWritePointer(dataBits);
            buffer.Write((ushort)0);

            ushort dataCrc = Checksum.Adler16(buffer.Data, 0, bufLen);

            //NetBase.CurrentContext.Log.Debug("Plain (len " + bufLen + "): " + Convert.ToBase64String(buffer.Data, 0, bufLen) + " Stated CRC: " + statedCrc + " Calc: " + realCrc);
            if (statedCrc != dataCrc)
            {
                if (NetBase.CurrentContext != null && NetBase.CurrentContext.Log != null)
                {
                    NetBase.CurrentContext.Log.Warning("CRC failure; expected " + dataCrc + " found " + statedCrc + " dropping packet!");
                }
                return(false);
            }

            // clean up
            buffer.LengthBits = dataBits;
            buffer.ResetReadPointer();

            return(true);
        }
Exemple #4
0
        internal void SendUnsentMessages(bool forceAcks, double frameLength)
        {
            if (m_unsentMessages.Count < 1 && !forceAcks)
            {
                if (m_status == NetConnectionStatus.Disconnecting)
                {
                    SetStatus(NetConnectionStatus.Disconnected, m_pendingDisconnectedReason);
                }
                return;                 // nothing to send
            }

            //if (m_unsentMessages.Count < 1 && forceAcks)
            //	m_parent.Log.Debug("FORCING EXPLICIT ACK");

            float sendBytesAllowed = (float)frameLength * (float)Configuration.ThrottleBytesPerSecond;

            if (m_throttleDebt > sendBytesAllowed)
            {
                // NetBase.CurrentContext.Log.Debug("Working off debt: " + m_throttleDebt + " bytes by " + sendBytesAllowed");
                m_throttleDebt -= sendBytesAllowed;
                return;
            }
            else if (m_throttleDebt > 0)
            {
                sendBytesAllowed -= m_throttleDebt;
                m_throttleDebt    = 0;
            }

            NetBuffer sendBuffer = m_parent.m_sendBuffer;

            sendBuffer.ResetWritePointer();

            int mtu = m_parent.Configuration.MaximumTransmissionUnit;

            float now = (float)NetTime.Now;

            int        pktMsgAdded = 0;
            int        ackMsgAdded = 0;
            int        usrMsgAdded = 0;
            NetMessage msg;

            // TODO: make ack bitfield if possible

            while (m_unsentAcknowledges.Count > 0 && sendBytesAllowed > 0)
            {
                msg = m_unsentAcknowledges.Dequeue();
                m_reusedAckMessage.SequenceChannel = msg.SequenceChannel;
                m_reusedAckMessage.SequenceNumber  = msg.SequenceNumber;

                if (sendBuffer.LengthBytes + 3 > mtu)
                {
                    // send buffer
                    m_parent.ExecuteSend(sendBuffer, this, m_remoteEndpoint);
                    sendBytesAllowed -= sendBuffer.LengthBytes;

                    Statistics.PacketsSent++;
                    Statistics.MessagesSent    += pktMsgAdded;
                    Statistics.AckMessagesSent += ackMsgAdded;
                    Statistics.BytesSent       += sendBuffer.LengthBytes;

                    sendBuffer.ResetWritePointer();
                    pktMsgAdded = 0;
                    ackMsgAdded = 0;
                }

                //m_parent.Log.Debug("Sending ack " + msg.SequenceChannel + "|" + msg.SequenceNumber);
                m_reusedAckMessage.Encode(this, sendBuffer);
                pktMsgAdded++;
                ackMsgAdded++;
            }

            // no unsent acks left!
            m_forceExplicitAckTime = 0.0;

            while (m_unsentMessages.Count > 0 && sendBytesAllowed > 0)
            {
                msg = m_unsentMessages.Dequeue();

                // make pessimistic estimate of message length
                int estMsgLen = msg.EstimateEncodedLength();

                if (sendBuffer.LengthBytes + estMsgLen > mtu)
                {
                    if (pktMsgAdded < 1)
                    {
                        throw new NetException("Message too large to send: " + estMsgLen + " bytes: " + msg);
                    }

                    // send buffer
                    m_parent.ExecuteSend(sendBuffer, this, m_remoteEndpoint);
                    sendBytesAllowed -= sendBuffer.LengthBytes;

                    Statistics.PacketsSent++;
                    Statistics.MessagesSent     += pktMsgAdded;
                    Statistics.UserMessagesSent += usrMsgAdded;
                    Statistics.AckMessagesSent  += ackMsgAdded;
                    Statistics.BytesSent        += sendBuffer.LengthBytes;

                    sendBuffer.ResetWritePointer();
                    pktMsgAdded = 0;
                    ackMsgAdded = 0;
                }

                msg.Encode(this, sendBuffer);
                if (msg.m_type == NetMessageType.User || msg.m_type == NetMessageType.UserFragmented)
                {
                    usrMsgAdded++;
                }
                pktMsgAdded++;

                // store until acknowledged
                if (msg.SequenceChannel >= NetChannel.ReliableUnordered)
                {
                    float nextResend = now + (msg.m_numResends < 1 ? Configuration.ResendFirstUnacknowledgedDelay : Configuration.ResendSubsequentUnacknowledgedDelay);
                    msg.m_nextResendTime = nextResend;
                    //m_parent.Log.Debug("Storing " + msg.SequenceChannel + "|" + msg.SequenceNumber + " @ " + now + " first resend: " + nextResend);
                    int seqChan = (int)msg.SequenceChannel;
                    if (m_savedReliableMessages[seqChan] == null)
                    {
                        m_savedReliableMessages[seqChan] = new List <NetMessage>();
                    }
                    m_savedReliableMessages[seqChan].Add(msg);
                }
            }

            if (pktMsgAdded > 0)
            {
                m_parent.ExecuteSend(sendBuffer, this, m_remoteEndpoint);
                sendBytesAllowed -= sendBuffer.LengthBytes;
                Statistics.PacketsSent++;
                Statistics.MessagesSent     += pktMsgAdded;
                Statistics.UserMessagesSent += usrMsgAdded;
                Statistics.AckMessagesSent  += ackMsgAdded;
                Statistics.BytesSent        += sendBuffer.LengthBytes;
            }

            Debug.Assert(m_throttleDebt == 0);
            if (sendBytesAllowed < 0)
            {
                m_throttleDebt = -sendBytesAllowed;
            }
        }
		/// <summary> 
		/// Decrypt using XTEA algo and verify CRC
		/// </summary>
		/// <returns>true for success, false for failure</returns>
		internal bool DecryptSymmetric(NetBuffer buffer)
		{
			int bufLen = buffer.LengthBytes;

			if (bufLen % 8 != 0)
			{
				if (NetBase.CurrentContext != null && NetBase.CurrentContext.Log != null)
					NetBase.CurrentContext.Log.Info("Bad buffer size in DecryptSymmetricInPlace()");
				return false;
			}

			//NetBase.CurrentContext.Log.Debug.Debug("Decrypting using key: " + Convert.ToBase64String(m_xtea.Key));

			// decrypt
			for (int i = 0; i < bufLen; i += 8)
				m_xtea.DecryptBlock(buffer.Data, i, buffer.Data, i);

			int numPadBits = buffer.Data[bufLen - 1];
			buffer.Data[bufLen - 1] = 0; // zap for correct crc calculation
			int dataBits = (bufLen * 8) - (24 + numPadBits); // include pad and crc

			buffer.ResetReadPointer(dataBits);
			ushort statedCrc = buffer.ReadUInt16();

			// zap crc to be able to compare
			buffer.ResetWritePointer(dataBits);
			buffer.Write((ushort)0);

			ushort dataCrc = Checksum.Adler16(buffer.Data, 0, bufLen);

			//NetBase.CurrentContext.Log.Debug("Plain (len " + bufLen + "): " + Convert.ToBase64String(buffer.Data, 0, bufLen) + " Stated CRC: " + statedCrc + " Calc: " + realCrc);
			if (statedCrc != dataCrc)
			{
				if (NetBase.CurrentContext != null && NetBase.CurrentContext.Log != null)
					NetBase.CurrentContext.Log.Warning("CRC failure; expected " + dataCrc + " found " + statedCrc + " dropping packet!");
				return false;
			}

			// clean up
			buffer.LengthBits = dataBits;
			buffer.ResetReadPointer();

			return true;
		}
		/// <summary>
		/// Append a CRC checksum and encrypt data in place using XTEA
		/// </summary>
		internal void EncryptSymmetric(NetBuffer buffer)
		{
			//string plain = Convert.ToBase64String(buffer.Data, 0, buffer.LengthBytes);
			int bufferLen = buffer.LengthBytes;

			// calculate number of pad bits
			int dataBits = buffer.LengthBits;
			int bitsNeeded = dataBits + 24; // 24 extra for crc and num-pad-bits
			int totalBits = bitsNeeded + (64 - (bitsNeeded % 64));
			int padBits = totalBits - bitsNeeded;

			// write to ensure zeroes in buffer (crc and num-pad-bits space)
			buffer.Write((uint)0, 24);

			if (padBits > 0)
				buffer.Write((ulong)0, padBits);
			int writePadBitsPosition = buffer.LengthBits - 8;

			// write crc
			ushort crc = Checksum.Adler16(buffer.Data, 0, buffer.LengthBytes);
			buffer.ResetWritePointer(dataBits);
			buffer.Write(crc);

			// write num-pad-bits in LAST byte
			buffer.ResetWritePointer(writePadBitsPosition);
			buffer.Write((byte)padBits);

			// encrypt in place
			int ptr = 0;
			bufferLen = buffer.LengthBytes;
			while (ptr < bufferLen)
			{
				m_xtea.EncryptBlock(buffer.Data, ptr, buffer.Data, ptr);
				ptr += 8;
			}

			return;
		}