Exemplo n.º 1
0
        public static string DecodeString(IByteBuffer src, int readerIndex, int len, Encoding encoding)
        {
            if (len == 0)
            {
                return(string.Empty);
            }

            if (src.IoBufferCount == 1)
            {
                ArraySegment <byte> ioBuf = src.GetIoBuffer(readerIndex, len);
                return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count));
            }
            else
            {
                int         maxLength = encoding.GetMaxCharCount(len);
                IByteBuffer buffer    = src.Allocator.HeapBuffer(maxLength);
                try
                {
                    buffer.WriteBytes(src, readerIndex, len);
                    ArraySegment <byte> ioBuf = src.GetIoBuffer();
                    return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count));
                }
                finally
                {
                    // Release the temporary buffer again.
                    buffer.Release();
                }
            }
        }
Exemplo n.º 2
0
        protected override void ScheduleMessageWrite(object message)
        {
            var envelope = message as IAddressedEnvelope <IByteBuffer>;

            if (envelope == null)
            {
                throw new InvalidOperationException(
                          $"Unexpected type: {message.GetType().FullName}, expecting DatagramPacket or IAddressedEnvelope.");
            }

            IByteBuffer data   = envelope.Content;
            int         length = data.ReadableBytes;

            if (length == 0)
            {
                return;
            }

            SocketChannelAsyncOperation operation = this.PrepareWriteOperation(data.GetIoBuffer(data.ReaderIndex, length));

            operation.RemoteEndPoint = envelope.Recipient;
            this.SetState(StateFlags.WriteScheduled);

            bool pending = this.Socket.SendToAsync(operation);

            if (!pending)
            {
                ((ISocketChannelUnsafe)this.Unsafe).FinishWrite(operation);
            }
        }
        protected override void Encode(IChannelHandlerContext context, IMessageLite message, List <object> output)
        {
            Contract.Requires(context != null);
            Contract.Requires(message != null);
            Contract.Requires(output != null);

            IByteBuffer buffer = null;

            try
            {
                int size = message.SerializedSize;
                if (size <= 0)
                {
                    return;
                }

                buffer = context.Allocator.Buffer(size);
                ArraySegment <byte> data   = buffer.GetIoBuffer(buffer.WriterIndex, size);
                CodedOutputStream   stream = CodedOutputStream.CreateInstance(data.Array, data.Offset, size);
                message.WriteTo(stream);
                buffer.SetWriterIndex(buffer.WriterIndex + size);

                output.Add(buffer);
                buffer = null;
            }
            catch (Exception exception)
            {
                throw new CodecException(exception);
            }
            finally
            {
                buffer?.Release();
            }
        }
Exemplo n.º 4
0
        protected override void ChannelRead0(IChannelHandlerContext context, IByteBuffer message)
        {
            int msgType = message.GetInt(4);
            int svrID   = msgType / 10000;
            int msgLen  = message.GetInt(0);
            var msgData = message.GetIoBuffer(8, msgLen - 8);

            Log.Info("msg : {0}", msgType);

            IGateMessage gate = null;

            if (svrID == 1)
            {
                gate = clusterClient.GetGrain <IGateMaster>(0);
            }

            if (svrID == 3)
            {
                gate = clusterClient.GetGrain <IGateBattle>(0);
            }

            if (gate != null)
            {
                Task.Run(async() =>
                {
                    var response = await gate.SendMessage(msgType, msgData.ToArray());
                    if (response != null)
                    {
                        //约定response msg id = req + 1
                        await Send(msgType + 1, response);
                    }
                });
            }
        }
Exemplo n.º 5
0
        public void TestNioBuffersExpand2()
        {
            TestChannel channel = new TestChannel();

            ChannelOutboundBuffer buffer = new ChannelOutboundBuffer(channel);

            CompositeByteBuffer comp = Unpooled.CompositeBuffer(256);
            IByteBuffer         buf  = Unpooled.DirectBuffer().WriteBytes(Encoding.ASCII.GetBytes("buf1"));

            for (int i = 0; i < 65; i++)
            {
                comp.AddComponent(true, buf.Copy());
            }
            buffer.AddMessage(comp, comp.ReadableBytes, channel.VoidPromise());

            Assert.Equal(0, buffer.NioBufferCount); // Should still be 0 as not flushed yet
            buffer.AddFlush();
            var buffers = buffer.GetSharedBufferList();

            Assert.Equal(65, buffer.NioBufferCount);
            for (int i = 0; i < buffer.NioBufferCount; i++)
            {
                if (i < 65)
                {
                    Assert.Equal(buffers[i], buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes));
                }
                else
                {
                    Assert.Null(buffers[i].Array);
                }
            }
            Release(buffer);
            buf.Release();
        }
        protected override bool DoWriteMessage(object msg, ChannelOutboundBuffer input)
        {
            EndPoint    remoteAddress = null;
            IByteBuffer data          = null;

            var envelope = msg as IAddressedEnvelope <IByteBuffer>;

            if (envelope != null)
            {
                remoteAddress = envelope.Recipient;
                data          = envelope.Content;
            }
            else if (msg is IByteBuffer)
            {
                data          = (IByteBuffer)msg;
                remoteAddress = this.RemoteAddressInternal;
            }

            if (data == null || remoteAddress == null)
            {
                return(false);
            }

            int length = data.ReadableBytes;

            if (length == 0)
            {
                return(true);
            }

            ArraySegment <byte> bytes = data.GetIoBuffer(data.ReaderIndex, length);
            int writtenBytes          = this.Socket.SendTo(bytes.Array, bytes.Offset, bytes.Count, SocketFlags.None, remoteAddress);

            return(writtenBytes > 0);
        }
Exemplo n.º 7
0
        public void TestNioBuffersMaxCount()
        {
            TestChannel channel = new TestChannel();

            ChannelOutboundBuffer buffer = new ChannelOutboundBuffer(channel);

            CompositeByteBuffer comp = Unpooled.CompositeBuffer(256);
            IByteBuffer         buf  = Unpooled.DirectBuffer().WriteBytes(Encoding.ASCII.GetBytes("buf1"));

            for (int i = 0; i < 65; i++)
            {
                comp.AddComponent(true, buf.Copy());
            }
            Assert.Equal(65, comp.IoBufferCount);
            buffer.AddMessage(comp, comp.ReadableBytes, channel.VoidPromise());
            Assert.Equal(0, buffer.NioBufferCount); // Should still be 0 as not flushed yet
            buffer.AddFlush();
            int maxCount = 10;                      // less than comp.nioBufferCount()
            var buffers  = buffer.GetSharedBufferList(maxCount, int.MaxValue);

            Assert.True(buffer.NioBufferCount <= maxCount); // Should not be greater than maxCount
            for (int i = 0; i < buffer.NioBufferCount; i++)
            {
                Assert.Equal(buffers[i], buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes));
            }
            Release(buffer);
            buf.Release();
        }
Exemplo n.º 8
0
        protected override void Encode(IChannelHandlerContext context, IMessage message, IByteBuffer output)
        {
            int iCode = PtlCodeHelper.Instance.GetCode(message.GetType());

            if (iCode <= 0)
            {
                return;
            }

            int bodyLength = message.CalculateSize();

            if (bodyLength == 0)
            {
                return;
            }

            int headerLength = sizeof(int) * 2;
            int totalLength  = bodyLength + headerLength;

            output.EnsureWritable(totalLength);
            output.WriteInt(totalLength); //长度
            output.WriteInt(iCode);       //协议号

            var buffer = output.GetIoBuffer(output.WriterIndex, bodyLength);

            using (MemoryStream memStream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count))
            {
                message.WriteTo(memStream);
                output.SetWriterIndex(output.WriterIndex + (int)memStream.Length);
            }
        }
Exemplo n.º 9
0
 public static ArraySegment <byte> GetIoBuffer(this IByteBuffer buf)
 {
     if (buf is IByteBuffer2 buffer2)
     {
         return(buffer2.GetIoBuffer());
     }
     return(buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes));
 }
Exemplo n.º 10
0
        protected override void ScheduleSocketRead()
        {
            try
            {
                SocketChannelAsyncOperation operation = this.ReadOperation;
                operation.RemoteEndPoint = this.anyRemoteEndPoint;

                IRecvByteBufAllocatorHandle handle = this.Unsafe.RecvBufAllocHandle;
                IByteBuffer buffer = handle.Allocate(this.config.Allocator);
                handle.AttemptedBytesRead = buffer.WritableBytes;
                operation.UserToken       = buffer;

                ArraySegment <byte> bytes = buffer.GetIoBuffer(0, buffer.WritableBytes);
                operation.SetBuffer(bytes.Array, bytes.Offset, bytes.Count);

                bool pending;
#if NETSTANDARD1_3
                pending = this.Socket.ReceiveFromAsync(operation);
#else
                if (this.isConnected)
                {
                    if (ExecutionContext.IsFlowSuppressed())
                    {
                        pending = this.Socket.ReceiveAsync(operation);
                    }
                    else
                    {
                        using (ExecutionContext.SuppressFlow())
                        {
                            pending = this.Socket.ReceiveAsync(operation);
                        }
                    }
                }
                else
                {
                    if (ExecutionContext.IsFlowSuppressed())
                    {
                        pending = this.Socket.ReceiveFromAsync(operation);
                    }
                    else
                    {
                        using (ExecutionContext.SuppressFlow())
                        {
                            pending = this.Socket.ReceiveFromAsync(operation);
                        }
                    }
                }
#endif
                if (!pending)
                {
                    this.EventLoop.Execute(ReceiveFromCompletedSyncCallback, this.Unsafe, operation);
                }
            }
            catch (Exception e)
            {
                this.Pipeline.FireExceptionCaught(e);
            }
        }
Exemplo n.º 11
0
        public static bool IsText(IByteBuffer buf, int index, int length, Encoding encoding)
        {
            if (buf is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.buf);
            }
            if (encoding is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.encoding);
            }

            int maxIndex = buf.ReaderIndex + buf.ReadableBytes;

            if (index < 0 || length < 0 || index > maxIndex - length)
            {
                ThrowHelper.ThrowIndexOutOfRangeException_IsText(index, length);
            }
            switch (encoding.CodePage)
            {
            case TextEncodings.UTF8CodePage:
                return(IsUtf8(buf, index, length));

            case TextEncodings.ASCIICodePage:
                return(IsAscii(buf, index, length));

            default:
                try
                {
                    if (buf.IsSingleIoBuffer)
                    {
                        ArraySegment <byte> segment = buf.GetIoBuffer();
                        _ = encoding.GetChars(segment.Array, segment.Offset, segment.Count);
                    }
                    else
                    {
                        IByteBuffer heapBuffer = buf.Allocator.HeapBuffer(length);
                        try
                        {
                            _ = heapBuffer.WriteBytes(buf, index, length);
                            ArraySegment <byte> segment = heapBuffer.GetIoBuffer();
                            _ = encoding.GetChars(segment.Array, segment.Offset, segment.Count);
                        }
                        finally
                        {
                            _ = heapBuffer.Release();
                        }
                    }
                    return(true);
                }
                catch
                {
                    return(false);
                }
            }
        }
        public static byte[] ToArray(this IByteBuffer buffer)
        {
            if (!buffer.IsReadable())
            {
                return(ArrayExtensions.ZeroBytes);
            }
            var segment = buffer.GetIoBuffer();
            var result  = new byte[segment.Count];

            Array.Copy(segment.Array, segment.Offset, result, 0, segment.Count);
            return(result);
        }
Exemplo n.º 13
0
        public static bool IsText(IByteBuffer buf, int index, int length, Encoding encoding)
        {
            Contract.Requires(buf != null);
            Contract.Requires(encoding != null);

            int maxIndex = buf.ReaderIndex + buf.ReadableBytes;

            if (index < 0 || length < 0 || index > maxIndex - length)
            {
                throw new IndexOutOfRangeException($"index: {index}length: {length}");
            }
            if (ReferenceEquals(Encoding.UTF8, encoding))
            {
                return(IsUtf8(buf, index, length));
            }
            else if (ReferenceEquals(Encoding.ASCII, encoding))
            {
                return(IsAscii(buf, index, length));
            }
            else
            {
                try
                {
                    if (buf.IoBufferCount == 1)
                    {
                        ArraySegment <byte> segment = buf.GetIoBuffer();
                        encoding.GetChars(segment.Array, segment.Offset, segment.Count);
                    }
                    else
                    {
                        IByteBuffer heapBuffer = buf.Allocator.HeapBuffer(length);
                        try
                        {
                            heapBuffer.WriteBytes(buf, index, length);
                            ArraySegment <byte> segment = heapBuffer.GetIoBuffer();
                            encoding.GetChars(segment.Array, segment.Offset, segment.Count);
                        }
                        finally
                        {
                            heapBuffer.Release();
                        }
                    }
                    return(true);
                }
                catch
                {
                    return(false);
                }
            }
        }
Exemplo n.º 14
0
        public static string DecodeString(IByteBuffer src, int readerIndex, int len, Encoding encoding)
        {
            if (0u >= (uint)len)
            {
                return(string.Empty);
            }

#if NET451
            if (src.IsSingleIoBuffer)
            {
                ArraySegment <byte> ioBuf = src.GetIoBuffer(readerIndex, len);
                return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count));
            }
            else
            {
                int         maxLength = encoding.GetMaxCharCount(len);
                IByteBuffer buffer    = src.Allocator.HeapBuffer(maxLength);
                try
                {
                    buffer.WriteBytes(src, readerIndex, len);
                    ArraySegment <byte> ioBuf = buffer.GetIoBuffer();
                    return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count));
                }
                finally
                {
                    // Release the temporary buffer again.
                    buffer.Release();
                }
            }
#else
            var source = src.GetReadableSpan(readerIndex, len);
#if NETCOREAPP || NETSTANDARD_2_0_GREATER
            return(encoding.GetString(source));
#else
            unsafe
            {
                fixed(byte *bytes = &MemoryMarshal.GetReference(source))
                {
                    return(encoding.GetString(bytes, source.Length));
                }
            }
#endif
#endif
        }
Exemplo n.º 15
0
        public override ArraySegment <byte>[] GetIoBuffers(int index, int length)
        {
            this.CheckIndex(index, length);
            if (length == 0)
            {
                return(new[] { EmptyNioBuffer });
            }

            var buffers = new List <ArraySegment <byte> >(this.components.Count);
            int i       = this.ToComponentIndex(index);

            while (length > 0)
            {
                ComponentEntry c           = this.components[i];
                IByteBuffer    s           = c.Buffer;
                int            adjustment  = c.Offset;
                int            localLength = Math.Min(length, s.Capacity - (index - adjustment));
                switch (s.IoBufferCount)
                {
                case 0:
                    throw new NotSupportedException();

                case 1:
                    buffers.Add(s.GetIoBuffer(index - adjustment, localLength));
                    break;

                default:
                    buffers.AddRange(s.GetIoBuffers(index - adjustment, localLength));
                    break;
                }

                index  += localLength;
                length -= localLength;
                i++;
            }

            return(buffers.ToArray());
        }
Exemplo n.º 16
0
        public void TestNioBuffersExpand()
        {
            TestChannel channel = new TestChannel();

            ChannelOutboundBuffer buffer = new ChannelOutboundBuffer(channel);

            IByteBuffer buf = Unpooled.DirectBuffer().WriteBytes(Encoding.ASCII.GetBytes("buf1"));

            for (int i = 0; i < 64; i++)
            {
                buffer.AddMessage(buf.Copy(), buf.ReadableBytes, channel.VoidPromise());
            }
            Assert.Equal(0, buffer.NioBufferCount); // Should still be 0 as not flushed yet
            buffer.AddFlush();
            var buffers = buffer.GetSharedBufferList();

            Assert.Equal(64, buffer.NioBufferCount);
            for (int i = 0; i < buffer.NioBufferCount; i++)
            {
                Assert.Equal(buffers[i], buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes));
            }
            Release(buffer);
            buf.Release();
        }
Exemplo n.º 17
0
        /// <summary>Unwraps inbound SSL records.</summary>
        private void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length)
        {
            bool pending = false;

            IByteBuffer outputBuffer = null;

            try
            {
#if NETCOREAPP || NETSTANDARD_2_0_GREATER
                ReadOnlyMemory <byte> inputIoBuffer = packet.GetReadableMemory(offset, length);
                _mediationStream.SetSource(inputIoBuffer, ctx.Allocator);
#else
                ArraySegment <byte> inputIoBuffer = packet.GetIoBuffer(offset, length);
                _mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset, ctx.Allocator);
#endif
                if (!EnsureAuthenticationCompleted(ctx))
                {
                    _mediationStream.ExpandSource(length);
                    return;
                }

                _mediationStream.ExpandSource(length);

                var currentReadFuture = _pendingSslStreamReadFuture;

                if (currentReadFuture is object)
                {
                    // restoring context from previous read
                    Debug.Assert(_pendingSslStreamReadBuffer is object);

                    outputBuffer = _pendingSslStreamReadBuffer;
                    var outputBufferLength = outputBuffer.WritableBytes;

                    _pendingSslStreamReadFuture = null;
                    _pendingSslStreamReadBuffer = null;

                    // there was a read pending already, so we make sure we completed that first
                    if (currentReadFuture.IsCompleted)
                    {
                        if (currentReadFuture.IsFailure())
                        {
                            // The decryption operation failed
                            ExceptionDispatchInfo.Capture(currentReadFuture.Exception.InnerException).Throw();
                        }
                        int read = currentReadFuture.Result;
                        if (0u >= (uint)read)
                        {
                            // Stream closed
                            NotifyClosePromise(null);
                            return;
                        }

                        // Now output the result of previous read and decide whether to do an extra read on the same source or move forward
                        outputBuffer.Advance(read);
                        _firedChannelRead = true;
                        ctx.FireChannelRead(outputBuffer);

                        currentReadFuture = null;
                        outputBuffer      = null;

                        if (0u >= (uint)_mediationStream.SourceReadableBytes)
                        {
                            // we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there

                            if (read < outputBufferLength)
                            {
                                // SslStream returned non-full buffer and there's no more input to go through ->
                                // typically it means SslStream is done reading current frame so we skip
                                return;
                            }

                            // we've read out `read` bytes out of current packet to fulfil previously outstanding read
                            outputBufferLength = length - read;
                            if ((uint)(outputBufferLength - 1) > SharedConstants.TooBigOrNegative) // <= 0
                            {
                                // after feeding to SslStream current frame it read out more bytes than current packet size
                                outputBufferLength = c_fallbackReadBufferSize;
                            }
                        }
                        outputBuffer      = ctx.Allocator.Buffer(outputBufferLength);
                        currentReadFuture = ReadFromSslStreamAsync(outputBuffer, outputBufferLength);
                    }
                }
                else
                {
                    // there was no pending read before so we estimate buffer of `length` bytes to be sufficient
                    outputBuffer      = ctx.Allocator.Buffer(length);
                    currentReadFuture = ReadFromSslStreamAsync(outputBuffer, length);
                }

                // read out the rest of SslStream's output (if any) at risk of going async
                // using FallbackReadBufferSize - buffer size we're ok to have pinned with the SslStream until it's done reading
                while (true)
                {
                    if (currentReadFuture is object)
                    {
                        if (!currentReadFuture.IsCompleted)
                        {
                            break;
                        }
                        if (currentReadFuture.IsFailure())
                        {
                            // The decryption operation failed
                            ExceptionDispatchInfo.Capture(currentReadFuture.Exception.InnerException).Throw();
                        }
                        int read = currentReadFuture.Result;

                        if (0u >= (uint)read)
                        {
                            // Stream closed
                            NotifyClosePromise(null);
                            return;
                        }

                        outputBuffer.Advance(read);
                        _firedChannelRead = true;
                        ctx.FireChannelRead(outputBuffer);

                        currentReadFuture = null;
                        outputBuffer      = null;
                        if (0u >= (uint)_mediationStream.SourceReadableBytes)
                        {
                            return;
                        }
                    }
                    outputBuffer      = ctx.Allocator.Buffer(c_fallbackReadBufferSize);
                    currentReadFuture = ReadFromSslStreamAsync(outputBuffer, c_fallbackReadBufferSize);
                }

                pending = true;
                _pendingSslStreamReadBuffer = outputBuffer;
                _pendingSslStreamReadFuture = currentReadFuture;
            }
            finally
            {
                _mediationStream.ResetSource(ctx.Allocator);
                if (!pending && outputBuffer is object)
                {
                    if (outputBuffer.IsReadable())
                    {
                        _firedChannelRead = true;
                        ctx.FireChannelRead(outputBuffer);
                    }
                    else
                    {
                        outputBuffer.SafeRelease();
                    }
                }
            }
        }
Exemplo n.º 18
0
 public virtual ArraySegment <byte> GetIoBuffer(int index, int length) => Buf.GetIoBuffer(index, length);
Exemplo n.º 19
0
        Task <int> ReadFromSslStreamAsync(IByteBuffer outputBuffer, int outputBufferLength)
        {
            ArraySegment <byte> outlet = outputBuffer.GetIoBuffer(outputBuffer.WriterIndex, outputBufferLength);

            return(this.sslStream.ReadAsync(outlet.Array, outlet.Offset, outlet.Count));
        }
Exemplo n.º 20
0
        /// <summary>Unwraps inbound SSL records.</summary>
        void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length, List <int> packetLengths, List <object> output)
        {
            Contract.Requires(packetLengths.Count > 0);

            //bool notifyClosure = false; // todo: netty/issues/137
            bool pending = false;

            IByteBuffer outputBuffer = null;

            try
            {
                ArraySegment <byte> inputIoBuffer = packet.GetIoBuffer(offset, length);
                this.mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset);

                int packetIndex = 0;

                while (!this.EnsureAuthenticated())
                {
                    this.mediationStream.ExpandSource(packetLengths[packetIndex]);
                    if (++packetIndex == packetLengths.Count)
                    {
                        return;
                    }
                }

                Task <int> currentReadFuture = this.pendingSslStreamReadFuture;

                int outputBufferLength;

                if (currentReadFuture != null)
                {
                    // restoring context from previous read
                    Contract.Assert(this.pendingSslStreamReadBuffer != null);

                    outputBuffer       = this.pendingSslStreamReadBuffer;
                    outputBufferLength = outputBuffer.WritableBytes;

                    this.pendingSslStreamReadFuture = null;
                    this.pendingSslStreamReadBuffer = null;
                }
                else
                {
                    outputBufferLength = 0;
                }

                // go through packets one by one (because SslStream does not consume more than 1 packet at a time)
                for (; packetIndex < packetLengths.Count; packetIndex++)
                {
                    int currentPacketLength = packetLengths[packetIndex];
                    this.mediationStream.ExpandSource(currentPacketLength);

                    if (currentReadFuture != null)
                    {
                        // there was a read pending already, so we make sure we completed that first

                        if (!currentReadFuture.IsCompleted)
                        {
                            // we did feed the whole current packet to SslStream yet it did not produce any result -> move to the next packet in input

                            continue;
                        }

                        int read = currentReadFuture.Result;

                        if (read == 0)
                        {
                            //Stream closed
                            return;
                        }

                        // Now output the result of previous read and decide whether to do an extra read on the same source or move forward
                        AddBufferToOutput(outputBuffer, read, output);

                        currentReadFuture = null;
                        outputBuffer      = null;
                        if (this.mediationStream.SourceReadableBytes == 0)
                        {
                            // we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there

                            if (read < outputBufferLength)
                            {
                                // SslStream returned non-full buffer and there's no more input to go through ->
                                // typically it means SslStream is done reading current frame so we skip
                                continue;
                            }

                            // we've read out `read` bytes out of current packet to fulfil previously outstanding read
                            outputBufferLength = currentPacketLength - read;
                            if (outputBufferLength <= 0)
                            {
                                // after feeding to SslStream current frame it read out more bytes than current packet size
                                outputBufferLength = FallbackReadBufferSize;
                            }
                        }
                        else
                        {
                            // SslStream did not get to reading current frame so it completed previous read sync
                            // and the next read will likely read out the new frame
                            outputBufferLength = currentPacketLength;
                        }
                    }
                    else
                    {
                        // there was no pending read before so we estimate buffer of `currentPacketLength` bytes to be sufficient
                        outputBufferLength = currentPacketLength;
                    }

                    outputBuffer      = ctx.Allocator.Buffer(outputBufferLength);
                    currentReadFuture = this.ReadFromSslStreamAsync(outputBuffer, outputBufferLength);
                }

                // read out the rest of SslStream's output (if any) at risk of going async
                // using FallbackReadBufferSize - buffer size we're ok to have pinned with the SslStream until it's done reading
                while (true)
                {
                    if (currentReadFuture != null)
                    {
                        if (!currentReadFuture.IsCompleted)
                        {
                            break;
                        }
                        int read = currentReadFuture.Result;
                        AddBufferToOutput(outputBuffer, read, output);
                    }
                    outputBuffer      = ctx.Allocator.Buffer(FallbackReadBufferSize);
                    currentReadFuture = this.ReadFromSslStreamAsync(outputBuffer, FallbackReadBufferSize);
                }

                pending = true;
                this.pendingSslStreamReadBuffer = outputBuffer;
                this.pendingSslStreamReadFuture = currentReadFuture;
            }
            catch (Exception ex)
            {
                this.HandleFailure(ex);
                throw;
            }
            finally
            {
                this.mediationStream.ResetSource();
                if (!pending && outputBuffer != null)
                {
                    if (outputBuffer.IsReadable())
                    {
                        output.Add(outputBuffer);
                    }
                    else
                    {
                        outputBuffer.SafeRelease();
                    }
                }
            }
        }
Exemplo n.º 21
0
        /// <summary>Unwraps inbound SSL records.</summary>
        private void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length, List <int> packetLengths, List <object> output)
        {
            if (0u >= (uint)packetLengths.Count)
            {
                ThrowHelper.ThrowArgumentException();
            }

            //bool notifyClosure = false; // todo: netty/issues/137
            bool pending = false;

            IByteBuffer outputBuffer = null;

            try
            {
#if NETCOREAPP || NETSTANDARD_2_0_GREATER
                ReadOnlyMemory <byte> inputIoBuffer = packet.GetReadableMemory(offset, length);
                _mediationStream.SetSource(inputIoBuffer);
#else
                ArraySegment <byte> inputIoBuffer = packet.GetIoBuffer(offset, length);
                _mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset);
#endif

                int packetIndex = 0;

                while (!EnsureAuthenticated(ctx))
                {
                    _mediationStream.ExpandSource(packetLengths[packetIndex]);
                    if ((uint)(++packetIndex) >= (uint)packetLengths.Count)
                    {
                        return;
                    }
                }

                var currentReadFuture = _pendingSslStreamReadFuture;

                int outputBufferLength;

                if (currentReadFuture is object)
                {
                    // restoring context from previous read
                    Debug.Assert(_pendingSslStreamReadBuffer is object);

                    outputBuffer       = _pendingSslStreamReadBuffer;
                    outputBufferLength = outputBuffer.WritableBytes;

                    _pendingSslStreamReadFuture = null;
                    _pendingSslStreamReadBuffer = null;
                }
                else
                {
                    outputBufferLength = 0;
                }

                // go through packets one by one (because SslStream does not consume more than 1 packet at a time)
                for (; packetIndex < packetLengths.Count; packetIndex++)
                {
                    int currentPacketLength = packetLengths[packetIndex];
                    _mediationStream.ExpandSource(currentPacketLength);

                    if (currentReadFuture is object)
                    {
                        // there was a read pending already, so we make sure we completed that first

                        if (!currentReadFuture.IsCompleted)
                        {
                            // we did feed the whole current packet to SslStream yet it did not produce any result -> move to the next packet in input

                            continue;
                        }

                        int read = currentReadFuture.Result;

                        if (0u >= (uint)read)
                        {
                            //Stream closed
                            return;
                        }

                        // Now output the result of previous read and decide whether to do an extra read on the same source or move forward
                        AddBufferToOutput(outputBuffer, read, output);

                        currentReadFuture = null;
                        outputBuffer      = null;
                        if (0u >= (uint)_mediationStream.SourceReadableBytes)
                        {
                            // we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there

                            if (read < outputBufferLength)
                            {
                                // SslStream returned non-full buffer and there's no more input to go through ->
                                // typically it means SslStream is done reading current frame so we skip
                                continue;
                            }

                            // we've read out `read` bytes out of current packet to fulfil previously outstanding read
                            outputBufferLength = currentPacketLength - read;
                            if ((uint)(outputBufferLength - 1) > SharedConstants.TooBigOrNegative) // <= 0
                            {
                                // after feeding to SslStream current frame it read out more bytes than current packet size
                                outputBufferLength = c_fallbackReadBufferSize;
                            }
                        }
                        else
                        {
                            // SslStream did not get to reading current frame so it completed previous read sync
                            // and the next read will likely read out the new frame
                            outputBufferLength = currentPacketLength;
                        }
                    }
                    else
                    {
                        // there was no pending read before so we estimate buffer of `currentPacketLength` bytes to be sufficient
                        outputBufferLength = currentPacketLength;
                    }

                    outputBuffer      = ctx.Allocator.Buffer(outputBufferLength);
                    currentReadFuture = ReadFromSslStreamAsync(outputBuffer, outputBufferLength);
                }

                // read out the rest of SslStream's output (if any) at risk of going async
                // using FallbackReadBufferSize - buffer size we're ok to have pinned with the SslStream until it's done reading
                while (true)
                {
                    if (currentReadFuture is object)
                    {
                        if (!currentReadFuture.IsCompleted)
                        {
                            break;
                        }
                        int read = currentReadFuture.Result;
                        AddBufferToOutput(outputBuffer, read, output);
                    }
                    outputBuffer      = ctx.Allocator.Buffer(c_fallbackReadBufferSize);
                    currentReadFuture = ReadFromSslStreamAsync(outputBuffer, c_fallbackReadBufferSize);
                }

                pending = true;
                _pendingSslStreamReadBuffer = outputBuffer;
                _pendingSslStreamReadFuture = currentReadFuture;
            }
            finally
            {
                _mediationStream.ResetSource();
                if (!pending && outputBuffer is object)
                {
                    if (outputBuffer.IsReadable())
                    {
                        output.Add(outputBuffer);
                    }
                    else
                    {
                        outputBuffer.SafeRelease();
                    }
                }
            }
        }
Exemplo n.º 22
0
 public ArraySegment <byte> GetIoBuffer(int index, int length)
 {
     CheckIndex(index, length);
     return(_buffer.GetIoBuffer(index, length));
 }
Exemplo n.º 23
0
 public void HandlePacket(EndPoint sender, IByteBuffer content)
 {
     Console.WriteLine(content.GetString(content.ArrayOffset, content.ReadableBytes, Encoding.UTF8));
     try
     {
         var identificator      = GetHeader(content);
         var DeserializedPacket = MessagePackSerializer.Deserialize(packetFactory.GetPacketById(identificator), content.GetIoBuffer().ToArray());
     }
     catch (Exception e)
     {
         Console.WriteLine(e);
     }
 }
Exemplo n.º 24
0
        public IPacket Deserialize(IByteBuffer byteBuffer)
        {
            try
            {
                var packet     = MessagePackSerializer.Deserialize <BasicPacketCapsule>(byteBuffer.GetIoBuffer().ToArray());
                var packetType = _packetFactory.GetPacketById(packet.Identifier);

                if (packetType == null)
                {
                    _log.Warn($"Packet with identifier: [{packet.Identifier}] couldn't be found.");
                    return(null);
                }

                return(MessagePackSerializer.Deserialize(packetType, packet.Packet) as IPacket);
            }
            catch (Exception e)
            {
                _log.Error("[DESERIALIZE]", e);
                return(null);
            }
        }
Exemplo n.º 25
0
        bool Add(IByteBuffer buf)
        {
            if (this.count == MaximumLimit)
            {
                return(false);
            }

            int len = buf.ReadableBytes;

            if (len == 0)
            {
                return(true);
            }

            if (this.maxBytes - len < this.size && this.count > 0)
            {
                return(false);
            }

            IntPtr addr = IntPtr.Zero;

            if (buf.HasMemoryAddress)
            {
                addr = buf.AddressOfPinnedMemory();
            }

            if (addr != IntPtr.Zero)
            {
                this.Add(addr, buf.ReaderIndex, len);
            }
            else
            {
                int bufferCount = buf.IoBufferCount;
                if (MaximumLimit - bufferCount < this.count)
                {
                    return(false);
                }

                if (bufferCount == 1)
                {
                    ArraySegment <byte> arraySegment = buf.GetIoBuffer();

                    byte[]   array  = arraySegment.Array;
                    GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
                    this.handles.Add(handle);

                    addr = handle.AddrOfPinnedObject();
                    this.Add(addr, arraySegment.Offset, arraySegment.Count);
                }
                else
                {
                    ArraySegment <byte>[] segments = buf.GetIoBuffers();
                    for (int i = 0; i < segments.Length; i++)
                    {
                        GCHandle handle = GCHandle.Alloc(segments[i].Array, GCHandleType.Pinned);
                        this.handles.Add(handle);

                        addr = handle.AddrOfPinnedObject();
                        this.Add(addr, segments[i].Offset, segments[i].Count);
                    }
                }
            }
            return(true);
        }
Exemplo n.º 26
0
        internal void Prepare()
        {
            IByteBuffer byteBuffer = this.buffer;
            int         index      = byteBuffer.ReaderIndex;
            int         length     = byteBuffer.ReadableBytes;
            IntPtr      addr       = byteBuffer.AddressOfPinnedMemory();

            if (addr != IntPtr.Zero)
            {
                this.bufs[0] = new uv_buf_t(addr + index, length);
                this.size    = 1;
                return;
            }

            if (byteBuffer.HasArray)
            {
                byte[]   array  = byteBuffer.Array;
                GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
                this.handles.Add(handle);

                addr         = handle.AddrOfPinnedObject();
                this.bufs[0] = new uv_buf_t(addr + this.buffer.ArrayOffset + index, length);
                this.size    = 1;
                return;
            }

            if (byteBuffer.IoBufferCount == 1)
            {
                ArraySegment <byte> arraySegment = byteBuffer.GetIoBuffer(index, length);

                byte[]   array  = arraySegment.Array;
                GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
                this.handles.Add(handle);

                addr         = handle.AddrOfPinnedObject();
                this.bufs[0] = new uv_buf_t(addr + arraySegment.Offset, arraySegment.Count);
                this.size    = 1;
                return;
            }

            ArraySegment <byte>[] segments = byteBuffer.GetIoBuffers(index, length);
            if (segments.Length > this.bufs.Length)
            {
                if (this.pin.IsAllocated)
                {
                    this.pin.Free();
                }
                this.bufs = new uv_buf_t[segments.Length];
                this.pin  = GCHandle.Alloc(this.bufs, GCHandleType.Pinned);
            }

            for (int i = 0; i < segments.Length; i++)
            {
                GCHandle handle = GCHandle.Alloc(segments[i].Array, GCHandleType.Pinned);
                this.handles.Add(handle);

                addr         = handle.AddrOfPinnedObject();
                this.bufs[i] = new uv_buf_t(addr + segments[i].Offset, segments[i].Count);
            }

            this.size = segments.Length;
        }