summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r--src/Network/BitTorrent/DHT.hs59
1 files changed, 41 insertions, 18 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs
index 7cc7e803..155a50ca 100644
--- a/src/Network/BitTorrent/DHT.hs
+++ b/src/Network/BitTorrent/DHT.hs
@@ -9,12 +9,15 @@ module Network.BitTorrent.DHT
9 ) where 9 ) where
10 10
11import Control.Applicative 11import Control.Applicative
12import Control.Concurrent.Lifted
13import Control.Exception.Lifted
12import Control.Monad 14import Control.Monad
13import Control.Monad.Logger 15import Control.Monad.Logger
14import Data.List as L 16import Data.List as L
15import Data.Monoid 17import Data.Monoid
16import Data.Text as T 18import Data.Text as T
17import Network.Socket (PortNumber) 19import Network.Socket (PortNumber)
20import System.Timeout.Lifted
18import Text.PrettyPrint as PP hiding ((<>)) 21import Text.PrettyPrint as PP hiding ((<>))
19import Text.PrettyPrint.Class 22import Text.PrettyPrint.Class
20 23
@@ -29,26 +32,32 @@ import Network.BitTorrent.DHT.Session
29-----------------------------------------------------------------------} 32-----------------------------------------------------------------------}
30 33
31pingH :: Address ip => NodeHandler ip 34pingH :: Address ip => NodeHandler ip
32pingH = nodeHandler $ \ _ Ping -> return Ping 35pingH = nodeHandler $ \ _ Ping -> do
36 $(logDebug) "ping received, sending pong"
37 return Ping
33 38
34{- 39findNodeH :: Address ip => NodeHandler ip
35findNodeH :: (Eq ip, Serialize ip, Typeable ip) => Handler (DHT ip) 40findNodeH = nodeHandler $ \ _ (FindNode nid) -> do
36findNodeH = dhtHandler $ \ _ (FindNode nid) -> 41 $(logDebug) "find_node received, sending closest nodes back"
37 NodeFound <$> getClosest nid 42 NodeFound <$> getClosest nid
38 43
39getPeersH :: (Eq ip, Serialize ip, Typeable ip) => Handler (DHT ip) 44getPeersH :: Address ip => NodeHandler ip
40getPeersH = dhtHandler $ \ addr (GetPeers ih) -> 45getPeersH = nodeHandler $ \ naddr (GetPeers ih) -> do
41 GotPeers <$> getPeerList ih <*> grantToken addr 46 $(logDebug) "get_peers received, trying to find peers"
47 GotPeers <$> getPeerList ih <*> grantToken naddr
42 48
43announceH :: Handler (DHT ip) 49announceH :: Address ip => NodeHandler ip
44announceH = dhtHandler $ \ addr (Announce {..}) -> do 50announceH = nodeHandler $ \ naddr (Announce {..}) -> do
45 checkToken addr sessionToken 51 $(logDebug) "announce received, trying to check token"
46 insertPeer topic undefined -- PeerAddr (add, port) 52 checkToken naddr sessionToken
47 return Announced 53 case fromAddr naddr of
48-} 54 Nothing -> undefined
55 Just paddr -> do
56 insertPeer topic paddr
57 return Announced
49 58
50handlers :: Address ip => [NodeHandler ip] 59handlers :: Address ip => [NodeHandler ip]
51handlers = [pingH] 60handlers = [pingH, findNodeH, getPeersH, announceH]
52 61
53{----------------------------------------------------------------------- 62{-----------------------------------------------------------------------
54-- Query 63-- Query
@@ -63,6 +72,7 @@ ping addr = do
63 Ping <- Ping <@> addr 72 Ping <- Ping <@> addr
64 return () 73 return ()
65 74
75-- TODO fork?
66-- | One good node may be sufficient. <note about 'Data.Torrent.tNodes'> 76-- | One good node may be sufficient. <note about 'Data.Torrent.tNodes'>
67bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () 77bootstrap :: Address ip => [NodeAddr ip] -> DHT ip ()
68bootstrap startNodes = do 78bootstrap startNodes = do
@@ -72,10 +82,23 @@ bootstrap startNodes = do
72 where 82 where
73 insertClosest addr = do 83 insertClosest addr = do
74 nid <- getNodeId 84 nid <- getNodeId
75 NodeFound closest <- FindNode nid <@> addr 85 result <- try $ timeout 1000000 $ FindNode nid <@> addr
76 $(logDebug) ("Get a list of closest nodes: " <> 86 case result of
77 T.pack (PP.render (pretty closest))) 87 Left e -> do
78 forM_ closest insertNode 88 $(logWarnS) "bootstrap" $ T.pack $ show (e :: IOError)
89
90 Right Nothing -> do
91 $(logWarnS) "bootstrap" $ "not responding @ "
92 <> T.pack (show (pretty addr))
93
94 Right (Just (NodeFound closest)) -> do
95 $(logDebug) ("Get a list of closest nodes: " <>
96 T.pack (PP.render (pretty closest)))
97 forM_ (L.take 2 closest) $ \ info @ NodeInfo {..} -> do
98 insertNode info
99 let prettyAddr = T.pack (show (pretty nodeAddr))
100 $(logInfoS) "bootstrap" $ "table detalization" <> prettyAddr
101 fork $ insertClosest nodeAddr
79 102
80-- | Get list of peers which downloading 103-- | Get list of peers which downloading
81lookup :: Address ip => InfoHash -> DHT ip [PeerAddr ip] 104lookup :: Address ip => InfoHash -> DHT ip [PeerAddr ip]