summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT.hs
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2014-01-02 16:36:43 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2014-01-02 16:36:43 +0400
commit5d576086294166fd97b24585c54c2b3820bab6aa (patch)
tree773add2e6cb3592718316742034d575af843013f /src/Network/BitTorrent/DHT.hs
parent2b1ce778669dc58e8b2bf60a942722ede2c0515b (diff)
Add documentation to the root DHT module
Diffstat (limited to 'src/Network/BitTorrent/DHT.hs')
-rw-r--r--src/Network/BitTorrent/DHT.hs56
1 files changed, 43 insertions, 13 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs
index 155a50ca..7eef0c67 100644
--- a/src/Network/BitTorrent/DHT.hs
+++ b/src/Network/BitTorrent/DHT.hs
@@ -1,11 +1,29 @@
1-- |
2-- Copyright : (c) Sam Truzjan 2013
3-- License : BSD3
4-- Maintainer : pxqr.sta@gmail.com
5-- Stability : experimental
6-- Portability : portable
7--
8-- BitTorrent uses a \"distributed sloppy hash table\" (DHT) for
9-- storing peer contact information for \"trackerless\" torrents. In
10-- effect, each peer becomes a tracker.
11--
12-- Normally you don't need to import other DHT modules.
13--
14-- For more info see:
15-- <http://www.bittorrent.org/beps/bep_0005.html>
16--
1{-# LANGUAGE FlexibleInstances #-} 17{-# LANGUAGE FlexibleInstances #-}
2{-# LANGUAGE TemplateHaskell #-} 18{-# LANGUAGE TemplateHaskell #-}
3module Network.BitTorrent.DHT 19module Network.BitTorrent.DHT
4 ( dht 20 ( -- * Distributed Hash Table
5 , ping 21 DHT
22 , dht
6 , Network.BitTorrent.DHT.bootstrap 23 , Network.BitTorrent.DHT.bootstrap
7 , Network.BitTorrent.DHT.lookup 24 , Network.BitTorrent.DHT.lookup
8 , Network.BitTorrent.DHT.insert 25 , Network.BitTorrent.DHT.insert
26 , Network.BitTorrent.DHT.delete
9 ) where 27 ) where
10 28
11import Control.Applicative 29import Control.Applicative
@@ -67,13 +85,11 @@ handlers = [pingH, findNodeH, getPeersH, announceH]
67dht :: Address ip => NodeAddr ip -> DHT ip a -> IO a 85dht :: Address ip => NodeAddr ip -> DHT ip a -> IO a
68dht addr = runDHT addr handlers 86dht addr = runDHT addr handlers
69 87
70ping :: Address ip => NodeAddr ip -> DHT ip () 88-- | One good node may be sufficient. The list of bootstrapping nodes
71ping addr = do 89-- usually obtained from 'Data.Torrent.tNodes' field.
72 Ping <- Ping <@> addr 90--
73 return () 91-- (TODO) This operation is asynchronous and do not block.
74 92--
75-- TODO fork?
76-- | One good node may be sufficient. <note about 'Data.Torrent.tNodes'>
77bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () 93bootstrap :: Address ip => [NodeAddr ip] -> DHT ip ()
78bootstrap startNodes = do 94bootstrap startNodes = do
79 $(logInfoS) "bootstrap" "Start node bootstrapping" 95 $(logInfoS) "bootstrap" "Start node bootstrapping"
@@ -95,22 +111,29 @@ bootstrap startNodes = do
95 $(logDebug) ("Get a list of closest nodes: " <> 111 $(logDebug) ("Get a list of closest nodes: " <>
96 T.pack (PP.render (pretty closest))) 112 T.pack (PP.render (pretty closest)))
97 forM_ (L.take 2 closest) $ \ info @ NodeInfo {..} -> do 113 forM_ (L.take 2 closest) $ \ info @ NodeInfo {..} -> do
98 insertNode info 114 _ <- insertNode info
99 let prettyAddr = T.pack (show (pretty nodeAddr)) 115 let prettyAddr = T.pack (show (pretty nodeAddr))
100 $(logInfoS) "bootstrap" $ "table detalization" <> prettyAddr 116 $(logInfoS) "bootstrap" $ "table detalization" <> prettyAddr
101 fork $ insertClosest nodeAddr 117 fork $ insertClosest nodeAddr
102 118
103-- | Get list of peers which downloading 119-- | Get list of peers which downloading this torrent.
120--
121-- (TODO) This operation is synchronous and do block.
122--
104lookup :: Address ip => InfoHash -> DHT ip [PeerAddr ip] 123lookup :: Address ip => InfoHash -> DHT ip [PeerAddr ip]
105lookup ih = getClosestHash ih >>= collect 124lookup topic = getClosestHash topic >>= collect
125 -- TODO retry getClosestHash if bucket is empty
106 where 126 where
107 collect nodes = L.concat <$> forM (nodeAddr <$> nodes) retrieve 127 collect nodes = L.concat <$> forM (nodeAddr <$> nodes) retrieve
108 retrieve addr = do 128 retrieve addr = do
109 GotPeers {..} <- GetPeers ih <@> addr 129 GotPeers {..} <- GetPeers topic <@> addr
110 either collect pure peers 130 either collect pure peers
111 131
112-- | Announce that /this/ peer may have some pieces of the specified 132-- | Announce that /this/ peer may have some pieces of the specified
113-- torrent. 133-- torrent.
134--
135-- (TODO) This operation is asynchronous and do not block.
136--
114insert :: Address ip => InfoHash -> PortNumber -> DHT ip () 137insert :: Address ip => InfoHash -> PortNumber -> DHT ip ()
115insert ih port = do 138insert ih port = do
116 nodes <- getClosestHash ih 139 nodes <- getClosestHash ih
@@ -118,3 +141,10 @@ insert ih port = do
118-- GotPeers {..} <- GetPeers ih <@> addr 141-- GotPeers {..} <- GetPeers ih <@> addr
119-- Announced <- Announce False ih undefined grantedToken <@> addr 142-- Announced <- Announce False ih undefined grantedToken <@> addr
120 return () 143 return ()
144
145-- | Stop announcing /this/ peer for the specified torrent.
146--
147-- This operation is atomic and do not block.
148--
149delete :: Address ip => InfoHash -> DHT ip ()
150delete = error "DHT.delete: not implemented" \ No newline at end of file