diff --git a/NOnion/Network/TorGuard.fs b/NOnion/Network/TorGuard.fs index 33bf4a45..d3ec329a 100644 --- a/NOnion/Network/TorGuard.fs +++ b/NOnion/Network/TorGuard.fs @@ -20,6 +20,28 @@ type internal GuardSendMessage = ReplyChannel: AsyncReplyChannel> } +module ExceptionUtil = + let RunGuardJobWIthExceptionHandlling<'T> (job) : Async<'T> = + async { + try + return! job + with + | exn -> + match FSharpUtil.FindException exn with + | Some authEx -> + return raise <| GuardConnectionFailedException authEx + | None -> + match FSharpUtil.FindException exn with + | Some socketEx -> + return raise <| GuardConnectionFailedException socketEx + | None -> + match FSharpUtil.FindException exn with + | Some ioEx -> + return raise <| GuardConnectionFailedException ioEx + | None -> + return raise <| FSharpUtil.ReRaise exn + } + type TorGuard private (client: TcpClient, sslStream: SslStream) = let shutdownToken = new CancellationTokenSource() @@ -87,25 +109,20 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) = static member NewClient(ipEndpoint: IPEndPoint) = async { let tcpClient = new TcpClient() + let innetConnectAsync (client: TcpClient) = + async { + ipEndpoint.ToString() + |> sprintf "TorGuard: trying to connect to %s guard node" + |> TorLogger.Log - try - ipEndpoint.ToString() - |> sprintf "TorGuard: trying to connect to %s guard node" - |> TorLogger.Log - - do! - tcpClient.ConnectAsync(ipEndpoint.Address, ipEndpoint.Port) - |> Async.AwaitTask - |> FSharpUtil.WithTimeout Constants.GuardConnectionTimeout - - with - | exn -> - let socketExOpt = FSharpUtil.FindException exn - - match socketExOpt with - | None -> return raise <| FSharpUtil.ReRaise exn - | Some socketEx -> - return raise <| GuardConnectionFailedException socketEx + do! + client.ConnectAsync(ipEndpoint.Address, ipEndpoint.Port) + |> Async.AwaitTask + |> FSharpUtil.WithTimeout Constants.GuardConnectionTimeout + } + do! + ExceptionUtil.RunGuardJobWIthExceptionHandlling + (innetConnectAsync tcpClient) let sslStream = new SslStream( @@ -118,26 +135,19 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) = |> sprintf "TorGuard: creating ssl connection to %s guard node" |> TorLogger.Log - try - do! - sslStream.AuthenticateAsClientAsync( - String.Empty, - null, - SslProtocols.Tls12, - false - ) - |> Async.AwaitTask - |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout - with - | exn -> - match FSharpUtil.FindException exn with - | Some authEx -> - return raise <| GuardConnectionFailedException authEx - | None -> - match FSharpUtil.FindException exn with - | Some socketEx -> - return raise <| GuardConnectionFailedException socketEx - | None -> return raise <| FSharpUtil.ReRaise exn + let innerAuthenticateAsClient(stream: SslStream) = + stream.AuthenticateAsClientAsync( + String.Empty, + null, + SslProtocols.Tls12, + false + ) + |> Async.AwaitTask + |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout + + do! + ExceptionUtil.RunGuardJobWIthExceptionHandlling + (innerAuthenticateAsClient sslStream) ipEndpoint.ToString() |> sprintf "TorGuard: ssl connection to %s guard node authenticated" @@ -296,14 +306,9 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) = async { let! maybeCell = async { - try - return! self.ReceiveMessage() - with - | exn -> - match FSharpUtil.FindException exn - with - | Some _socketExn -> return None - | None -> return raise <| FSharpUtil.ReRaise exn + return! + ExceptionUtil.RunGuardJobWIthExceptionHandlling> + (self.ReceiveMessage()) } match maybeCell with