summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/DHT.hs')
-rw-r--r--src/Network/BitTorrent/DHT.hs58
1 files changed, 16 insertions, 42 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs
index 7f1fa295..7c892349 100644
--- a/src/Network/BitTorrent/DHT.hs
+++ b/src/Network/BitTorrent/DHT.hs
@@ -77,20 +77,6 @@ handlers :: Address ip => [NodeHandler ip]
77handlers = [pingH, findNodeH, getPeersH, announceH] 77handlers = [pingH, findNodeH, getPeersH, announceH]
78 78
79{----------------------------------------------------------------------- 79{-----------------------------------------------------------------------
80-- Query
81-----------------------------------------------------------------------}
82
83findNodeQ :: Address ip => NodeId -> Iteration ip NodeAddr NodeInfo
84findNodeQ nid addr = do
85 NodeFound closest <- FindNode nid <@> addr
86 return $ Right closest
87
88getPeersQ :: Address ip => InfoHash -> Iteration ip NodeInfo PeerAddr
89getPeersQ topic NodeInfo {..} = do
90 GotPeers {..} <- GetPeers topic <@> nodeAddr
91 return peers
92
93{-----------------------------------------------------------------------
94-- DHT operations 80-- DHT operations
95-----------------------------------------------------------------------} 81-----------------------------------------------------------------------}
96 82
@@ -107,48 +93,36 @@ dht = runDHT handlers
107-- usually obtained from 'Data.Torrent.tNodes' field. Bootstrapping 93-- usually obtained from 'Data.Torrent.tNodes' field. Bootstrapping
108-- process can take up to 5 minutes. 94-- process can take up to 5 minutes.
109-- 95--
110-- (TODO) This operation is asynchronous and do not block. 96-- This operation is synchronous and do block, use 'async' if needed.
111-- 97--
112bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () 98bootstrap :: Address ip => [NodeAddr ip] -> DHT ip ()
113bootstrap startNodes = do 99bootstrap startNodes = do
114 $(logInfoS) "bootstrap" "Start node bootstrapping" 100 $(logInfoS) "bootstrap" "Start node bootstrapping"
115 M.mapM_ insertClosest startNodes 101 nid <- getNodeId
116 $(logInfoS) "bootstrap" "Node bootstrapping finished" 102 aliveNodes <- queryParallel (ping <$> startNodes)
117 where 103 _ <- sourceList [aliveNodes] $= search nid (findNodeQ nid) $$ C.consume
118 insertClosest addr = do 104 $(logInfoS) "bootstrap" "Node bootstrapping finished"
119 t <- getTable 105-- t <- getTable
120 unless (full t) $ do 106-- unless (full t) $ do
121 nid <- getNodeId 107-- nid <- getNodeId
122 result <- try $ FindNode nid <@> addr
123 case result of
124 Left e -> do
125 $(logWarnS) "bootstrap" $ T.pack $ show (e :: QueryFailure)
126
127 Right (NodeFound closest) -> do
128 $(logDebug) $ "Get a list of closest nodes: " <>
129 T.pack (PP.render (pretty closest))
130 forM_ closest $ \ info @ NodeInfo {..} -> do
131 let prettyAddr = T.pack (show (pretty nodeAddr))
132 $(logInfoS) "bootstrap" $ "table detalization" <> prettyAddr
133 insertClosest nodeAddr
134 108
135-- | Get list of peers which downloading this torrent. 109-- | Get list of peers which downloading this torrent.
136-- 110--
137-- (TODO) This operation is synchronous and do block. 111-- This operation is incremental and do block.
138-- 112--
139lookup :: Address ip => InfoHash -> DHT ip `Source` [PeerAddr ip] 113lookup :: Address ip => InfoHash -> DHT ip `Source` [PeerAddr ip]
140lookup topic = do -- TODO retry getClosestHash if bucket is empty 114lookup topic = do -- TODO retry getClosest if bucket is empty
141 closest <- lift $ getClosestHash topic 115 closest <- lift $ getClosest topic
142 sourceList [closest] $= search (getPeersQ topic) 116 sourceList [closest] $= search topic (getPeersQ topic)
143 117
144-- | Announce that /this/ peer may have some pieces of the specified 118-- | Announce that /this/ peer may have some pieces of the specified
145-- torrent. 119-- torrent.
146-- 120--
147-- (TODO) This operation is asynchronous and do not block. 121-- This operation is synchronous and do block, use 'async' if needed.
148-- 122--
149insert :: Address ip => InfoHash -> PortNumber -> DHT ip () 123insert :: Address ip => InfoHash -> PortNumber -> DHT ip ()
150insert ih port = do 124insert ih port = do
151 nodes <- getClosestHash ih 125 nodes <- getClosest ih
152 forM_ (nodeAddr <$> nodes) $ \ addr -> do 126 forM_ (nodeAddr <$> nodes) $ \ addr -> do
153-- GotPeers {..} <- GetPeers ih <@> addr 127-- GotPeers {..} <- GetPeers ih <@> addr
154-- Announced <- Announce False ih undefined grantedToken <@> addr 128-- Announced <- Announce False ih undefined grantedToken <@> addr
@@ -156,7 +130,7 @@ insert ih port = do
156 130
157-- | Stop announcing /this/ peer for the specified torrent. 131-- | Stop announcing /this/ peer for the specified torrent.
158-- 132--
159-- This operation is atomic and do not block. 133-- This operation is atomic and may block for a while.
160-- 134--
161delete :: Address ip => InfoHash -> DHT ip () 135delete :: Address ip => InfoHash -> DHT ip ()
162delete = error "DHT.delete: not implemented" \ No newline at end of file 136delete = error "DHT.delete: not implemented" \ No newline at end of file