summaryrefslogtreecommitdiff
path: root/src/Network/Tox/Onion/Handlers.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2018-06-09 01:31:23 -0400
committerjoe <joe@jerkface.net>2018-06-09 01:32:08 -0400
commitfb0c6758ec415c5cda5cc7c182e1f83906f365fb (patch)
treec07aa47ca461d90199b63af230f4433da9827935 /src/Network/Tox/Onion/Handlers.hs
parentfa15dabe75703516c7bbb54fdba2a13ae6c6e9cc (diff)
Expire old tox key announcements after 5 minutes.
Diffstat (limited to 'src/Network/Tox/Onion/Handlers.hs')
-rw-r--r--src/Network/Tox/Onion/Handlers.hs33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/Network/Tox/Onion/Handlers.hs b/src/Network/Tox/Onion/Handlers.hs
index 99ef3c69..263d60bd 100644
--- a/src/Network/Tox/Onion/Handlers.hs
+++ b/src/Network/Tox/Onion/Handlers.hs
@@ -11,7 +11,7 @@ import Network.QueryResponse as QR hiding (Client)
11import qualified Network.QueryResponse as QR (Client) 11import qualified Network.QueryResponse as QR (Client)
12import Crypto.Tox 12import Crypto.Tox
13import qualified Data.Wrapper.PSQ as PSQ 13import qualified Data.Wrapper.PSQ as PSQ
14 ;import Data.Wrapper.PSQ (PSQ) 14 ;import Data.Wrapper.PSQ (PSQ,pattern (:->))
15#ifdef CRYPTONITE_BACKPORT 15#ifdef CRYPTONITE_BACKPORT
16import Crypto.Error.Types (CryptoFailable (..), 16import Crypto.Error.Types (CryptoFailable (..),
17 throwCryptoError) 17 throwCryptoError)
@@ -35,6 +35,12 @@ import Network.BitTorrent.DHT.Token as Token
35 35
36import Control.Exception hiding (Handler) 36import Control.Exception hiding (Handler)
37import Control.Monad 37import Control.Monad
38#ifdef THREAD_DEBUG
39import Control.Concurrent.Lifted.Instrument
40#else
41import Control.Concurrent
42import GHC.Conc (labelThread)
43#endif
38import Control.Concurrent.STM 44import Control.Concurrent.STM
39import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) 45import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime)
40import Network.Socket 46import Network.Socket
@@ -159,7 +165,7 @@ toOnionDestination (AnnouncedRoute ni rpath) = OnionToOwner ni rpath
159-- structure. 165-- structure.
160-- 166--
161data AnnouncedKeys = AnnouncedKeys 167data AnnouncedKeys = AnnouncedKeys
162 { keyByAge :: !(PSQ NodeId (Down POSIXTime{-Time at which they announced to you-})) -- TODO: timeout of 300 seconds 168 { keyByAge :: !(PSQ NodeId (POSIXTime{-Time at which they announced to you-}))
163 , keyAssoc :: !(MinMaxPSQ' NodeId NodeDistance (Int{-count of route usage-},AnnouncedRoute)) 169 , keyAssoc :: !(MinMaxPSQ' NodeId NodeDistance (Int{-count of route usage-},AnnouncedRoute))
164 -- ^ PSQ using NodeId(user/public key) as Key 170 -- ^ PSQ using NodeId(user/public key) as Key
165 -- and using 'NodeDistance' as priority. 171 -- and using 'NodeDistance' as priority.
@@ -172,12 +178,33 @@ data AnnouncedKeys = AnnouncedKeys
172 178
173insertKey :: POSIXTime -> NodeId -> AnnouncedRoute -> NodeDistance -> AnnouncedKeys -> AnnouncedKeys 179insertKey :: POSIXTime -> NodeId -> AnnouncedRoute -> NodeDistance -> AnnouncedKeys -> AnnouncedKeys
174insertKey tm pub toxpath d keydb = AnnouncedKeys 180insertKey tm pub toxpath d keydb = AnnouncedKeys
175 { keyByAge = PSQ.insert pub (Down tm) (keyByAge keydb) 181 { keyByAge = PSQ.insert pub tm (keyByAge keydb)
176 , keyAssoc = case MinMaxPSQ.lookup' pub (keyAssoc keydb) of 182 , keyAssoc = case MinMaxPSQ.lookup' pub (keyAssoc keydb) of
177 Just (_,(cnt,_)) -> MinMaxPSQ.insert' pub (cnt,toxpath) d (keyAssoc keydb) 183 Just (_,(cnt,_)) -> MinMaxPSQ.insert' pub (cnt,toxpath) d (keyAssoc keydb)
178 Nothing -> MinMaxPSQ.insert' pub (0 ,toxpath) d (keyAssoc keydb) 184 Nothing -> MinMaxPSQ.insert' pub (0 ,toxpath) d (keyAssoc keydb)
179 } 185 }
180 186
187-- | Forks a thread to garbage-collect old key announcements. Keys may be
188-- discarded after 5 minutes.
189forkAnnouncedKeysGC :: TVar AnnouncedKeys -> IO ThreadId
190forkAnnouncedKeysGC db = forkIO $ do
191 myThreadId >>= flip labelThread "gc:toxids"
192 fix $ \loop -> do
193 cutoff <- getPOSIXTime
194 threadDelay 300000000 -- 300 seconds
195 join $ atomically $ do
196 fix $ \gc -> do
197 keys <- readTVar db
198 case PSQ.minView (keyByAge keys) of
199 Nothing -> return loop
200 Just (pub :-> tm,kba')
201 | tm > cutoff -> return loop
202 | otherwise -> do writeTVar db keys
203 { keyByAge = kba'
204 , keyAssoc = MinMaxPSQ.delete pub (keyAssoc keys)
205 }
206 gc
207
181areq :: Message -> Either String AnnounceRequest 208areq :: Message -> Either String AnnounceRequest
182areq (OnionAnnounce asymm) = Right $ fst $ runIdentity $ asymmData asymm 209areq (OnionAnnounce asymm) = Right $ fst $ runIdentity $ asymmData asymm
183areq _ = Left "Unexpected non-announce OnionMessage" 210areq _ = Left "Unexpected non-announce OnionMessage"