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.hs61
1 files changed, 33 insertions, 28 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs
index 1c62a0e0..3867d182 100644
--- a/src/Network/BitTorrent/DHT.hs
+++ b/src/Network/BitTorrent/DHT.hs
@@ -33,7 +33,6 @@ module Network.BitTorrent.DHT
33 33
34 -- * Initialization 34 -- * Initialization
35 , snapshot 35 , snapshot
36 , restore
37 36
38 -- * Operations 37 -- * Operations
39 , Network.BitTorrent.DHT.lookup 38 , Network.BitTorrent.DHT.lookup
@@ -162,24 +161,39 @@ resolveHostName NodeAddr {..} = do
162-- 161--
163-- This operation do block, use 162-- This operation do block, use
164-- 'Control.Concurrent.Async.Lifted.async' if needed. 163-- 'Control.Concurrent.Async.Lifted.async' if needed.
165bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () 164bootstrap :: Address ip => Maybe BS.ByteString -> [NodeAddr ip] -> DHT ip ()
166bootstrap startNodes = do 165bootstrap mbs startNodes = do
166 restored <-
167 case decode <$> mbs of
168 Just (Right tbl) -> return (T.toList tbl)
169 Just (Left e) -> do $(logWarnS) "restore" (Text.pack e)
170 return []
171 Nothing -> return []
172
167 $(logInfoS) "bootstrap" "Start node bootstrapping" 173 $(logInfoS) "bootstrap" "Start node bootstrapping"
168 nid <- asks thisNodeId 174 let searchAll aliveNodes = do
169 let searchAll aliveNodes 175 nid <- myNodeIdAccordingTo (error "FIXME")
170 = C.sourceList [aliveNodes] $= search nid (findNodeQ nid) $$ C.consume 176 C.sourceList [aliveNodes] $= search nid (findNodeQ nid) $$ C.consume
177 input_nodes <- (restored ++) . T.toList <$> getTable
171 -- Step 1: Use iterative searches to flesh out the table.. 178 -- Step 1: Use iterative searches to flesh out the table..
172 do knowns <- map (map $ nodeAddr . fst) . T.toList <$> getTable 179 do let knowns = map (map $ nodeAddr . fst) input_nodes
173 alive_knowns <- queryParallel (pingQ <$> concat knowns) 180 -- Below, we reverse the nodes since the table serialization puts the
174 nss <- searchAll alive_knowns 181 -- nearest nodes last and we want to choose a similar node id to bootstrap
175 -- We only use the supplied bootstrap nodes when we don't know of any 182 -- faster.
176 -- others to try. 183 (alive_knowns,_) <- unzip <$> queryParallel (pingQ <$> reverse (concat knowns))
177 when (null nss) $ do 184 b <- isBootstrapped
178 -- TODO filter duplicated in startNodes list 185 -- If our cached nodes are alive and our IP address did not change, it's possible
179 -- TODO retransmissions for startNodes 186 -- we are already bootsrapped, so no need to do any searches.
180 aliveNodes <- queryParallel (pingQ <$> startNodes) 187 when (not b) $ do
181 _ <- searchAll aliveNodes 188 nss <- searchAll $ take 2 alive_knowns
182 return () 189 -- We only use the supplied bootstrap nodes when we don't know of any
190 -- others to try.
191 when (null nss) $ do
192 -- TODO filter duplicated in startNodes list
193 -- TODO retransmissions for startNodes
194 (aliveNodes,_) <- unzip <$> queryParallel (pingQ <$> startNodes)
195 _ <- searchAll $ take 2 aliveNodes
196 return ()
183 -- Step 2: Repeatedly refresh incomplete buckets until the table is full. 197 -- Step 2: Repeatedly refresh incomplete buckets until the table is full.
184 maxbuckets <- asks $ optBucketCount . options 198 maxbuckets <- asks $ optBucketCount . options
185 flip fix 0 $ \loop icnt -> do 199 flip fix 0 $ \loop icnt -> do
@@ -195,6 +209,7 @@ bootstrap startNodes = do
195 p:ps -> p:unfull ps 209 p:ps -> p:unfull ps
196 [] -> [] 210 [] -> []
197 forM_ us $ \(is_last,(index,_)) -> do 211 forM_ us $ \(is_last,(index,_)) -> do
212 nid <- myNodeIdAccordingTo (error "FIXME")
198 sample <- liftIO $ genBucketSample nid (bucketRange index is_last) 213 sample <- liftIO $ genBucketSample nid (bucketRange index is_last)
199 $(logDebugS) "bootstrapping" 214 $(logDebugS) "bootstrapping"
200 $ "BOOTSTRAP sample" 215 $ "BOOTSTRAP sample"
@@ -213,23 +228,13 @@ bootstrap startNodes = do
213-- 228--
214-- This operation do not block. 229-- This operation do not block.
215-- 230--
216isBootstrapped :: DHT ip Bool 231isBootstrapped :: Eq ip => DHT ip Bool
217isBootstrapped = T.full <$> getTable 232isBootstrapped = T.full <$> getTable
218 233
219{----------------------------------------------------------------------- 234{-----------------------------------------------------------------------
220-- Initialization 235-- Initialization
221-----------------------------------------------------------------------} 236-----------------------------------------------------------------------}
222 237
223-- | Load previous session. (corrupted - exception/ignore ?)
224--
225-- This is blocking operation, use
226-- 'Control.Concurrent.Async.Lifted.async' if needed.
227restore :: Address ip => BS.ByteString -> DHT ip ()
228restore bs = do
229 case decode bs of
230 Right tbl -> restoreTable tbl
231 Left e -> $(logWarnS) "restore" (Text.pack e)
232
233-- | Serialize current DHT session to byte string. 238-- | Serialize current DHT session to byte string.
234-- 239--
235-- This is blocking operation, use 240-- This is blocking operation, use