summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Crayne <jim.crayne@gmail.com>2018-06-14 06:18:04 +0000
committerJames Crayne <jim.crayne@gmail.com>2018-06-16 02:27:52 +0000
commitbc5a84c34ba400f3d319387f34a7259923ca64e6 (patch)
tree5dc429f3417d46a431c5d1f846edf854b79c2caa
parentb384cd2e1a806c882359d0cf619e6cce04784d58 (diff)
Experimental Connection.Tox integration
-rw-r--r--Connection/Tox.hs18
-rw-r--r--src/Network/Tox.hs20
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs22
3 files changed, 42 insertions, 18 deletions
diff --git a/Connection/Tox.hs b/Connection/Tox.hs
index 5a9dc5eb..08a930bf 100644
--- a/Connection/Tox.hs
+++ b/Connection/Tox.hs
@@ -13,9 +13,9 @@ import Control.Monad
13import Data.Functor.Identity 13import Data.Functor.Identity
14import qualified Data.Map as Map 14import qualified Data.Map as Map
15import Connection.Tox.Threads 15import Connection.Tox.Threads
16import Network.Tox
17import Network.Tox.NodeId 16import Network.Tox.NodeId
18import Network.Tox.DHT.Handlers 17import Network.Tox.DHT.Handlers
18import Network.Tox.Crypto.Handlers
19import PingMachine 19import PingMachine
20import Text.Read 20import Text.Read
21#ifdef THREAD_DEBUG 21#ifdef THREAD_DEBUG
@@ -31,16 +31,12 @@ import GHC.Conc (threadStatus,ThreadStatus(..))
31 31
32data Parameters = Parameters 32data Parameters = Parameters
33 { -- | Various Tox transports and clients. 33 { -- | Various Tox transports and clients.
34 toxTransports :: Tox 34 dhtRouting :: Routing
35 -- | Thread to be forked when a connection is established. 35 -- | Thread to be forked when a connection is established.
36 -- TODO: this function should accept relevant parameters. 36 -- TODO: this function should accept relevant parameters.
37 , onToxSession :: IO () 37 , onToxSession :: IO ()
38 } 38 }
39 39
40data Key = Key NodeId{-me-} NodeId{-them-}
41 deriving (Eq,Ord)
42
43instance Show Key where show = show . showKey_
44 40
45{- 41{-
46-- | A conneciton status that is tagged with a state type that is specific to 42-- | A conneciton status that is tagged with a state type that is specific to
@@ -165,7 +161,7 @@ setToxPolicy params conmap k policy = case policy of
165 $ freshenContact getPolicy _get_status freshen_methods 161 $ freshenContact getPolicy _get_status freshen_methods
166 atomically $ do 162 atomically $ do
167 writeTVar (sessionTasks st) $ SessionTasks accepting persuing refreshing 163 writeTVar (sessionTasks st) $ SessionTasks accepting persuing refreshing
168 let routing = toxRouting $ toxTransports params 164 let routing = dhtRouting params
169 Key _ nid = k 165 Key _ nid = k
170 registerNodeCallback routing $ NodeInfoCallback 166 registerNodeCallback routing $ NodeInfoCallback
171 { interestingNodeId = nid 167 { interestingNodeId = nid
@@ -182,7 +178,7 @@ setToxPolicy params conmap k policy = case policy of
182 -- Here we block until they finish. 178 -- Here we block until they finish.
183 forM_ mst $ \st -> do 179 forM_ mst $ \st -> do
184 atomically $ do 180 atomically $ do
185 let routing = toxRouting $ toxTransports params 181 let routing = dhtRouting params
186 Key _ nid = k 182 Key _ nid = k
187 unregisterNodeCallback callbackId routing nid 183 unregisterNodeCallback callbackId routing nid
188 atomically $ do 184 atomically $ do
@@ -201,7 +197,7 @@ setToxPolicy params conmap k policy = case policy of
201 (G.InProgress $ toEnum 0) 197 (G.InProgress $ toEnum 0)
202 $ acceptContact getPolicy _accept_methods 198 $ acceptContact getPolicy _accept_methods
203 atomically $ do 199 atomically $ do
204 let routing = toxRouting $ toxTransports params 200 let routing = dhtRouting params
205 Key _ nid = k 201 Key _ nid = k
206 registerNodeCallback routing $ NodeInfoCallback 202 registerNodeCallback routing $ NodeInfoCallback
207 { interestingNodeId = nid 203 { interestingNodeId = nid
@@ -210,10 +206,6 @@ setToxPolicy params conmap k policy = case policy of
210 , rumoredAddress = \saddr ni -> return () -- TODO 206 , rumoredAddress = \saddr ni -> return () -- TODO
211 } 207 }
212 208
213
214showKey_ :: Key -> String
215showKey_ (Key me them) = show me ++ ":" ++ show them
216
217stringToKey_ :: String -> Maybe Key 209stringToKey_ :: String -> Maybe Key
218stringToKey_ s = let (xs,ys) = break (==':') s 210stringToKey_ s = let (xs,ys) = break (==':') s
219 in if null ys then Nothing 211 in if null ys then Nothing
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 41deff42..3324c934 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -98,6 +98,7 @@ import Network.BitTorrent.DHT.Token as Token
98import GHC.TypeLits 98import GHC.TypeLits
99 99
100import Connection 100import Connection
101import Connection.Tox
101import Crypto.Tox 102import Crypto.Tox
102import Data.Word64Map (fitsInInt) 103import Data.Word64Map (fitsInInt)
103import qualified Data.Word64Map (empty) 104import qualified Data.Word64Map (empty)
@@ -254,6 +255,7 @@ data Tox = Tox
254 , toxOnionRoutes :: OnionRouter 255 , toxOnionRoutes :: OnionRouter
255 , toxContactInfo :: ContactInfo 256 , toxContactInfo :: ContactInfo
256 , toxAnnounceToLan :: IO () 257 , toxAnnounceToLan :: IO ()
258 , toxMgr :: Manager ToxProgress Key
257 } 259 }
258 260
259-- | initiate a netcrypto session, blocking 261-- | initiate a netcrypto session, blocking
@@ -440,14 +442,26 @@ newTox keydb addr mbSessionsState suppliedDHTKey = do
440 orouter <- newOnionRouter ignoreErrors 442 orouter <- newOnionRouter ignoreErrors
441 (cryptonet,dhtcrypt,onioncrypt,dtacrypt,handshakes) <- toxTransport crypto orouter lookupClose udp 443 (cryptonet,dhtcrypt,onioncrypt,dtacrypt,handshakes) <- toxTransport crypto orouter lookupClose udp
442 444
443 let sessionsState = sessionsState0 { sendHandshake = sendMessage handshakes
444 , sendSessionPacket = sendMessage cryptonet
445 , transportCrypto = crypto }
446 let dhtnet0 = layerTransportM (DHT.decrypt crypto) (DHT.encrypt crypto) dhtcrypt 445 let dhtnet0 = layerTransportM (DHT.decrypt crypto) (DHT.encrypt crypto) dhtcrypt
447 tbl4 = DHT.routing4 $ mkrouting (error "missing client") 446 tbl4 = DHT.routing4 $ mkrouting (error "missing client")
448 tbl6 = DHT.routing6 $ mkrouting (error "missing client") 447 tbl6 = DHT.routing6 $ mkrouting (error "missing client")
449 dhtclient <- newClient drg dhtnet0 DHT.classify (myAddr tbl4 tbl6) (DHT.handlers crypto . mkrouting) id 448 dhtclient <- newClient drg dhtnet0 DHT.classify (myAddr tbl4 tbl6) (DHT.handlers crypto . mkrouting) id
450 $ \client net -> onInbound (DHT.updateRouting client (mkrouting client) orouter) net 449 $ \client net -> onInbound (DHT.updateRouting client (mkrouting client) orouter) net
450 mgr <- toxManager (Parameters { dhtRouting = mkrouting dhtclient
451 , onToxSession = return () -- TODO
452 })
453
454 let policylookup key = do
455 mp <- connections mgr
456 case Map.lookup key mp of
457 Nothing -> return OpenToConnect
458 Just conn -> Connection.connPolicy conn
459
460 let sessionsState = sessionsState0 { sendHandshake = sendMessage handshakes
461 , sendSessionPacket = sendMessage cryptonet
462 , transportCrypto = crypto
463 , netCryptoPolicyByKey = policylookup
464 }
451 465
452 orouter' <- forkRouteBuilder orouter 466 orouter' <- forkRouteBuilder orouter
453 $ \nid ni -> fmap (\(_,ns,_)->ns) 467 $ \nid ni -> fmap (\(_,ns,_)->ns)
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index 20560a48..61b2ab3c 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -55,9 +55,18 @@ import DPut
55import Debug.Trace 55import Debug.Trace
56import Text.Printf 56import Text.Printf
57import Data.Bool 57import Data.Bool
58import Connection (Status(..)) 58import Connection (Status(..), Policy(..))
59import Connection.Tox.Threads (ToxProgress(..)) 59import Connection.Tox.Threads (ToxProgress(..))
60 60
61type LookupPolicyFunction = Key -> STM Policy
62
63data Key = Key NodeId{-me-} NodeId{-them-}
64 deriving (Eq,Ord)
65
66instance Show Key where show = show . showKey_
67
68showKey_ :: Key -> String
69showKey_ (Key me them) = show me ++ ":" ++ show them
61 70
62-- * These types are isomorphic to Maybe, but have the advantage of documenting 71-- * These types are isomorphic to Maybe, but have the advantage of documenting
63-- when an item is expected to become known. 72-- when an item is expected to become known.
@@ -296,6 +305,7 @@ data NetCryptoSession = NCrypto
296data NetCryptoSessions = NCSessions 305data NetCryptoSessions = NCSessions
297 { netCryptoSessions :: TVar (Map.Map SockAddr NetCryptoSession) 306 { netCryptoSessions :: TVar (Map.Map SockAddr NetCryptoSession)
298 , netCryptoSessionsByKey :: TVar (Map.Map PublicKey [NetCryptoSession]) 307 , netCryptoSessionsByKey :: TVar (Map.Map PublicKey [NetCryptoSession])
308 , netCryptoPolicyByKey :: LookupPolicyFunction
299 , transportCrypto :: TransportCrypto 309 , transportCrypto :: TransportCrypto
300 , defaultHooks :: Map.Map MessageType [NetCryptoHook] 310 , defaultHooks :: Map.Map MessageType [NetCryptoHook]
301 , defaultUnrecognizedHook :: MessageType -> NetCryptoHook 311 , defaultUnrecognizedHook :: MessageType -> NetCryptoHook
@@ -361,6 +371,7 @@ newSessionsState crypto unrechook hooks = do
361 lsupplyVar <- atomically (newTVar lsupply) 371 lsupplyVar <- atomically (newTVar lsupply)
362 return NCSessions { netCryptoSessions = x 372 return NCSessions { netCryptoSessions = x
363 , netCryptoSessionsByKey = x2 373 , netCryptoSessionsByKey = x2
374 , netCryptoPolicyByKey = \_ -> return OpenToConnect
364 , transportCrypto = crypto 375 , transportCrypto = crypto
365 , defaultHooks = hooks 376 , defaultHooks = hooks
366 , defaultUnrecognizedHook = unrechook 377 , defaultUnrecognizedHook = unrechook
@@ -872,7 +883,14 @@ handshakeH sessions addrRaw hshake@(Handshake (Cookie n24 ecookie) nonce24 encry
872 case Map.lookup addr sessionsmap of 883 case Map.lookup addr sessionsmap of
873 Nothing -> do 884 Nothing -> do
874 dmsg $ "sockaddr(" ++ show addr ++ ") not in session map(" ++ show (map (second ncSessionId) (Map.assocs sessionsmap)) ++ "), so freshCryptoSession" 885 dmsg $ "sockaddr(" ++ show addr ++ ") not in session map(" ++ show (map (second ncSessionId) (Map.assocs sessionsmap)) ++ "), so freshCryptoSession"
875 freshCryptoSession sessions addr newsession timestamp hp -- create new session 886 let k = Key (key2id . toPublic $ key) (key2id remotePublicKey)
887 policy <- netCryptoPolicyByKey sessions k
888 case policy of
889 x | x `elem` [OpenToConnect,TryingToConnect] ->
890 freshCryptoSession sessions addr newsession timestamp hp -- create new session
891 x -> do
892 dmsg $ "Ignoring Handshake from " ++ show (key2id remotePublicKey) ++ " due to policy: " ++ show x
893 return (Nothing,return ())
876 Just session -> do 894 Just session -> do
877 dmsg "sockaddr ALREADY in session map, so updateCryptoSession" 895 dmsg "sockaddr ALREADY in session map, so updateCryptoSession"
878 updateCryptoSession sessions addr (ncSessionSecret session) timestamp hp session hshake -- update existing session 896 updateCryptoSession sessions addr (ncSessionSecret session) timestamp hp session hshake -- update existing session