public async Task Ipv6()
        {
            var commandReply = new CommandReply(
                CommandReplyType.Succeeded,
                new IPEndPoint(IPAddress.Parse("2001:db8:85a3:8d3:1319:8a2e:370:7348"), 65534));

            var stream = new MemoryWriteOnlyStream();
            await commandReply.WriteToAsync(stream, this._bufferPool).ConfigureAwait(true);

            stream.ToArray().Should().Equal(
                5,
                (byte)CommandReplyType.Succeeded,
                0,
                (byte)AddressType.Ipv6,
                32,
                1,
                13,
                184,
                133,
                163,
                8,
                211,
                19,
                25,
                138,
                46,
                3,
                112,
                115,
                72,
                255,
                254);
        }
        public async Task Domain()
        {
            var commandReply = new CommandReply(CommandReplyType.Succeeded, new DnsEndPoint("google.com", 65534));
            var stream       = new MemoryWriteOnlyStream();
            await commandReply.WriteToAsync(stream, this._bufferPool).ConfigureAwait(true);

            stream.ToArray().Should().Equal(
                5,
                (byte)CommandReplyType.Succeeded,
                0,
                (byte)AddressType.DomainName,
                10,
                103,
                111,
                111,
                103,
                108,
                101,
                46,
                99,
                111,
                109,
                255,
                254);
        }
        async Task RunProxyAsync(CancellationToken cancellationToken)
        {
            IProxy proxy;

            try
            {
                var command = await Command.ReadFromAsync(this._clientStream, this._bufferPool).ConfigureAwait(false);

                switch (command.CommandType)
                {
                case CommandType.Connect:
                    proxy = this._proxyFactory.CreateTcpProxy(
                        this._clientStream,
                        command.EndPoint,
                        this._bufferPool);
                    break;

                case CommandType.UdpAssociate:
                    proxy = this._proxyFactory.CreateUdpProxy(this._clientStream, this._bufferPool);
                    break;

                default:
                    throw new ProtocolException(CommandReplyType.CommandNotSupported);
                }
            }
            catch (Exception ex)
            {
                var commandReplyType = CommandReplyType.GeneralFailure;
                switch (ex)
                {
                case ProtocolException socksEx:
                    this._log.LogError(socksEx, "Protocol error");
                    commandReplyType = socksEx.ErrorCode;
                    break;

                case IOException _:
                case SocketException _:
                    this._log.LogError("Network error: {0}", ex.Message);
                    break;

                default:
                    this._log.LogError("Connection error.", ex);
                    break;
                }

                await new CommandReply(commandReplyType, s_EmptyEndPoint)
                .WriteToAsync(this._clientStream, this._bufferPool)
                .ConfigureAwait(false);
                return;
            }

            var reply = new CommandReply(CommandReplyType.Succeeded, proxy.BindEndPoint);
            await reply.WriteToAsync(this._clientStream, this._bufferPool).ConfigureAwait(false);

            using (proxy)
            {
                await proxy.RunAsync(cancellationToken).ConfigureAwait(false);
            }
        }
        public async Task Ipv4()
        {
            var commandReply = new CommandReply(
                CommandReplyType.Succeeded,
                new IPEndPoint(IPAddress.Parse("1.2.3.4"), 65534));

            var stream = new MemoryWriteOnlyStream();
            await commandReply.WriteToAsync(stream, this._bufferPool).ConfigureAwait(true);

            stream.ToArray().Should().Equal(
                5,
                (byte)CommandReplyType.Succeeded,
                0,
                (byte)AddressType.Ipv4,
                1,
                2,
                3,
                4,
                255,
                254);
        }