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); }
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); }