summaryrefslogtreecommitdiff
path: root/OnionRouter.hs
diff options
context:
space:
mode:
Diffstat (limited to 'OnionRouter.hs')
-rw-r--r--OnionRouter.hs32
1 files changed, 18 insertions, 14 deletions
diff --git a/OnionRouter.hs b/OnionRouter.hs
index e3c32fbe..b11a0bf6 100644
--- a/OnionRouter.hs
+++ b/OnionRouter.hs
@@ -72,7 +72,7 @@ data OnionRouter = OnionRouter
72 -- | Each of the 12 routes has a version number here that is set larger 72 -- | Each of the 12 routes has a version number here that is set larger
73 -- than the 'routeVersion' set in 'routeMap' when the route should be 73 -- than the 'routeVersion' set in 'routeMap' when the route should be
74 -- discarded and replaced with a fresh one. 74 -- discarded and replaced with a fresh one.
75 , pendingRoutes :: IntMap (TVar Int) 75 , pendingRoutes :: TArray Int Int
76 -- | Debug prints are written to this channel which is then flushed to 76 -- | Debug prints are written to this channel which is then flushed to
77 -- 'routeLogger'. 77 -- 'routeLogger'.
78 , routeLog :: TChan String 78 , routeLog :: TChan String
@@ -134,7 +134,7 @@ gotTimeout rr = rr
134 { timeoutCount = succ $ timeoutCount rr 134 { timeoutCount = succ $ timeoutCount rr
135 } 135 }
136 136
137data RouteEvent = BuildRoute RouteId 137newtype RouteEvent = BuildRoute RouteId
138 138
139newOnionRouter :: (String -> IO ()) -> IO OnionRouter 139newOnionRouter :: (String -> IO ()) -> IO OnionRouter
140newOnionRouter perror = do 140newOnionRouter perror = do
@@ -148,10 +148,10 @@ newOnionRouter perror = do
148 tn <- newTVar IntMap.empty 148 tn <- newTVar IntMap.empty
149 ti <- newTVar HashMap.empty 149 ti <- newTVar HashMap.empty
150 tc <- newTVar 0 150 tc <- newTVar 0
151 vs <- sequence $ replicate 12 (newTVar 0) 151 pr <- newArray (0,11) 0
152 rlog <- newTChan 152 rlog <- newTChan
153 return OnionRouter 153 return OnionRouter
154 { pendingRoutes = IntMap.fromList $ zip [0..11] vs 154 { pendingRoutes = pr
155 , onionDRG = drg 155 , onionDRG = drg
156 , pendingQueries = pq 156 , pendingQueries = pq
157 , routeMap = rm 157 , routeMap = rm
@@ -170,17 +170,19 @@ forkRouteBuilder or getnodes = do
170 me <- myThreadId 170 me <- myThreadId
171 labelThread me "OnionRouter" 171 labelThread me "OnionRouter"
172 forever $ do 172 forever $ do
173 let checkRebuild rid want_build stm = flip orElse stm $ do 173 let checkRebuild :: Int -> Int -> STM RouteEvent
174 wanted_ver <- readTVar want_build 174 checkRebuild rid wanted_ver = do
175 current_ver <- fmap routeVersion <$> readArray (routeMap or) rid 175 current_ver <- fmap routeVersion <$> readArray (routeMap or) rid
176 writeTChan (routeLog or) $ "ONION checkRebuild "++show(current_ver,wanted_ver) 176 writeTChan (routeLog or) $ "ONION checkRebuild "++show(current_ver,wanted_ver)
177 check $ maybe True (< wanted_ver) current_ver 177 check $ maybe True (< wanted_ver) current_ver
178 return $ BuildRoute $ RouteId rid 178 return $ BuildRoute $ RouteId rid
179 io <- atomically $ 179 io <- atomically $ {-# SCC "forkRouteBuilder.log" #-}
180 (readTChan (routeLog or) >>= return . routeLogger or) 180 (readTChan (routeLog or) >>= return . routeLogger or)
181 `orElse` 181 `orElse` {-# SCC "forkRouteBuilder.checkRebuild" #-}
182 (IntMap.foldrWithKey checkRebuild retry (pendingRoutes or) 182 (let stms = map (\rid -> checkRebuild rid =<< readArray (pendingRoutes or) rid)
183 >>= return . handleEvent getnodes or { routeThread = me }) 183 [0..11]
184 in do event <- foldr1 orElse stms
185 return $ handleEvent getnodes or { routeThread = me } event)
184 io 186 io
185 return or { routeThread = tid } 187 return or { routeThread = tid }
186 188
@@ -240,7 +242,9 @@ selectTrampolines or = do
240 routeLogger or $ unwords 242 routeLogger or $ unwords
241 ( "ONION Discarding insecure trampolines:" : (map (show . nodeAddr) ns) ) 243 ( "ONION Discarding insecure trampolines:" : (map (show . nodeAddr) ns) )
242 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep") 244 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep")
243 threadDelay 1000000 245 case ns of
246 [_,_,_] -> threadDelay 1000000 -- wait 1 second if we failed the distinct3by predicate.
247 _ -> threadDelay 5000000 -- wait 5 seconds if insufficient nodes.
244 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines") 248 myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines")
245 selectTrampolines or 249 selectTrampolines or
246 Right ns -> do 250 Right ns -> do
@@ -347,7 +351,7 @@ handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do
347 (freshRoute now r) 351 (freshRoute now r)
348 rid 352 rid
349 v <- routeVersion . fromJust <$> readArray (routeMap or) rid 353 v <- routeVersion . fromJust <$> readArray (routeMap or) rid
350 writeTVar (pendingRoutes or IntMap.! rid) v 354 writeArray (pendingRoutes or) rid v
351 ) 355 )
352 mb 356 mb
353 case mb of 357 case mb of
@@ -390,7 +394,7 @@ hookQueries or t8 tmethods = TransactionMethods
390 { dispatchRegister = \mvar od d -> {-# SCC "hookQ.dispatchRegister" #-} do -- :: MVar x -> d -> STM (tid, d) 394 { dispatchRegister = \mvar od d -> {-# SCC "hookQ.dispatchRegister" #-} do -- :: MVar x -> d -> STM (tid, d)
391 let ni = onionNodeInfo od 395 let ni = onionNodeInfo od
392 rid@(RouteId ridn) = fromMaybe (routeId (nodeId ni)) $ onionRouteSpec od 396 rid@(RouteId ridn) = fromMaybe (routeId (nodeId ni)) $ onionRouteSpec od
393 wanted <- {-# SCC "hookQ.wanted" #-} (readTVar (pendingRoutes or IntMap.! ridn)) 397 wanted <- {-# SCC "hookQ.wanted" #-} (readArray (pendingRoutes or) ridn)
394 mr <- {-# SCC "hookQ.mr_action" #-} (readArray (routeMap or) ridn) 398 mr <- {-# SCC "hookQ.mr_action" #-} (readArray (routeMap or) ridn)
395 -- Block query until a route is ready. 399 -- Block query until a route is ready.
396 check $ fromMaybe False $ do 400 check $ fromMaybe False $ do
@@ -431,7 +435,7 @@ hookQueries or t8 tmethods = TransactionMethods
431 mrr <- readArray (routeMap or) rid 435 mrr <- readArray (routeMap or) rid
432 forM_ mrr $ \rr -> do 436 forM_ mrr $ \rr -> do
433 when (routeVersion rr == pendingVersion pq) $ do 437 when (routeVersion rr == pendingVersion pq) $ do
434 let expireRoute = modifyTVar' (pendingRoutes or IntMap.! rid) expire 438 let expireRoute = modifyArray (pendingRoutes or) expire rid
435 expire ver | ver <= succ (pendingVersion pq) = succ (pendingVersion pq) 439 expire ver | ver <= succ (pendingVersion pq) = succ (pendingVersion pq)
436 | otherwise = ver 440 | otherwise = ver
437 modifyArray (routeMap or) (fmap gotTimeout) rid 441 modifyArray (routeMap or) (fmap gotTimeout) rid