Example #1
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            // Note that ByteToMessageDecoder handles input.Release calls for us.
            // In fact, we receive here a potentially surviving _internalBuffer of the base class
            // that is being built by its cumulator.

            // Output buffers that we create will be released by the next handler in the pipeline.
            while (input.ReadableBytes >= Frame.BlockSize)
            {
                switch (_state)
                {
                case FrameDecoderState.WaitingForHeader:
                {
                    ReadHeader(input);
                    _state = FrameDecoderState.WaitingForHeaderMac;
                    break;
                }

                case FrameDecoderState.WaitingForHeaderMac:
                {
                    AuthenticateHeader(input);
                    DecryptHeader();
                    ReadFrameSize();
                    AllocateFrameBuffer(context);     // it will be released by the next handler in the pipeline
                    _state = FrameDecoderState.WaitingForPayload;
                    break;
                }

                case FrameDecoderState.WaitingForPayload:
                {
                    ProcessOneBlock(input);
                    if (_remainingPayloadBlocks == 0)
                    {
                        _state = FrameDecoderState.WaitingForPayloadMac;
                    }
                    break;
                }

                case FrameDecoderState.WaitingForPayloadMac:
                {
                    AuthenticatePayload(input);
                    PassFrame(output);
                    _state = FrameDecoderState.WaitingForHeader;
                    break;
                }

                default:
                    throw new NotSupportedException($"{nameof(ZeroFrameDecoder)} does not support {_state} state.");
                }
            }
        }
Example #2
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            if (_state == FrameDecoderState.WaitingForHeader)
            {
                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decoding frame header {input.ReadableBytes}");
                }

                if (input.ReadableBytes == 0)
                {
                    _logger.Warn($"{context.Channel.RemoteAddress} sent an empty frame, disconnecting");
                    context.CloseAsync();
                    return;
                }

                if (input.ReadableBytes >= 32)
                {
                    input.ReadBytes(_headerBuffer);
                    if (_logger.IsTraceEnabled)
                    {
                        _logger.Trace($"Decoding encrypted frame header {new Hex(_headerBuffer)}");
                    }

                    _frameMacProcessor.CheckMac(_headerBuffer, 0, 16, true);
                    _frameCipher.Decrypt(_headerBuffer, 0, 16, _headerBuffer, 0);

                    _totalBodySize = _headerBuffer[0] & 0xFF;
                    _totalBodySize = (_totalBodySize << 8) + (_headerBuffer[1] & 0xFF);
                    _totalBodySize = (_totalBodySize << 8) + (_headerBuffer[2] & 0xFF);
                    _state         = FrameDecoderState.WaitingForPayload;

                    int paddingSize = 16 - _totalBodySize % 16;
                    if (paddingSize == 16)
                    {
                        paddingSize = 0;
                    }

                    if (_logger.IsTraceEnabled)
                    {
                        _logger.Trace($"Expecting a message {_totalBodySize} + {paddingSize} + 16");
                    }
                }
                else
                {
                    if (_logger.IsTraceEnabled)
                    {
                        _logger.Trace("Waiting for full 32 bytes of the header");
                    }

                    return;
                }
            }

            if (_state == FrameDecoderState.WaitingForPayload)
            {
                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decoding payload {input.ReadableBytes}");
                }

                int paddingSize = 16 - _totalBodySize % 16;
                if (paddingSize == 16)
                {
                    paddingSize = 0;
                }

                int    expectedSize = _totalBodySize + paddingSize + MacSize;
                byte[] buffer;
                if (input.ReadableBytes >= expectedSize)
                {
                    buffer = new byte[expectedSize];
                    input.ReadBytes(buffer);
                }
                else
                {
                    return;
                }

                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decoding encrypted payload {new Hex(buffer)}");
                }

                int frameSize = buffer.Length - MacSize;
                _frameMacProcessor.CheckMac(buffer, 0, frameSize, false);
                _frameCipher.Decrypt(buffer, 0, frameSize, buffer, 0);

                output.Add(Bytes.Concat(_headerBuffer, buffer));

                if (_logger.IsTraceEnabled)
                {
                    _logger.Trace($"Decrypted message {new Hex((byte[])output.Last())}");
                }

                _state = FrameDecoderState.WaitingForHeader;
            }
        }