diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT/Query.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT/Query.hs | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/src/Network/BitTorrent/DHT/Query.hs b/src/Network/BitTorrent/DHT/Query.hs index e5d9bd5f..67dc4541 100644 --- a/src/Network/BitTorrent/DHT/Query.hs +++ b/src/Network/BitTorrent/DHT/Query.hs | |||
@@ -16,6 +16,8 @@ | |||
16 | {-# LANGUAGE TupleSections #-} | 16 | {-# LANGUAGE TupleSections #-} |
17 | {-# LANGUAGE PartialTypeSignatures #-} | 17 | {-# LANGUAGE PartialTypeSignatures #-} |
18 | {-# LANGUAGE GADTs #-} | 18 | {-# LANGUAGE GADTs #-} |
19 | {-# LANGUAGE RankNTypes #-} | ||
20 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
19 | module Network.BitTorrent.DHT.Query | 21 | module Network.BitTorrent.DHT.Query |
20 | ( -- * Handler | 22 | ( -- * Handler |
21 | -- | To bind specific set of handlers you need to pass | 23 | -- | To bind specific set of handlers you need to pass |
@@ -25,6 +27,7 @@ module Network.BitTorrent.DHT.Query | |||
25 | , getPeersH | 27 | , getPeersH |
26 | , announceH | 28 | , announceH |
27 | , defaultHandlers | 29 | , defaultHandlers |
30 | , DataHandlers | ||
28 | 31 | ||
29 | -- * Query | 32 | -- * Query |
30 | -- ** Basic | 33 | -- ** Basic |
@@ -113,6 +116,7 @@ import Data.Serialize | |||
113 | import System.IO.Unsafe (unsafeInterleaveIO) | 116 | import System.IO.Unsafe (unsafeInterleaveIO) |
114 | import Data.String | 117 | import Data.String |
115 | 118 | ||
119 | |||
116 | {----------------------------------------------------------------------- | 120 | {----------------------------------------------------------------------- |
117 | -- Handlers | 121 | -- Handlers |
118 | -----------------------------------------------------------------------} | 122 | -----------------------------------------------------------------------} |
@@ -215,20 +219,68 @@ kademliaHandlers logger = do | |||
215 | , handler (nameFindNodes dht) $ findNodeH getclosest | 219 | , handler (nameFindNodes dht) $ findNodeH getclosest |
216 | ] | 220 | ] |
217 | 221 | ||
222 | class DataHandlers raw dht where | ||
223 | dataHandlers :: | ||
224 | ( Ord ip , Hashable ip, Typeable ip, Serialize ip) => | ||
225 | (NodeId dht -> IO [NodeInfo dht ip ()]) | ||
226 | -> DHTData dht ip | ||
227 | -> [MethodHandler raw dht ip] | ||
228 | |||
229 | instance DataHandlers BValue KMessageOf where | ||
230 | dataHandlers = bthandlers | ||
231 | |||
232 | bthandlers :: | ||
233 | ( Ord ip , Hashable ip, Typeable ip, Serialize ip) => | ||
234 | (NodeId KMessageOf -> IO [NodeInfo KMessageOf ip ()]) | ||
235 | -> DHTData KMessageOf ip | ||
236 | -> [MethodHandler BValue KMessageOf ip] | ||
237 | bthandlers getclosest dta = | ||
238 | [ MethodHandler "get_peers" $ getPeersH (getpeers dta) (sessionTokens dta) | ||
239 | , MethodHandler "announce_peer" $ announceH (contactInfo dta) (sessionTokens dta) | ||
240 | ] | ||
241 | where | ||
242 | getpeers dta ih = do | ||
243 | ps <- lookupPeers (contactInfo dta) ih | ||
244 | if L.null ps | ||
245 | then Left <$> getclosest (toNodeId ih) | ||
246 | else return (Right ps) | ||
247 | |||
248 | data MethodHandler raw dht ip = | ||
249 | forall a b. ( SerializableTo raw (Response dht b) | ||
250 | , SerializableTo raw (Query dht a) | ||
251 | ) => MethodHandler (QueryMethod dht) (NodeAddr ip -> a -> IO b) | ||
218 | 252 | ||
219 | -- | Includes all default query handlers. | 253 | -- | Includes all default query handlers. |
220 | defaultHandlers :: forall ip. (Eq ip, Ord ip, Address ip) => LogFun -> DHT BValue KMessageOf () ip [NodeHandler] | 254 | defaultHandlers :: forall raw dht u ip. |
255 | ( Ord (TransactionID dht) | ||
256 | , Ord (NodeId dht) | ||
257 | , Show u | ||
258 | , SerializableTo raw (Response dht (Ping dht)) | ||
259 | , SerializableTo raw (Query dht (Ping dht)) | ||
260 | , Show (QueryMethod dht) | ||
261 | , Show (NodeId dht) | ||
262 | , FiniteBits (NodeId dht) | ||
263 | , Default u | ||
264 | , Serialize (TransactionID dht) | ||
265 | , WireFormat raw dht | ||
266 | , Kademlia dht | ||
267 | , KRPC (Query dht (Ping dht)) (Response dht (Ping dht)) | ||
268 | , Functor dht | ||
269 | , Pretty (NodeInfo dht ip u) | ||
270 | , KRPC (Query dht (FindNode dht ip)) (Response dht (NodeFound dht ip)) | ||
271 | , SerializableTo raw (Response dht (NodeFound dht ip)) | ||
272 | , SerializableTo raw (Query dht (FindNode dht ip)) | ||
273 | , Eq ip, Ord ip, Address ip, DataHandlers raw dht | ||
274 | ) => LogFun -> DHT raw dht u ip [Handler IO dht raw] | ||
221 | defaultHandlers logger = do | 275 | defaultHandlers logger = do |
222 | groknode <- insertNode1 | 276 | groknode <- insertNode1 |
223 | mynid <- myNodeIdAccordingTo1 | 277 | mynid <- myNodeIdAccordingTo1 |
224 | let handler :: KRPC (Query KMessageOf a) (Response KMessageOf b) => QueryMethod KMessageOf -> (NodeAddr ip -> a -> IO b) -> NodeHandler | 278 | let handler :: MethodHandler raw dht ip -> Handler IO dht raw |
225 | handler = nodeHandler groknode mynid (logt logger) | 279 | handler (MethodHandler name action) = nodeHandler groknode mynid (logt logger) name action |
226 | toks <- asks sessionTokens | 280 | dta <- asks dhtData |
227 | peers <- asks contactInfo | 281 | getclosest <- getClosest1 |
228 | getpeers <- getPeerList1 | ||
229 | hs <- kademliaHandlers logger | 282 | hs <- kademliaHandlers logger |
230 | return $ hs ++ [ handler "get_peers" $ getPeersH getpeers toks | 283 | return $ hs ++ L.map handler (dataHandlers (fmap (fmap (fmap (const ()))) . getclosest) dta) |
231 | , handler "announce_peer" $ announceH peers toks ] | ||
232 | 284 | ||
233 | {----------------------------------------------------------------------- | 285 | {----------------------------------------------------------------------- |
234 | -- Basic queries | 286 | -- Basic queries |