From 8ac0bf689f33b97a8ab6434fecd0e4727e018acb Mon Sep 17 00:00:00 2001 From: Afshin Arani Date: Wed, 3 May 2023 15:43:06 +0330 Subject: [PATCH] Services,Tests: create HS streams on demand There are multiple usecases when you need multiple streams for your communication with HS client (e.g sending multiple http requests), this was not supported before and this commit fixes that. --- NOnion.Tests/HiddenServicesTests.cs | 9 +++++---- NOnion/Services/TorServiceClient.fs | 21 +++++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/NOnion.Tests/HiddenServicesTests.cs b/NOnion.Tests/HiddenServicesTests.cs index 72ddbd2e..2223639b 100644 --- a/NOnion.Tests/HiddenServicesTests.cs +++ b/NOnion.Tests/HiddenServicesTests.cs @@ -106,7 +106,8 @@ public async Task BrowseFacebookOverHS() using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); var serviceClient = await TorServiceClient.ConnectAsync(torClient, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); - var httpClient = new TorHttpClient(serviceClient.GetStream(), "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); + var stream = await serviceClient.GetStreamAsync(); + var httpClient = new TorHttpClient(stream, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); try { @@ -131,8 +132,8 @@ public async Task BrowseFacebookOverHSWithTLS() using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); var serviceClient = await TorServiceClient.ConnectAsync(torClient, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion:443"); - - var sslStream = new SslStream(serviceClient.GetStream(), true, (sender, cert, chain, sslPolicyErrors) => true); + var stream = await serviceClient.GetStreamAsync(); + var sslStream = new SslStream(stream, true, (sender, cert, chain, sslPolicyErrors) => true); await sslStream.AuthenticateAsClientAsync(string.Empty, null, SslProtocols.Tls12, false); var httpClientOverSslStream = new TorHttpClient(sslStream, "www.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); @@ -185,7 +186,7 @@ public async Task EstablishAndCommunicateOverHSConnectionOnionStyle() var clientSide = Task.Run(async () => { var serviceClient = await TorServiceClient.ConnectAsync(torClient, host.ExportUrl()); - var stream = serviceClient.GetStream(); + var stream = await serviceClient.GetStreamAsync(); var lengthBytes = new byte[sizeof(int)]; await ReadExact(stream, lengthBytes, 0, lengthBytes.Length); var length = BitConverter.ToInt32(lengthBytes); diff --git a/NOnion/Services/TorServiceClient.fs b/NOnion/Services/TorServiceClient.fs index 074de3e3..d32995fc 100644 --- a/NOnion/Services/TorServiceClient.fs +++ b/NOnion/Services/TorServiceClient.fs @@ -24,11 +24,21 @@ type TorServiceClient = { TorClient: TorClient RendezvousCircuit: TorCircuit - Stream: TorStream + Port: int } member self.GetStream() = - self.Stream + async { + // We can't use the "use" keyword since this stream needs + // to outlive this function. + let serviceStream = new TorStream(self.RendezvousCircuit) + do! serviceStream.ConnectToService self.Port |> Async.Ignore + + return serviceStream + } + + member self.GetStreamAsync() = + self.GetStream() |> Async.StartAsTask static member ConnectAsync (client: TorClient) (url: string) = TorServiceClient.Connect client url |> Async.StartAsTask @@ -475,16 +485,11 @@ type TorServiceClient = Async.Parallel [ introduceJob; rendezvousJoin ] |> Async.Ignore - // We can't use the "use" keyword since this stream needs - // to outlive this function. - let serviceStream = new TorStream(rendezvousCircuit) - do! serviceStream.ConnectToService port |> Async.Ignore - return { TorClient = client RendezvousCircuit = rendezvousCircuit - Stream = serviceStream + Port = port } | _ -> return