summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dht-client.cabal1
-rw-r--r--examples/dhtd.hs30
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs24
-rw-r--r--src/Network/Tox/Crypto/Transport.hs9
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
21import Control.Arrow 21import Control.Arrow
22import Control.Applicative 22import Control.Applicative
23import Control.Concurrent.STM 23import Control.Concurrent.STM
24import Control.Concurrent.STM.TMChan
24import Control.Exception 25import Control.Exception
25import Control.Monad 26import Control.Monad
26import Control.Monad.IO.Class (liftIO) 27import Control.Monad.IO.Class (liftIO)
@@ -88,7 +89,7 @@ import qualified Network.Tox.DHT.Transport as Tox
88import qualified Network.Tox.DHT.Handlers as Tox 89import qualified Network.Tox.DHT.Handlers as Tox
89import qualified Network.Tox.Onion.Transport as Tox 90import qualified Network.Tox.Onion.Transport as Tox
90import qualified Network.Tox.Onion.Handlers as Tox 91import qualified Network.Tox.Onion.Handlers as Tox
91import qualified Network.Tox.Crypto.Transport as Tox (CryptoMessage) 92import qualified Network.Tox.Crypto.Transport as Tox (CryptoMessage(..),CryptoData(..), isOFFLINE, isKillPacket)
92import qualified Network.Tox.Crypto.Handlers as Tox 93import qualified Network.Tox.Crypto.Handlers as Tox
93import Data.Typeable 94import Data.Typeable
94import Network.Tox.ContactInfo as Tox 95import Network.Tox.ContactInfo as Tox
@@ -1000,13 +1001,14 @@ noArgPing :: (x -> IO (Maybe r)) -> [String] -> x -> IO (Maybe r)
1000noArgPing f [] x = f x 1001noArgPing f [] x = f x
1001noArgPing _ _ _ = return Nothing 1002noArgPing _ _ _ = return Nothing
1002 1003
1003newXmmpSource :: Tox.NetCryptoSession -> C.Source IO Tox.CryptoMessage 1004-- todo: session parameter obsolete?
1004newXmmpSource session = do 1005newXmmpSource :: (IO (Maybe Tox.CryptoMessage)) -> Tox.NetCryptoSession -> C.Source IO Tox.CryptoMessage
1005 v <- liftIO $ Tox.receiveCrypto session 1006newXmmpSource 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
1011newXmmpSink :: Tox.NetCryptoSession -> C.Sink (Flush Tox.CryptoMessage) IO () 1013newXmmpSink :: Tox.NetCryptoSession -> C.Sink (Flush Tox.CryptoMessage) IO ()
1012newXmmpSink session@(Tox.NCrypto { ncOutgoingQueue, ncPacketQueue }) = C.awaitForever $ \flush_cyptomessage -> do 1014newXmmpSink 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
1050announceToxXMPPClients :: TChan ((ConnectionKey,SockAddr), Tcp.ConnectionEvent XML.Event) 1053announceToxXMPPClients :: 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
1069main :: IO () 1072main :: IO ()
1070main = runResourceT $ liftBaseWith $ \resT -> do 1073main = 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
28import qualified Data.Array.Unboxed as A 28import qualified Data.Array.Unboxed as A
29import SensibleDir 29import SensibleDir
30import System.FilePath 30import System.FilePath
31import System.IO
32import System.IO.Temp 31import System.IO.Temp
33import System.Environment 32import System.Environment
34import System.Directory 33import 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
694lossyness (fromEnum -> 255) = Lossless 695lossyness (fromEnum -> 255) = Lossless
695lossyness _ = UnknownLossyness 696lossyness _ = UnknownLossyness
696 697
698isKillPacket :: MessageType -> Bool
699isKillPacket (Msg KillPacket) = True
700isKillPacket _ = False
701
702isOFFLINE :: MessageType -> Bool
703isOFFLINE (Msg OFFLINE) = True
704isOFFLINE _ = False
705
697-- TODO: Flesh this out. 706-- TODO: Flesh this out.
698data MessageID -- First byte indicates data 707data 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)