summaryrefslogtreecommitdiff
path: root/OnionRouter.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-12-12 20:06:53 -0500
committerJoe Crayne <joe@jerkface.net>2018-12-16 14:08:27 -0500
commita1ed3d4d5440e57e5b7336bb131907eacc593c9b (patch)
tree49045a21bfbf5eddab08b0c6c643b208e9ec196f /OnionRouter.hs
parenteca9d293170f2c12528f93c4929e73f8eff61f6f (diff)
Generalized selectTrampolines
Diffstat (limited to 'OnionRouter.hs')
-rw-r--r--OnionRouter.hs38
1 files changed, 25 insertions, 13 deletions
diff --git a/OnionRouter.hs b/OnionRouter.hs
index 39b3a872..bfd517fd 100644
--- a/OnionRouter.hs
+++ b/OnionRouter.hs
@@ -291,24 +291,31 @@ randomIvalInteger (l,h) rng
291-- 291--
292-- Only the DRG random seed is updated. Hopefully another thread will change the 292-- Only the DRG random seed is updated. Hopefully another thread will change the
293-- trampolineNodes set so that selection can succeed. 293-- trampolineNodes set so that selection can succeed.
294selectTrampolines :: OnionRouter -> IO [NodeInfo] 294selectTrampolines :: Show ni => OnionRouter -> TrampolineSet ni -> IO [ni]
295selectTrampolines or = do 295selectTrampolines or tset = do
296 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines") 296 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines")
297 atomically (selectTrampolines' or) >>= \case 297 atomically (selectTrampolines' tset) >>= \case
298 Left ns -> do 298 Left ns -> do
299 -- atomically $ writeTChan (routeLog or) 299 -- atomically $ writeTChan (routeLog or)
300 routeLogger or $ unwords 300 routeLogger or $ unwords
301 ( "ONION Discarding insecure trampolines:" : (map (show . nodeAddr) ns) ) 301 ( "ONION Discarding insecure trampolines:" : (map show ns) )
302 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep") 302 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep")
303 case ns of 303 case ns of
304 [_,_,_] -> threadDelay 1000000 -- wait 1 second if we failed the distinct3by predicate. 304 [_,_,_] -> threadDelay 1000000 -- wait 1 second if we failed the distinct3by predicate.
305 _ -> threadDelay 5000000 -- wait 5 seconds if insufficient nodes. 305 _ -> threadDelay 5000000 -- wait 5 seconds if insufficient nodes.
306 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines") 306 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines")
307 selectTrampolines or 307 selectTrampolines or tset
308 Right ns -> do 308 Right ns -> do
309 myThreadId >>= flip labelThread ("OnionRouter") 309 myThreadId >>= flip labelThread ("OnionRouter")
310 return ns 310 return ns
311 311
312data TrampolineSet ni = TrampolineSet
313 { setNodes :: TVar (IntMap ni)
314 , setCount :: TVar Int
315 , setDRG :: TVar ChaChaDRG
316 , setNodeClass :: ni -> IPClass
317 }
318
312choose3 :: (Integral a, DRG drg) => drg -> a -> ([a], drg) 319choose3 :: (Integral a, DRG drg) => drg -> a -> ([a], drg)
313choose3 drg0 cnt = ([a,b,c], drg) 320choose3 drg0 cnt = ([a,b,c], drg)
314 where 321 where
@@ -329,25 +336,30 @@ choose3 drg0 cnt = ([a,b,c], drg)
329-- 336--
330-- The only write this function does to STM state is that the onionDRG random 337-- The only write this function does to STM state is that the onionDRG random
331-- seed will be updated. 338-- seed will be updated.
332selectTrampolines' :: OnionRouter -> STM (Either [NodeInfo] [NodeInfo]) 339selectTrampolines' :: TrampolineSet ni -> STM (Either [ni] [ni])
333selectTrampolines' or = do 340selectTrampolines' TrampolineSet{..} = do
334 cnt <- readTVar (trampolineCount or) 341 cnt <- readTVar setCount
335 ts <- readTVar (trampolineNodes or) 342 ts <- readTVar setNodes
336 drg0 <- readTVar (onionDRG or) 343 drg0 <- readTVar setDRG
337 let ([a,b,c],drg) = choose3 drg0 cnt 344 let ([a,b,c],drg) = choose3 drg0 cnt
338 ns = mapMaybe (\n -> IntMap.lookup n ts) [a,b,c] 345 ns = mapMaybe (\n -> IntMap.lookup n ts) [a,b,c]
339 ns' <- case ns of 346 ns' <- case ns of
340 [an,bn,cn] | distinct3by nodeClass an bn cn 347 [an,bn,cn] | distinct3by setNodeClass an bn cn
341 -> return $ Right ns 348 -> return $ Right ns
342 _ -> return $ Left ns 349 _ -> return $ Left ns
343 writeTVar (onionDRG or) drg 350 writeTVar setDRG drg
344 return ns' 351 return ns'
345 352
346handleEvent :: (NodeId -> NodeInfo -> IO (Maybe [NodeInfo])) -> OnionRouter -> RouteEvent -> IO () 353handleEvent :: (NodeId -> NodeInfo -> IO (Maybe [NodeInfo])) -> OnionRouter -> RouteEvent -> IO ()
347handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do 354handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do
348 routeLogger or $ "ONION Rebuilding RouteId " ++ show rid 355 routeLogger or $ "ONION Rebuilding RouteId " ++ show rid
349 mb <- do 356 mb <- do
350 ts <- selectTrampolines or 357 ts <- selectTrampolines or TrampolineSet
358 { setNodes = trampolineNodes or
359 , setCount = trampolineCount or
360 , setDRG = onionDRG or
361 , setNodeClass = nodeClass
362 }
351 join . atomically $ do 363 join . atomically $ do
352 drg <- readTVar (onionDRG or) 364 drg <- readTVar (onionDRG or)
353 av <- newTVar Nothing 365 av <- newTVar Nothing