diff options
Diffstat (limited to 'src/Network/Tox/DHT/Handlers.hs')
-rw-r--r-- | src/Network/Tox/DHT/Handlers.hs | 41 |
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 #-} | ||
4 | module Network.Tox.DHT.Handlers where | 5 | module Network.Tox.DHT.Handlers where |
5 | 6 | ||
6 | import Network.Tox.DHT.Transport as DHTTransport | 7 | import Network.Tox.DHT.Transport as DHTTransport |
@@ -31,6 +32,7 @@ import Data.Maybe | |||
31 | import Data.Bits | 32 | import Data.Bits |
32 | import Data.Serialize (Serialize) | 33 | import Data.Serialize (Serialize) |
33 | import Data.Word | 34 | import Data.Word |
35 | import Data.List | ||
34 | import System.IO | 36 | import System.IO |
35 | 37 | ||
36 | data TransactionId = TransactionId | 38 | data 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 | ||
246 | cookieRequest :: TVar [(SockAddr,(Int,NodeInfo))] -> PublicKey -> Client -> NodeInfo -> IO (Maybe Cookie) | ||
247 | cookieRequest 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 | |||
279 | unCookie (DHTCookie n24 fcookie) = Just fcookie | ||
280 | unCookie _ = Nothing | ||
281 | |||
243 | unsendNodes :: Message -> Maybe (Asymm (Nonce8,SendNodes)) | 282 | unsendNodes :: Message -> Maybe (Asymm (Nonce8,SendNodes)) |
244 | unsendNodes (DHTSendNodes asymm) = Just asymm | 283 | unsendNodes (DHTSendNodes asymm) = Just asymm |
245 | unsendNodes _ = Nothing | 284 | unsendNodes _ = 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 | ||
267 | updateTable :: Client -> NodeInfo -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TriadCommittee NodeId SockAddr -> TVar (Int.PSQ POSIXTime) -> IO () | 307 | updateTable :: Client -> NodeInfo -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TriadCommittee NodeId SockAddr -> TVar (Int.PSQ POSIXTime) -> IO () |
268 | updateTable client naddr orouter tbl committee sched = do | 308 | updateTable client naddr orouter tbl committee sched = do |
@@ -327,6 +367,7 @@ handlers :: TransportCrypto -> Routing -> PacketKind -> Maybe Handler | |||
327 | handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong pingH | 367 | handlers _ routing PingType = Just $ MethodHandler (isPing snd) mkPong pingH |
328 | handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing | 368 | handlers _ routing GetNodesType = Just $ MethodHandler (isGetNodes snd) mkSendNodes $ getNodesH routing |
329 | handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto | 369 | handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieRequest snd) mkCookie $ cookieRequestH crypto |
370 | handlers _ _ _ = error "TODO handlers" | ||
330 | 371 | ||
331 | nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo | 372 | nodeSearch :: Client -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo |
332 | nodeSearch client = Search | 373 | nodeSearch client = Search |