Exemple #1
0
 public ProxyClient(IProxyServer server, ISharkClient shark)
 {
     Disposed = false;
     Id       = RandomIdGenerator.NewId();
     Server   = server;
     Shark    = shark;
 }
Exemple #2
0
        public static async Task ProcessConnect(this ISharkClient client, BlockData block, bool isFastConnect = false, byte[] challengeResp = null)
        {
            ISocketClient remote = null;
            BlockData     resp   = new BlockData()
            {
                Type = BlockType.CONNECTED, Id = block.Id
            };

            if (isFastConnect)
            {
                if (challengeResp == null)
                {
                    throw new ArgumentNullException(nameof(challengeResp), "challege response cannot be null in fast conenct request");
                }
                var buffer = new byte[4 + challengeResp.Length];

                BitConverter.TryWriteBytes(buffer, client.Id);
                challengeResp.CopyTo(buffer, 4);

                resp.Data = buffer;
            }
            try
            {
                client.Logger.LogInformation("Process connect {0}", block.Id);
                var host = JsonSerializer.Deserialize <HostData>(Encoding.UTF8.GetString(block.Data.Span));
                remote = await client.ConnectTo(host.Address, host.Port, host.Type, block.Id);

                client.Logger.LogInformation("Connected {0}", block.Id);
            }
            catch (Exception)
            {
                client.Logger.LogError("Connect failed {0}", block.Id);
                resp.Type = BlockType.CONNECT_FAILED;
                if (remote != null)
                {
                    remote.Dispose();
                    client.RemoteClients.Remove(remote.Id);
                }
            }

            try
            {
                client.EncryptBlock(ref resp);
                await client.WriteBlock(resp);

                if (resp.Type == BlockType.CONNECTED)
                {
                    client.RunRemoteLoop(remote);
                }
            }
            catch (Exception e)
            {
                client.Logger.LogError(e, "Shark errored");
                client.Dispose();
            }
        }
Exemple #3
0
 public HttpProxyClient(TcpClient tcp, IProxyServer server, ISharkClient shark, ILogger <HttpProxyClient> logger, IServiceProvider servicdeProvider) : base(server, shark)
 {
     ServiceProvider = servicdeProvider;
     Logger          = logger;
     _client         = tcp;
     _stream         = _client.GetStream();
     _request        = new HttpProxyRequest();
     _pipe           = new Pipe(DefaultPipeOptions);
     _httpFailed     = false;
 }
Exemple #4
0
 private static async Task ProcessData(this ISharkClient client, BlockData block)
 {
     if (client.RemoteClients.TryGetValue(block.Id, out var http))
     {
         try
         {
             await http.WriteAsync(block.Data);
         }
         catch (Exception)
         {
             client.Logger.LogError("Http client errored closed, {0}", http.Id);
             client.DisconnectQueue.Enqueue(http.Id);
             http.Dispose();
             client.RemoveRemoteClient(http.Id);
         }
     }
 }
Exemple #5
0
        public static Task RunSharkLoop(this ISharkClient client)
        {
            return(Task.Factory.StartNew(async() =>
            {
                try
                {
                    while (client.CanRead)
                    {
                        var block = await client.ReadBlock();
                        if (block.IsValid)
                        {
                            client.DecryptBlock(ref block);
#pragma warning disable CS4014 // no waiting the http processing
                            if (block.Type == BlockType.CONNECT)
                            {
                                client.ProcessConnect(block);
                            }
                            else if (block.Type == BlockType.DATA)
                            {
                                client.ProcessData(block);
                            }
#pragma warning restore CS4014
                            else if (block.Type == BlockType.DISCONNECT)
                            {
                                var ids = JsonSerializer.Deserialize <List <int> >(Encoding.UTF8.GetString(block.Data.Span));
                                foreach (var id in ids)
                                {
                                    if (client.RemoteClients.TryGetValue(id, out var item))
                                    {
                                        item.Dispose();
                                        client.RemoteClients.Remove(item.Id);
                                        item.Logger.LogDebug("Remote request disconnect {0}", id);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    client.Logger.LogError(e, "Shark errored");
                }
            })
                   .Unwrap());
        }
Exemple #6
0
        public Socks5Client(TcpClient tcp,
                            IProxyServer server,
                            ISharkClient shark,
                            ILogger <Socks5Client> logger,
                            IConfiguration configuration,
                            IServiceProvider servicdeProvider) : base(server, shark)
        {
            Logger          = logger;
            ServiceProvider = servicdeProvider;
            _client         = tcp;
            _stream         = _client.GetStream();
            _pipe           = new Pipe(DefaultPipeOptions);
            _socksFailed    = false;
            _udpBuffer      = new byte[1500];
            _lastEndpoint   = new IPEndPoint(0, 0);

            if (!bool.TryParse(configuration["privoxy:supported"], out _supportPrivoxy))
            {
                _supportPrivoxy = false;
            }
        }
Exemple #7
0
        private static void RunRemoteLoop(this ISharkClient client, ISocketClient socketClient)
        {
            var task = Task.Factory.StartNew(async() =>
            {
                var buffer = new byte[BUFFER_SIZE];
                int number = 0;
                try
                {
                    var readed = 0;
                    while ((readed = await socketClient.ReadAsync(buffer)) != 0)
                    {
                        var block = new BlockData()
                        {
                            Id          = socketClient.Id,
                            Data        = new byte[readed],
                            BlockNumber = number++,
                            Type        = BlockType.DATA
                        };

                        new ReadOnlyMemory <byte>(buffer, 0, readed).CopyTo(block.Data);

                        client.EncryptBlock(ref block);
                        await client.WriteBlock(block);
                    }
                    socketClient.Logger.LogInformation("Remote closed {0}", socketClient.Id);
                }
                catch (Exception)
                {
                    client.Logger.LogError("Remote client errored closed, {0}", socketClient.Id);
                }
                client.DisconnectQueue.Enqueue(socketClient.Id);
                socketClient.Dispose();
                client.RemoveRemoteClient(socketClient.Id);
            })
                       .Unwrap();
        }
Exemple #8
0
 public void RemoveClient(ISharkClient client)
 {
     RemoveClient(client.Id);
 }
Exemple #9
0
 protected override IProxyClient CreateClient(TcpClient tcp, ISharkClient shark)
 {
     return(ActivatorUtilities.CreateInstance <Socks5Client>(shark.ServiceProvider, tcp, this, shark));
 }
Exemple #10
0
 protected abstract IProxyClient CreateClient(TcpClient tcp, ISharkClient shark);
Exemple #11
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());
        }