Esempio n. 1
0
        public void SendPacket(int command, ByteBuffer payload)
        {
            ByteBuffer buffer = ByteBuffer.Allocate(1 + 2 + payload.Remaining);

            /* Set IV. */
            this.session.ShannonSend.nonce(IntUtils.ToBytes(this.session.KeySendIv));

            /* Build packet. */
            buffer.Put((byte)command);
            buffer.PutShort((short)payload.Remaining);
            buffer.Put(payload.ToArray());

            byte[] bytes = buffer.ToArray();
            byte[] mac   = new byte[4];

            /* Encrypt packet and get MAC. */
            this.session.ShannonSend.encrypt(bytes);
            this.session.ShannonSend.finish(mac);

            buffer = ByteBuffer.Allocate(buffer.Position + 4);
            buffer.Put(bytes);
            buffer.Put(mac);
            buffer.Flip();

            /* Send encrypted packet. */
            this.Send(buffer);

            /* Increment IV. */
            this.session.KeySendIv++;
        }
Esempio n. 2
0
        protected virtual void OnReceivePacketHeaderReceived(IAsyncResult asyn)
        {
            byte[] header = (byte[])asyn.AsyncState;
            int    command, payloadLength, macLength = 4;

            // TODO: Find a good way to implement detection of closed socket here,
            // so that the function doesn't extrapolate incorrect data from null data.

            /* Set IV. */
            this.session.ShannonRecv.nonce(IntUtils.ToBytes(this.session.KeyRecvIv));

            /* Decrypt header. */
            this.session.ShannonRecv.decrypt(header);

            /* Get command and payload length from header. */
            ByteBuffer headerBuffer = ByteBuffer.Wrap(header);

            command       = headerBuffer.Get() & 0xff;
            payloadLength = headerBuffer.GetShort() & 0xffff;

            /* Allocate buffer. Account for MAC. */
            byte[] bytes = new byte[payloadLength + macLength];
            //ByteBuffer buffer = ByteBuffer.Wrap(bytes);

            /* Limit buffer to payload length, so we can read the payload. */
            //buffer.Limit = payloadLength;

            try{
                this.Receive(bytes, 0, payloadLength);
                ////for(int n = payloadLength, r; n > 0 && (r = this.channel.Client.Receive(buffer)) > 0; n -= r);
                //int n = 0;
                //int r = -1;
                //while ((n < payloadLength) && (r != 0))
                //{
                //    r = this.client.Client.Receive(bytes, n, payloadLength - n, SocketFlags.None);
                //    n += r;
                //}
            }
            catch (IOException e)
            {
                throw new ProtocolException("Failed to read payload!", e);
            }

            /* Extend it again to payload and mac length. */
            //buffer.Limit = payloadLength + macLength;

            try
            {
                this.Receive(bytes, payloadLength, macLength);
                ////for(int n = macLength, r; n > 0 && (r = this.channel.Read(buffer)) > 0; n -= r);
                //int n = payloadLength;
                //int r = -1;
                //while ((n < bytes.Length) && (r != 0))
                //{
                //    r = this.Receive(bytes, n, bytes.Length - n);
                //    n += r;
                //}
            }
            catch (IOException e)
            {
                throw new ProtocolException("Failed to read MAC!", e);
            }

            /* Decrypt payload. */
            this.session.ShannonRecv.decrypt(bytes);

            /*Allocate buffer*/
            ByteBuffer buffer = ByteBuffer.Wrap(bytes);

            /* Get payload bytes from buffer (throw away MAC). */
            byte[] payload = new byte[payloadLength];

            buffer.Flip();
            buffer.Get(payload);

            /* Increment IV. */
            this.session.KeyRecvIv++;

            /* Fire events. */
            foreach (ICommandListener listener in this.listeners)
            {
                listener.CommandReceived(command, payload);
            }
            ReceivePacket();
        }