Skip to content

Commit

Permalink
Network: rework TorGuard exception handling (#49)
Browse files Browse the repository at this point in the history
Move TorGuard exception handling to a new module so that
every time we want to handle a new type of exception, we
won't be bothered by adding a lot of try/except expressions.

While we're at it, we wrap IOException (necessary for
fixing [1]).

Fixes #45
[1] nblockchain/geewallet#184
  • Loading branch information
parhamsaremi authored Nov 14, 2022
1 parent 418e583 commit 258ab3d
Showing 1 changed file with 54 additions and 44 deletions.
98 changes: 54 additions & 44 deletions NOnion/Network/TorGuard.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ type internal GuardSendMessage =
ReplyChannel: AsyncReplyChannel<OperationResult<unit>>
}

module ExceptionUtil =
let RunGuardJobWithExceptionHandling<'T> job : Async<'T> =
async {
try
return! job
with
| exn ->
match FSharpUtil.FindException<AuthenticationException> exn with
| Some authEx ->
return raise <| GuardConnectionFailedException authEx
| None ->
match FSharpUtil.FindException<SocketException> exn with
| Some socketEx ->
return raise <| GuardConnectionFailedException socketEx
| None ->
match FSharpUtil.FindException<IOException> 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()

Expand Down Expand Up @@ -88,24 +109,23 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) =
async {
let tcpClient = new TcpClient()

try
ipEndpoint.ToString()
|> sprintf "TorGuard: trying to connect to %s guard node"
|> TorLogger.Log
let innerConnectAsync(client: TcpClient) =
async {
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<SocketException> exn
do!
client.ConnectAsync(ipEndpoint.Address, ipEndpoint.Port)
|> Async.AwaitTask
|> FSharpUtil.WithTimeout
Constants.GuardConnectionTimeout
}

match socketExOpt with
| None -> return raise <| FSharpUtil.ReRaise exn
| Some socketEx ->
return raise <| GuardConnectionFailedException socketEx
do!
ExceptionUtil.RunGuardJobWithExceptionHandling<unit>(
innerConnectAsync tcpClient
)

let sslStream =
new SslStream(
Expand All @@ -118,26 +138,20 @@ 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<AuthenticationException> exn with
| Some authEx ->
return raise <| GuardConnectionFailedException authEx
| None ->
match FSharpUtil.FindException<SocketException> 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.RunGuardJobWithExceptionHandling<unit>(
innerAuthenticateAsClient sslStream
)

ipEndpoint.ToString()
|> sprintf "TorGuard: ssl connection to %s guard node authenticated"
Expand Down Expand Up @@ -296,14 +310,10 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) =
async {
let! maybeCell =
async {
try
return! self.ReceiveMessage()
with
| exn ->
match FSharpUtil.FindException<SocketException> exn
with
| Some _socketExn -> return None
| None -> return raise <| FSharpUtil.ReRaise exn
return!
ExceptionUtil.RunGuardJobWithExceptionHandling<Option<(uint16 * ICell)>>(
self.ReceiveMessage()
)
}

match maybeCell with
Expand Down

0 comments on commit 258ab3d

Please sign in to comment.