예제 #1
0
        protected override async ValueTask <ConnectState> ConnectProxyAsync(EndPoint remoteEndPoint, ConnectState state, CancellationToken cancellationToken)
        {
            var encoding = Encoding.ASCII;
            var request  = string.Empty;
            var channel  = state.CreateChannel <TextPackageInfo>(new LinePipelineFilter(encoding), new ChannelOptions {
                ReadAsDemand = true
            });

            if (remoteEndPoint is DnsEndPoint dnsEndPoint)
            {
                request = string.Format(_requestTemplate, dnsEndPoint.Host, dnsEndPoint.Port);
            }
            else if (remoteEndPoint is IPEndPoint ipEndPoint)
            {
                request = string.Format(_requestTemplate, ipEndPoint.Address, ipEndPoint.Port);
            }
            else
            {
                return(new ConnectState
                {
                    Result = false,
                    Exception = new Exception($"The endpint type {remoteEndPoint.GetType().ToString()} is not supported.")
                });
            }

            // send request
            await channel.SendAsync((writer) =>
            {
                writer.Write(request, encoding);

                if (!string.IsNullOrEmpty(_username) || !string.IsNullOrEmpty(_password))
                {
                    writer.Write("Proxy-Authorization: Basic ", encoding);
                    writer.Write(Convert.ToBase64String(encoding.GetBytes($"{_username}:{_password}")), encoding);
                    writer.Write("\r\n\r\n", encoding);
                }
                else
                {
                    writer.Write("\r\n", encoding);
                }
            });

            var packStream = channel.GetPackageStream();
            var p          = await packStream.ReceiveAsync();

            if (!HandleResponse(p, out string errorMessage))
            {
                await channel.CloseAsync();

                return(new ConnectState
                {
                    Result = false,
                    Exception = new Exception(errorMessage)
                });
            }

            await channel.DetachAsync();

            return(state);
        }
예제 #2
0
        protected override async ValueTask <ConnectState> ConnectProxyAsync(EndPoint remoteEndPoint, ConnectState state, CancellationToken cancellationToken)
        {
            var channel = state.CreateChannel <Socks5Pack>(new Socks5AuthPipelineFilter(), new ChannelOptions {
                ReadAsDemand = true
            });

            var packStream = channel.GetPackageStream();

            await channel.SendAsync(_authenHandshakeRequest);

            var response = await packStream.ReceiveAsync();

            if (!HandleResponse(response, Socket5ResponseType.Handshake, out string errorMessage))
            {
                await channel.CloseAsync();

                return(new ConnectState
                {
                    Result = false,
                    Exception = new Exception(errorMessage)
                });
            }

            if (response.Status == 0x02)// need pass auth
            {
                var passAuthenRequest = GetPassAuthenBytes();

                await channel.SendAsync(passAuthenRequest);

                response = await packStream.ReceiveAsync();

                if (!HandleResponse(response, Socket5ResponseType.AuthUserName, out errorMessage))
                {
                    await channel.CloseAsync();

                    return(new ConnectState
                    {
                        Result = false,
                        Exception = new Exception(errorMessage)
                    });
                }
            }

            var endPointRequest = GetEndPointBytes(remoteEndPoint);

            await channel.SendAsync(endPointRequest);

            response = await packStream.ReceiveAsync();

            if (!HandleResponse(response, Socket5ResponseType.AuthEndPoint, out errorMessage))
            {
                await channel.CloseAsync();

                return(new ConnectState
                {
                    Result = false,
                    Exception = new Exception(errorMessage)
                });
            }

            await channel.DetachAsync();

            return(state);
        }