Example #1
0
        protected virtual void Dispose(bool disposing)
        {
            if (!Disposed)
            {
                if (disposing)
                {
                    // dispose managed state (managed objects).
                    foreach (var clientPair in Clients)
                    {
                        clientPair.Value.Dispose();
                    }
                    Clients.Clear();

                    foreach (var sharkPair in Sharks)
                    {
                        sharkPair.Value.Dispose();
                    }
                    Sharks.Clear();
                }

                // free unmanaged resources (unmanaged objects) and override a finalizer below.
                // set large fields to null.
                Disposed = true;
            }
        }
Example #2
0
        private async void StartClientLoop(TcpClient client)
        {
            IProxyClient proxyClient = null;

            try
            {
                var shark = await GetOrCreateSharkClient();

                proxyClient = CreateClient(client, shark);

                var sharkFirstInitialized = false;

                shark.RemoteClients.Add(proxyClient.Id, proxyClient);
                Clients.Add(proxyClient.Id, proxyClient);

                try
                {
                    var host = await proxyClient.StartAndProcessRequest();

                    if (!shark.Initialized)
                    {
                        var result = await shark.FastConnect(proxyClient.Id, host);

                        Sharks.Add(shark.Id, shark);
                        sharkFirstInitialized = true;
                        Interlocked.Decrement(ref _waitingCount);
                        await proxyClient.ProcessSharkData(result);
                    }
                    else
                    {
                        await shark.ProxyTo(proxyClient.Id, host);
                    }

                    proxyClient.RemoteDisconnected += OnClientRemoteDisconencted;
                }
                catch (AuthenticationException ex)
                {
                    Logger.LogError(ex, $"Client Auth failed");
                    shark.Dispose();
                    Interlocked.Decrement(ref _waitingCount);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, $"Process Connect failed for {proxyClient.Id}");

                    shark.RemoteClients.Remove(proxyClient.Id);
                    Clients.Remove(proxyClient.Id);
                    proxyClient.Dispose();

                    if (!shark.Initialized)
                    {
                        try
                        {
                            await shark.Auth();

                            Sharks.Add(shark.Id, shark);
                            sharkFirstInitialized = true;
                        }
                        catch (Exception e)
                        {
                            shark.Dispose();
                            shark.Logger.LogWarning($"Shark client {shark.Id} initlialize failed, {e} ");
                            throw;
                        }
                        finally
                        {
                            Interlocked.Decrement(ref _waitingCount);
                        }
                    }
                }

                if (sharkFirstInitialized)
                {
#pragma warning disable CS4014
                    StartSharkLoop(shark);
#pragma warning restore CS4014
                }
            }
            catch (Exception)
            {
                Logger.LogWarning("Failed to start client loop");
                if (proxyClient != null)
                {
                    proxyClient.Dispose();
                }
                else
                {
                    try
                    {
                        client.Client.Shutdown(SocketShutdown.Both);
                        client.Client.Disconnect(false);
                    }
                    catch (Exception)
                    {
                        //
                    }
                    client.Dispose();
                }
            }
        }
Example #3
0
        protected Task StartSharkLoop(ISharkClient shark)
        {
            return(Task.Factory.StartNew(async() =>
            {
                var taskMap = new Dictionary <int, Task <bool> >();
                try
                {
                    while (true)
                    {
                        var block = await shark.ReadBlock();
                        shark.DecryptBlock(ref block);
                        if (block.Type == BlockType.DISCONNECT)
                        {
                            var idData = Encoding.UTF8.GetString(block.Data.Span);
                            var ids = JsonSerializer.Deserialize <List <int> >(idData);
                            Logger.LogDebug("Remote request disconnect {0}", idData);
                            foreach (var id in ids)
                            {
                                Clients.TryGetValue(id, out var item);

                                shark.RemoteClients.Remove(id);

                                if (Clients.Remove(id))
                                {
                                    item.Dispose();
                                    item.Logger.LogDebug("Disconnected {0}", id);
                                }
                                else
                                {
                                    Logger.LogDebug("Remote request disconnect failed {0}", id);
                                }
                            }
                            continue;
                        }

                        if (Clients.TryGetValue(block.Id, out var client))
                        {
                            if (taskMap.TryGetValue(block.Id, out var t))
                            {
                                t = t.ContinueWith(task =>
                                {
                                    if (!task.IsCompletedSuccessfully || !task.Result)
                                    {
                                        if (!client.Disposed)
                                        {
                                            RemoveClient(client);
                                            client.Dispose();
                                            taskMap.Remove(block.Id);
                                        }
                                        return Task.FromResult(false);
                                    }
                                    return client.ProcessSharkData(block);
                                }).Unwrap();
                            }
                            else
                            {
                                t = client.ProcessSharkData(block);
                            }

                            taskMap[block.Id] = t;
                        }
                        else
                        {
                            // handle cases
                            taskMap.Remove(block.Id);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Shark error");
                }
                finally
                {
                    var clients = shark.RemoteClients;

                    foreach (var clientPair in clients)
                    {
                        Clients.Remove(clientPair.Key);
                        clientPair.Value.Dispose();
                    }

                    Sharks.Remove(shark.Id);
                    shark.Dispose();
                    taskMap.Clear();
                }
            }).Unwrap());
        }