summaryrefslogtreecommitdiff
path: root/examples/dhtd.hs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/dhtd.hs')
-rw-r--r--examples/dhtd.hs65
1 files changed, 47 insertions, 18 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index f98b05bd..67888eb4 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -39,6 +39,7 @@ import GHC.Conc (labelThread)
39#endif 39#endif
40 40
41import Network.Address hiding (NodeId, NodeInfo(..)) 41import Network.Address hiding (NodeId, NodeInfo(..))
42import Network.BitTorrent.DHT.Search
42import Network.QueryResponse 43import Network.QueryResponse
43import Network.StreamServer 44import Network.StreamServer
44import Kademlia 45import Kademlia
@@ -68,23 +69,31 @@ hPutClient h s = hPutStr h ('.' : marshalForClient s)
68hPutClientChunk :: Handle -> String -> IO () 69hPutClientChunk :: Handle -> String -> IO ()
69hPutClientChunk h s = hPutStr h (' ' : marshalForClient s) 70hPutClientChunk h s = hPutStr h (' ' : marshalForClient s)
70 71
71data DHT = forall ni. ( Show ni 72data DHTQuery nid ni = forall addr r tok. DHTQuery
72 , Read ni 73 { qsearch :: Search nid addr tok ni r
73 , ToJSON ni 74 , qhandler :: ni -> nid -> IO ([ni], [r], tok)
74 , FromJSON ni 75 , qshowR :: r -> String
75 ) => 76 , qshowTok :: tok -> Maybe String
77 }
78
79data DHT = forall nid ni. ( Show ni
80 , Read ni
81 , ToJSON ni
82 , FromJSON ni
83 ) =>
76 DHT 84 DHT
77 { dhtBuckets :: TVar (BucketList ni) 85 { dhtBuckets :: TVar (BucketList ni)
78 , dhtPing :: ni -> IO Bool 86 , dhtPing :: ni -> IO Bool
79 -- dhtClient :: Client err meth tid addr x 87 , dhtQuery :: Map.Map String (DHTQuery nid ni)
88 , dhtParseId :: String -> Either String nid
80 } 89 }
81 90
82nodesFileName :: String -> String 91nodesFileName :: String -> String
83nodesFileName netname = netname ++ "-nodes.json" 92nodesFileName netname = netname ++ "-nodes.json"
84 93
85saveNodes :: String -> DHT -> IO () 94saveNodes :: String -> DHT -> IO ()
86saveNodes netname (DHT var _) = do 95saveNodes netname DHT{dhtBuckets} = do
87 bkts <- atomically $ readTVar var 96 bkts <- atomically $ readTVar dhtBuckets
88 let ns = map fst $ concat $ R.toList bkts 97 let ns = map fst $ concat $ R.toList bkts
89 bs = J.encode ns 98 bs = J.encode ns
90 fname = nodesFileName netname 99 fname = nodesFileName netname
@@ -99,7 +108,7 @@ loadNodes netname = do
99 either (const $ return []) return attempt 108 either (const $ return []) return attempt
100 109
101pingNodes :: String -> DHT -> IO Bool 110pingNodes :: String -> DHT -> IO Bool
102pingNodes netname (DHT _ ping) = do 111pingNodes netname DHT{dhtPing} = do
103 let fname = nodesFileName netname 112 let fname = nodesFileName netname
104 attempt <- tryIOError $ do 113 attempt <- tryIOError $ do
105 J.decode <$> L.readFile fname 114 J.decode <$> L.readFile fname
@@ -110,7 +119,7 @@ pingNodes netname (DHT _ ping) = do
110 myThreadId >>= flip labelThread ("pinging."++fname) 119 myThreadId >>= flip labelThread ("pinging."++fname)
111 putStrLn $ "Forked "++show fname 120 putStrLn $ "Forked "++show fname
112 withTaskGroup 10 $ \g -> do 121 withTaskGroup 10 $ \g -> do
113 mapTasks_ g (map ping ns) 122 mapTasks_ g (map dhtPing ns)
114 putStrLn $ "Load finished "++show fname 123 putStrLn $ "Load finished "++show fname
115 return True 124 return True
116 125
@@ -189,9 +198,9 @@ clientSession s@Session{..} sock cnum h = do
189 _ -> hPutClient h "error." 198 _ -> hPutClient h "error."
190 199
191#endif 200#endif
192 ("ls", _) | Just (DHT var _) <- Map.lookup netname dhts 201 ("ls", _) | Just DHT{dhtBuckets} <- Map.lookup netname dhts
193 -> cmd0 $ do 202 -> cmd0 $ do
194 bkts <- atomically $ readTVar var 203 bkts <- atomically $ readTVar dhtBuckets
195 let r = reportTable bkts 204 let r = reportTable bkts
196 hPutClient h $ 205 hPutClient h $
197 showReport $ 206 showReport $
@@ -199,10 +208,10 @@ clientSession s@Session{..} sock cnum h = do
199 , ("node-id", show $ thisNode bkts) 208 , ("node-id", show $ thisNode bkts)
200 , ("network", netname) ] 209 , ("network", netname) ]
201 210
202 ("ping", s) | Just (DHT _ ping) <- Map.lookup netname dhts 211 ("ping", s) | Just DHT{dhtPing} <- Map.lookup netname dhts
203 -> cmd0 $ do 212 -> cmd0 $ do
204 case readEither s of 213 case readEither s of
205 Right addr -> do result <- ping addr 214 Right addr -> do result <- dhtPing addr
206 let rs = [" ", show result] 215 let rs = [" ", show result]
207 hPutClient h $ unlines rs 216 hPutClient h $ unlines rs
208 Left er -> hPutClient h er 217 Left er -> hPutClient h er
@@ -238,15 +247,35 @@ main = do
238 _ -> return defaultPort 247 _ -> return defaultPort
239 addr <- getBindAddress p True{- ipv6 -} 248 addr <- getBindAddress p True{- ipv6 -}
240 249
241 (bt,btR) <- Mainline.newClient addr 250 (bt,btR,swarms) <- Mainline.newClient addr
242 quitBt <- forkListener bt 251 quitBt <- forkListener bt
243 252
244 tox <- return $ error "TODO: Tox.newClient" 253 tox <- return $ error "TODO: Tox.newClient"
245 quitTox <- return $ return () -- TODO: forkListener tox 254 quitTox <- return $ return () -- TODO: forkListener tox
246 255
247 let dhts = Map.fromList 256 let mainlineDHT bkts = DHT
248 [ ("bt4", DHT (Mainline.routing4 btR) (Mainline.ping bt)) 257 { dhtBuckets = bkts btR
249 , ("bt6", DHT (Mainline.routing6 btR) (Mainline.ping bt)) 258 , dhtPing = Mainline.ping bt
259 , dhtQuery = Map.fromList
260 [ ("node", DHTQuery (Mainline.nodeSearch bt)
261 (\ni -> fmap Mainline.unwrapNodes
262 . Mainline.findNodeH btR ni
263 . flip Mainline.FindNode (Just Mainline.Want_Both))
264 show
265 (const Nothing))
266 , ("peer", DHTQuery (Mainline.peerSearch bt)
267 (\ni -> fmap Mainline.unwrapPeers
268 . Mainline.getPeersH btR swarms ni
269 . flip Mainline.GetPeers (Just Mainline.Want_Both)
270 . (read . show)) -- TODO: InfoHash -> NodeId
271 show
272 (Just . show))
273 ]
274 , dhtParseId = readEither :: String -> Either String Mainline.NodeId
275 }
276 dhts = Map.fromList
277 [ ("bt4", mainlineDHT Mainline.routing4)
278 , ("bt6", mainlineDHT Mainline.routing6)
250 ] 279 ]
251 280
252 waitForSignal <- do 281 waitForSignal <- do