diff options
author | joe <joe@jerkface.net> | 2017-06-30 13:21:29 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-06-30 13:21:29 -0400 |
commit | e1b2fc9c7a5efd828a8c66f3e3a1d0a547397080 (patch) | |
tree | ea85593b4400fbd03118d032bd89fef53e5b1dc0 /src/Network/DHT/Mainline.hs | |
parent | 3195c0877b443e5ccd4d489f03944fc059d4d7aa (diff) |
It builds!
Diffstat (limited to 'src/Network/DHT/Mainline.hs')
-rw-r--r-- | src/Network/DHT/Mainline.hs | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/src/Network/DHT/Mainline.hs b/src/Network/DHT/Mainline.hs index 29d4231d..aefd7742 100644 --- a/src/Network/DHT/Mainline.hs +++ b/src/Network/DHT/Mainline.hs | |||
@@ -88,6 +88,10 @@ module Network.DHT.Mainline | |||
88 | , Announce (..) | 88 | , Announce (..) |
89 | , Announced (..) | 89 | , Announced (..) |
90 | #endif | 90 | #endif |
91 | , DHTData(..) | ||
92 | , SessionTokens(..) | ||
93 | , grantToken | ||
94 | , checkToken | ||
91 | ) where | 95 | ) where |
92 | 96 | ||
93 | import Control.Applicative | 97 | import Control.Applicative |
@@ -118,13 +122,19 @@ import Network.DatagramServer.Mainline | |||
118 | import Data.Maybe | 122 | import Data.Maybe |
119 | 123 | ||
120 | import Data.Torrent (InfoHash) | 124 | import Data.Torrent (InfoHash) |
121 | import Network.BitTorrent.DHT.Token | 125 | import Network.BitTorrent.DHT.Token as T |
126 | import Network.BitTorrent.DHT.ContactInfo | ||
122 | #ifdef VERSION_bencoding | 127 | #ifdef VERSION_bencoding |
123 | import Network.DatagramServer () | 128 | import Network.DatagramServer () |
124 | #endif | 129 | #endif |
125 | import Network.DatagramServer.Types hiding (Query,Response) | 130 | import Network.DatagramServer.Types hiding (Query,Response) |
126 | import Network.DHT.Types | 131 | import Network.DHT.Types |
127 | import Network.DHT.Routing | 132 | import Network.DHT.Routing |
133 | import Data.Time | ||
134 | import Control.Concurrent.STM | ||
135 | import System.Random | ||
136 | import Data.Hashable | ||
137 | |||
128 | 138 | ||
129 | {----------------------------------------------------------------------- | 139 | {----------------------------------------------------------------------- |
130 | -- envelopes | 140 | -- envelopes |
@@ -472,6 +482,59 @@ bep42 addr (NodeId r) | |||
472 | where msk | BS.length ip == 4 = ip4mask | 482 | where msk | BS.length ip == 4 = ip4mask |
473 | | otherwise = ip6mask | 483 | | otherwise = ip6mask |
474 | 484 | ||
485 | {----------------------------------------------------------------------- | ||
486 | -- Tokens policy | ||
487 | -----------------------------------------------------------------------} | ||
488 | |||
489 | data SessionTokens = SessionTokens | ||
490 | { tokenMap :: !TokenMap | ||
491 | , lastUpdate :: !UTCTime | ||
492 | , maxInterval :: !NominalDiffTime | ||
493 | } | ||
494 | |||
495 | nullSessionTokens :: IO SessionTokens | ||
496 | nullSessionTokens = SessionTokens | ||
497 | <$> (tokens <$> randomIO) | ||
498 | <*> getCurrentTime | ||
499 | <*> pure defaultUpdateInterval | ||
500 | |||
501 | -- TODO invalidate *twice* if needed | ||
502 | invalidateTokens :: UTCTime -> SessionTokens -> SessionTokens | ||
503 | invalidateTokens curTime ts @ SessionTokens {..} | ||
504 | | curTime `diffUTCTime` lastUpdate > maxInterval = SessionTokens | ||
505 | { tokenMap = update tokenMap | ||
506 | , lastUpdate = curTime | ||
507 | , maxInterval = maxInterval | ||
508 | } | ||
509 | | otherwise = ts | ||
510 | |||
511 | {----------------------------------------------------------------------- | ||
512 | -- Tokens | ||
513 | -----------------------------------------------------------------------} | ||
514 | |||
515 | tryUpdateSecret :: TVar SessionTokens -> IO () | ||
516 | tryUpdateSecret toks = do | ||
517 | curTime <- getCurrentTime | ||
518 | atomically $ modifyTVar' toks (invalidateTokens curTime) | ||
519 | |||
520 | grantToken :: Hashable a => TVar SessionTokens -> NodeAddr a -> IO Token | ||
521 | grantToken sessionTokens addr = do | ||
522 | tryUpdateSecret sessionTokens | ||
523 | toks <- readTVarIO sessionTokens | ||
524 | return $ T.lookup addr $ tokenMap toks | ||
525 | |||
526 | -- | Throws 'HandlerError' if the token is invalid or already | ||
527 | -- expired. See 'TokenMap' for details. | ||
528 | checkToken :: Hashable a => TVar SessionTokens -> NodeAddr a -> Token -> IO Bool | ||
529 | checkToken sessionTokens addr questionableToken = do | ||
530 | tryUpdateSecret sessionTokens | ||
531 | toks <- readTVarIO sessionTokens | ||
532 | return $ T.member addr questionableToken (tokenMap toks) | ||
533 | |||
534 | |||
535 | -------------------------- | ||
536 | |||
537 | |||
475 | instance Kademlia KMessageOf where | 538 | instance Kademlia KMessageOf where |
476 | data Ping KMessageOf = Ping | 539 | data Ping KMessageOf = Ping |
477 | deriving (Show, Eq, Typeable) | 540 | deriving (Show, Eq, Typeable) |
@@ -479,10 +542,17 @@ instance Kademlia KMessageOf where | |||
479 | deriving (Show, Eq, Typeable) | 542 | deriving (Show, Eq, Typeable) |
480 | newtype NodeFound KMessageOf ip = NodeFound [NodeInfo KMessageOf ip ()] | 543 | newtype NodeFound KMessageOf ip = NodeFound [NodeInfo KMessageOf ip ()] |
481 | deriving (Show, Eq, Typeable) | 544 | deriving (Show, Eq, Typeable) |
545 | data DHTData KMessageOf ip = TorrentData | ||
546 | { contactInfo :: !(TVar (PeerStore ip )) -- ^ published by other nodes; | ||
547 | , sessionTokens :: !(TVar SessionTokens ) -- ^ query session IDs. | ||
548 | } | ||
549 | |||
482 | pingMessage _ = Ping | 550 | pingMessage _ = Ping |
483 | pongMessage _ = Ping | 551 | pongMessage _ = Ping |
484 | findNodeMessage _ k = FindNode (toNodeId k) | 552 | findNodeMessage _ k = FindNode (toNodeId k) |
553 | findWho (FindNode nid) = nid | ||
485 | foundNodes (NodeFound ns) = ns | 554 | foundNodes (NodeFound ns) = ns |
555 | foundNodesMessage ns = NodeFound ns | ||
486 | 556 | ||
487 | dhtAdjustID _ fallback ip0 arrival | 557 | dhtAdjustID _ fallback ip0 arrival |
488 | = fromMaybe fallback $ do | 558 | = fromMaybe fallback $ do |
@@ -494,3 +564,7 @@ instance Kademlia KMessageOf where | |||
494 | 564 | ||
495 | namePing _ = "ping" | 565 | namePing _ = "ping" |
496 | nameFindNodes _ = "find-nodes" | 566 | nameFindNodes _ = "find-nodes" |
567 | |||
568 | initializeDHTData = TorrentData | ||
569 | <$> newTVarIO def | ||
570 | <*> (newTVarIO =<< nullSessionTokens) | ||