Beispiel #1
0
        public int PeekRead(IByteBuffer buffer)
        {
            buffer.Clear();
            ArraySegment <byte> segment = buffer.ToSegment(true);

            return(buffer.End = _socket.Peek(segment.Array, segment.Offset, segment.Count) + buffer.Start);
        }
Beispiel #2
0
        /*
         * Resets the state of this transport so it can be used to write more messages
         */
        public void ResetOutputBuffer()
        {
            int shrunkenSize = ShrinkBufferSize();

            if (_outputBuffer.WriterIndex < shrunkenSize)
            {
                // Less than the shrunken size of the buffer was actually used, so increment
                // the under-use counter
                ++_bufferUnderUsedCounter;
            }
            else
            {
                // More than the shrunken size of the buffer was actually used, reset
                // the counter so we won't shrink the buffer soon
                _bufferUnderUsedCounter = 0;
            }

            if (ShouldShrinkBuffer())
            {
                if ((_outputBuffer?.ReferenceCount ?? 0) > 0)
                {
                    _outputBuffer?.Release();
                }
                _outputBuffer           = Unpooled.Buffer(shrunkenSize);
                _bufferUnderUsedCounter = 0;
            }
            else
            {
                _outputBuffer.Clear();
            }
        }
Beispiel #3
0
        /// <inheritdoc/>
        public void Clear(int position, int count)
        {
            EnsureValidPositionAndCount(position, count);
            ThrowIfDisposed();

            _buffer.Clear(position + _offset, count);
        }
Beispiel #4
0
 public void RegisterSocketRead(IEvent e, BufferedSocket socket, IEventHandler protocol, ReadFunction callback)
 {
     e.RegisterSocketRead(socket, () =>
     {
         EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
         try
         {
             protocol.Read(socket, _msg, ref ep);
         }
         catch (SocketException ex)
         {
             Console.WriteLine("SocketException occured: " + ex.Message);
             _msg.Clear();
         }
         callback(_msg, ep);
     });
 }
 private void PrepareToWrite(int count)
 {
     _buffer.EnsureCapacity(_position + count);
     _buffer.Length = _buffer.Capacity;
     if (_length < _position)
     {
         _buffer.Clear(_length, _position - _length);
     }
 }
Beispiel #6
0
        public int ReceiveFrom(IByteBuffer message, ref IPEndPoint to)
        {
            message.Clear();
            EndPoint ep     = to;
            int      length = ReceiveFrom(message, ref ep);

            to = (IPEndPoint)ep;
            return(length);
        }
Beispiel #7
0
        public int ReceiveFrom(IByteBuffer message, ref EndPoint to)
        {
            message.Clear();
            ArraySegment <byte> segment = message.ToSegment(true);
            int length = _socket.ReceiveFrom(segment.Array, segment.Offset, segment.Count, ref to);

            message.End = length;
            return(length);
        }
Beispiel #8
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            byte[] array = new byte[input.ReadableBytes];
            input.GetBytes(input.ReaderIndex, array, 0, input.ReadableBytes);
            input.Clear();

            var msg = new Message();

            output.Add(msg.Prase(array));
        }
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            var request = new PacketRequest <IMessage>();

            request.Checkbit  = input.ReadInt();
            request.Length    = input.ReadInt();
            request.CommandId = input.ReadInt();
            IByteBuffer result = Unpooled.Buffer(request.Length - 4 * 3);

            input.ReadBytes(result, request.Length - 4 * 3);
            request.Deserialize(result.Array);
            output.Add(request);
            result.Clear();
        }
Beispiel #10
0
        private void PrepareToWrite(int count)
        {
            var minimumCapacity = (long)_position + (long)count;

            if (minimumCapacity > int.MaxValue)
            {
                throw new IOException("Stream was too long.");
            }

            _buffer.EnsureCapacity((int)minimumCapacity);
            _buffer.Length = _buffer.Capacity;
            if (_length < _position)
            {
                _buffer.Clear(_length, _position - _length);
            }
        }
        public static void MakeSpace(this IByteBuffer output, int length, string reason = null)
        {
            if (output.WritableBytes < length)
            {
                if (output.ReaderIndex == output.WriterIndex)
                {
                    output.Clear();
                }
                else
                {
                    output.DiscardReadBytes();
                }

                if (output.WritableBytes < length)
                {
                    output.EnsureWritable(length, true);
                }
            }
        }
Beispiel #12
0
        public void TestDecodeLargerThanMaxHeaderListSizeUpdatesDynamicTable()
        {
            IByteBuffer input = Unpooled.Buffer(300);

            try
            {
                hpackDecoder.SetMaxHeaderListSize(200);
                HpackEncoder hpackEncoder = new HpackEncoder(true);

                // encode headers that are slightly larger than maxHeaderListSize
                IHttp2Headers toEncode = new DefaultHttp2Headers();
                toEncode.Add((AsciiString)"test_1", (AsciiString)"1");
                toEncode.Add((AsciiString)"test_2", (AsciiString)"2");
                toEncode.Add((AsciiString)"long", (AsciiString)"A".PadRight(100, 'A')); //string.Format("{0,0100:d}", 0).Replace('0', 'A')
                toEncode.Add((AsciiString)"test_3", (AsciiString)"3");
                hpackEncoder.EncodeHeaders(1, input, toEncode, NeverSensitiveDetector.Instance);

                // decode the headers, we should get an exception
                IHttp2Headers decoded = new DefaultHttp2Headers();
                Assert.Throws <HeaderListSizeException>(() => hpackDecoder.Decode(1, input, decoded, true));

                // but the dynamic table should have been updated, so that later blocks
                // can refer to earlier headers
                input.Clear();
                // 0x80, "indexed header field representation"
                // index 62, the first (most recent) dynamic table entry
                input.WriteByte(0x80 | 62);
                IHttp2Headers decoded2 = new DefaultHttp2Headers();
                hpackDecoder.Decode(1, input, decoded2, true);

                IHttp2Headers golden = new DefaultHttp2Headers();
                golden.Add((AsciiString)"test_3", (AsciiString)"3");
                Assert.Equal(golden, decoded2);
            }
            finally
            {
                input.Release();
            }
        }
Beispiel #13
0
        public void EncodeHeaders(int streamId, IHttp2Headers headers, IByteBuffer buffer)
        {
            try
            {
                // If there was a change in the table size, serialize the output from the hpackEncoder
                // resulting from that change.
                if (_tableSizeChangeOutput.IsReadable())
                {
                    _ = buffer.WriteBytes(_tableSizeChangeOutput);
                    _ = _tableSizeChangeOutput.Clear();
                }

                _hpackEncoder.EncodeHeaders(streamId, buffer, headers, _sensitivityDetector);
            }
            catch (Http2Exception)
            {
                throw;
            }
            catch (Exception t)
            {
                ThrowHelper.ThrowConnectionError_FailedEncodingHeadersBlock(t);
            }
        }
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            //0 if (!input.HasArray) return;

            var request = new PacketRequest <string>();

            request.Checkbit  = input.ReadInt(); //0-4
            request.Length    = input.ReadInt(); //4-8
            request.CommandId = input.ReadInt(); //8-12
            IByteBuffer result = Unpooled.Buffer(request.Length - 4 * 3);

            input.ReadBytes(result, request.Length - 4 * 3);//12 - (20 - 4 * 3) 从第12个字节位置开始往后读8个字节
            request.Deserialize(result.Array);
            output.Add(request);
            result.Clear();

            //1 显式丢弃消息
            //ReferenceCountUtil.Release(msg);

            //2增加引用计数防止释放
            //ReferenceCountUtil.retain(message)

            //3 IByteBuffer.Read 读字节 IByteBuffer.Write 写字节

            /*
             * 4 移除可丢弃字节
             * 所谓可丢弃字节就是调用read方法之后,readindex已经移动过了的区域,这段区域的字节称为可丢弃字节。
             * 只有在内存十分宝贵需要清理的时候再调用这个方法,随便调用有可能会造成内存的复制,降低效率。
             */
            //message.DiscardReadBytes();

            //5 读取所有可读字节(移动读索引)
            //while (message.IsReadable())
            //{
            //    Console.WriteLine(message.ReadByte());
            //}
        }
Beispiel #15
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            if (!_suppressRead && !_handshakeFailed)
            {
                Exception error = null;
                try
                {
                    int readerIndex     = input.ReaderIndex;
                    int readableBytes   = input.ReadableBytes;
                    int handshakeLength = -1;

                    // Check if we have enough data to determine the record type and length.
                    while (readableBytes >= TlsUtils.SSL_RECORD_HEADER_LENGTH)
                    {
                        int contentType = input.GetByte(readerIndex);
                        // tls, but not handshake command
                        switch (contentType)
                        {
                        case TlsUtils.SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC:
                        // fall-through
                        case TlsUtils.SSL_CONTENT_TYPE_ALERT:
                            int len = TlsUtils.GetEncryptedPacketLength(input, readerIndex);

                            // Not an SSL/TLS packet
                            if (len == TlsUtils.NOT_ENCRYPTED)
                            {
                                _handshakeFailed = true;
                                var e = new NotSslRecordException(
                                    "not an SSL/TLS record: " + ByteBufferUtil.HexDump(input));
                                _ = input.SkipBytes(input.ReadableBytes);
                                _ = context.FireUserEventTriggered(new SniCompletionEvent(e));
                                TlsUtils.NotifyHandshakeFailure(context, e, true);
                                throw e;
                            }
                            if (len == TlsUtils.NOT_ENOUGH_DATA)
                            {
                                // Not enough data
                                return;
                            }
                            // SNI can't be present in an ALERT or CHANGE_CIPHER_SPEC record, so we'll fall back and
                            // assume no SNI is present. Let's let the actual TLS implementation sort this out.
                            // Just select the default SslContext
                            goto SelectDefault;

                        case TlsUtils.SSL_CONTENT_TYPE_HANDSHAKE:
                            int majorVersion = input.GetByte(readerIndex + 1);

                            // SSLv3 or TLS
                            if (majorVersion == 3)
                            {
                                int packetLength = input.GetUnsignedShort(readerIndex + 3) + TlsUtils.SSL_RECORD_HEADER_LENGTH;

                                if (readableBytes < packetLength)
                                {
                                    // client hello incomplete; try again to decode once more data is ready.
                                    return;
                                }
                                else if (packetLength == TlsUtils.SSL_RECORD_HEADER_LENGTH)
                                {
                                    goto SelectDefault;
                                }


                                int endOffset = readerIndex + packetLength;

                                // Let's check if we already parsed the handshake length or not.
                                if (handshakeLength == -1)
                                {
                                    if (readerIndex + 4 > endOffset)
                                    {
                                        // Need more data to read HandshakeType and handshakeLength (4 bytes)
                                        return;
                                    }

                                    int handshakeType = input.GetByte(readerIndex + TlsUtils.SSL_RECORD_HEADER_LENGTH);

                                    // Check if this is a clientHello(1)
                                    // See https://tools.ietf.org/html/rfc5246#section-7.4
                                    if (handshakeType != 1)
                                    {
                                        goto SelectDefault;
                                    }

                                    // Read the length of the handshake as it may arrive in fragments
                                    // See https://tools.ietf.org/html/rfc5246#section-7.4
                                    handshakeLength = input.GetUnsignedMedium(readerIndex + TlsUtils.SSL_RECORD_HEADER_LENGTH + 1);

                                    // Consume handshakeType and handshakeLength (this sums up as 4 bytes)
                                    readerIndex  += 4;
                                    packetLength -= 4;

                                    if (handshakeLength + 4 + TlsUtils.SSL_RECORD_HEADER_LENGTH <= packetLength)
                                    {
                                        // We have everything we need in one packet.
                                        // Skip the record header
                                        readerIndex += TlsUtils.SSL_RECORD_HEADER_LENGTH;
                                        Select(context, ExtractSniHostname(input, readerIndex, readerIndex + handshakeLength));
                                        return;
                                    }
                                    else
                                    {
                                        if (_handshakeBuffer is null)
                                        {
                                            _handshakeBuffer = context.Allocator.Buffer(handshakeLength);
                                        }
                                        else
                                        {
                                            // Clear the buffer so we can aggregate into it again.
                                            _ = _handshakeBuffer.Clear();
                                        }
                                    }
                                }

                                // Combine the encapsulated data in one buffer but not include the SSL_RECORD_HEADER
                                _ = _handshakeBuffer.WriteBytes(input, readerIndex + TlsUtils.SSL_RECORD_HEADER_LENGTH,
                                                                packetLength - TlsUtils.SSL_RECORD_HEADER_LENGTH);
                                readerIndex   += packetLength;
                                readableBytes -= packetLength;
                                if (handshakeLength <= _handshakeBuffer.ReadableBytes)
                                {
                                    Select(context, ExtractSniHostname(_handshakeBuffer, 0, handshakeLength));
                                    return;
                                }
                            }
                            break;

                        default:
                            //not tls, ssl or application data, do not try sni
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    error = e;

                    // unexpected encoding, ignore sni and use default
                    if (Logger.WarnEnabled)
                    {
                        Logger.UnexpectedClientHelloPacket(input, e);
                    }
                }

SelectDefault:
                if (_serverTlsSniSettings.DefaultServerHostName is object)
                {
                    // Just select the default server TLS setting
                    Select(context, _serverTlsSniSettings.DefaultServerHostName);
                }
                else
                {
                    ReleaseHandshakeBuffer();

                    _handshakeFailed = true;
                    var e = new DecoderException($"failed to get the server TLS setting {error}");
                    TlsUtils.NotifyHandshakeFailure(context, e, true);
                    throw e;
                }
            }
        }
Beispiel #16
0
    //패킷 완성후, 다음 데이터가 없는지 체크하는 함수.
    //패킷 완성후, 다시 자기자신을 호출하여 다음 데이터가 없을때까지 계속 자기자신을 호출한다.
    bool isCompleteSizePacket(int packet_size, IChannelHandlerContext ctx, IByteBuffer msg)
    {
        //아직 버퍼에 데이터가 충분하지 않다면 다시 되돌려서 패킷을 이어서 더 받아오게끔 하는 부분!
        if (msg.ReadableBytes < packet_size + 8)
        {
            //정상적으로 데이터를 다 읽은것이 아니므로 아까 MarkReaderIndex로 저장했던 0값으로 readerIndex 4 -> 0로 초기화함.
            msg.ResetReaderIndex();
            return(false); //다시 되돌려서 패킷을 이어서 더 받아오게끔 하는 부분!
        }
        //패킷이 뭉쳐서 데이터를 더 받아왔을 경우! 원래 받아야 할 부분만 받고, 나머지는 다시 되돌려서 뒤이어 오는 패킷과 합쳐서 받을 것!
        else if (msg.ReadableBytes > packet_size + 8)
        {
            //받아온 데이터.
            byte[] packet_data = new byte[msg.ReadableBytes];
            msg.ReadBytes(packet_data, 0, msg.ReadableBytes);

            //버퍼의 현재 용량에서 추가로 기록가능한 영역이 10KB 이하라면,
            //이미 읽은 분량만큼은 필요없으므로 Index 0의 위치로 데이터를 옮겨 추가로 기록가능한 영역을 늘린다.
            if (msg.Capacity - msg.WriterIndex < 10000)
            {
                msg.DiscardReadBytes();
            }



            //받아온 데이터를 메인스레드와 통신하기 위한 목적으로 만들어둔 수신 Queue에 삽입.
            //멀티스레드에서 공유하는 Queue이므로, Locking 처리.  NetworkManager.locking 는 스레드 lock용 모니터 객체이다.
            lock (NetworkManager.locking)
            {
                //받아온 데이터를 수신Queue에 삽입하는 부분.

                //데이터 삽입.
                NetworkManager.packet_Queue.Enqueue(new Packet_Data(packet_data));
            }



            //패킷 완성후 남은 데이터가 헤더크기인 12byte보다 작을 경우.
            if (msg.ReadableBytes < 12)
            {
                return(false);
            }
            else
            {
                msg.MarkReaderIndex();
                int amountSize = msg.ReadIntLE();

                //비정상적인 데이터가 도달하였다면.
                if (!isAvailablePacketSize(amountSize))
                {
                    //연결 종료
                    ctx.CloseAsync();  //채널이 닫힌다면 msg는 release 된다.
                    return(false);
                }

                return(isCompleteSizePacket(amountSize, ctx, msg)); //재귀함수 처리
                //패킷 완성후, 남은데이터가 없을때까지 계속 반복한다.
            }
        }
        else //정확한 데이터일 경우. [msg.ReadableBytes > packet_size + 8] 또는 [msg.readableBytes() + 4 == packet_size + 12]
        {
            //받아온 데이터.
            byte[] packet_data = new byte[msg.ReadableBytes];
            msg.ReadBytes(packet_data, 0, msg.ReadableBytes);

            //버퍼에 읽어와야 할 데이터가 남아있지 않으므로 readerIndex, writerIndex를 각각 0으로 초기화 한다.
            //내부 버퍼 데이터를 변경하지 않고 index값만 변경하므로 자원을 적게 소모한다.
            msg.Clear();


            //받아온 데이터를 메인스레드와 통신하기 위한 목적으로 만들어둔 수신 Queue에 삽입.
            //멀티스레드에서 공유하는 Queue이므로, Locking 처리.  NetworkManager.locking 는 스레드 lock용 모니터 객체이다.
            lock (NetworkManager.locking)
            {
                //받아온 데이터를 수신Queue에 삽입하는 부분.

                //데이터 삽입.
                NetworkManager.packet_Queue.Enqueue(new Packet_Data(packet_data));
            }

            //다시 되돌려서 패킷을 이어서 더 받아오게끔 하는 부분!
            return(false);
        }
    }
Beispiel #17
0
 /// <summary>
 /// Clears the data in the buffer.
 /// </summary>
 public void Clear()
 {
     ThrowIfDisposed();
     _byteBuffer.Clear();
 }
Beispiel #18
0
 public int Read(IByteBuffer buffer)
 {
     buffer.Clear();
     ArraySegment<byte> segment = buffer.ToSegment(true);
     buffer.End = _socket.Receive(segment.Array, segment.Offset, segment.Count) + buffer.Start;
     return buffer.End;
 }
Beispiel #19
0
 public int ReceiveFrom(IByteBuffer message, ref EndPoint to)
 {
     message.Clear();
     ArraySegment<byte> segment = message.ToSegment(true);
     int length = _socket.ReceiveFrom(segment.Array, segment.Offset, segment.Count, ref to);
     message.End = length;
     return length;
 }
Beispiel #20
0
 public IByteBuffer Clear()
 {
     _ = Buf.Clear();
     return(this);
 }
Beispiel #21
0
 public int ReceiveFrom(IByteBuffer message, ref IPEndPoint to)
 {
     message.Clear();
     EndPoint ep = to;
     int length = ReceiveFrom(message, ref ep);
     to = (IPEndPoint) ep;
     return length;
 }
 public void Clear()
 {
     _bb.Clear();
 }