diff options
-rw-r--r-- | dht-client.cabal | 1 | ||||
-rw-r--r-- | examples/dhtd.hs | 30 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Handlers.hs | 24 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Transport.hs | 9 |
4 files changed, 45 insertions, 19 deletions
diff --git a/dht-client.cabal b/dht-client.cabal index a9e1f847..023f837e 100644 --- a/dht-client.cabal +++ b/dht-client.cabal | |||
@@ -249,6 +249,7 @@ executable dhtd | |||
249 | , unix | 249 | , unix |
250 | , containers | 250 | , containers |
251 | , stm | 251 | , stm |
252 | , stm-chans | ||
252 | , cereal | 253 | , cereal |
253 | , bencoding | 254 | , bencoding |
254 | , unordered-containers | 255 | , unordered-containers |
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index 89b747be..088e0c67 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -21,6 +21,7 @@ module Main where | |||
21 | import Control.Arrow | 21 | import Control.Arrow |
22 | import Control.Applicative | 22 | import Control.Applicative |
23 | import Control.Concurrent.STM | 23 | import Control.Concurrent.STM |
24 | import Control.Concurrent.STM.TMChan | ||
24 | import Control.Exception | 25 | import Control.Exception |
25 | import Control.Monad | 26 | import Control.Monad |
26 | import Control.Monad.IO.Class (liftIO) | 27 | import Control.Monad.IO.Class (liftIO) |
@@ -88,7 +89,7 @@ import qualified Network.Tox.DHT.Transport as Tox | |||
88 | import qualified Network.Tox.DHT.Handlers as Tox | 89 | import qualified Network.Tox.DHT.Handlers as Tox |
89 | import qualified Network.Tox.Onion.Transport as Tox | 90 | import qualified Network.Tox.Onion.Transport as Tox |
90 | import qualified Network.Tox.Onion.Handlers as Tox | 91 | import qualified Network.Tox.Onion.Handlers as Tox |
91 | import qualified Network.Tox.Crypto.Transport as Tox (CryptoMessage) | 92 | import qualified Network.Tox.Crypto.Transport as Tox (CryptoMessage(..),CryptoData(..), isOFFLINE, isKillPacket) |
92 | import qualified Network.Tox.Crypto.Handlers as Tox | 93 | import qualified Network.Tox.Crypto.Handlers as Tox |
93 | import Data.Typeable | 94 | import Data.Typeable |
94 | import Network.Tox.ContactInfo as Tox | 95 | import Network.Tox.ContactInfo as Tox |
@@ -1000,13 +1001,14 @@ noArgPing :: (x -> IO (Maybe r)) -> [String] -> x -> IO (Maybe r) | |||
1000 | noArgPing f [] x = f x | 1001 | noArgPing f [] x = f x |
1001 | noArgPing _ _ _ = return Nothing | 1002 | noArgPing _ _ _ = return Nothing |
1002 | 1003 | ||
1003 | newXmmpSource :: Tox.NetCryptoSession -> C.Source IO Tox.CryptoMessage | 1004 | -- todo: session parameter obsolete? |
1004 | newXmmpSource session = do | 1005 | newXmmpSource :: (IO (Maybe Tox.CryptoMessage)) -> Tox.NetCryptoSession -> C.Source IO Tox.CryptoMessage |
1005 | v <- liftIO $ Tox.receiveCrypto session | 1006 | newXmmpSource receiveCrypto session = do |
1007 | v <- liftIO receiveCrypto | ||
1006 | case v of | 1008 | case v of |
1007 | Nothing -> return () -- Nothing indicates EOF. | 1009 | Nothing -> return () -- Nothing indicates EOF. |
1008 | Just cryptomessage -> do C.yield cryptomessage | 1010 | Just cryptomessage -> do C.yield cryptomessage |
1009 | newXmmpSource session | 1011 | newXmmpSource receiveCrypto session |
1010 | 1012 | ||
1011 | newXmmpSink :: Tox.NetCryptoSession -> C.Sink (Flush Tox.CryptoMessage) IO () | 1013 | newXmmpSink :: Tox.NetCryptoSession -> C.Sink (Flush Tox.CryptoMessage) IO () |
1012 | newXmmpSink session@(Tox.NCrypto { ncOutgoingQueue, ncPacketQueue }) = C.awaitForever $ \flush_cyptomessage -> do | 1014 | newXmmpSink session@(Tox.NCrypto { ncOutgoingQueue, ncPacketQueue }) = C.awaitForever $ \flush_cyptomessage -> do |
@@ -1046,6 +1048,7 @@ toxman tox = ToxManager | |||
1046 | _ -> return () -- Remove contact. | 1048 | _ -> return () -- Remove contact. |
1047 | } | 1049 | } |
1048 | 1050 | ||
1051 | #ifdef XMPP | ||
1049 | 1052 | ||
1050 | announceToxXMPPClients :: TChan ((ConnectionKey,SockAddr), Tcp.ConnectionEvent XML.Event) | 1053 | announceToxXMPPClients :: TChan ((ConnectionKey,SockAddr), Tcp.ConnectionEvent XML.Event) |
1051 | -> SockAddr | 1054 | -> SockAddr |
@@ -1064,7 +1067,7 @@ announceToxXMPPClients echan laddr saddr pingflag tsrc tsnk | |||
1064 | xsrc = tsrc =$= toxToXmpp | 1067 | xsrc = tsrc =$= toxToXmpp |
1065 | xsnk = flushPassThrough xmppToTox =$= tsnk | 1068 | xsnk = flushPassThrough xmppToTox =$= tsnk |
1066 | 1069 | ||
1067 | 1070 | #endif | |
1068 | 1071 | ||
1069 | main :: IO () | 1072 | main :: IO () |
1070 | main = runResourceT $ liftBaseWith $ \resT -> do | 1073 | main = runResourceT $ liftBaseWith $ \resT -> do |
@@ -1379,11 +1382,24 @@ main = runResourceT $ liftBaseWith $ \resT -> do | |||
1379 | 1382 | ||
1380 | forM_ (take 1 taddrs) $ \addrTox -> do | 1383 | forM_ (take 1 taddrs) $ \addrTox -> do |
1381 | atomically $ Tox.addNewSessionHook netCryptoSessionsState $ \mbNoSpam netcrypto -> do | 1384 | atomically $ Tox.addNewSessionHook netCryptoSessionsState $ \mbNoSpam netcrypto -> do |
1385 | tmchan <- atomically newTMChan | ||
1382 | let Just pingMachine = Tox.ncPingMachine netcrypto | 1386 | let Just pingMachine = Tox.ncPingMachine netcrypto |
1383 | pingflag = readTVar (pingFlag pingMachine) | 1387 | pingflag = readTVar (pingFlag pingMachine) |
1384 | xmppSrc = newXmmpSource netcrypto | 1388 | receiveCrypto = atomically $ readTMChan tmchan |
1389 | handleIncoming typ session cd | any ($ typ) [Tox.isKillPacket, Tox.isOFFLINE] = atomically $ do | ||
1390 | closeTMChan tmchan | ||
1391 | Tox.forgetCrypto crypto netCryptoSessionsState netcrypto | ||
1392 | return Nothing | ||
1393 | handleIncoming mTyp session cd = do | ||
1394 | atomically $ writeTMChan tmchan (Tox.bufferData cd) | ||
1395 | return Nothing | ||
1396 | #ifdef XMPP | ||
1397 | xmppSrc = newXmmpSource receiveCrypto netcrypto | ||
1385 | xmppSink = newXmmpSink netcrypto | 1398 | xmppSink = newXmmpSink netcrypto |
1386 | announceToxXMPPClients (xmppEventChannel sv) addrTox (Tox.ncSockAddr netcrypto) pingflag xmppSrc xmppSink | 1399 | announceToxXMPPClients (xmppEventChannel sv) addrTox (Tox.ncSockAddr netcrypto) pingflag xmppSrc xmppSink |
1400 | #endif | ||
1401 | atomically $ writeTVar (Tox.ncUnrecognizedHook netcrypto) handleIncoming | ||
1402 | return Nothing | ||
1387 | 1403 | ||
1388 | let dhts = Map.union btdhts toxdhts | 1404 | let dhts = Map.union btdhts toxdhts |
1389 | 1405 | ||
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs index 4f53888b..50dd8c67 100644 --- a/src/Network/Tox/Crypto/Handlers.hs +++ b/src/Network/Tox/Crypto/Handlers.hs | |||
@@ -28,7 +28,6 @@ import qualified Data.Set as Set | |||
28 | import qualified Data.Array.Unboxed as A | 28 | import qualified Data.Array.Unboxed as A |
29 | import SensibleDir | 29 | import SensibleDir |
30 | import System.FilePath | 30 | import System.FilePath |
31 | import System.IO | ||
32 | import System.IO.Temp | 31 | import System.IO.Temp |
33 | import System.Environment | 32 | import System.Environment |
34 | import System.Directory | 33 | import System.Directory |
@@ -108,6 +107,7 @@ data NetCryptoSession = NCrypto | |||
108 | , ncView :: TVar SessionView | 107 | , ncView :: TVar SessionView |
109 | , ncPacketQueue :: PacketQueue CryptoData | 108 | , ncPacketQueue :: PacketQueue CryptoData |
110 | , ncBufferStart :: TVar Word32 | 109 | , ncBufferStart :: TVar Word32 |
110 | , ncDequeueThread :: Maybe ThreadId | ||
111 | , ncPingMachine :: Maybe PingMachine | 111 | , ncPingMachine :: Maybe PingMachine |
112 | , ncOutgoingQueue :: PQ.PacketOutQueue (State,Nonce24,TVar MsgOutMap) | 112 | , ncOutgoingQueue :: PQ.PacketOutQueue (State,Nonce24,TVar MsgOutMap) |
113 | CryptoMessage | 113 | CryptoMessage |
@@ -364,24 +364,23 @@ freshCryptoSession sessions | |||
364 | , ncView = ncView0 | 364 | , ncView = ncView0 |
365 | , ncPacketQueue = pktq | 365 | , ncPacketQueue = pktq |
366 | , ncBufferStart = bufstart | 366 | , ncBufferStart = bufstart |
367 | , ncDequeueThread = Nothing -- error "you want the NetCrypto-Dequeue thread id, but is it started?" | ||
367 | , ncPingMachine = Nothing -- error "you want the NetCrypto-PingMachine, but is it started?" | 368 | , ncPingMachine = Nothing -- error "you want the NetCrypto-PingMachine, but is it started?" |
368 | , ncOutgoingQueue = pktoq | 369 | , ncOutgoingQueue = pktoq |
369 | } | 370 | } |
370 | 371 | -- launch dequeue thread | |
371 | hooks <- atomically $ readTVar (announceNewSessionHooks sessions) | 372 | threadid <- forkIO $ do |
372 | 373 | tid <- myThreadId | |
373 | -- Dequeue thread: | 374 | labelThread tid ("NetCryptoDequeue." ++ show (key2id remotePublicKey)) |
374 | -- | 375 | fix $ \loop -> do |
375 | -- Hopefully, somebody will launch a thread to repeatedly call | 376 | cd <- atomically $ PQ.dequeue pktq |
376 | -- 'receiveCrypto' in order to dequeue messages from ncPacketQueue. | 377 | _ <- runCryptoHook (netCryptoSession0 {ncDequeueThread=Just tid}) cd |
377 | when (null hooks) $ do | 378 | loop |
378 | hPutStrLn stderr "Warning: Missing new-session handler. Lost session!" | ||
379 | |||
380 | -- launch ping thread | 379 | -- launch ping thread |
381 | fuzz <- randomRIO (0,2000) | 380 | fuzz <- randomRIO (0,2000) |
382 | pingMachine <- forkPingMachine ("NetCrypto." ++ show (key2id remotePublicKey)) (15000 + fuzz) 2000 | 381 | pingMachine <- forkPingMachine ("NetCrypto." ++ show (key2id remotePublicKey)) (15000 + fuzz) 2000 |
383 | -- update session with thread ids | 382 | -- update session with thread ids |
384 | let netCryptoSession = netCryptoSession0 {ncPingMachine=Just pingMachine} | 383 | let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid, ncPingMachine=Just pingMachine} |
385 | -- add this session to the lookup maps | 384 | -- add this session to the lookup maps |
386 | atomically $ do | 385 | atomically $ do |
387 | modifyTVar allsessions (Map.insert addr netCryptoSession) | 386 | modifyTVar allsessions (Map.insert addr netCryptoSession) |
@@ -390,6 +389,7 @@ freshCryptoSession sessions | |||
390 | Nothing -> modifyTVar allsessionsByKey (Map.insert remotePublicKey [netCryptoSession]) | 389 | Nothing -> modifyTVar allsessionsByKey (Map.insert remotePublicKey [netCryptoSession]) |
391 | Just xs -> modifyTVar allsessionsByKey (Map.insert remotePublicKey (netCryptoSession:xs)) | 390 | Just xs -> modifyTVar allsessionsByKey (Map.insert remotePublicKey (netCryptoSession:xs)) |
392 | -- run announceNewSessionHooks | 391 | -- run announceNewSessionHooks |
392 | hooks <- atomically $ readTVar (announceNewSessionHooks sessions) | ||
393 | flip fix (hooks,netCryptoSession) $ \loop (hooks,session) -> | 393 | flip fix (hooks,netCryptoSession) $ \loop (hooks,session) -> |
394 | case hooks of | 394 | case hooks of |
395 | [] -> return () | 395 | [] -> return () |
diff --git a/src/Network/Tox/Crypto/Transport.hs b/src/Network/Tox/Crypto/Transport.hs index 3133ee9b..70405a3e 100644 --- a/src/Network/Tox/Crypto/Transport.hs +++ b/src/Network/Tox/Crypto/Transport.hs | |||
@@ -21,6 +21,7 @@ module Network.Tox.Crypto.Transport | |||
21 | , TypingStatus(..) | 21 | , TypingStatus(..) |
22 | , GroupChatId(..) | 22 | , GroupChatId(..) |
23 | , MessageType(..) | 23 | , MessageType(..) |
24 | , isKillPacket, isOFFLINE | ||
24 | , KnownLossyness(..) | 25 | , KnownLossyness(..) |
25 | , AsWord16(..) | 26 | , AsWord16(..) |
26 | , AsWord64(..) | 27 | , AsWord64(..) |
@@ -694,6 +695,14 @@ lossyness (fromEnum -> x) | x >= 192, x < 255 = Lossy | |||
694 | lossyness (fromEnum -> 255) = Lossless | 695 | lossyness (fromEnum -> 255) = Lossless |
695 | lossyness _ = UnknownLossyness | 696 | lossyness _ = UnknownLossyness |
696 | 697 | ||
698 | isKillPacket :: MessageType -> Bool | ||
699 | isKillPacket (Msg KillPacket) = True | ||
700 | isKillPacket _ = False | ||
701 | |||
702 | isOFFLINE :: MessageType -> Bool | ||
703 | isOFFLINE (Msg OFFLINE) = True | ||
704 | isOFFLINE _ = False | ||
705 | |||
697 | -- TODO: Flesh this out. | 706 | -- TODO: Flesh this out. |
698 | data MessageID -- First byte indicates data | 707 | data MessageID -- First byte indicates data |
699 | = Padding -- ^ 0 padding (skipped until we hit a non zero (data id) byte) | 708 | = Padding -- ^ 0 padding (skipped until we hit a non zero (data id) byte) |