Beispiel #1
0
        protected override void Encode(IChannelHandlerContext context, IByteBuffer input, IByteBuffer output)
        {
            while (input.IsReadable())
            {
                if (input.ReadableBytes % Frame.BlockSize != 0)
                {
                    throw new CorruptedFrameException($"Frame prepared for sending was in incorrect format: length was {input.ReadableBytes}");
                }

                FrameHeaderReader.FrameInfo frame = _headerReader.ReadFrameHeader(input);

                // 0 if the buffer has enough writable bytes, and its capacity is unchanged.
                // 1 if the buffer does not have enough bytes, and its capacity is unchanged.
                // 2 if the buffer has enough writable bytes, and its capacity has been increased.
                // 3 if the buffer does not have enough bytes, but its capacity has been increased to its maximum.
                int code = output.EnsureWritable(Frame.HeaderSize + Frame.MacSize + frame.PayloadSize + Frame.MacSize, true);

                WriteHeader(output);
                WriteHeaderMac(output);
                for (int i = 0; i < frame.PayloadSize / Frame.BlockSize; i++)
                {
                    WritePayloadBlock(input, output);
                }

                WritePayloadMac(output);
            }
        }
Beispiel #2
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            // Note that each input is a full frame header16|payload that are automatically released by the base class.
            // If the input is not a full and valid frame we can throw as this is an unexpected behaviour from the
            // decoder up the pipeline.

            // Moreover we will never receive more than a full packet in a single input so the input buffer
            // is expected to have no readable bytes after the merging operation.

            if (_logger.IsTrace)
            {
                _logger.Trace("Merging frames");
            }
            if (input.ReferenceCount != 1)
            {
                throw new IllegalReferenceCountException(input.ReferenceCount);
            }

            FrameHeaderReader.FrameInfo frame = _headerReader.ReadFrameHeader(input);
            if (frame.IsFirst)
            {
                ReadFirstChunk(context, input, frame);
            }
            else
            {
                ReadChunk(input, frame);
            }

            if (!_zeroPacket.Content.IsWritable())
            {
                input.SkipBytes(frame.Padding);
                output.Add(_zeroPacket);
                _zeroPacket = null;

                if (input.IsReadable())
                {
                    throw new CorruptedFrameException($"{nameof(ZeroFrameMerger)} received a corrupted frame - {input.ReadableBytes} longer than expected");
                }
            }
        }
Beispiel #3
0
        private void ReadFirstChunk(IChannelHandlerContext context, IByteBuffer input, FrameHeaderReader.FrameInfo frame)
        {
            byte        packetTypeRlp = input.ReadByte();
            IByteBuffer content;

            if (frame.IsChunked)
            {
                content = context.Allocator.Buffer(frame.TotalPacketSize - 1);
            }
            else
            {
                content = input.ReadSlice(frame.Size - 1);

                // Since we will call release in the next handler and we use a derived buffer here
                // we need to call Retain to prevent the buffer from being released twice
                // (once in the next handler and once in the base class).
                content.Retain();
            }

            _zeroPacket            = new ZeroPacket(content);
            _zeroPacket.PacketType = GetPacketType(packetTypeRlp);

            // If not chunked then we already used a slice of the input,
            // otherwise we need to read into the freshly allocated buffer.
            if (frame.IsChunked)
            {
                input.ReadBytes(_zeroPacket.Content, frame.Size - 1);
                // do not call Release since the input buffer is managed by
            }
        }
Beispiel #4
0
 private void ReadChunk(IByteBuffer input, FrameHeaderReader.FrameInfo frame)
 {
     input.ReadBytes(_zeroPacket.Content, frame.Size);
 }