1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
{-# LANGUAGE ExistentialQuantification #-}
module Network.Kademlia.CommonAPI where
import Control.Concurrent
import Control.Concurrent.STM
import Data.Aeson as J (FromJSON, ToJSON)
import Data.Hashable
import qualified Data.Map as Map
import Data.Serialize as S
import qualified Data.Set as Set
import Data.Time.Clock.POSIX
import Data.Typeable
import Network.Kademlia.Search
import Network.Kademlia.Routing as R
import Crypto.Tox (SecretKey,PublicKey)
data DHT = forall nid ni. ( Show ni
, Read ni
, ToJSON ni
, FromJSON ni
, Ord ni
, Hashable ni
, Show nid
, Ord nid
, Hashable nid
, Typeable ni
, S.Serialize nid
) =>
DHT
{ dhtBuckets :: TVar (BucketList ni)
, dhtSecretKey :: STM (Maybe SecretKey)
, dhtPing :: Map.Map String (DHTPing ni)
, dhtQuery :: Map.Map String (DHTQuery nid ni)
, dhtAnnouncables :: Map.Map String (DHTAnnouncable nid)
, dhtParseId :: String -> Either String nid
, dhtSearches :: TVar (Map.Map (String,nid) (DHTSearch nid ni))
, dhtFallbackNodes :: IO [ni]
, dhtBootstrap :: [ni] -> [ni] -> IO ()
}
data DHTQuery nid ni = forall addr r tok.
( Ord addr
, Typeable r
, Typeable tok
, Typeable ni
) => DHTQuery
{ qsearch :: Search nid addr tok ni r
, qhandler :: ni -> nid -> IO ([ni], [r], Maybe tok) -- ^ Invoked on local node, when there is no query destination.
, qshowR :: r -> String
, qshowTok :: tok -> Maybe String
}
data DHTAnnouncable nid = forall dta tok ni r.
( Show r
, Typeable dta -- information being announced
, Typeable tok -- token
, Typeable r -- search result
, Typeable ni -- node
) => DHTAnnouncable
{ announceParseData :: String -> Either String dta
, announceParseToken :: dta -> String -> Either String tok
, announceParseAddress :: String -> Either String ni
, announceSendData :: Either ( String {- search name -}
, String -> Either String r
, PublicKey {- me -} -> dta -> r -> IO ())
(dta -> tok -> Maybe ni -> IO (Maybe r))
, announceInterval :: POSIXTime
, announceTarget :: dta -> nid
}
data DHTSearch nid ni = forall addr tok r. DHTSearch
{ searchThread :: ThreadId
, searchState :: SearchState nid addr tok ni r
, searchShowTok :: tok -> Maybe String
, searchResults :: TVar (Set.Set String)
}
data DHTPing ni = forall r. DHTPing
{ pingQuery :: [String] -> ni -> IO (Maybe r)
, pingShowResult :: r -> String
}
|