예제 #1
0
        public void Abort(ConnectionAbortedException error)
        {
            lock (_writeLock)
            {
                if (_aborted)
                {
                    return;
                }

                _aborted = true;
                _connectionContext.Abort(error);

                Complete();
            }
        }
예제 #2
0
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            var context = connection.GetHttpContext();

            if (context == null || !context.WebSockets.IsWebSocketRequest)
            {
                connection.Abort();
                return;
            }

            var websocket = await context.WebSockets.AcceptWebSocketAsync()
                            .ConfigureAwait(false);

            var node = new NodeInfo {
                Address = new IPEndPoint(context.Connection.RemoteIpAddress, context.Connection.RemotePort),
                Socket  = websocket
            };

            _blockchain.AddNode(node);
            _logger.LogInformation($"Added node with {node.Address} address.");

            node.ReceiveAsync()
            .ConfigureAwait(false);

            _logger.LogInformation($"Receiving data from {node.Address} address.");
        }
예제 #3
0
        /// <summary>
        /// Check if the client is allowed to connect based on certain criteria.
        /// </summary>
        /// <returns>When criteria is met returns <c>true</c>, to allow connection.</returns>
        private bool EnsurePeerCanConnect(ConnectionContext connection, IPeerContext peerContext)
        {
            if (_serverPeerConnectionGuards == null)
            {
                return(false);
            }

            ServerPeerConnectionGuardResult?result = (
                from guard in _serverPeerConnectionGuards
                let guardResult = guard.Check(peerContext)
                                  where guardResult.IsDenied
                                  select guardResult
                )
                                                     .DefaultIfEmpty(ServerPeerConnectionGuardResult.Success)
                                                     .FirstOrDefault();

            if (result == null)
            {
                return(true);             // no guards
            }
            if (result.IsDenied)
            {
                _logger.LogDebug("Connection from client '{ConnectingPeerEndPoint}' was rejected because of {ClientDisconnectedReason} and will be closed.", connection.RemoteEndPoint, result.DenyReason);
                connection.Abort(new ConnectionAbortedException(result.DenyReason));
                _eventBus.Publish(new PeerConnectionRejected(peerContext, result.DenyReason));
                return(false);
            }

            return(true);
        }
예제 #4
0
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            if (connection is null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            using IDisposable loggerScope = _logger.BeginScope("Peer {PeerId} connected to server {ServerEndpoint}", connection.ConnectionId, connection.LocalEndPoint);

            ProtocolReader reader = connection.CreateReader();
            INetworkProtocolMessageSerializer protocol = _serviceProvider.GetRequiredService <INetworkProtocolMessageSerializer>();

            using IPeerContext peerContext = _peerContextFactory.CreateIncomingPeerContext(connection.ConnectionId,
                                                                                           connection.LocalEndPoint !.AsIPEndPoint().EnsureIPv6(),
                                                                                           connection.RemoteEndPoint !.AsIPEndPoint().EnsureIPv6(),
                                                                                           new NetworkMessageWriter(protocol, connection.CreateWriter()));

            using CancellationTokenRegistration cancellationRegistration = peerContext.ConnectionCancellationTokenSource.Token.Register(() =>
            {
                connection.Abort(new ConnectionAbortedException("Requested by PeerContext"));
            });

            connection.Features.Set(peerContext);
            protocol.SetPeerContext(peerContext);

            if (EnsurePeerCanConnect(connection, peerContext))
            {
                _eventBus.Publish(new PeerConnected(peerContext));

                await _networkMessageProcessorFactory.StartProcessorsAsync(peerContext).ConfigureAwait(false);

                while (true)
                {
                    try
                    {
                        ProtocolReadResult <INetworkMessage> result = await reader.ReadAsync(protocol).ConfigureAwait(false);

                        if (result.IsCompleted)
                        {
                            break;
                        }

                        await ProcessMessageAsync(result.Message, peerContext, connection.ConnectionClosed).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogDebug(ex, "Unexpected connection terminated because of {DisconnectionReason}.", ex.Message);
                        break;
                    }
                    finally
                    {
                        reader.Advance();
                    }
                }

                return;
            }
        }
예제 #5
0
        public async Task OnConnectedAsync(ConnectionContext connectionContext)
        {
            if (_cancellationTokenSource.IsCancellationRequested || _shuttingDown)
            {
                connectionContext.Abort();
            }
            else
            {
                connectionContext.ConnectionId = Guid.NewGuid().ToString("N");
                var networkConnection = new TelnetConnection(_messageService, (TransportConnection)connectionContext,
                                                             _cancellationTokenSource);
                var linkedTokenSource = networkConnection.GetLinkedTokenSource();
                if (_connections.TryAdd(connectionContext.ConnectionId, networkConnection))
                {
                    _logger.LogInformation(connectionContext.ConnectionId + " connected");
                    try
                    {
                        networkConnection.Send(_initialCommunication);
                        while (!linkedTokenSource.IsCancellationRequested)
                        {
                            var result = await connectionContext.Transport.Input.ReadAsync(linkedTokenSource.Token);

                            var buffer = result.Buffer;
                            try
                            {
                                if (!buffer.IsEmpty)
                                {
                                    networkConnection.Receive(buffer.ToArray());
                                }
                                else if (result.IsCompleted)
                                {
                                    break;
                                }
                            }
                            finally
                            {
                                connectionContext.Transport.Input.AdvanceTo(buffer.End);
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        // Expected
                    }
                    finally
                    {
                        if (_connections.TryRemove(connectionContext.ConnectionId, out var connection))
                        {
                            connection.Close(false);
                            _logger.LogInformation(connectionContext.ConnectionId + " disconnected");
                        }
                    }
                }
            }
        }
        public async Task StartAsync()
        {
            _context = await _client.ConnectAsync(RemoteEndPoint, _cts.Token).ConfigureAwait(false);

            _protocol    = new RabbitMQProtocol(_context);
            Channel0     = new RabbitMQChannelZero(_builder, _protocol);
            _readingTask = StartReading();
            bool openned = await Channel0.TryOpenChannelAsync().ConfigureAwait(false);

            if (!openned)
            {
                _context.Abort();
                _cts.Cancel();
                return;
            }
        }
예제 #7
0
        public void Abort(ConnectionAbortedException error)
        {
            // Abort can be called after Dispose if there's a flush timeout.
            // It's important to still call _lifetimeFeature.Abort() in this case.

            lock (_contextLock)
            {
                if (_aborted)
                {
                    return;
                }

                _aborted = true;
                _connectionContext.Abort(error);
                Dispose();
            }
        }
예제 #8
0
        /// <summary>
        /// on connected as an asynchronous operation.
        /// </summary>
        /// <param name="connection">The new <see cref="T:Microsoft.AspNetCore.Connections.ConnectionContext" /></param>
        /// <returns>A <see cref="T:System.Threading.Tasks.Task" /> that represents the connection lifetime. When the task completes, the connection is complete.</returns>
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            this.context = connection;
            this.reader  = connection.CreateReader();
            this.writer  = connection.CreateWriter();

            SessionManager.Singleton.AcceptSession(connection, writer, this.protocol);

            //IConnectionHeartbeatFeature heartbeatFeature = connection.Features.Get<IConnectionHeartbeatFeature>();
            //heartbeatFeature.OnHeartbeat(this.SendHeartbeat, null);

            while (true)
            {
                try
                {
                    var result = await reader.ReadAsync(protocol);

                    var message = result.Message;

                    _logger.LogInformation("Received a message of {Length} bytes", message.Payload.Length);

                    if (result.IsCompleted)
                    {
                        break;
                    }



                    await writer.WriteAsync(protocol, message);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message);
                    connection.Abort();
                    break;
                }
                finally
                {
                    reader.Advance();
                }
            }
        }
예제 #9
0
        private static void Release(ConnectionContext connection)
        {
            try
            {
                connection.Abort(new ConnectionAbortedException("Failed socket verification."));
            }
            catch (Exception ex)
            {
                NetState.TraceException(ex);
            }

            try
            {
                // TODO: Is this needed?
                connection.DisposeAsync();
            }
            catch (Exception ex)
            {
                NetState.TraceException(ex);
            }
        }
예제 #10
0
        /// <summary>
        /// Check if the client is allowed to connect based on certain criteria.
        /// </summary>
        /// <returns>When criteria is met returns <c>true</c>, to allow connection.</returns>
        private void EnsurePeerCanConnect(ConnectionContext connection)
        {
            if (this.serverPeerConnectionGuards == null)
            {
                return;
            }

            IPeerContext peerContext = new PeerContext((IPEndPoint)connection.LocalEndPoint, (IPEndPoint)connection.RemoteEndPoint);

            ServerPeerConnectionGuardResult result = (
                from guard in this.serverPeerConnectionGuards
                let guardResult = guard.Check(peerContext)
                                  where guardResult.IsDenied
                                  select guardResult
                )
                                                     .DefaultIfEmpty(ServerPeerConnectionGuardResult.Success)
                                                     .FirstOrDefault();

            if (result.IsDenied)
            {
                this.logger.LogDebug("Connection from client '{ConnectingPeerEndPoint}' was rejected because of {ClientDisconnectedReason} and will be closed.", connection.RemoteEndPoint, result.DenyReason);
                connection.Abort(new ConnectionAbortedException(result.DenyReason));
            }
        }
예제 #11
0
 public override void Abort()
 {
     _inner.Abort();
 }
예제 #12
0
 public void Abort()
 {
     _context.Abort();
 }
        private async Task StartReading()
        {
            var headerReader = new FrameHeaderReader();

            try
            {
                while (true)
                {
                    var result = await _protocol.Reader.ReadAsync(headerReader, _cts.Token).ConfigureAwait(false);

                    _protocol.Reader.Advance();
                    if (result.IsCompleted)
                    {
                        break;
                    }
                    var header = result.Message;
                    // Debug.WriteLine($"{header.FrameType} {header.Channel} {header.PaylodaSize}");
                    switch (header.FrameType)
                    {
                    case 1:
                    {
                        if (header.Channel == 0)
                        {
                            await Channel0.HandleAsync(header).ConfigureAwait(false);

                            break;
                        }
                        await ProcessChannels(header).ConfigureAwait(false);

                        break;
                    }

                    case 2:
                    {
                        await ProcessChannels(header).ConfigureAwait(false);

                        break;
                    }

                    case 8:
                    {
                        await _protocol.Reader.ReadAsync(new NoPayloadReader()).ConfigureAwait(false);

                        _protocol.Reader.Advance();
                        await _protocol.Writer.WriteAsync(new HeartbeatWriter(), false).ConfigureAwait(false);

                        break;
                    }


                    default: throw new Exception($"Frame type missmatch:{header.FrameType}, {header.Channel}, {header.PaylodaSize}");
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                _context.Abort();
                _cts.Cancel();
                _endReading.SetResult(false);
            }
        }