diff --git a/NOnion/Directory/KeyCertificatesDocument.fs b/NOnion/Directory/KeyCertificatesDocument.fs
index ebb12b9a..c3014c8d 100644
--- a/NOnion/Directory/KeyCertificatesDocument.fs
+++ b/NOnion/Directory/KeyCertificatesDocument.fs
@@ -6,7 +6,7 @@ open System.Text
open Org.BouncyCastle.Asn1
open NOnion.Crypto.DirectoryCipher
-open NOnion.Utility.FSharpUtil
+open NOnion.Utility.AsyncUtil
open NOnion.Utility.PemUtility
type KeyCertificateEntry =
diff --git a/NOnion/Directory/TorDirectory.fs b/NOnion/Directory/TorDirectory.fs
index 7e03a77a..4ad9b92c 100644
--- a/NOnion/Directory/TorDirectory.fs
+++ b/NOnion/Directory/TorDirectory.fs
@@ -13,7 +13,7 @@ open NOnion.Crypto
open NOnion.Network
open NOnion.Http
open NOnion.Utility
-open NOnion.Utility.FSharpUtil
+open NOnion.Utility.AsyncUtil
type RouterType =
| Normal
@@ -48,7 +48,8 @@ type TorDirectory =
static member private GetTrustedAuthorities() =
let authDirText =
- EmbeddedResourceUtility
+ Fsdk
+ .Misc
.ExtractEmbeddedResourceFileContents("auth_dirs.inc")
.Replace("\r\n", "\n")
diff --git a/NOnion/Http/TorHttpClient.fs b/NOnion/Http/TorHttpClient.fs
index 6b3ea42d..2a6d748b 100644
--- a/NOnion/Http/TorHttpClient.fs
+++ b/NOnion/Http/TorHttpClient.fs
@@ -42,7 +42,7 @@ type TorHttpClient(stream: Stream, host: string) =
do!
ReceiveAll memStream
- |> FSharpUtil.WithTimeout Constants.HttpGetResponseTimeout
+ |> AsyncUtil.WithTimeout Constants.HttpGetResponseTimeout
let httpResponse = memStream.ToArray()
@@ -135,7 +135,7 @@ type TorHttpClient(stream: Stream, host: string) =
do!
ReceiveAll memStream
- |> FSharpUtil.WithTimeout Constants.HttpPostResponseTimeout
+ |> AsyncUtil.WithTimeout Constants.HttpPostResponseTimeout
let httpResponse = memStream.ToArray()
diff --git a/NOnion/NOnion.fsproj b/NOnion/NOnion.fsproj
index 50428413..6f361aeb 100644
--- a/NOnion/NOnion.fsproj
+++ b/NOnion/NOnion.fsproj
@@ -19,9 +19,8 @@
-
+
-
@@ -91,6 +90,7 @@
+
diff --git a/NOnion/Network/TorCircuit.fs b/NOnion/Network/TorCircuit.fs
index 39edec50..22ddda11 100644
--- a/NOnion/Network/TorCircuit.fs
+++ b/NOnion/Network/TorCircuit.fs
@@ -1118,7 +1118,7 @@ and TorCircuit
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
}
member __.Extend(nodeDetail: CircuitNodeDetail) =
@@ -1135,7 +1135,7 @@ and TorCircuit
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
}
member __.RegisterAsIntroductionPoint
@@ -1161,7 +1161,7 @@ and TorCircuit
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
}
member __.RegisterAsRendezvousPoint(cookie: array) =
@@ -1182,7 +1182,7 @@ and TorCircuit
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
}
member self.ExtendAsync nodeDetail =
@@ -1208,7 +1208,7 @@ and TorCircuit
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
}
member __.WaitingForRendezvousJoin
@@ -1236,7 +1236,7 @@ and TorCircuit
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitRendezvousTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitRendezvousTimeout
}
diff --git a/NOnion/Network/TorGuard.fs b/NOnion/Network/TorGuard.fs
index 8450be42..4f58619d 100644
--- a/NOnion/Network/TorGuard.fs
+++ b/NOnion/Network/TorGuard.fs
@@ -11,6 +11,7 @@ open System.Threading
open Org.BouncyCastle.Security
open Org.BouncyCastle.X509
+open Fsdk
open NOnion
open NOnion.Cells
@@ -130,7 +131,7 @@ type TorGuard
do!
client.ConnectAsync(ipEndpoint.Address, ipEndpoint.Port)
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout
+ |> AsyncUtil.WithTimeout
Constants.GuardConnectionTimeout
}
@@ -158,7 +159,7 @@ type TorGuard
false
)
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
do!
ExceptionUtil.RunGuardJobWithExceptionHandling(
@@ -533,7 +534,7 @@ type TorGuard
TorLogger.Log "TorGuard: finished handshake process"
//TODO: do security checks on handshake data
}
- |> FSharpUtil.WithTimeout Constants.CircuitOperationTimeout
+ |> AsyncUtil.WithTimeout Constants.CircuitOperationTimeout
member internal __.RegisterCircuit(circuit: ITorCircuit) : uint16 =
let rec createCircuitId(retry: int) =
diff --git a/NOnion/Network/TorStream.fs b/NOnion/Network/TorStream.fs
index 4fc2ec27..488aed87 100644
--- a/NOnion/Network/TorStream.fs
+++ b/NOnion/Network/TorStream.fs
@@ -479,7 +479,7 @@ type TorStream(circuit: TorCircuit) =
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.StreamCreationTimeout
+ |> AsyncUtil.WithTimeout Constants.StreamCreationTimeout
}
member self.ConnectToDirectory() =
@@ -499,7 +499,7 @@ type TorStream(circuit: TorCircuit) =
completionTaskResult
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.StreamCreationTimeout
+ |> AsyncUtil.WithTimeout Constants.StreamCreationTimeout
}
member self.ConnectToDirectoryAsync() =
@@ -523,7 +523,7 @@ type TorStream(circuit: TorCircuit) =
completionTaskRes
|> UnwrapResult
|> Async.AwaitTask
- |> FSharpUtil.WithTimeout Constants.StreamCreationTimeout
+ |> AsyncUtil.WithTimeout Constants.StreamCreationTimeout
}
member self.ConnectToOutsideAsync(address, port) =
diff --git a/NOnion/Services/TorServiceHost.fs b/NOnion/Services/TorServiceHost.fs
index 7d6c10e0..8823bd79 100644
--- a/NOnion/Services/TorServiceHost.fs
+++ b/NOnion/Services/TorServiceHost.fs
@@ -15,6 +15,7 @@ open Org.BouncyCastle.Crypto.Parameters
open Org.BouncyCastle.Crypto.Generators
open Org.BouncyCastle.Crypto.Signers
open Org.BouncyCastle.Security
+open Fsdk
open NOnion
open NOnion.Cells.Relay
@@ -249,7 +250,7 @@ type TorServiceHost
introEncPubKey
do!
- FSharpUtil.Retry
+ AsyncUtil.Retry
connectToRendezvousJob
maxRendezvousConnectRetryCount
diff --git a/NOnion/Utility/AsyncUtil.fs b/NOnion/Utility/AsyncUtil.fs
new file mode 100644
index 00000000..71afd8f6
--- /dev/null
+++ b/NOnion/Utility/AsyncUtil.fs
@@ -0,0 +1,47 @@
+namespace NOnion.Utility
+
+open System
+
+open Fsdk
+
+open NOnion
+
+module AsyncUtil =
+ let WithTimeout (timeSpan: TimeSpan) (job: Async<'R>) : Async<'R> =
+ async {
+ let! result = FSharpUtil.WithTimeout timeSpan job
+
+ match result with
+ | Some value -> return value
+ | None -> return raise <| TimeoutErrorException()
+ }
+
+ let Retry<'TEx when 'TEx :> Exception>
+ (jobToRetry: Async)
+ (maxRetryCount: int)
+ =
+ async {
+ try
+ do!
+ FSharpUtil.Retry<_, 'TEx>
+ (fun () -> jobToRetry)
+ maxRetryCount
+ with
+ | :? 'TEx as ex ->
+ sprintf "Maximum retry count reached, ex = %s" (ex.ToString())
+ |> TorLogger.Log
+
+ return raise <| FSharpUtil.ReRaise ex
+ | ex ->
+ sprintf
+ "Unexpected exception happened in the retry loop, ex = %s"
+ (ex.ToString())
+ |> TorLogger.Log
+
+ return raise <| FSharpUtil.ReRaise ex
+ }
+
+ let UnwrapOption<'T> (opt: Option<'T>) (msg: string) : 'T =
+ match opt with
+ | Some value -> value
+ | None -> failwith <| sprintf "error unwrapping Option: %s" msg
diff --git a/NOnion/Utility/EmbeddedResourceUtility.fs b/NOnion/Utility/EmbeddedResourceUtility.fs
deleted file mode 100644
index e4defe8e..00000000
--- a/NOnion/Utility/EmbeddedResourceUtility.fs
+++ /dev/null
@@ -1,40 +0,0 @@
-namespace NOnion.Utility
-
-open System
-open System.IO
-open System.Reflection
-
-module EmbeddedResourceUtility =
-
- // Code from https://github.com/nblockchain/geewallet/blob/428cb77d21dba20fc38c7ea032003c5861aac950/src/GWallet.Backend/Config.fs#L156
- let ExtractEmbeddedResourceFileContents(resourceName: string) : string =
- let assembly = Assembly.GetExecutingAssembly()
- let ress = String.Join(";", assembly.GetManifestResourceNames())
-
- let fullNameOpt =
- assembly.GetManifestResourceNames()
- |> Seq.filter(fun aResourceName ->
- aResourceName = resourceName
- || aResourceName.EndsWith("." + resourceName)
- )
- |> Seq.tryExactlyOne
-
- match fullNameOpt with
- | Some fullName ->
- use stream = assembly.GetManifestResourceStream fullName
-
- if isNull stream then
- failwithf
- "Embedded resource %s (%s) not found in assembly %s"
- resourceName
- fullName
- assembly.FullName
-
- use reader = new StreamReader(stream)
- reader.ReadToEnd()
- | None ->
- failwithf
- "Embedded resource %s not found at all in assembly %s (resource names: %s)"
- resourceName
- assembly.FullName
- ress
diff --git a/NOnion/Utility/FSharpUtil.fs b/NOnion/Utility/FSharpUtil.fs
deleted file mode 100644
index f4a67a17..00000000
--- a/NOnion/Utility/FSharpUtil.fs
+++ /dev/null
@@ -1,102 +0,0 @@
-namespace NOnion.Utility
-
-open System
-open System.Runtime.ExceptionServices
-
-open FSharpx.Collections
-
-open NOnion
-
-module FSharpUtil =
- //Implementation copied from https://github.com/nblockchain/geewallet/blob/master/src/GWallet.Backend/FSharpUtil.fs
- let ReRaise(ex: Exception) : Exception =
- (ExceptionDispatchInfo.Capture ex).Throw()
- failwith "Should be unreachable"
- ex
-
- let rec public FindException<'T when 'T :> Exception>
- (ex: Exception)
- : Option<'T> =
- let rec findExInSeq(sq: seq) =
- match Seq.tryHeadTail sq with
- | Some(head, tail) ->
- match FindException head with
- | Some ex -> Some ex
- | None -> findExInSeq <| tail
- | None -> None
-
- if isNull ex then
- None
- else
- match ex with
- | :? 'T as specificEx -> Some specificEx
- | :? AggregateException as aggEx ->
- findExInSeq aggEx.InnerExceptions
- | _ -> FindException<'T> ex.InnerException
-
- type private Either<'Val, 'Err when 'Err :> Exception> =
- | FailureResult of 'Err
- | SuccessfulValue of 'Val
-
- let WithTimeout (timeSpan: TimeSpan) (job: Async<'R>) : Async<'R> =
- async {
- let read =
- async {
- let! value = job
- return value |> SuccessfulValue |> Some
- }
-
- let delay =
- async {
- let total = int timeSpan.TotalMilliseconds
- do! Async.Sleep total
- return FailureResult <| TimeoutException() |> Some
- }
-
- let! dummyOption = Async.Choice([ read; delay ])
-
- match dummyOption with
- | Some theResult ->
- match theResult with
- | SuccessfulValue r -> return r
- | FailureResult _ -> return raise <| TimeoutErrorException()
- | None ->
- // none of the jobs passed to Async.Choice returns None
- return failwith "unreachable"
- }
-
- let Retry<'E1, 'E2 when 'E1 :> Exception and 'E2 :> Exception>
- (jobToRetry: Async)
- (maxRetryCount: int)
- =
- let rec retryLoop(tryNumber: int) =
- async {
- try
- do! jobToRetry
- with
- | :? 'E1
- | :? 'E2 as ex ->
- if tryNumber < maxRetryCount then
- return! retryLoop(tryNumber + 1)
- else
- sprintf
- "Maximum retry count reached, ex = %s"
- (ex.ToString())
- |> TorLogger.Log
-
- return raise <| ReRaise ex
- | ex ->
- sprintf
- "Unexpected exception happened in the retry loop, ex = %s"
- (ex.ToString())
- |> TorLogger.Log
-
- return raise <| ReRaise ex
- }
-
- retryLoop 0
-
- let UnwrapOption<'T> (opt: Option<'T>) (msg: string) : 'T =
- match opt with
- | Some value -> value
- | None -> failwith <| sprintf "error unwrapping Option: %s" msg
diff --git a/NOnion/Utility/MailboxUtil.fs b/NOnion/Utility/MailboxUtil.fs
index 6024f954..515fbb4a 100644
--- a/NOnion/Utility/MailboxUtil.fs
+++ b/NOnion/Utility/MailboxUtil.fs
@@ -2,6 +2,8 @@
open System.Net.Sockets
+open Fsdk
+
open NOnion
module internal MailboxResultUtil =
diff --git a/NOnion/Utility/ResultUtil.fs b/NOnion/Utility/ResultUtil.fs
index e997ec7c..28dcfe7b 100644
--- a/NOnion/Utility/ResultUtil.fs
+++ b/NOnion/Utility/ResultUtil.fs
@@ -1,5 +1,7 @@
namespace NOnion.Utility
+open Fsdk
+
//FIXME: for some reason FSharpUtil is in NOnion namespace instead of NOnion.Utility
open NOnion