diff options
-rw-r--r-- | dht-client.cabal | 5 | ||||
-rw-r--r-- | src/Network/QueryResponse.hs | 6 | ||||
-rw-r--r-- | src/Network/Tox.hs | 17 | ||||
-rw-r--r-- | src/Network/Tox/DHT/Handlers.hs | 41 | ||||
-rw-r--r-- | src/Network/Tox/DHT/Transport.hs | 1 | ||||
-rw-r--r-- | src/Network/Tox/Onion/Transport.hs | 4 |
6 files changed, 62 insertions, 12 deletions
diff --git a/dht-client.cabal b/dht-client.cabal index 347924ee..de6eb33f 100644 --- a/dht-client.cabal +++ b/dht-client.cabal | |||
@@ -91,6 +91,7 @@ library | |||
91 | Control.TriadCommittee | 91 | Control.TriadCommittee |
92 | Crypto.Tox | 92 | Crypto.Tox |
93 | Text.XXD | 93 | Text.XXD |
94 | Roster | ||
94 | 95 | ||
95 | build-depends: base | 96 | build-depends: base |
96 | , containers | 97 | , containers |
@@ -196,6 +197,10 @@ executable dhtd | |||
196 | , stm | 197 | , stm |
197 | , cereal | 198 | , cereal |
198 | , bencoding | 199 | , bencoding |
200 | , unordered-containers | ||
201 | , vector | ||
202 | , text | ||
203 | |||
199 | if flag(thread-debug) | 204 | if flag(thread-debug) |
200 | build-depends: time | 205 | build-depends: time |
201 | cpp-options: -DTHREAD_DEBUG | 206 | cpp-options: -DTHREAD_DEBUG |
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs index 9563fa7c..fca6d5cc 100644 --- a/src/Network/QueryResponse.hs +++ b/src/Network/QueryResponse.hs | |||
@@ -27,7 +27,9 @@ import qualified Data.IntMap.Strict as IntMap | |||
27 | ;import Data.IntMap.Strict (IntMap) | 27 | ;import Data.IntMap.Strict (IntMap) |
28 | import qualified Data.Map.Strict as Map | 28 | import qualified Data.Map.Strict as Map |
29 | ;import Data.Map.Strict (Map) | 29 | ;import Data.Map.Strict (Map) |
30 | import qualified Data.Word64Map as W64Map | 30 | import qualified Data.Word64Map as W64Map |
31 | ;import Data.Word64Map (Word64Map) | ||
32 | import Data.Word | ||
31 | import Data.Maybe | 33 | import Data.Maybe |
32 | import Data.Typeable | 34 | import Data.Typeable |
33 | import Network.Socket | 35 | import Network.Socket |
@@ -333,7 +335,7 @@ intMapMethods :: TableMethods IntMap Int | |||
333 | intMapMethods = TableMethods IntMap.insert IntMap.delete IntMap.lookup | 335 | intMapMethods = TableMethods IntMap.insert IntMap.delete IntMap.lookup |
334 | 336 | ||
335 | -- | Methods for using 'Data.Word64Map'. | 337 | -- | Methods for using 'Data.Word64Map'. |
336 | w64MapMethods :: TableMethods IntMap Int | 338 | w64MapMethods :: TableMethods Word64Map Word64 |
337 | w64MapMethods = TableMethods W64Map.insert W64Map.delete W64Map.lookup | 339 | w64MapMethods = TableMethods W64Map.insert W64Map.delete W64Map.lookup |
338 | 340 | ||
339 | -- | Methods for using 'Data.Map' | 341 | -- | Methods for using 'Data.Map' |
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs index c587578d..e9220fcb 100644 --- a/src/Network/Tox.hs +++ b/src/Network/Tox.hs | |||
@@ -87,6 +87,7 @@ import GHC.TypeLits | |||
87 | 87 | ||
88 | import Crypto.Tox | 88 | import Crypto.Tox |
89 | import Data.Word64Map (fitsInInt) | 89 | import Data.Word64Map (fitsInInt) |
90 | import qualified Data.Word64Map (empty) | ||
90 | import Network.Tox.Crypto.Transport (NetCrypto) | 91 | import Network.Tox.Crypto.Transport (NetCrypto) |
91 | import qualified Network.Tox.DHT.Handlers as DHT | 92 | import qualified Network.Tox.DHT.Handlers as DHT |
92 | import qualified Network.Tox.DHT.Transport as DHT | 93 | import qualified Network.Tox.DHT.Transport as DHT |
@@ -189,8 +190,8 @@ newClient drg net classify selfAddr handlers modifytbl modifynet = do | |||
189 | intmap_var <- atomically $ newTVar (drg, mempty) | 190 | intmap_var <- atomically $ newTVar (drg, mempty) |
190 | return $ Right (intmapT,intmap_var) | 191 | return $ Right (intmapT,intmap_var) |
191 | else do | 192 | else do |
192 | let word64mapT = transactionMethods (contramap w64key w64MapMethods) gen | 193 | let word64mapT = transactionMethods (contramap w64Key w64MapMethods) gen |
193 | map_var <- atomically $ newTVar (drg, mempty) | 194 | map_var <- atomically $ newTVar (drg, Data.Word64Map.empty) |
194 | return $ Left (word64mapT,map_var) | 195 | return $ Left (word64mapT,map_var) |
195 | let dispatch tbl var handlers = DispatchMethods | 196 | let dispatch tbl var handlers = DispatchMethods |
196 | { classifyInbound = classify | 197 | { classifyInbound = classify |
@@ -236,12 +237,12 @@ getContactInfo Tox{toxCryptoKeys,toxRouting} = join $ atomically $ do | |||
236 | ns = filter (DHT.isGlobal . nodeIP) [n4,n6] | 237 | ns = filter (DHT.isGlobal . nodeIP) [n4,n6] |
237 | ++ concat (zipWith (\a b -> [a,b]) n4s n6s) | 238 | ++ concat (zipWith (\a b -> [a,b]) n4s n6s) |
238 | return $ do | 239 | return $ do |
239 | timestamp <- round . (* 1000000) <$> getPOSIXTime | 240 | timestamp <- round . (* 1000000) <$> getPOSIXTime |
240 | return DHT.DHTPublicKey | 241 | return DHT.DHTPublicKey |
241 | { dhtpkNonce = timestamp | 242 | { dhtpkNonce = timestamp |
242 | , dhtpk = id2key self | 243 | , dhtpk = id2key self |
243 | , dhtpkNodes = DHT.SendNodes $ take 4 ns | 244 | , dhtpkNodes = DHT.SendNodes $ take 4 ns |
244 | } | 245 | } |
245 | 246 | ||
246 | isLocalHost :: SockAddr -> Bool | 247 | isLocalHost :: SockAddr -> Bool |
247 | isLocalHost (SockAddrInet _ host32) = (fromBE32 host32 == 0x7f000001) | 248 | isLocalHost (SockAddrInet _ host32) = (fromBE32 host32 == 0x7f000001) |
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 |
diff --git a/src/Network/Tox/DHT/Transport.hs b/src/Network/Tox/DHT/Transport.hs index 5ebe8b15..79643fad 100644 --- a/src/Network/Tox/DHT/Transport.hs +++ b/src/Network/Tox/DHT/Transport.hs | |||
@@ -21,6 +21,7 @@ module Network.Tox.DHT.Transport | |||
21 | , NoSpam(..) | 21 | , NoSpam(..) |
22 | , verifyChecksum | 22 | , verifyChecksum |
23 | , CookieRequest(..) | 23 | , CookieRequest(..) |
24 | , CookieResponse(..) | ||
24 | , Cookie(..) | 25 | , Cookie(..) |
25 | , CookieData(..) | 26 | , CookieData(..) |
26 | , DHTRequest | 27 | , DHTRequest |
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs index 85cf095d..baadbbe8 100644 --- a/src/Network/Tox/Onion/Transport.hs +++ b/src/Network/Tox/Onion/Transport.hs | |||
@@ -681,8 +681,8 @@ decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO | |||
681 | decrypt crypto msg addr = do | 681 | decrypt crypto msg addr = do |
682 | (skey,pkey) <- selectKey crypto msg addr | 682 | (skey,pkey) <- selectKey crypto msg addr |
683 | return $ do | 683 | return $ do |
684 | msg <- sequenceMessage $ transcode (\n -> decryptMessage (skey,pkey) n . left (senderkey addr)) msg | 684 | msg <- sequenceMessage $ transcode (\n -> decryptMessage (skey,pkey) n . left (senderkey addr)) msg |
685 | Right (msg, addr) | 685 | Right (msg, addr) |
686 | 686 | ||
687 | senderkey :: OnionDestination r -> t -> (PublicKey, t) | 687 | senderkey :: OnionDestination r -> t -> (PublicKey, t) |
688 | senderkey addr e = (onionKey addr, e) | 688 | senderkey addr e = (onionKey addr, e) |