summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/Tox/DHT/Handlers.hs40
1 files changed, 23 insertions, 17 deletions
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs
index d010f36d..4576fc85 100644
--- a/src/Network/Tox/DHT/Handlers.hs
+++ b/src/Network/Tox/DHT/Handlers.hs
@@ -259,26 +259,31 @@ ping client addr = do
259 hPutStrLn stderr $ show addr ++ " -pong-> " ++ show reply 259 hPutStrLn stderr $ show addr ++ " -pong-> " ++ show reply
260 maybe (return False) (\Pong -> return True) $ join reply 260 maybe (return False) (\Pong -> return True) $ join reply
261 261
262
263saveCookieKey :: TVar [(SockAddr, (Int, PublicKey))] -> SockAddr -> PublicKey -> STM ()
264saveCookieKey var saddr pk = do
265 cookiekeys <- readTVar var
266 case break (\(stored,_) -> stored == saddr) cookiekeys of
267 (xs,[]) -> writeTVar var $ (saddr, (1 ,pk)) : xs
268 (xs,(_,(c,stored)):ys) | stored == pk -> writeTVar var $ (saddr, (c+1,pk)) : xs ++ ys
269 _ -> retry -- Wait for requests to this address
270 -- under a different key to time out
271 -- before we try this key.
272
273loseCookieKey :: TVar [(SockAddr, (Int, PublicKey))] -> SockAddr -> PublicKey -> STM ()
274loseCookieKey var saddr pk = do
275 cookiekeys <- readTVar var
276 case break (\(stored,_) -> stored == saddr) cookiekeys of
277 (xs,(_,(1,stored)):ys) | stored == pk -> writeTVar var $ xs ++ ys
278 (xs,(_,(c,stored)):ys) | stored == pk -> writeTVar var $ (saddr, (c-1,pk)) : xs ++ ys
279 _ -> return () -- unreachable?
280
281
262cookieRequest :: TransportCrypto -> Client -> PublicKey -> NodeInfo -> IO (Maybe Cookie) 282cookieRequest :: TransportCrypto -> Client -> PublicKey -> NodeInfo -> IO (Maybe Cookie)
263cookieRequest crypto client localUserKey addr = do 283cookieRequest crypto client localUserKey addr = do
264 let sockAddr = nodeAddr addr 284 let sockAddr = nodeAddr addr
265 nid = id2key $ nodeId addr 285 nid = id2key $ nodeId addr
266 let incAddr sockMap 286 cookieSerializer
267 = case partition ((==sockAddr) . fst) sockMap of
268 ([],xs) -> (sockAddr, (1 ,nid)) : xs
269 ([(_,(c,addr'))],xs) | addr' == nid -> (sockAddr, (c+1,nid)) : xs
270 anythingElse -> error $ "unreachable at " ++ __FILE__ ++ show __LINE__ ++ show anythingElse ++ show (sockAddr,addr)
271 decAddr sockMap
272 = case partition ((==sockAddr) . fst) sockMap of
273 ([],xs) -> xs -- unreachable?
274 ([(_,(1,addr'))],xs) | addr' == nid -> xs
275 ([(_,(c,addr'))],xs) | addr' == nid -> (sockAddr,(c-1,nid)) : xs
276 anythingElse -> error $ "unreachable at " ++ __FILE__ ++ show __LINE__ ++ show anythingElse ++ show (sockAddr,addr)
277 sockMap <- atomically $ do
278 mp <- incAddr <$> readTVar (pendingCookies crypto)
279 writeTVar (pendingCookies crypto) mp
280 return mp
281 let cookieSerializer
282 = MethodSerializer 287 = MethodSerializer
283 { methodTimeout = \tid addr -> return (addr, 5000000) 288 { methodTimeout = \tid addr -> return (addr, 5000000)
284 , method = CookieRequestType 289 , method = CookieRequestType
@@ -286,9 +291,10 @@ cookieRequest crypto client localUserKey addr = do
286 , unwrapResponse = fmap snd . unCookie 291 , unwrapResponse = fmap snd . unCookie
287 } 292 }
288 cookieRequest = CookieRequest localUserKey 293 cookieRequest = CookieRequest localUserKey
294 atomically $ saveCookieKey (pendingCookies crypto) sockAddr nid
289 hPutStrLn stderr $ show addr ++ " <-- cookieRequest" 295 hPutStrLn stderr $ show addr ++ " <-- cookieRequest"
290 reply <- QR.sendQuery client cookieSerializer cookieRequest addr 296 reply <- QR.sendQuery client cookieSerializer cookieRequest addr
291 atomically $ modifyTVar (pendingCookies crypto) decAddr 297 atomically $ loseCookieKey (pendingCookies crypto) sockAddr nid
292 hPutStrLn stderr $ show addr ++ " -cookieResponse-> " ++ show reply 298 hPutStrLn stderr $ show addr ++ " -cookieResponse-> " ++ show reply
293 return $ join reply 299 return $ join reply
294 300