diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-30 18:41:14 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-30 18:41:14 +0400 |
commit | d52c84101661de38bd984de96d84e5a61f2ad9da (patch) | |
tree | d0b19a37ccb7d159ebac62d4a5e99a8234a4a517 | |
parent | fd489f1be5eff3d11c978165017c0984493794fe (diff) |
Add module header to DHT Messages
-rw-r--r-- | src/Network/BitTorrent/DHT/Message.hs | 74 |
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 () | |||
49 | node_id_key :: BKey | 103 | node_id_key :: BKey |
50 | node_id_key = "id" | 104 | node_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. |
54 | data Query a = Query | 108 | data 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 | ||
59 | instance BEncode a => BEncode (Query a) where | 113 | instance 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. |
74 | data Response a = Response | 128 | data 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 | ||
79 | instance BEncode a => BEncode (Response a) where | 133 | instance 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\" | ||
204 | instance (Typeable ip, Serialize ip) => | 259 | instance (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\" | ||
268 | instance KRPC (Query Announce) (Response Announced) where | 324 | instance KRPC (Query Announce) (Response Announced) where |
269 | method = "announce_peer" \ No newline at end of file | 325 | method = "announce_peer" |