Exemplo n.º 1
0
        public override void ChannelRead(IChannelHandlerContext ctx, object msg)
        {
            if (!(msg is IFullHttpResponse))
            {
                ctx.FireChannelRead(msg);
                return;
            }

            var response = (IFullHttpResponse)msg;

            try
            {
                if (!this.handshaker.IsHandshakeComplete)
                {
                    this.handshaker.FinishHandshake(ctx.Channel, response);
                    ctx.FireUserEventTriggered(WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HandshakeComplete);
                    ctx.Channel.Pipeline.Remove(this);
                    return;
                }

                throw new InvalidOperationException("WebSocketClientHandshaker should have been non finished yet");
            }
            finally
            {
                response.Release();
            }
        }
Exemplo n.º 2
0
        private void SetConnectSuccess()
        {
            _finished = true;
            var removedCodec = true;

            removedCodec &= SafeRemoveEncoder();

            _ctx.FireUserEventTriggered(new ProxyConnectionEvent(Protocol, AuthScheme, _proxyAddress,
                                                                 DestinationAddress));

            removedCodec &= SafeRemoveDecoder();

            if (removedCodec)
            {
                WritePendingWrites();

                if (_flushedPrematurely)
                {
                    _ctx.Flush();
                }
            }
            else
            {
                // We are at inconsistent state because we failed to remove all codec handlers.
                Exception cause = new ProxyConnectException(
                    "failed to remove all codec handlers added by the proxy handler; bug?",
                    new InvalidOperationException());
                FailPendingWrites(cause);
                _ctx.FireExceptionCaught(cause);
                _ctx.CloseAsync();
            }
        }
Exemplo n.º 3
0
        public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
        {
            bool release = true;

            try
            {
                if (AcceptEvent(evt))
                {
                    I ievt = (I)evt;
                    EventReceived(ctx, ievt);
                }
                else
                {
                    release = false;
                    _       = ctx.FireUserEventTriggered(evt);
                }
            }
            finally
            {
                if (_autoRelease && release)
                {
                    _ = ReferenceCountUtil.Release(evt);
                }
            }
        }
        protected override void Decode(IChannelHandlerContext ctx, IByteBuffer input, List <object> output)
        {
            int prefaceLength = CONNECTION_PREFACE.ReadableBytes;
            int bytesRead     = Math.Min(input.ReadableBytes, prefaceLength);

            var pipeline = ctx.Pipeline;

            if (!ByteBufferUtil.Equals(CONNECTION_PREFACE, CONNECTION_PREFACE.ReaderIndex,
                                       input, input.ReaderIndex, bytesRead))
            {
                _ = pipeline.Remove(this);
            }
            else if (0u >= (uint)(bytesRead - prefaceLength))
            {
                // Full h2 preface match, removed source codec, using http2 codec to handle
                // following network traffic
                _ = pipeline
                    .Remove(_httpServerCodec)
                    .Remove(_httpServerUpgradeHandler);

                _ = pipeline.AddAfter(ctx.Name, null, _http2ServerHandler);
                _ = pipeline.Remove(this);

                _ = ctx.FireUserEventTriggered(PriorKnowledgeUpgradeEvent.Instance);
            }
        }
        private void setConnectSuccess(IChannelHandlerContext context)
        {
            finished = true;

            cancelConnectTimeoutFuture();

            if (connectPromise.IsCompleted)
            {
                bool removedCodec = true;

                removedCodec &= safeRemoveEncoder(context);

                context.FireUserEventTriggered(new ProxyConnectionEvent(protocol(), authScheme(), proxyAddress, destinationAddress));

                removedCodec &= safeRemoveDecoder(context);

                if (removedCodec)
                {
                    writePendingWrites();

                    if (flushedPrematurely)
                    {
                        context.Flush();
                    }
                    //connectPromise.TrySetResult(ctx.Channel);
                }
                else
                {
                    // We are at inconsistent state because we failed to remove all codec handlers.
                    Exception cause = new ProxyConnectException("failed to remove all codec handlers added by the proxy handler; bug?", new Exception("failed to remove all codec handlers added by the proxy handler; bug?"));

                    failPendingWritesAndClose(cause);
                }
            }
        }
Exemplo n.º 6
0
        /// <inheritdoc/>
        public override void ChannelRead(IChannelHandlerContext ctx, object msg)
        {
            if (!(msg is IFullHttpResponse response))
            {
                _ = ctx.FireChannelRead(msg);
                return;
            }

            try
            {
                if (!_handshaker.IsHandshakeComplete)
                {
                    _handshaker.FinishHandshake(ctx.Channel, response);
                    _ = _handshakePromise.TryComplete();
                    _ = ctx.FireUserEventTriggered(WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HandshakeComplete);
                    _ = ctx.Pipeline.Remove(this);
                    return;
                }

                ThrowHelper.ThrowInvalidOperationException_WebSocketClientHandshaker();
            }
            finally
            {
                _ = response.Release();
            }
        }
        private void HandleUnwrapThrowable(IChannelHandlerContext context, Exception cause)
        {
            try
            {
                // We should attempt to notify the handshake failure before writing any pending data. If we are in unwrap
                // and failed during the handshake process, and we attempt to wrap, then promises will fail, and if
                // listeners immediately close the Channel then we may end up firing the handshake event after the Channel
                // has been closed.
                if (_handshakePromise.TrySetException(cause))
                {
                    context.FireUserEventTriggered(new TlsHandshakeCompletionEvent(cause));
                }

                // We need to flush one time as there may be an alert that we should send to the remote peer because
                // of the SSLException reported here.
                WrapAndFlush(context);
            }
            catch (Exception exc)
            {
                if (exc is ArgumentNullException // sslstream closed
                    or IOException
                    or NotSupportedException
                    or OperationCanceledException)
                {
#if DEBUG
                    if (s_logger.DebugEnabled)
                    {
                        s_logger.Debug("SSLException during trying to call TlsHandler.Wrap(...)" +
                                       " because of an previous SSLException, ignoring...", exc);
                    }
#endif
                }
Exemplo n.º 8
0
 /// <inheritdoc />
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     if (Logger.IsEnabled(MsLogLevel.Debug))
     {
         Logger.LogDebug("Channel {0} triggered user event [{1}]", ctx.Channel, evt);
     }
     ctx.FireUserEventTriggered(evt);
 }
Exemplo n.º 9
0
 public override void UserEventTriggered(IChannelHandlerContext context, object evt)
 {
     if (evt is IdleStateEvent idleStateEvent)
     {
         _userEvents.Add(idleStateEvent);
     }
     context.FireUserEventTriggered(evt);
 }
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     if (this.Logger.IsEnabled(this.InternalLevel))
     {
         this.Logger.Log(this.InternalLevel, this.Format(ctx, "USER_EVENT", evt));
     }
     ctx.FireUserEventTriggered(evt);
 }
Exemplo n.º 11
0
 public static void NotifyHandshakeFailure(IChannelHandlerContext ctx, Exception cause)
 {
     // We have may haven written some parts of data before an exception was thrown so ensure we always flush.
     // See https://github.com/netty/netty/issues/3900#issuecomment-172481830
     ctx.Flush();
     ctx.FireUserEventTriggered(new TlsHandshakeCompletionEvent(cause));
     ctx.CloseAsync();
 }
Exemplo n.º 12
0
        public override void UserEventTriggered(IChannelHandlerContext context, object evt)
        {
            var channel = context.Channel;

            if (evt is IdleStateEvent)
            {
                HeartBeatTimeoutEvent heartEvent = null;

                var eventState = evt as IdleStateEvent;
                if (eventState.State == IdleState.ReaderIdle)
                {
                    /*读超时*/
                    // 失败计数器次数大于等于3次的时候,关闭链接,等待client重连
                    if (unRecPingTimes >= MAX_UN_REC_PING_TIMES)
                    {
                        // 连续超过N次未收到client的ping消息,那么关闭该通道,等待client重连
                        heartEvent = new HeartBeatTimeoutEvent
                        {
                            Channel = channel,
                            State   = IdleState.ReaderIdle
                        };
                    }
                    else
                    {
                        // 失败计数器加1
                        unRecPingTimes++;
                    }
                }
                else if (eventState.State == IdleState.WriterIdle)
                {
                    /*写超时*/
                    heartEvent = new HeartBeatTimeoutEvent
                    {
                        Channel = context.Channel,
                        State   = IdleState.WriterIdle
                    };
                }
                else if (eventState.State == IdleState.AllIdle)
                {
                    /*总超时*/
                    heartEvent = new HeartBeatTimeoutEvent
                    {
                        Channel = context.Channel,
                        State   = IdleState.AllIdle
                    };
                }

                if (heartEvent != null)
                {
                    channel.Pipeline.FireUserEventTriggered(heartEvent);
                    channel.Pipeline.DisconnectAsync();
                }
            }
            else
            {
                context.FireUserEventTriggered(evt);
            }
        }
Exemplo n.º 13
0
 /// <inheritdoc />
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     if (evt is ChannelInputShutdownEvent)
     {
         // The decodeLast method is invoked when a channelInactive event is encountered.
         // This method is responsible for ending requests in some situations and must be called
         // when the input has been shutdown.
         ChannelInputClosed(ctx, false);
     }
     _ = ctx.FireUserEventTriggered(evt);
 }
Exemplo n.º 14
0
        /// <summary>
        /// Handles the cleartext HTTP upgrade event. If an upgrade occurred, sends a simple response via
        /// HTTP/2 on stream 1 (the stream specifically reserved for cleartext HTTP upgrade).
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="evt"></param>
        public sealed override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
        {
            if (evt == Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.Instance)
            {
                // The user event implies that we are on the client.
                TryExpandConnectionFlowControlWindow(Connection);

                // We schedule this on the EventExecutor to allow to have any extra handlers added to the pipeline
                // before we pass the event to the next handler. This is needed as the event may be called from within
                // handlerAdded(...) which will be run before other handlers will be added to the pipeline.
                ctx.Executor.Execute(() => ctx.FireUserEventTriggered(evt));
            }
            else if (evt is HttpServerUpgradeHandler.UpgradeEvent upgrade)
            {
                try
                {
                    OnUpgradeEvent(ctx, (HttpServerUpgradeHandler.UpgradeEvent)upgrade.Retain());
                    var stream = Connection.Stream(Http2CodecUtil.HttpUpgradeStreamId);
                    if (stream.GetProperty <IHttp2FrameStream>(_streamKey) is null)
                    {
                        // TODO: improve handler/stream lifecycle so that stream isn't active before handler added.
                        // The stream was already made active, but ctx may have been null so it wasn't initialized.
                        // https://github.com/netty/netty/issues/4942
                        OnStreamActive0(stream);
                    }
                    _ = upgrade.UpgradeRequest.Headers.SetInt(
                        HttpConversionUtil.ExtensionHeaderNames.StreamId, Http2CodecUtil.HttpUpgradeStreamId);
                    _ = stream.SetProperty(_upgradeKey, true);
                    InboundHttpToHttp2Adapter.Handle(
                        ctx, Connection, Decoder.FrameListener, (IFullHttpMessage)upgrade.UpgradeRequest.Retain());
                }
                finally
                {
                    _ = upgrade.Release();
                }
            }
            else
            {
                _ = ctx.FireUserEventTriggered(evt);
            }
        }
        public override void ChannelRead(IChannelHandlerContext ctx, object msg)
        {
            var req = (IFullHttpRequest)msg;

            if (this.IsNotWebSocketPath(req))
            {
                ctx.FireChannelRead(msg);
                return;
            }

            try
            {
                if (!Equals(req.Method, Get))
                {
                    SendHttpResponse(ctx, req, new DefaultFullHttpResponse(Http11, Forbidden));
                    return;
                }

                var wsFactory = new WebSocketServerHandshakerFactory(
                    GetWebSocketLocation(ctx.Channel.Pipeline, req, this.websocketPath), this.subprotocols,
                    this.allowExtensions, this.maxFramePayloadSize, this.allowMaskMismatch);
                WebSocketServerHandshaker handshaker = wsFactory.NewHandshaker(req);
                if (handshaker == null)
                {
                    WebSocketServerHandshakerFactory.SendUnsupportedVersionResponse(ctx.Channel);
                }
                else
                {
                    Task task = handshaker.HandshakeAsync(ctx.Channel, req);
                    task.ContinueWith(t =>
                    {
                        if (t.Status != TaskStatus.RanToCompletion)
                        {
                            ctx.FireExceptionCaught(t.Exception);
                        }
                        else
                        {
                            ctx.FireUserEventTriggered(new WebSocketServerProtocolHandler.HandshakeComplete(
                                                           req.Uri, req.Headers, handshaker.SelectedSubprotocol));
                        }
                    },
                                      TaskContinuationOptions.ExecuteSynchronously);

                    WebSocketServerProtocolHandler.SetHandshaker(ctx.Channel, handshaker);
                    ctx.Channel.Pipeline.Replace(this, "WS403Responder",
                                                 WebSocketServerProtocolHandler.ForbiddenHttpRequestResponder());
                }
            }
            finally
            {
                req.Release();
            }
        }
Exemplo n.º 16
0
        public override void UserEventTriggered(IChannelHandlerContext context, object @event)
        {
            var handshakeCompletionEvent = @event as TlsHandshakeCompletionEvent;

            if (handshakeCompletionEvent != null && !handshakeCompletionEvent.IsSuccessful)
            {
                CommonEventSource.Log.Warning("TLS handshake failed.", handshakeCompletionEvent.Exception.ToString());
            }

            // send it down to the MqttAdapter
            context.FireUserEventTriggered(@event);
        }
Exemplo n.º 17
0
 public override void UserEventTriggered(IChannelHandlerContext context, object evt)
 {
     //用户断开连接事件。。包括超时。客户端主动断开
     if (evt is ClientDisconnectEvent)
     {
         var eventState = evt as ClientDisconnectEvent;
         var child      = eventState.Channel;
         channelGroup.Remove(child);
     }
     else
     {
         context.FireUserEventTriggered(evt);
     }
 }
Exemplo n.º 18
0
 public override void UserEventTriggered(IChannelHandlerContext context, object evt)
 {
     //心跳超时状态
     if (evt is HeartBeatTimeoutEvent)
     {
         var eventState = evt as HeartBeatTimeoutEvent;
         messageHandler.HandlerTimeout(eventState.Channel);
     }
     else if (evt is HandShakeEvent)
     {
         //当客户端连接成功后.会触发握手事件.然后主动向客户端推送sid和clienid
         var response = messageFactory.CreateHandShake(channelGroup.FindConnectionInfo(context.Channel));
         context.Channel.WriteAndFlushAsync(response);
     }
     context.FireUserEventTriggered(evt);
 }
Exemplo n.º 19
0
        protected override void ChannelRead0(IChannelHandlerContext ctx, IObject msg)
        {
            switch (msg)
            {
            case TResPQ resPq:
                Guard.That(resPq.Nonce).IsItemsEquals(_nonce);

                Log.Debug($"#{ClientSettings.ClientSession.SessionId}: TResPQ step complete");

                var requestReqDhParams = Step2ClientHelper.GetRequest(resPq, ClientSettings.PublicKey, out _newNonce);
                ctx.WriteAndFlushAsync(requestReqDhParams);
                break;

            case TServerDHParamsOk dhParamsOk:
                Log.Debug($"#{ClientSettings.ClientSession.SessionId}: TServerDHParamsOk step complete");

                var request = Step3ClientHelper.GetRequest(dhParamsOk, _newNonce, out _clientAgree, out var serverTime);
                ClientSettings.ClientSession.TimeOffset = serverTime - (int)DateTimeOffset.Now.ToUnixTimeSeconds();

                SessionWriter.Save(ClientSettings.ClientSession)
                .ContinueWith(_ => ctx.WriteAndFlushAsync(request));

                break;

            case TDhGenOk dhGenOk:
                Log.Debug($"#{ClientSettings.ClientSession.SessionId}: TDhGenOk step complete");

                ClientSettings.ClientSession.AuthKey    = new AuthKey(_clientAgree);
                ClientSettings.ClientSession.ServerSalt = SaltHelper.ComputeSalt(_newNonce, dhGenOk.ServerNonce);

                SessionWriter.Save(ClientSettings.ClientSession)
                .ContinueWith(_ => ctx.FireUserEventTriggered(ESystemNotification.HandshakeComplete));
                break;

            case TServerDHParamsFail _:
            case TDhGenRetry _:
            case TDhGenFail _:
                throw new NotSupportedException();

            default:
                ctx.FireChannelRead(msg);
                break;
            }
        }
Exemplo n.º 20
0
        private void WriteIdle(IChannelHandlerContext context)
        {
            if (Open == false)
            {
                return;
            }
            var delay = _lastWriteTime.Add(_writerIdleTime) - DateTime.Now;

            if (delay.Ticks <= 0)
            {
                context.Channel.EventExecutor.Schedule(() => { WriteIdle(context); }, _writerIdleTime);
                //触发写空闲事件
                var first = _firstWriterIdleEvent;
                _firstWriterIdleEvent = false;
                context.FireUserEventTriggered(new IdleStateEvent(IdleState.WriterIdle, first));
            }
            else
            {
                context.Channel.EventExecutor.Schedule(() => { WriteIdle(context); }, delay);
            }
        }
        public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
        {
            if (evt is TlsHandshakeCompletionEvent handshakeEvent)
            {
                try
                {
                    if (handshakeEvent.IsSuccessful)
                    {
                        var sslHandler = ctx.Pipeline.Get <TlsHandler>();
                        if (sslHandler is null)
                        {
                            ThrowInvalidOperationException();
                        }

                        var protocol = sslHandler.NegotiatedApplicationProtocol;
                        this.ConfigurePipeline(ctx, !protocol.Protocol.IsEmpty ? protocol : fallbackProtocol);
                    }
                    else
                    {
                        this.HandshakeFailure(ctx, handshakeEvent.Exception);
                    }
                }
                catch (Exception exc)
                {
                    this.ExceptionCaught(ctx, exc);
                }
                finally
                {
                    var pipeline = ctx.Pipeline;
                    if (pipeline.Context(this) is object)
                    {
                        pipeline.Remove(this);
                    }
                }
            }

            ctx.FireUserEventTriggered(evt);
        }
Exemplo n.º 22
0
        public override Task WriteAsync(IChannelHandlerContext context, object message)
        {
            if (!(message is IHttpRequest))
            {
                return(context.WriteAsync(message));
            }

            if (this.upgradeRequested)
            {
                return(TaskEx.FromException(new InvalidOperationException("Attempting to write HTTP request with upgrade in progress")));
            }

            this.upgradeRequested = true;
            this.SetUpgradeRequestHeaders(context, (IHttpRequest)message);

            // Continue writing the request.
            Task task = context.WriteAsync(message);

            // Notify that the upgrade request was issued.
            context.FireUserEventTriggered(UpgradeEvent.UpgradeIssued);
            // Now we wait for the next HTTP response to see if we switch protocols.
            return(task);
        }
Exemplo n.º 23
0
        /// <inheritdoc />
        public override void Write(IChannelHandlerContext context, object message, IPromise promise)
        {
            if (!(message is IHttpRequest request))
            {
                _ = context.WriteAsync(message, promise);
                return;
            }

            if (this.upgradeRequested)
            {
                Util.SafeSetFailure(promise, ThrowHelper.GetInvalidOperationException_Attempting(), Logger);
                return;
            }

            this.upgradeRequested = true;
            this.SetUpgradeRequestHeaders(context, request);

            // Continue writing the request.
            _ = context.WriteAsync(message, promise);

            // Notify that the upgrade request was issued.
            _ = context.FireUserEventTriggered(UpgradeEvent.UpgradeIssued);
            // Now we wait for the next HTTP response to see if we switch protocols.
        }
        bool Upgrade(IChannelHandlerContext ctx, IFullHttpRequest request)
        {
            // Select the best protocol based on those requested in the UPGRADE header.
            IList <ICharSequence> requestedProtocols = SplitHeader(request.Headers.Get(HttpHeaderNames.Upgrade, null));
            int           numRequestedProtocols      = requestedProtocols.Count;
            IUpgradeCodec upgradeCodec    = null;
            ICharSequence upgradeProtocol = null;

            for (int i = 0; i < numRequestedProtocols; i++)
            {
                ICharSequence p = requestedProtocols[i];
                IUpgradeCodec c = this.upgradeCodecFactory.NewUpgradeCodec(p);
                if (c != null)
                {
                    upgradeProtocol = p;
                    upgradeCodec    = c;
                    break;
                }
            }

            if (upgradeCodec == null)
            {
                // None of the requested protocols are supported, don't upgrade.
                return(false);
            }

            // Make sure the CONNECTION header is present.
            if (!request.Headers.TryGet(HttpHeaderNames.Connection, out ICharSequence connectionHeader))
            {
                return(false);
            }

            // Make sure the CONNECTION header contains UPGRADE as well as all protocol-specific headers.
            ICollection <AsciiString> requiredHeaders = upgradeCodec.RequiredUpgradeHeaders;
            IList <ICharSequence>     values          = SplitHeader(connectionHeader);

            if (!AsciiString.ContainsContentEqualsIgnoreCase(values, HttpHeaderNames.Upgrade) ||
                !AsciiString.ContainsAllContentEqualsIgnoreCase(values, requiredHeaders))
            {
                return(false);
            }

            // Ensure that all required protocol-specific headers are found in the request.
            foreach (AsciiString requiredHeader in requiredHeaders)
            {
                if (!request.Headers.Contains(requiredHeader))
                {
                    return(false);
                }
            }

            // Prepare and send the upgrade response. Wait for this write to complete before upgrading,
            // since we need the old codec in-place to properly encode the response.
            IFullHttpResponse upgradeResponse = CreateUpgradeResponse(upgradeProtocol);

            if (!upgradeCodec.PrepareUpgradeResponse(ctx, request, upgradeResponse.Headers))
            {
                return(false);
            }

            // Create the user event to be fired once the upgrade completes.
            var upgradeEvent = new UpgradeEvent(upgradeProtocol, request);

            IUpgradeCodec finalUpgradeCodec = upgradeCodec;

            ctx.WriteAndFlushAsync(upgradeResponse).ContinueWith(t =>
            {
                try
                {
                    if (t.Status == TaskStatus.RanToCompletion)
                    {
                        // Perform the upgrade to the new protocol.
                        this.sourceCodec.UpgradeFrom(ctx);
                        finalUpgradeCodec.UpgradeTo(ctx, request);

                        // Notify that the upgrade has occurred. Retain the event to offset
                        // the release() in the finally block.
                        ctx.FireUserEventTriggered(upgradeEvent.Retain());

                        // Remove this handler from the pipeline.
                        ctx.Channel.Pipeline.Remove(this);
                    }
                    else
                    {
                        ctx.Channel.CloseAsync();
                    }
                }
                finally
                {
                    // Release the event if the upgrade event wasn't fired.
                    upgradeEvent.Release();
                }
            }, TaskContinuationOptions.ExecuteSynchronously);
            return(true);
        }
 public IChannelHandlerContext FireUserEventTriggered(object evt)
 {
     _ = _ctx.FireUserEventTriggered(evt);
     return(this);
 }
Exemplo n.º 26
0
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     _log.Debug("Channel {0} triggered user event [{1}]", ctx.Channel, evt);
     ctx.FireUserEventTriggered(evt);
 }
 public override void UserEventTriggered(IChannelHandlerContext context, object evt)
 {
     s_logger.LogInformation("User Event Triggered: " + evt);
     context.FireUserEventTriggered(evt);
 }
Exemplo n.º 28
0
        /// <summary>
        /// Decodes the byte buffer and builds QuickBlockTransfer packets.
        /// </summary>
        /// <param name="context">The handler context.</param>
        /// <param name="input">The input byte buffer from the socket.</param>
        /// <param name="output">The output packets.</param>
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
        {
            switch (State)
            {
                case DecoderState.ReSync:
                    if (!input.IsReadable(QuickBlockV1BodySize + FrameSyncBytes)) break;
                    PerformanceCounters.FrameSyncTotal.Increment();
                    if (!SynchronizeFrame(input)) break;
                    State = DecoderState.StartFrame;
                    goto case DecoderState.StartFrame;

                case DecoderState.StartFrame:
                    if (!SkipNullBytes(input)) break;
                    State = DecoderState.FrameType;
                    goto case DecoderState.FrameType;

                case DecoderState.FrameType:
                    if (!input.IsReadable(QuickBlockHeaderSize)) break;
                    if (IsDataBlockHeader(input))
                    {
                        State = DecoderState.BlockHeader;
                        goto case DecoderState.BlockHeader;
                    }
                    if (IsServerList(input))
                    {
                        PerformanceCounters.ServerListReceivedTotal.Increment();
                        State = DecoderState.ServerList;
                        goto case DecoderState.ServerList;
                    }
                    throw new InvalidOperationException("Unknown frame type");

                case DecoderState.ServerList:
                    var content = ReadString(input);
                    if (content.Length == 0) break;
                    context.FireUserEventTriggered(ParseServerList(content));
                    State = DecoderState.StartFrame;
                    goto case DecoderState.StartFrame;

                case DecoderState.BlockHeader:
                    Packet = ParsePacketHeader(input);
                    PerformanceCounters.BlocksReceivedTotal.Increment();
                    if (Packet.Version == 2)
                        PerformanceCounters.CompressedBlocksReceivedTotal.Increment();
                    State = DecoderState.BlockBody;
                    goto case DecoderState.BlockBody;

                case DecoderState.BlockBody:
                    if (!input.IsReadable(Packet.Length)) break;
                    Packet.Content = ReadPacketBody(input, Packet.Length, Packet.Version);
                    PerformanceCounters.BlocksProcessedPerSecond.Increment();
                    State = DecoderState.Validate;
                    goto case DecoderState.Validate;

                case DecoderState.Validate:
                    if (Packet.TotalBlocks <= 0 || Packet.BlockNumber <= 0)
                    {
                        PerformanceCounters.ChecksumErrorsTotal.Increment();
                        throw new InvalidDataException("Header block values out of range. " + Packet);
                    }

                    if (VerifyChecksum(Packet.Content, Packet.Checksum))
                    {
                        ByteBlasterEventSource.Log.PacketCreated(Packet.ToString());
                        context.FireUserEventTriggered(Packet);
                    }
                    else
                    {
                        PerformanceCounters.ChecksumErrorsTotal.Increment();
                        throw new InvalidDataException("Block Checksum failed. " + Packet);
                    }

                    State = DecoderState.StartFrame;
                    goto case DecoderState.StartFrame;

                default:
                    throw new InvalidOperationException("Unknown Decoder State: " + State);
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// Decodes the byte buffer and builds QuickBlockTransfer packets.
        /// </summary>
        /// <param name="context">The handler context.</param>
        /// <param name="input">The input byte buffer from the socket.</param>
        /// <param name="output">The output packets.</param>
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            switch (State)
            {
            case DecoderState.ReSync:
                if (!input.IsReadable(QuickBlockV1BodySize + FrameSyncBytes))
                {
                    break;
                }
                PerformanceCounters.FrameSyncTotal.Increment();
                if (!SynchronizeFrame(input))
                {
                    break;
                }
                State = DecoderState.StartFrame;
                goto case DecoderState.StartFrame;

            case DecoderState.StartFrame:
                if (!SkipNullBytes(input))
                {
                    break;
                }
                State = DecoderState.FrameType;
                goto case DecoderState.FrameType;

            case DecoderState.FrameType:
                if (!input.IsReadable(QuickBlockHeaderSize))
                {
                    break;
                }
                if (IsDataBlockHeader(input))
                {
                    State = DecoderState.BlockHeader;
                    goto case DecoderState.BlockHeader;
                }
                if (IsServerList(input))
                {
                    PerformanceCounters.ServerListReceivedTotal.Increment();
                    State = DecoderState.ServerList;
                    goto case DecoderState.ServerList;
                }
                throw new InvalidOperationException("Unknown frame type");

            case DecoderState.ServerList:
                var content = ReadString(input);
                if (content.Length == 0)
                {
                    break;
                }
                context.FireUserEventTriggered(ParseServerList(content));
                State = DecoderState.StartFrame;
                goto case DecoderState.StartFrame;

            case DecoderState.BlockHeader:
                Packet = ParsePacketHeader(input);
                PerformanceCounters.BlocksReceivedTotal.Increment();
                if (Packet.Version == 2)
                {
                    PerformanceCounters.CompressedBlocksReceivedTotal.Increment();
                }
                State = DecoderState.BlockBody;
                goto case DecoderState.BlockBody;

            case DecoderState.BlockBody:
                if (!input.IsReadable(Packet.Length))
                {
                    break;
                }
                Packet.Content = ReadPacketBody(input, Packet.Length, Packet.Version);
                PerformanceCounters.BlocksProcessedPerSecond.Increment();
                State = DecoderState.Validate;
                goto case DecoderState.Validate;

            case DecoderState.Validate:
                if (Packet.TotalBlocks <= 0 || Packet.BlockNumber <= 0)
                {
                    PerformanceCounters.ChecksumErrorsTotal.Increment();
                    throw new InvalidDataException("Header block values out of range. " + Packet);
                }

                if (VerifyChecksum(Packet.Content, Packet.Checksum))
                {
                    ByteBlasterEventSource.Log.PacketCreated(Packet.ToString());
                    context.FireUserEventTriggered(Packet);
                }
                else
                {
                    PerformanceCounters.ChecksumErrorsTotal.Increment();
                    throw new InvalidDataException("Block Checksum failed. " + Packet);
                }

                State = DecoderState.StartFrame;
                goto case DecoderState.StartFrame;

            default:
                throw new InvalidOperationException("Unknown Decoder State: " + State);
            }
        }
Exemplo n.º 30
0
 public static void NotifyHandshakeFailure(IChannelHandlerContext ctx, Exception cause)
 {
     // We have may haven written some parts of data before an exception was thrown so ensure we always flush.
     // See https://github.com/netty/netty/issues/3900#issuecomment-172481830
     ctx.Flush();
     ctx.FireUserEventTriggered(new TlsHandshakeCompletionEvent(cause));
     ctx.CloseAsync();
 }
Exemplo n.º 31
0
 /// <summary>
 /// Is called when an <see cref="IdleStateEvent"/> should be fired. This implementation calls
 /// <see cref="IChannelHandlerContext.FireUserEventTriggered(object)"/>.
 /// </summary>
 /// <param name="context">Context.</param>
 /// <param name="stateEvent">Evt.</param>
 protected void ChannelIdle(IChannelHandlerContext context, IdleStateEvent stateEvent)
 {
     context.FireUserEventTriggered(stateEvent);
 }
Exemplo n.º 32
0
 public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
 {
     if (this.Logger.IsEnabled(this.InternalLevel))
     {
         this.Logger.Log(this.InternalLevel, this.Format(ctx, "USER_EVENT", evt));
     }
     ctx.FireUserEventTriggered(evt);
 }
Exemplo n.º 33
0
 public virtual void UserEventTriggered(IChannelHandlerContext context, object evt) => context.FireUserEventTriggered(evt);
Exemplo n.º 34
0
        /// <summary>
        /// Attempts to upgrade to the protocol(s) identified by the <see cref="HttpHeaderNames.Upgrade"/> header (if provided
        /// in the request).
        /// </summary>
        /// <param name="ctx">the context for this handler.</param>
        /// <param name="request">the HTTP request.</param>
        /// <returns><c>true</c> if the upgrade occurred, otherwise <c>false</c>.</returns>
        bool Upgrade(IChannelHandlerContext ctx, IFullHttpRequest request)
        {
            // Select the best protocol based on those requested in the UPGRADE header.
            var           requestedProtocols    = SplitHeader(request.Headers.Get(HttpHeaderNames.Upgrade, null));
            int           numRequestedProtocols = requestedProtocols.Count;
            IUpgradeCodec upgradeCodec          = null;
            ICharSequence upgradeProtocol       = null;

            for (int i = 0; i < numRequestedProtocols; i++)
            {
                ICharSequence p = requestedProtocols[i];
                IUpgradeCodec c = this.upgradeCodecFactory.NewUpgradeCodec(p);
                if (c is object)
                {
                    upgradeProtocol = p;
                    upgradeCodec    = c;
                    break;
                }
            }

            if (upgradeCodec is null)
            {
                // None of the requested protocols are supported, don't upgrade.
                return(false);
            }

            // Make sure the CONNECTION header is present.
            var connectionHeaderValues = request.Headers.GetAll(HttpHeaderNames.Connection);

            if (connectionHeaderValues is null)
            {
                return(false);
            }

            var concatenatedConnectionValue = StringBuilderManager.Allocate(connectionHeaderValues.Count * 10);

            for (var idx = 0; idx < connectionHeaderValues.Count; idx++)
            {
                var connectionHeaderValue = connectionHeaderValues[idx];
                _ = concatenatedConnectionValue
                    .Append(connectionHeaderValue.ToString())
                    .Append(StringUtil.Comma);
            }
            concatenatedConnectionValue.Length -= 1;

            // Make sure the CONNECTION header contains UPGRADE as well as all protocol-specific headers.
            var requiredHeaders = upgradeCodec.RequiredUpgradeHeaders;
            var values          = SplitHeader(StringBuilderManager.ReturnAndFree(concatenatedConnectionValue).AsSpan());

            if (!AsciiString.ContainsContentEqualsIgnoreCase(values, HttpHeaderNames.Upgrade) ||
                !AsciiString.ContainsAllContentEqualsIgnoreCase(values, requiredHeaders))
            {
                return(false);
            }

            // Ensure that all required protocol-specific headers are found in the request.
            for (int idx = 0; idx < requiredHeaders.Count; idx++)
            {
                if (!request.Headers.Contains(requiredHeaders[idx]))
                {
                    return(false);
                }
            }

            // Prepare and send the upgrade response. Wait for this write to complete before upgrading,
            // since we need the old codec in-place to properly encode the response.
            IFullHttpResponse upgradeResponse = CreateUpgradeResponse(upgradeProtocol);

            if (!upgradeCodec.PrepareUpgradeResponse(ctx, request, upgradeResponse.Headers))
            {
                return(false);
            }

            // Create the user event to be fired once the upgrade completes.
            var upgradeEvent = new UpgradeEvent(upgradeProtocol, request);

            // After writing the upgrade response we immediately prepare the
            // pipeline for the next protocol to avoid a race between completion
            // of the write future and receiving data before the pipeline is
            // restructured.
            try
            {
                var writeComplete = ctx.WriteAndFlushAsync(upgradeResponse);

                // Perform the upgrade to the new protocol.
                this.sourceCodec.UpgradeFrom(ctx);
                upgradeCodec.UpgradeTo(ctx, request);

                // Remove this handler from the pipeline.
                _ = ctx.Pipeline.Remove(this);

                // Notify that the upgrade has occurred. Retain the event to offset
                // the release() in the finally block.
                _ = ctx.FireUserEventTriggered(upgradeEvent.Retain());

                // Add the listener last to avoid firing upgrade logic after
                // the channel is already closed since the listener may fire
                // immediately if the write failed eagerly.
                _ = writeComplete.ContinueWith(CloseOnFailureAction, ctx, TaskContinuationOptions.ExecuteSynchronously);
            }
            finally
            {
                // Release the event if the upgrade event wasn't fired.
                _ = upgradeEvent.Release();
            }
            return(true);
        }