diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT.hs | 86 |
1 files changed, 83 insertions, 3 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs index b0aac002..bdb76c76 100644 --- a/src/Network/BitTorrent/DHT.hs +++ b/src/Network/BitTorrent/DHT.hs | |||
@@ -1,6 +1,86 @@ | |||
1 | module Network.BitTorrent.DHT | 1 | module Network.BitTorrent.DHT |
2 | ( newNodeSession | 2 | ( dht |
3 | , dhtServer | 3 | , ping |
4 | , Network.BitTorrent.DHT.bootstrap | ||
5 | , Network.BitTorrent.DHT.lookup | ||
6 | , Network.BitTorrent.DHT.insert | ||
4 | ) where | 7 | ) where |
5 | 8 | ||
6 | import Network.BitTorrent.DHT.Protocol \ No newline at end of file | 9 | import Control.Applicative |
10 | import Control.Monad | ||
11 | import Control.Monad.Reader | ||
12 | import Data.List as L | ||
13 | import Network.Socket (PortNumber) | ||
14 | |||
15 | import Data.Torrent.InfoHash | ||
16 | import Network.BitTorrent.Core | ||
17 | import Network.BitTorrent.DHT.Message | ||
18 | import Network.BitTorrent.DHT.Session | ||
19 | |||
20 | |||
21 | {----------------------------------------------------------------------- | ||
22 | -- Handlers | ||
23 | -----------------------------------------------------------------------} | ||
24 | |||
25 | pingH :: Address ip => NodeHandler ip | ||
26 | pingH = nodeHandler $ \ _ Ping -> return Ping | ||
27 | |||
28 | {- | ||
29 | findNodeH :: (Eq ip, Serialize ip, Typeable ip) => Handler (DHT ip) | ||
30 | findNodeH = dhtHandler $ \ _ (FindNode nid) -> | ||
31 | NodeFound <$> getClosest nid | ||
32 | |||
33 | getPeersH :: (Eq ip, Serialize ip, Typeable ip) => Handler (DHT ip) | ||
34 | getPeersH = dhtHandler $ \ addr (GetPeers ih) -> | ||
35 | GotPeers <$> getPeerList ih <*> grantToken addr | ||
36 | |||
37 | announceH :: Handler (DHT ip) | ||
38 | announceH = dhtHandler $ \ addr (Announce {..}) -> do | ||
39 | checkToken addr sessionToken | ||
40 | insertPeer topic undefined -- PeerAddr (add, port) | ||
41 | return Announced | ||
42 | -} | ||
43 | |||
44 | handlers :: Address ip => [NodeHandler ip] | ||
45 | handlers = [pingH] | ||
46 | |||
47 | {----------------------------------------------------------------------- | ||
48 | -- Query | ||
49 | -----------------------------------------------------------------------} | ||
50 | |||
51 | -- | Run DHT on specified port. <add note about resources> | ||
52 | dht :: Address ip => NodeAddr ip -> DHT ip a -> IO a | ||
53 | dht addr = runDHT addr handlers | ||
54 | |||
55 | ping :: Address ip => NodeAddr ip -> DHT ip () | ||
56 | ping addr = do | ||
57 | Ping <- Ping <@> addr | ||
58 | return () | ||
59 | |||
60 | -- | One good node may be sufficient. <note about 'Data.Torrent.tNodes'> | ||
61 | bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () | ||
62 | bootstrap = mapM_ insertClosest | ||
63 | where | ||
64 | insertClosest addr = do | ||
65 | nid <- getNodeId | ||
66 | NodeFound closest <- FindNode nid <@> addr | ||
67 | forM_ closest insertNode | ||
68 | |||
69 | -- | Get list of peers which downloading | ||
70 | lookup :: Address ip => InfoHash -> DHT ip [PeerAddr ip] | ||
71 | lookup ih = getClosestHash ih >>= collect | ||
72 | where | ||
73 | collect nodes = L.concat <$> forM (nodeAddr <$> nodes) retrieve | ||
74 | retrieve addr = do | ||
75 | GotPeers {..} <- GetPeers ih <@> addr | ||
76 | either collect pure peers | ||
77 | |||
78 | -- | Announce that /this/ peer may have some pieces of the specified | ||
79 | -- torrent. | ||
80 | insert :: Address ip => InfoHash -> PortNumber -> DHT ip () | ||
81 | insert ih port = do | ||
82 | nodes <- getClosestHash ih | ||
83 | forM_ (nodeAddr <$> nodes) $ \ addr -> do | ||
84 | -- GotPeers {..} <- GetPeers ih <@> addr | ||
85 | -- Announced <- Announce False ih undefined grantedToken <@> addr | ||
86 | return () | ||