public async Task HandleTcp(IClient client, CancellationToken cancellationToken = default)
        {
            if (null == client)
            {
                return;
            }

            await HandleClient(client, Defaults.ReceiveBufferSize,
                               (pipe) =>
            {
                var cipher = _remoteServerConfig.CreateCipher(_logger);
                IClientFilter cipherFilter = new Cipher.TcpCipherFilter(cipher, _logger);
                pipe.AddFilter(client, cipherFilter);
            },
                               async (targetIPEndPoint) =>
            {
                return(await TcpClient1.ConnectAsync(targetIPEndPoint, _logger));
            },
                               async (request, pipe, targetClient, targetSsAddr) =>
            {
                pipe.ClientB = targetClient;

                if (request.SignificantLength > targetSsAddr.RawMemory.Length)   //have some payload
                {
                    _logger?.LogInformation($"Writing payload before piping...");
                    //await targetClient.WriteAsync(request.SignificantMemory.Slice(ssaddr.RawMemory.Length));
                    await pipe.GetWriter(targetClient).Write(request.SignificantMemory.Slice(targetSsAddr.RawMemory.Length), cancellationToken);
                }
                request.Dispose();
            },
                               cancellationToken);

            await Task.CompletedTask;
        }
        public async Task HandleTcp(IClient client, CancellationToken cancellationToken = default)
        {
            if (null == client)
            {
                return;
            }
            using (SmartBuffer localRequestCipher = SmartBuffer.Rent(Defaults.ReceiveBufferSize))
            {
                localRequestCipher.SignificantLength = await client.ReadAsync(localRequestCipher.Memory, cancellationToken);//A. Receive target addr.

                //decrypt
                var cipher = _remoteServerConfig.CreateCipher(_logger);
                using (var localReqestPlain = cipher.DecryptTcp(localRequestCipher.SignificanMemory))
                {
                    if (0 == localRequestCipher.SignificantLength)
                    {
                        //decrypt failed, available options: 1.leave it. 2.close connection. 3.add to blocklist.
                        _logger?.LogWarning($"Decrypt target addr failed, client=[{client.EndPoint.ToString()}]");
                        client.Close();//->local pipe broken-> local pipe close.
                        return;
                    }
                    IPAddress targetIP = IPAddress.Any;                                                        //TODO target address check
                    if (ShadowsocksAddress.TryResolve(localReqestPlain.Memory, out ShadowsocksAddress ssaddr)) //B. Resolve target addr.
                    {
                        if (0x3 == ssaddr.ATYP)                                                                //a domain name
                        {
                            var ips = await _dnsCache.ResolveHost(Encoding.UTF8.GetString(ssaddr.Address.ToArray()));

                            if (ips != null && ips.Length > 0)
                            {
                                targetIP = ips[0];
                            }
                        }
                        else//IPv4/v6
                        {
                            targetIP = new IPAddress(ssaddr.Address.Span);
                        }
                        if (IPAddress.Any == targetIP)//a empty IP.
                        {
                            _logger?.LogWarning($"Invalid target addr. client=[{client.EndPoint.ToString()}]");
                            client.Close();
                            return;
                        }
                        IPEndPoint ipeTarget = new IPEndPoint(targetIP, ssaddr.Port);
                        _logger.LogInformation($"Resolved target address:[{ipeTarget.ToString()}]");
                        _logger.LogInformation($"Connecting to [{ipeTarget.ToString()}]...");
                        var targetClient = await TcpClient1.ConnectAsync(ipeTarget, _logger); //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()}]");

                        if (localReqestPlain.Memory.Length > ssaddr.RawMemory.Length)//have some payload
                        {
                            _logger.LogInformation($"Writing payload before piping...");
                            await targetClient.WriteAsync(localReqestPlain.SignificanMemory.Slice(ssaddr.RawMemory.Length));
                        }
                        _logger.LogInformation($"Start piping...");
                        PipeTcp(client, targetClient, cipher, cancellationToken);//D. start piping.
                    }
                    else//invalid socks5 addr
                    {
                        _logger?.LogWarning($"StandardRemoteSocks5Handler HandleTcp resolve target addr failed. client=[{client.EndPoint.ToString()}]");
                        client.Close();
                        return;
                    }
                }
            }
            await Task.CompletedTask;
        }