async Task HandleClient(IClient client, int pipeBufferSize, Action <DuplexPipe> pipeCreatedAction, Func <IPEndPoint, Task <IClient> > createTargetClientFunc, Action <SmartBuffer, DuplexPipe, IClient, ShadowsocksAddress> targetClientConnectedAction, CancellationToken cancellationToken) { try { DuplexPipe pipe = new DuplexPipe(pipeBufferSize, _logger); pipe.ClientA = client; pipeCreatedAction(pipe);/////////////////// var readClientResult = await pipe.GetReader(client).Read(cancellationToken);//A. Read target addr (and payload). if (readClientResult.Result != ReadWriteResult.Succeeded) { client.Close(); return; } if (readClientResult.Read <= 0) { _logger?.LogWarning($"This should not happen. [{client.EndPoint.ToString()}]"); ////decrypt failed? available options: 1.leave it. 2.close connection. 3.add to blocklist. client.Close(); return; } var request = readClientResult.Memory; IPAddress targetIP = IPAddress.Any; //TODO target address check if (ShadowsocksAddress.TryResolve(request.SignificantMemory, out ShadowsocksAddress ssaddr)) //B. Resolve target addr. { _logger?.LogWarning($"Reading target addr. ATYP={ssaddr.ATYP}, client=[{client.EndPoint.ToString()}]"); IPEndPoint ipeTarget = await ssaddr.ToIPEndPoint(); if (IPAddress.Any == ipeTarget.Address || IPAddress.IPv6Any == ipeTarget.Address)//an empty IP. { _logger?.LogWarning($"Invalid target addr. client=[{client.EndPoint.ToString()}]"); client.Close(); return; } _logger?.LogInformation($"Resolved target address:[{ipeTarget.ToString()}]. Connecting..."); IClient targetClient = await createTargetClientFunc(ipeTarget); //C. Connect target /////////////////////////////// if (null == targetClient) //connect target failed. { _logger?.LogInformation($"Unable to connect target [{ipeTarget.ToString()}]. client=[{client.EndPoint.ToString()}]"); client.Close(); return; } _logger?.LogInformation($"Connected to [{ipeTarget.ToString()}]"); targetClientConnectedAction(request, pipe, targetClient, ssaddr);//////////////////////////////// _logger?.LogInformation($"Start piping..."); PipeClient(pipe, cancellationToken);//D. start piping. } else//invalid socks5 addr { _logger?.LogWarning($"Resolve target addr failed. client=[{client.EndPoint.ToString()}]"); client.Close(); return; } await Task.CompletedTask; } catch (Exception ex) { _logger?.LogError(ex, "HandleClient"); } }