summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT/Message.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/DHT/Message.hs')
-rw-r--r--src/Network/BitTorrent/DHT/Message.hs74
1 files changed, 65 insertions, 9 deletions
diff --git a/src/Network/BitTorrent/DHT/Message.hs b/src/Network/BitTorrent/DHT/Message.hs
index 83413752..461c8f83 100644
--- a/src/Network/BitTorrent/DHT/Message.hs
+++ b/src/Network/BitTorrent/DHT/Message.hs
@@ -1,6 +1,60 @@
1-- | For more info see: 1-- |
2-- Copyright : (c) Sam Truzjan 2013
3-- License : BSD3
4-- Maintainer : pxqr.sta@gmail.com
5-- Stability : experimental
6-- Portability : portable
7--
8-- This module provides message datatypes which is used for /Node to
9-- Node/ communication. Bittorrent DHT is based on Kademlia
10-- specification, but have a slightly different set of messages
11-- which have been adopted for /peer/ discovery mechanism. Messages
12-- are sent over "Network.KRPC" protocol, but normally you should
13-- use "Network.BitTorrent.DHT.Session" to send and receive
14-- messages.
15--
16-- DHT queries are not /recursive/, they are /iterative/. This means
17-- that /querying/ node . While original specification (namely BEP5)
18-- do not impose any restrictions for /quered/ node behaviour, a
19-- good DHT implementation should follow some rules to guarantee
20-- that unlimit recursion will never happen. The following set of
21-- restrictions:
22--
23-- * 'Ping' query must not trigger any message.
24--
25-- * 'FindNode' query /may/ trigger 'Ping' query to check if a
26-- list of nodes to return is /good/. See
27-- 'Network.BitTorrent.DHT.Routing.Routing' for further explanation.
28--
29-- * 'GetPeers' query may trigger 'Ping' query for the same reason.
30--
31-- * 'Announce' query must trigger 'Ping' query for the same reason.
32--
33-- It is easy to see that the most long RPC chain is:
34--
35-- @
36-- | | |
37-- Node_A | |
38-- | FindNode or GetPeers or Announce | |
39-- | ------------------------------------> Node_B |
40-- | | Ping |
41-- | | -----------> |
42-- | | Node_C
43-- | | Pong |
44-- | NodeFound or GotPeers or Announced | <----------- |
45-- | <------------------------------------- Node_B |
46-- Node_A | |
47-- | | |
48-- @
49--
50-- where in some cases 'Node_C' is 'Node_A'.
51--
52-- For more info see:
2-- <http://www.bittorrent.org/beps/bep_0005.html#dht-queries> 53-- <http://www.bittorrent.org/beps/bep_0005.html#dht-queries>
3-- 54--
55-- For Kamelia messages see original Kademlia paper:
56-- <http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf>
57--
4{-# LANGUAGE DeriveDataTypeable #-} 58{-# LANGUAGE DeriveDataTypeable #-}
5{-# LANGUAGE FlexibleInstances #-} 59{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE MultiParamTypeClasses #-} 60{-# LANGUAGE MultiParamTypeClasses #-}
@@ -49,11 +103,11 @@ import Network.KRPC ()
49node_id_key :: BKey 103node_id_key :: BKey
50node_id_key = "id" 104node_id_key = "id"
51 105
52-- | All queries have an "id" key and value containing the node ID of 106-- | All queries have an \"id\" key and value containing the node ID
53-- the querying node. 107-- of the querying node.
54data Query a = Query 108data Query a = Query
55 { thisNodeId :: NodeId 109 { thisNodeId :: NodeId -- ^ node id of /quering/ node;
56 , queryParams :: a 110 , queryParams :: a -- ^ query parameters.
57 } deriving (Show, Eq) 111 } deriving (Show, Eq)
58 112
59instance BEncode a => BEncode (Query a) where 113instance BEncode a => BEncode (Query a) where
@@ -69,11 +123,11 @@ instance BEncode a => BEncode (Query a) where
69 Query <$> fromDict (field (req node_id_key)) v 123 Query <$> fromDict (field (req node_id_key)) v
70 <*> fromBEncode v 124 <*> fromBEncode v
71 125
72-- | All responses have an "id" key and value containing the node ID 126-- | All responses have an \"id\" key and value containing the node ID
73-- of the responding node. 127-- of the responding node.
74data Response a = Response 128data Response a = Response
75 { remoteNodeId :: NodeId 129 { remoteNodeId :: NodeId -- ^ node id of /quered/ node;
76 , responseVals :: a 130 , responseVals :: a -- ^ query result.
77 } deriving (Show, Eq) 131 } deriving (Show, Eq)
78 132
79instance BEncode a => BEncode (Response a) where 133instance BEncode a => BEncode (Response a) where
@@ -201,6 +255,7 @@ instance (Typeable ip, Serialize ip) => BEncode (GotPeers ip) where
201 where 255 where
202 decodePeers = either fail pure . mapM S.decode 256 decodePeers = either fail pure . mapM S.decode
203 257
258-- | \"q" = \"get_peers\"
204instance (Typeable ip, Serialize ip) => 259instance (Typeable ip, Serialize ip) =>
205 KRPC (Query GetPeers) (Response (GotPeers ip)) where 260 KRPC (Query GetPeers) (Response (GotPeers ip)) where
206 method = "get_peers" 261 method = "get_peers"
@@ -265,5 +320,6 @@ instance BEncode Announced where
265 toBEncode _ = toBEncode Ping 320 toBEncode _ = toBEncode Ping
266 fromBEncode _ = pure Announced 321 fromBEncode _ = pure Announced
267 322
323-- | \"q" = \"announce\"
268instance KRPC (Query Announce) (Response Announced) where 324instance KRPC (Query Announce) (Response Announced) where
269 method = "announce_peer" \ No newline at end of file 325 method = "announce_peer"