summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT/Session.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/DHT/Session.hs')
-rw-r--r--src/Network/BitTorrent/DHT/Session.hs102
1 files changed, 70 insertions, 32 deletions
diff --git a/src/Network/BitTorrent/DHT/Session.hs b/src/Network/BitTorrent/DHT/Session.hs
index 7e87df6c..d8665773 100644
--- a/src/Network/BitTorrent/DHT/Session.hs
+++ b/src/Network/BitTorrent/DHT/Session.hs
@@ -31,12 +31,19 @@ module Network.BitTorrent.DHT.Session
31 , options 31 , options
32 , tentativeNodeId 32 , tentativeNodeId
33 , myNodeIdAccordingTo 33 , myNodeIdAccordingTo
34 , myNodeIdAccordingTo1
34 , routingInfo 35 , routingInfo
35 , routableAddress 36 , routableAddress
36 , getTimestamp 37 , getTimestamp
38 , SessionTokens
39 , sessionTokens
40 , contactInfo
41 , PeerStore
42 , manager
37 43
38 -- ** Initialization 44 -- ** Initialization
39 , LogFun 45 , LogFun
46 , logt
40 , NodeHandler 47 , NodeHandler
41 , newNode 48 , newNode
42 , closeNode 49 , closeNode
@@ -54,11 +61,13 @@ module Network.BitTorrent.DHT.Session
54 -- ** Routing table 61 -- ** Routing table
55 , getTable 62 , getTable
56 , getClosest 63 , getClosest
64 , getClosest1
57 65
58#ifdef VERSION_bencoding 66#ifdef VERSION_bencoding
59 -- ** Peer storage 67 -- ** Peer storage
60 , insertPeer 68 , insertPeer
61 , getPeerList 69 , getPeerList
70 , getPeerList1
62 , insertTopic 71 , insertTopic
63 , deleteTopic 72 , deleteTopic
64 , getSwarms 73 , getSwarms
@@ -333,7 +342,7 @@ instance MonadLogger (DHT ip) where
333 liftIO $ logger loc src lvl (toLogStr msg) 342 liftIO $ logger loc src lvl (toLogStr msg)
334 343
335#ifdef VERSION_bencoding 344#ifdef VERSION_bencoding
336type NodeHandler ip = Handler IO KMessageOf BValue 345type NodeHandler = Handler IO KMessageOf BValue
337#else 346#else
338type NodeHandler ip = Handler (DHT ip) Tox.Message ByteString 347type NodeHandler ip = Handler (DHT ip) Tox.Message ByteString
339#endif 348#endif
@@ -368,10 +377,10 @@ locFromCS cs = case getCallStack cs of
368-- 'closeNode' function, otherwise socket or other scarce resources may 377-- 'closeNode' function, otherwise socket or other scarce resources may
369-- leak. 378-- leak.
370newNode :: Address ip 379newNode :: Address ip
371 => [NodeHandler ip] -- ^ handlers to run on accepted queries; 380 => [NodeHandler] -- ^ handlers to run on accepted queries;
372 -> Options -- ^ various dht options; 381 -> Options -- ^ various dht options;
373 -> NodeAddr ip -- ^ node address to bind; 382 -> NodeAddr ip -- ^ node address to bind;
374 -> LogFun -- ^ 383 -> LogFun -- ^ invoked on log messages;
375#ifdef VERSION_bencoding 384#ifdef VERSION_bencoding
376 -> Maybe (NodeId KMessageOf) -- ^ use this NodeId, if not given a new one is generated. 385 -> Maybe (NodeId KMessageOf) -- ^ use this NodeId, if not given a new one is generated.
377#else 386#else
@@ -420,24 +429,23 @@ runDHT node action = runReaderT (unDHT action) node
420-- Tokens 429-- Tokens
421-----------------------------------------------------------------------} 430-----------------------------------------------------------------------}
422 431
423tryUpdateSecret :: DHT ip () 432tryUpdateSecret :: TVar SessionTokens -> IO ()
424tryUpdateSecret = do 433tryUpdateSecret toks = do
425 curTime <- liftIO getCurrentTime 434 curTime <- liftIO getCurrentTime
426 toks <- asks sessionTokens
427 liftIO $ atomically $ modifyTVar' toks (invalidateTokens curTime) 435 liftIO $ atomically $ modifyTVar' toks (invalidateTokens curTime)
428 436
429grantToken :: Hashable a => NodeAddr a -> DHT ip Token 437grantToken :: Hashable a => TVar SessionTokens -> NodeAddr a -> IO Token
430grantToken addr = do 438grantToken sessionTokens addr = do
431 tryUpdateSecret 439 tryUpdateSecret sessionTokens
432 toks <- asks sessionTokens >>= liftIO . readTVarIO 440 toks <- readTVarIO sessionTokens
433 return $ T.lookup addr $ tokenMap toks 441 return $ T.lookup addr $ tokenMap toks
434 442
435-- | Throws 'HandlerError' if the token is invalid or already 443-- | Throws 'HandlerError' if the token is invalid or already
436-- expired. See 'TokenMap' for details. 444-- expired. See 'TokenMap' for details.
437checkToken :: Hashable a => NodeAddr a -> Token -> DHT ip Bool 445checkToken :: Hashable a => TVar SessionTokens -> NodeAddr a -> Token -> IO Bool
438checkToken addr questionableToken = do 446checkToken sessionTokens addr questionableToken = do
439 tryUpdateSecret 447 tryUpdateSecret sessionTokens
440 toks <- asks sessionTokens >>= liftIO . readTVarIO 448 toks <- readTVarIO sessionTokens
441 return $ T.member addr questionableToken (tokenMap toks) 449 return $ T.member addr questionableToken (tokenMap toks)
442 450
443 451
@@ -463,6 +471,14 @@ myNodeIdAccordingTo _ = do
463 (return . myNodeId) 471 (return . myNodeId)
464 info 472 info
465 473
474myNodeIdAccordingTo1 :: DHT ip ( NodeAddr ip -> IO (NodeId KMessageOf) )
475myNodeIdAccordingTo1 = do
476 var <- asks routingInfo
477 tid <- asks tentativeNodeId
478 return $ \ _ -> do
479 info <- atomically $ readTVar var
480 return $ maybe tid myNodeId info
481
466-- | Get current routing table. Normally you don't need to use this 482-- | Get current routing table. Normally you don't need to use this
467-- function, but it can be usefull for debugging and profiling purposes. 483-- function, but it can be usefull for debugging and profiling purposes.
468#ifdef VERSION_bencoding 484#ifdef VERSION_bencoding
@@ -515,38 +531,48 @@ getClosest node = do
515 k <- asks (optK . options) 531 k <- asks (optK . options)
516 kclosest k node <$> getTable 532 kclosest k node <$> getTable
517 533
534getClosest1 :: ( Eq ip
535 , TableKey KMessageOf k
536 ) => DHT ip (k -> IO [NodeInfo KMessageOf ip ()])
537getClosest1 = do
538 k <- asks (optK . options)
539 nobkts <- asks (optBucketCount . options)
540 myid <- asks tentativeNodeId
541 var <- asks routingInfo
542 return $ \node -> do nfo <- atomically $ readTVar var
543 let tbl = maybe (nullTable myid nobkts) R.myBuckets nfo
544 return $ kclosest k node tbl
545
518{----------------------------------------------------------------------- 546{-----------------------------------------------------------------------
519-- Peer storage 547-- Peer storage
520-----------------------------------------------------------------------} 548-----------------------------------------------------------------------}
521 549
522refreshContacts :: DHT ip () 550refreshContacts :: Ord ip => TVar (PeerStore ip) -> IO ()
523refreshContacts = 551refreshContacts var =
524 -- TODO limit dht peer store in size (probably by removing oldest peers) 552 -- TODO limit dht peer store in size (probably by removing oldest peers)
525 return () 553 return ()
526 554
527 555
528-- | Insert peer to peer store. Used to handle announce requests. 556-- | Insert peer to peer store. Used to handle announce requests.
529insertPeer :: Ord ip => InfoHash -> Maybe ByteString -> PeerAddr ip -> DHT ip () 557insertPeer :: Ord ip => TVar (PeerStore ip) -> InfoHash -> Maybe ByteString -> PeerAddr ip -> IO ()
530insertPeer ih name addr = do 558insertPeer var ih name addr = do
531 refreshContacts 559 refreshContacts var
532 var <- asks contactInfo 560 atomically $ modifyTVar' var (P.insertPeer ih name addr)
533 liftIO $ atomically $ modifyTVar' var (P.insertPeer ih name addr)
534 561
535-- | Get peer set for specific swarm. 562-- | Get peer set for specific swarm.
536lookupPeers :: Ord ip => InfoHash -> DHT ip [PeerAddr ip] 563lookupPeers :: Ord ip => TVar (PeerStore ip) -> InfoHash -> IO [PeerAddr ip]
537lookupPeers ih = do 564lookupPeers var ih = do
538 refreshContacts 565 refreshContacts var
539 var <- asks contactInfo
540 tm <- getTimestamp 566 tm <- getTimestamp
541 liftIO $ atomically $ do 567 atomically $ do
542 (ps,store') <- P.freshPeers ih tm <$> readTVar var 568 (ps,store') <- P.freshPeers ih tm <$> readTVar var
543 writeTVar var store' 569 writeTVar var store'
544 return ps 570 return ps
545 571
546getTimestamp :: DHT ip Timestamp 572getTimestamp :: IO Timestamp
547getTimestamp = do 573getTimestamp = do
548 utcTime <- liftIO $ getCurrentTime 574 utcTime <- getCurrentTime
549 $(logDebugS) "routing.make_timestamp" (Text.pack (render (pPrint utcTime))) 575 -- $(logDebugS) "routing.make_timestamp" (Text.pack (render (pPrint utcTime)))
550 return $ utcTimeToPOSIXSeconds utcTime 576 return $ utcTimeToPOSIXSeconds utcTime
551 577
552 578
@@ -557,11 +583,23 @@ getTimestamp = do
557-- 583--
558getPeerList :: Ord ip => InfoHash -> DHT ip (PeerList ip) 584getPeerList :: Ord ip => InfoHash -> DHT ip (PeerList ip)
559getPeerList ih = do 585getPeerList ih = do
560 ps <- lookupPeers ih 586 var <- asks contactInfo
587 ps <- liftIO $ lookupPeers var ih
561 if L.null ps 588 if L.null ps
562 then Left <$> getClosest ih 589 then Left <$> getClosest ih
563 else return (Right ps) 590 else return (Right ps)
564 591
592getPeerList1 :: Ord ip => DHT ip (InfoHash -> IO (PeerList ip))
593getPeerList1 = do
594 var <- asks contactInfo
595 getclosest <- getClosest1
596 return $ \ih -> do
597 ps <- lookupPeers var ih
598 if L.null ps
599 then Left <$> getclosest ih
600 else return (Right ps)
601
602
565insertTopic :: InfoHash -> PortNumber -> DHT ip () 603insertTopic :: InfoHash -> PortNumber -> DHT ip ()
566insertTopic ih p = do 604insertTopic ih p = do
567 var <- asks announceInfo 605 var <- asks announceInfo