diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT/Query.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT/Query.hs | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/src/Network/BitTorrent/DHT/Query.hs b/src/Network/BitTorrent/DHT/Query.hs index 2ddd51ca..d1fa36e5 100644 --- a/src/Network/BitTorrent/DHT/Query.hs +++ b/src/Network/BitTorrent/DHT/Query.hs | |||
@@ -148,7 +148,8 @@ pingQ addr = do | |||
148 | findNodeQ :: Address ip => TableKey key => key -> Iteration ip NodeInfo | 148 | findNodeQ :: Address ip => TableKey key => key -> Iteration ip NodeInfo |
149 | findNodeQ key NodeInfo {..} = do | 149 | findNodeQ key NodeInfo {..} = do |
150 | NodeFound closest <- FindNode (toNodeId key) <@> nodeAddr | 150 | NodeFound closest <- FindNode (toNodeId key) <@> nodeAddr |
151 | $(logInfoS) "findNodeQ" $ "NodeFound " <> T.pack (show $ L.map pPrint closest) | 151 | $(logInfoS) "findNodeQ" $ "NodeFound\n" |
152 | <> T.pack (L.unlines $ L.map ((' ' :) . show . pPrint) closest) | ||
152 | return $ Right closest | 153 | return $ Right closest |
153 | 154 | ||
154 | getPeersQ :: Address ip => InfoHash -> Iteration ip PeerAddr | 155 | getPeersQ :: Address ip => InfoHash -> Iteration ip PeerAddr |
@@ -260,23 +261,44 @@ insertNode info witnessed_ip = fork $ do | |||
260 | case minfo of | 261 | case minfo of |
261 | Just info -> do | 262 | Just info -> do |
262 | (ps,t') <- R.insert tm arrival $ myBuckets info | 263 | (ps,t') <- R.insert tm arrival $ myBuckets info |
263 | -- TODO: Check witnessed_ip against myAddress. | ||
264 | -- If 3 nodes witness a different address, change the table. | ||
265 | -- Require these witnesses satisfy bep-42 and that their | ||
266 | -- first 3 bits are unique. | ||
267 | writeTVar var $ Just $ info { myBuckets = t' } | 264 | writeTVar var $ Just $ info { myBuckets = t' } |
268 | return ps | ||
269 | -- Ignore non-witnessing nodes until somebody tells | ||
270 | -- us our ip address. | ||
271 | Nothing -> fromMaybe (return []) $ do | ||
272 | ReflectedIP ip0 <- witnessed_ip | ||
273 | ip <- fromSockAddr ip0 | ||
274 | let nil = nullTable (change ip) maxbuckets | ||
275 | return $ do | 265 | return $ do |
276 | (ps,t') <- R.insert tm arrival nil | 266 | case witnessed_ip of |
277 | writeTVar var $ Just $ R.Info t' (change ip) ip | 267 | Just (ReflectedIP ip0) |
268 | | fromSockAddr ip0 /= Just (myAddress info) | ||
269 | -> $(logInfo) ( T.pack $ L.unwords | ||
270 | $ [ "Possible NAT?" | ||
271 | , show (toSockAddr $ nodeAddr $ foreignNode arrival) | ||
272 | , "reports my address:" | ||
273 | , show ip0 ] ) | ||
274 | -- TODO: Let routing table vote on my IP/NodeId. | ||
275 | _ -> return () | ||
278 | return ps | 276 | return ps |
279 | ps <- liftIO $ atomically $ atomicInsert arrival witnessed_ip | 277 | Nothing -> |
278 | let dropped = return $ do | ||
279 | -- Ignore non-witnessing nodes until somebody tells | ||
280 | -- us our ip address. | ||
281 | $(logWarnS) "insertNode" ("Dropped " | ||
282 | <> T.pack (show (toSockAddr $ nodeAddr $ foreignNode arrival))) | ||
283 | return [] | ||
284 | in fromMaybe dropped $ do | ||
285 | ReflectedIP ip0 <- witnessed_ip | ||
286 | ip <- fromSockAddr ip0 | ||
287 | let nil = nullTable (change ip) maxbuckets | ||
288 | return $ do | ||
289 | (ps,t') <- R.insert tm arrival nil | ||
290 | let new_info = R.Info t' (change ip) ip | ||
291 | writeTVar var $ Just new_info | ||
292 | return $ do | ||
293 | $(logInfo) ( T.pack $ L.unwords | ||
294 | [ "External IP address:" | ||
295 | , show ip0 | ||
296 | , "(reported by" | ||
297 | , show (toSockAddr $ nodeAddr $ foreignNode arrival) | ||
298 | <> ")" | ||
299 | ] ) | ||
300 | return ps | ||
301 | ps <- join $ liftIO $ atomically $ atomicInsert arrival witnessed_ip | ||
280 | showTable | 302 | showTable |
281 | fork $ forM_ ps $ \(CheckPing ns)-> do | 303 | fork $ forM_ ps $ \(CheckPing ns)-> do |
282 | forM_ ns $ \n -> do | 304 | forM_ ns $ \n -> do |
@@ -284,7 +306,7 @@ insertNode info witnessed_ip = fork $ do | |||
284 | let alive = PingResult n b | 306 | let alive = PingResult n b |
285 | $(logDebugS) "insertNode" $ T.pack ("PingResult "++show (nodeId n,b)) | 307 | $(logDebugS) "insertNode" $ T.pack ("PingResult "++show (nodeId n,b)) |
286 | tm <- getTimestamp | 308 | tm <- getTimestamp |
287 | liftIO $ atomically $ atomicInsert alive mip | 309 | join $ liftIO $ atomically $ atomicInsert alive mip |
288 | showTable | 310 | showTable |
289 | return () | 311 | return () |
290 | 312 | ||
@@ -299,8 +321,8 @@ queryNode' addr q = do | |||
299 | nid <- myNodeIdAccordingTo addr | 321 | nid <- myNodeIdAccordingTo addr |
300 | let read_only = False -- TODO: check for NAT issues. (BEP 43) | 322 | let read_only = False -- TODO: check for NAT issues. (BEP 43) |
301 | (Response remoteId r, witnessed_ip) <- query' (toSockAddr addr) (Query nid read_only q) | 323 | (Response remoteId r, witnessed_ip) <- query' (toSockAddr addr) (Query nid read_only q) |
302 | $(logInfoS) "queryNode" $ "Witnessed address: " <> T.pack (show witnessed_ip) | 324 | -- $(logDebugS) "queryNode" $ "Witnessed address: " <> T.pack (show witnessed_ip) |
303 | <> " by " <> T.pack (show (toSockAddr addr)) | 325 | -- <> " by " <> T.pack (show (toSockAddr addr)) |
304 | insertNode (NodeInfo remoteId addr) witnessed_ip | 326 | insertNode (NodeInfo remoteId addr) witnessed_ip |
305 | return (remoteId, r, witnessed_ip) | 327 | return (remoteId, r, witnessed_ip) |
306 | 328 | ||