diff options
author | joe <joe@jerkface.net> | 2018-06-09 01:31:23 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2018-06-09 01:32:08 -0400 |
commit | fb0c6758ec415c5cda5cc7c182e1f83906f365fb (patch) | |
tree | c07aa47ca461d90199b63af230f4433da9827935 /src/Network/Tox | |
parent | fa15dabe75703516c7bbb54fdba2a13ae6c6e9cc (diff) |
Expire old tox key announcements after 5 minutes.
Diffstat (limited to 'src/Network/Tox')
-rw-r--r-- | src/Network/Tox/Onion/Handlers.hs | 33 |
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) | |||
11 | import qualified Network.QueryResponse as QR (Client) | 11 | import qualified Network.QueryResponse as QR (Client) |
12 | import Crypto.Tox | 12 | import Crypto.Tox |
13 | import qualified Data.Wrapper.PSQ as PSQ | 13 | import 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 |
16 | import Crypto.Error.Types (CryptoFailable (..), | 16 | import Crypto.Error.Types (CryptoFailable (..), |
17 | throwCryptoError) | 17 | throwCryptoError) |
@@ -35,6 +35,12 @@ import Network.BitTorrent.DHT.Token as Token | |||
35 | 35 | ||
36 | import Control.Exception hiding (Handler) | 36 | import Control.Exception hiding (Handler) |
37 | import Control.Monad | 37 | import Control.Monad |
38 | #ifdef THREAD_DEBUG | ||
39 | import Control.Concurrent.Lifted.Instrument | ||
40 | #else | ||
41 | import Control.Concurrent | ||
42 | import GHC.Conc (labelThread) | ||
43 | #endif | ||
38 | import Control.Concurrent.STM | 44 | import Control.Concurrent.STM |
39 | import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) | 45 | import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) |
40 | import Network.Socket | 46 | import Network.Socket |
@@ -159,7 +165,7 @@ toOnionDestination (AnnouncedRoute ni rpath) = OnionToOwner ni rpath | |||
159 | -- structure. | 165 | -- structure. |
160 | -- | 166 | -- |
161 | data AnnouncedKeys = AnnouncedKeys | 167 | data 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 | ||
173 | insertKey :: POSIXTime -> NodeId -> AnnouncedRoute -> NodeDistance -> AnnouncedKeys -> AnnouncedKeys | 179 | insertKey :: POSIXTime -> NodeId -> AnnouncedRoute -> NodeDistance -> AnnouncedKeys -> AnnouncedKeys |
174 | insertKey tm pub toxpath d keydb = AnnouncedKeys | 180 | insertKey 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. | ||
189 | forkAnnouncedKeysGC :: TVar AnnouncedKeys -> IO ThreadId | ||
190 | forkAnnouncedKeysGC 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 | |||
181 | areq :: Message -> Either String AnnounceRequest | 208 | areq :: Message -> Either String AnnounceRequest |
182 | areq (OnionAnnounce asymm) = Right $ fst $ runIdentity $ asymmData asymm | 209 | areq (OnionAnnounce asymm) = Right $ fst $ runIdentity $ asymmData asymm |
183 | areq _ = Left "Unexpected non-announce OnionMessage" | 210 | areq _ = Left "Unexpected non-announce OnionMessage" |