Exemple #1
0
        private void OnClientConnected(Tcp con, IPEndPoint endpointConfig, Loop loop)
        {
            try
            {
                var remoteEndPoint = con.GetPeerEndPoint();

                // get rid of banned clients as early as possible
                if (banManager?.IsBanned(remoteEndPoint.Address) == true)
                {
                    logger.Debug(() => $"[{LogCat}] Disconnecting banned ip {remoteEndPoint.Address}");
                    con.Dispose();
                    return;
                }

                var connectionId = CorrelationIdGenerator.GetNextId();
                logger.Debug(() => $"[{LogCat}] Accepting connection [{connectionId}] from {remoteEndPoint.Address}:{remoteEndPoint.Port}");

                // setup client connection
                con.KeepAlive(true, 1);

                // setup client
                var client = new StratumClient();

                client.Init(loop, con, ctx, clock, endpointConfig, connectionId,
                            data => OnReceive(client, data),
                            () => OnReceiveComplete(client),
                            ex => OnReceiveError(client, ex));

                // register client
                lock (clients)
                {
                    clients[connectionId] = client;
                }

                OnConnect(client);
            }

            catch (Exception ex)
            {
                logger.Error(ex, () => nameof(OnClientConnected));
            }
        }
        private void OnClientConnected(Tcp con, IPEndPoint endpointConfig, Loop loop)
        {
            try
            {
                var remoteEndPoint = con.GetPeerEndPoint();

                // get rid of banned clients as early as possible
                if (banManager?.IsBanned(remoteEndPoint.Address) == true)
                {
                    logger.Debug(() => $"[{LogCat}] Disconnecting banned ip {remoteEndPoint.Address}");
                    con.Dispose();
                    return;
                }

                var connectionId = CorrelationIdGenerator.GetNextId();
                logger.Debug(() => $"[{LogCat}] Accepting connection [{connectionId}] from {remoteEndPoint.Address}:{remoteEndPoint.Port}");

                // setup client
                var client = new StratumClient <TClientContext>();
                client.Init(loop, con, ctx, endpointConfig, connectionId);

                // request subscription
                var sub = client.Received
                          .Select(data => Observable.FromAsync(() => Task.Run(() => // get off of LibUV event-loop-thread immediately
                {
                    // boot pre-connected clients
                    if (banManager?.IsBanned(client.RemoteEndpoint.Address) == true)
                    {
                        logger.Info(() => $"[{LogCat}] [{connectionId}] Disconnecting banned client @ {remoteEndPoint.Address}");
                        DisconnectClient(client);
                        data.Dispose();
                        return(Unit.Default);
                    }

                    logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Received request data: {StratumClient<TClientContext>.Encoding.GetString(data.Array, 0, data.Size)}");

                    // parse request
                    var request = ParseRequest(data);

                    logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Dispatching request '{request.Method}' [{request.Id}]");

                    try
                    {
                        // dispatch request
                        OnRequestAsync(client, new Timestamped <JsonRpcRequest>(request, clock.UtcNow)).Wait();
                    }

                    catch (Exception ex)
                    {
                        logger.Error(ex, () => $"[{LogCat}] [{client.ConnectionId}] Error processing request {request.Method} [{request.Id}]");
                    }

                    return(Unit.Default);
                })))
                          .Concat()
                          .Subscribe(_ => { }, ex => OnReceiveError(client, ex), () => OnReceiveComplete(client));

                // ensure subscription is disposed on loop thread
                var disposer = loop.CreateAsync((handle) =>
                {
                    sub.Dispose();

                    handle.Dispose();
                });

                client.Subscription = Disposable.Create(() => { disposer.Send(); });

                // register client
                lock (clients)
                {
                    clients[connectionId] = client;
                }

                OnConnect(client);
            }

            catch (Exception ex)
            {
                logger.Error(ex, () => nameof(OnClientConnected));
            }
        }
Exemple #3
0
        private void OnClientConnected(Tcp con, IPEndPoint endpointConfig, Loop loop)
        {
            try
            {
                var remoteEndPoint = con.GetPeerEndPoint();

                // get rid of banned clients as early as possible
                if (banManager?.IsBanned(remoteEndPoint.Address) == true)
                {
                    logger.Trace(() => $"[{LogCat}] Disconnecting banned ip {remoteEndPoint.Address}");
                    con.Dispose();
                    return;
                }

                var connectionId = CorrelationIdGenerator.GetNextId();
                logger.Trace(() => $"[{LogCat}] Accepting connection [{connectionId}] from {remoteEndPoint.Address}:{remoteEndPoint.Port}");

                // setup client
                var client = new StratumClient <TClientContext>();
                client.Init(con, ctx, endpointConfig, connectionId);

                // request subscription
                var sub = client.Requests
                          .ObserveOn(TaskPoolScheduler.Default) // WARN: never add .SubscribeOn here (must sub/unsub on UV event-loop thread)
                          .Subscribe(async tsRequest =>
                {
                    var request = tsRequest.Value;
                    logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Received request {request.Method} [{request.Id}]");

                    try
                    {
                        // boot pre-connected clients
                        if (banManager?.IsBanned(client.RemoteEndpoint.Address) == true)
                        {
                            logger.Trace(() => $"[{LogCat}] [{connectionId}] Disconnecting banned client @ {remoteEndPoint.Address}");
                            DisconnectClient(client);
                            return;
                        }

                        await OnRequestAsync(client, tsRequest);
                    }

                    catch (Exception ex)
                    {
                        logger.Error(ex, () => $"Error handling request: {request.Method}");
                    }
                }, ex => OnReceiveError(client, ex), () => OnReceiveComplete(client));

                // ensure subscription is disposed on loop thread
                var disposer = loop.CreateAsync((handle) =>
                {
                    sub.Dispose();

                    handle.Dispose();
                });

                client.Subscription = Disposable.Create(() =>
                {
                    disposer.Send();
                });

                // register client
                lock (clients)
                {
                    clients[connectionId] = client;
                }

                OnConnect(client);
            }

            catch (Exception ex)
            {
                logger.Error(ex, () => nameof(OnClientConnected));
            }
        }
Exemple #4
0
        private void OnClientConnected(Tcp con, IPEndPoint endpointConfig, Loop loop)
        {
            try
            {
                var remoteEndPoint = con.GetPeerEndPoint();

                // get rid of banned clients as early as possible
                if (banManager?.IsBanned(remoteEndPoint.Address) == true)
                {
                    logger.Debug(() => $"[{LogCat}] Disconnecting banned ip {remoteEndPoint.Address}");
                    con.Dispose();
                    return;
                }

                var connectionId = CorrelationIdGenerator.GetNextId();
                logger.Debug(() => $"[{LogCat}] Accepting connection [{connectionId}] from {remoteEndPoint.Address}:{remoteEndPoint.Port}");

                // setup client
                var client = new StratumClient <TClientContext>();
                client.Init(loop, con, ctx, endpointConfig, connectionId);

                var sub = client.Received.Subscribe(data =>
                {
                    // get off of LibUV event-loop-thread immediately
                    Task.Run(() =>
                    {
                        using (data)
                        {
                            JsonRpcRequest request = null;

                            try
                            {
                                // boot pre-connected clients
                                if (banManager?.IsBanned(client.RemoteEndpoint.Address) == true)
                                {
                                    logger.Info(() => $"[{LogCat}] [{connectionId}] Disconnecting banned client @ {remoteEndPoint.Address}");
                                    DisconnectClient(client);
                                    return;
                                }

                                // de-serialize
                                logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Received request data: {StratumClient<TClientContext>.Encoding.GetString(data.Array, 0, data.Size)}");
                                request = DeserializeRequest(data);

                                if (request != null)
                                {
                                    // dispatch
                                    logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Dispatching request '{request.Method}' [{request.Id}]");
                                    OnRequestAsync(client, new Timestamped <JsonRpcRequest>(request, clock.UtcNow)).Wait();
                                }

                                else
                                {
                                    logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Unable to deserialize request");
                                }
                            }

                            catch (JsonReaderException jsonEx)
                            {
                                // junk received (no valid json)
                                logger.Error(() => $"[{LogCat}] [{client.ConnectionId}] Connection json error state: {jsonEx.Message}");

                                if (clusterConfig.Banning?.BanOnJunkReceive.HasValue == false || clusterConfig.Banning?.BanOnJunkReceive == true)
                                {
                                    logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Banning client for sending junk");
                                    banManager?.Ban(client.RemoteEndpoint.Address, TimeSpan.FromMinutes(30));
                                }
                            }

                            catch (Exception ex)
                            {
                                if (request != null)
                                {
                                    logger.Error(ex, () => $"[{LogCat}] [{client.ConnectionId}] Error processing request {request.Method} [{request.Id}]");
                                }
                            }
                        }
                    });
                }, ex => OnReceiveError(client, ex), () => OnReceiveComplete(client));

                // ensure subscription is disposed on loop thread
                var disposer = loop.CreateAsync((handle) =>
                {
                    sub.Dispose();

                    handle.Dispose();
                });

                client.Subscription = Disposable.Create(() => { disposer.Send(); });

                // register client
                lock (clients)
                {
                    clients[connectionId] = client;
                }

                OnConnect(client);
            }

            catch (Exception ex)
            {
                logger.Error(ex, () => nameof(OnClientConnected));
            }
        }
        private void OnClientConnected(Tcp con, IPEndPoint endpointConfig, Loop loop)
        {
            try
            {
                var remoteEndPoint = con.GetPeerEndPoint();

                // get rid of banned clients as early as possible
                if (banManager?.IsBanned(remoteEndPoint.Address) == true)
                {
                    logger.Trace(() => $"[{LogCat}] Disconnecting banned ip {remoteEndPoint.Address}");
                    con.Dispose();
                    return;
                }

                var connectionId = CorrelationIdGenerator.GetNextId();
                logger.Trace(() => $"[{LogCat}] Accepting connection [{connectionId}] from {remoteEndPoint.Address}:{remoteEndPoint.Port}");

                // setup client
                var client = new StratumClient <TClientContext>();
                client.Init(loop, con, ctx, endpointConfig, connectionId);

                // request subscription
                var sub = client.Requests
                          .Do(x => logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Received request {x.Value.Method} [{x.Value.Id}]"))
                          .Select(tsRequest => Observable.FromAsync(() => Task.Run(() => // get off of LibUV event-loop-thread immediately
                {
                    var request = tsRequest.Value;
                    logger.Trace(() => $"[{LogCat}] [{client.ConnectionId}] Dispatching request {request.Method} [{request.Id}]");

                    try
                    {
                        // boot pre-connected clients
                        if (banManager?.IsBanned(client.RemoteEndpoint.Address) == true)
                        {
                            logger.Trace(() => $"[{LogCat}] [{connectionId}] Disconnecting banned client @ {remoteEndPoint.Address}");
                            DisconnectClient(client);
                            return;
                        }

                        OnRequestAsync(client, tsRequest).Wait();
                    }

                    catch (Exception ex)
                    {
                        logger.Error(ex, () => $"Error handling request: {request.Method}");
                    }
                })))
                          .Concat()
                          .Subscribe(_ => { }, ex => OnReceiveError(client, ex), () => OnReceiveComplete(client));

                // ensure subscription is disposed on loop thread
                var disposer = loop.CreateAsync((handle) =>
                {
                    sub.Dispose();

                    handle.Dispose();
                });

                client.Subscription = Disposable.Create(() => { disposer.Send(); });

                // register client
                lock (clients)
                {
                    clients[connectionId] = client;
                }

                OnConnect(client);
            }

            catch (Exception ex)
            {
                logger.Error(ex, () => nameof(OnClientConnected));
            }
        }