public ProxyClient(IProxyServer server, ISharkClient shark) { Disposed = false; Id = RandomIdGenerator.NewId(); Server = server; Shark = shark; }
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(); } }
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; }
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); } } }
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()); }
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; } }
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(); }
public void RemoveClient(ISharkClient client) { RemoveClient(client.Id); }
protected override IProxyClient CreateClient(TcpClient tcp, ISharkClient shark) { return(ActivatorUtilities.CreateInstance <Socks5Client>(shark.ServiceProvider, tcp, this, shark)); }
protected abstract IProxyClient CreateClient(TcpClient tcp, ISharkClient shark);
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()); }