summaryrefslogtreecommitdiff
path: root/src/Network/Tox/DHT/Handlers.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/Tox/DHT/Handlers.hs')
-rw-r--r--src/Network/Tox/DHT/Handlers.hs41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs
index 9cdf0d06..840e2e6b 100644
--- a/src/Network/Tox/DHT/Handlers.hs
+++ b/src/Network/Tox/DHT/Handlers.hs
@@ -1,6 +1,7 @@
1{-# LANGUAGE GeneralizedNewtypeDeriving #-} 1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE PatternSynonyms #-} 2{-# LANGUAGE PatternSynonyms #-}
3{-# LANGUAGE TupleSections #-} 3{-# LANGUAGE TupleSections #-}
4{-# LANGUAGE CPP #-}
4module Network.Tox.DHT.Handlers where 5module Network.Tox.DHT.Handlers where
5 6
6import Network.Tox.DHT.Transport as DHTTransport 7import Network.Tox.DHT.Transport as DHTTransport
@@ -31,6 +32,7 @@ import Data.Maybe
31import Data.Bits 32import Data.Bits
32import Data.Serialize (Serialize) 33import Data.Serialize (Serialize)
33import Data.Word 34import Data.Word
35import Data.List
34import System.IO 36import System.IO
35 37
36data TransactionId = TransactionId 38data TransactionId = TransactionId
@@ -175,6 +177,7 @@ getNodesH routing addr (GetNodes nid) = do
175 ks6 <- go append6 $ routing6 routing 177 ks6 <- go append6 $ routing6 routing
176 let (ns1,ns2) = case preferred of Want_IP6 -> (ks6,ks) 178 let (ns1,ns2) = case preferred of Want_IP6 -> (ks6,ks)
177 Want_IP4 -> (ks,ks6) 179 Want_IP4 -> (ks,ks6)
180 Want_Both -> error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__
178 return $ SendNodes 181 return $ SendNodes
179 $ if null ns2 then ns1 182 $ if null ns2 then ns1
180 else take 4 (take 3 ns1 ++ ns2) 183 else take 4 (take 3 ns1 ++ ns2)
@@ -240,6 +243,42 @@ ping client addr = do
240 hPutStrLn stderr $ show addr ++ " -pong-> " ++ show reply 243 hPutStrLn stderr $ show addr ++ " -pong-> " ++ show reply
241 maybe (return False) (\Pong -> return True) $ join reply 244 maybe (return False) (\Pong -> return True) $ join reply
242 245
246cookieRequest :: TVar [(SockAddr,(Int,NodeInfo))] -> PublicKey -> Client -> NodeInfo -> IO (Maybe Cookie)
247cookieRequest tvar myDhtKey client addr = do
248 let sockAddr = nodeAddr addr
249 let incAddr sockMap
250 = case partition ((==sockAddr) . fst) sockMap of
251 ([],xs) -> insert (sockAddr, (1 ,addr)) xs
252 ([(_,(c,addr'))],xs) | addr' == addr -> insert (sockAddr, (c+1,addr)) xs
253 anythingElse -> error $ "unreachable at " ++ __FILE__ ++ show __LINE__ ++ show anythingElse ++ show (sockAddr,addr)
254 decAddr sockMap
255 = case partition ((==sockAddr) . fst) sockMap of
256 ([],xs) -> xs -- unreachable?
257 ([(_,(1,addr'))],xs) | addr' == addr -> xs
258 ([(_,(c,addr'))],xs) | addr' == addr -> insert (sockAddr,(c-1,addr)) xs
259 anythingElse -> error $ "unreachable at " ++ __FILE__ ++ show __LINE__ ++ show anythingElse ++ show (sockAddr,addr)
260 sockMap <- atomically $ do
261 mp <- incAddr <$> readTVar tvar
262 writeTVar tvar mp
263 return mp
264 let cookieSerializer
265 = MethodSerializer
266 { methodTimeout = \tid addr -> do
267 modifyTVar tvar decAddr
268 return (addr, 5000000)
269 , method = CookieRequestType
270 , wrapQuery = \tid src dst cr -> DHTCookieRequest $ wrapAsymm tid src dst (, cr)
271 , unwrapResponse = fmap snd . unCookie
272 }
273 cookieRequest = CookieRequest myDhtKey
274 hPutStrLn stderr $ show addr ++ " <-- cookieRequest"
275 reply <- QR.sendQuery client cookieSerializer cookieRequest addr
276 hPutStrLn stderr $ show addr ++ " -cookieResponse-> " ++ show reply
277 return $ join reply
278
279unCookie (DHTCookie n24 fcookie) = Just fcookie
280unCookie _ = Nothing
281
243unsendNodes :: Message -> Maybe (Asymm (Nonce8,SendNodes)) 282unsendNodes :: Message -> Maybe (Asymm (Nonce8,SendNodes))
244unsendNodes (DHTSendNodes asymm) = Just asymm 283unsendNodes (DHTSendNodes asymm) = Just asymm
245unsendNodes _ = Nothing 284unsendNodes _ = Nothing
@@ -263,6 +302,7 @@ updateRouting client routing orouter naddr msg = do
263 case prefer4or6 naddr Nothing of 302 case prefer4or6 naddr Nothing of
264 Want_IP4 -> updateTable client naddr orouter (routing4 routing) (committee4 routing) (sched4 routing) 303 Want_IP4 -> updateTable client naddr orouter (routing4 routing) (committee4 routing) (sched4 routing)
265 Want_IP6 -> updateTable client naddr orouter (routing6 routing) (committee6 routing) (sched6 routing) 304 Want_IP6 -> updateTable client naddr orouter (routing6 routing) (committee6 routing) (sched6 routing)
305 Want_Both -> error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__
266 306
267updateTable :: Client -> NodeInfo -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TriadCommittee NodeId SockAddr -> TVar (Int.PSQ POSIXTime) -> IO () 307updateTable :: Client -> NodeInfo -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TriadCommittee NodeId SockAddr -> TVar (Int.PSQ POSIXTime) -> IO ()
268updateTable client naddr orouter tbl committee sched = do 308updateTable client naddr orouter tbl committee sched = do
@@ -327,6 +367,7 @@ handlers :: TransportCrypto -> Routing -> PacketKind -> Maybe Handler
327handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong pingH 367handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong pingH
328handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing 368handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing
329handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto 369handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto
370handlers _ _ _ = error "TODO handlers"
330 371
331nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo 372nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo
332nodeSearch client = Search 373nodeSearch client = Search