diff options
-rw-r--r-- | network-bittorrent.cabal | 9 | ||||
-rw-r--r-- | src/Data/Kademlia/RoutingTable.hs | 28 | ||||
-rw-r--r-- | src/Network/DHT/Kademlia.hs | 68 |
3 files changed, 103 insertions, 2 deletions
diff --git a/network-bittorrent.cabal b/network-bittorrent.cabal index 53cadcd8..da4e6818 100644 --- a/network-bittorrent.cabal +++ b/network-bittorrent.cabal | |||
@@ -22,8 +22,8 @@ source-repository head | |||
22 | 22 | ||
23 | library | 23 | library |
24 | exposed-modules: Data.Torrent | 24 | exposed-modules: Data.Torrent |
25 | , Data.Bitfield | ||
26 | , Data.Torrent.InfoHash | 25 | , Data.Torrent.InfoHash |
26 | , Data.Bitfield | ||
27 | 27 | ||
28 | , Network.BitTorrent | 28 | , Network.BitTorrent |
29 | , Network.BitTorrent.Extension | 29 | , Network.BitTorrent.Extension |
@@ -44,6 +44,10 @@ library | |||
44 | , Network.BitTorrent.PeerWire.Message | 44 | , Network.BitTorrent.PeerWire.Message |
45 | , Network.BitTorrent.PeerWire.Handshake | 45 | , Network.BitTorrent.PeerWire.Handshake |
46 | 46 | ||
47 | -- DHT | ||
48 | , Data.Kademlia.RoutingTable | ||
49 | , Network.DHT.Kademlia | ||
50 | |||
47 | other-modules: | 51 | other-modules: |
48 | 52 | ||
49 | 53 | ||
@@ -69,8 +73,9 @@ library | |||
69 | -- network related packages | 73 | -- network related packages |
70 | , network >= 2.4 | 74 | , network >= 2.4 |
71 | , HTTP >= 4000.2 | 75 | , HTTP >= 4000.2 |
72 | , cryptohash | 76 | , krpc |
73 | 77 | ||
78 | , cryptohash | ||
74 | , filepath == 1.* | 79 | , filepath == 1.* |
75 | 80 | ||
76 | 81 | ||
diff --git a/src/Data/Kademlia/RoutingTable.hs b/src/Data/Kademlia/RoutingTable.hs new file mode 100644 index 00000000..98e15a0b --- /dev/null +++ b/src/Data/Kademlia/RoutingTable.hs | |||
@@ -0,0 +1,28 @@ | |||
1 | module Data.Kademlia.RoutingTable | ||
2 | ( | ||
3 | ) where | ||
4 | |||
5 | import Data.ByteString | ||
6 | |||
7 | type NodeID = ByteString | ||
8 | type InfoHash = ByteString | ||
9 | |||
10 | type Bucket = [NodeID] | ||
11 | |||
12 | data Tree | ||
13 | = Tip Bucket | ||
14 | | Bin Table Table | ||
15 | |||
16 | data Table = Table { | ||
17 | tree :: Tree | ||
18 | , bucketSize :: Int | ||
19 | } | ||
20 | |||
21 | closest :: InfoHash -> Table -> [NodeID] | ||
22 | closest = undefined | ||
23 | |||
24 | insert :: NodeID -> Table -> Table | ||
25 | insert x t = undefined | ||
26 | |||
27 | -- TODO table serialization: usually we need to save table between | ||
28 | -- target program executions | ||
diff --git a/src/Network/DHT/Kademlia.hs b/src/Network/DHT/Kademlia.hs new file mode 100644 index 00000000..d5418beb --- /dev/null +++ b/src/Network/DHT/Kademlia.hs | |||
@@ -0,0 +1,68 @@ | |||
1 | -- TODO move to Network.DHT.Kademlia | ||
2 | {-# LANGUAGE OverloadedStrings #-} | ||
3 | module Network.DHT.Kademlia | ||
4 | ( | ||
5 | ) where | ||
6 | |||
7 | import Data.ByteString | ||
8 | import Network | ||
9 | import Remote.KRPC | ||
10 | |||
11 | |||
12 | |||
13 | -- | Global unique identifier of the node. Size of the identifier | ||
14 | -- should(!) be equal to the size of DHT keys. This limitation arises | ||
15 | -- from the design of Kademlia: we should estimate distance between | ||
16 | -- keys and NodeId in routing algorithms. | ||
17 | -- | ||
18 | type NodeID = ByteString | ||
19 | |||
20 | type NodeAddr = ByteString | ||
21 | type InfoHash = ByteString | ||
22 | type Token = ByteString | ||
23 | |||
24 | -- | Used to check out if a node is alive or not. This has a tow-fold effect: | ||
25 | -- | ||
26 | -- * If(!) caller get response it should update the bucket | ||
27 | -- corresponding to the callee. | ||
28 | -- | ||
29 | -- * Callee of the ping should update the bucket corresponding | ||
30 | -- to the caller as well. | ||
31 | -- | ||
32 | ping :: Method NodeID NodeID | ||
33 | ping = method "ping" ["id"] ["id"] | ||
34 | |||
35 | type PeerContact = () | ||
36 | data NodeContact = NodeContact { | ||
37 | peerContact :: PeerContact | ||
38 | , nodeID :: NodeID | ||
39 | } | ||
40 | |||
41 | -- | Used to lookup peer ID from node ID. | ||
42 | -- | ||
43 | find_node :: Method (NodeID, NodeID) (NodeID, NodeContact) | ||
44 | find_node = method "find_node" ["id", "target"] ["id", "nodes"] | ||
45 | |||
46 | -- | | ||
47 | announce_peer :: Method (NodeID, InfoHash, PortNumber, Token) NodeID | ||
48 | announce_peer = undefined | ||
49 | |||
50 | genNodeID :: IO NodeID | ||
51 | genNodeID = undefined | ||
52 | |||
53 | {- | ||
54 | type InfoHash = Int | ||
55 | type Token = Int | ||
56 | |||
57 | ping :: Method NodeId NodeId | ||
58 | ping = method "ping" ["id"] ["id"] | ||
59 | |||
60 | get_peers :: Method (NodeId :*: InfoHash) (NodeId, Token, NodeAddr :|: NodeAddr) | ||
61 | get_peers = method "get_peers" | ||
62 | ("id", "target") | ||
63 | ("id", "token", view ("values" :|: "nodes")) | ||
64 | |||
65 | |||
66 | |||
67 | |||
68 | -} \ No newline at end of file | ||