diff options
-rw-r--r-- | PingMachine.hs | 7 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Handlers.hs | 20 |
2 files changed, 22 insertions, 5 deletions
diff --git a/PingMachine.hs b/PingMachine.hs index b714d71e..5cd70f95 100644 --- a/PingMachine.hs +++ b/PingMachine.hs | |||
@@ -48,17 +48,18 @@ data PingMachine = PingMachine | |||
48 | -- 'pingFlag' is difficult to use properly because it is up to the caller to | 48 | -- 'pingFlag' is difficult to use properly because it is up to the caller to |
49 | -- remember that the ping is already in progress. | 49 | -- remember that the ping is already in progress. |
50 | forkPingMachine | 50 | forkPingMachine |
51 | :: PingInterval -- ^ Milliseconds of idle before a ping is considered necessary. | 51 | :: String |
52 | -> PingInterval -- ^ Milliseconds of idle before a ping is considered necessary. | ||
52 | -> TimeOut -- ^ Milliseconds after 'PingIdle' before we signal 'PingTimeOut'. | 53 | -> TimeOut -- ^ Milliseconds after 'PingIdle' before we signal 'PingTimeOut'. |
53 | -> IO PingMachine | 54 | -> IO PingMachine |
54 | forkPingMachine idle timeout = do | 55 | forkPingMachine label idle timeout = do |
55 | d <- interruptibleDelay | 56 | d <- interruptibleDelay |
56 | flag <- atomically $ newTVar False | 57 | flag <- atomically $ newTVar False |
57 | canceled <- atomically $ newTVar False | 58 | canceled <- atomically $ newTVar False |
58 | event <- atomically newEmptyTMVar | 59 | event <- atomically newEmptyTMVar |
59 | started <- atomically $ newEmptyTMVar | 60 | started <- atomically $ newEmptyTMVar |
60 | when (idle/=0) $ void . forkIO $ do | 61 | when (idle/=0) $ void . forkIO $ do |
61 | myThreadId >>= flip labelThread ("ping.watchdog") | 62 | myThreadId >>= flip labelThread ("Ping." ++ label) -- ("ping.watchdog") |
62 | (>>=) (atomically (readTMVar started)) $ flip when $ do | 63 | (>>=) (atomically (readTMVar started)) $ flip when $ do |
63 | fix $ \loop -> do | 64 | fix $ \loop -> do |
64 | atomically $ writeTVar flag False | 65 | atomically $ writeTVar flag False |
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs index 10a24e50..cbd820de 100644 --- a/src/Network/Tox/Crypto/Handlers.hs +++ b/src/Network/Tox/Crypto/Handlers.hs | |||
@@ -32,9 +32,11 @@ import System.FilePath | |||
32 | import System.IO.Temp | 32 | import System.IO.Temp |
33 | import System.Environment | 33 | import System.Environment |
34 | import System.Directory | 34 | import System.Directory |
35 | import System.Random -- for ping fuzz | ||
35 | import Control.Concurrent | 36 | import Control.Concurrent |
36 | import GHC.Conc (labelThread) | 37 | import GHC.Conc (labelThread) |
37 | import System.IO.Unsafe(unsafeDupablePerformIO {- unsafeIOToSTM -}) | 38 | import System.IO.Unsafe(unsafeDupablePerformIO {- unsafeIOToSTM -}) |
39 | import PingMachine | ||
38 | 40 | ||
39 | -- util, todo: move to another module | 41 | -- util, todo: move to another module |
40 | maybeToEither :: Maybe b -> Either String b | 42 | maybeToEither :: Maybe b -> Either String b |
@@ -101,6 +103,7 @@ data NetCryptoSession = NCrypto { ncState :: TVar NetCryptoSessionStatu | |||
101 | , ncPacketQueue :: PacketQueue CryptoData | 103 | , ncPacketQueue :: PacketQueue CryptoData |
102 | , ncBufferStart :: TVar Word32 | 104 | , ncBufferStart :: TVar Word32 |
103 | , ncDequeueThread :: Maybe ThreadId | 105 | , ncDequeueThread :: Maybe ThreadId |
106 | , ncPingMachine :: Maybe PingMachine | ||
104 | , ncOutgoingQueue :: PQ.PacketOutQueue (State,Nonce24,TVar MsgOutMap) CryptoMessage (CryptoPacket Encrypted) CryptoData | 107 | , ncOutgoingQueue :: PQ.PacketOutQueue (State,Nonce24,TVar MsgOutMap) CryptoMessage (CryptoPacket Encrypted) CryptoData |
105 | } | 108 | } |
106 | 109 | ||
@@ -350,8 +353,10 @@ freshCryptoSession sessions | |||
350 | , ncPacketQueue = pktq | 353 | , ncPacketQueue = pktq |
351 | , ncBufferStart = bufstart | 354 | , ncBufferStart = bufstart |
352 | , ncDequeueThread = Nothing -- error "you want the NetCrypto-Dequeue thread id, but is it started?" | 355 | , ncDequeueThread = Nothing -- error "you want the NetCrypto-Dequeue thread id, but is it started?" |
356 | , ncPingMachine = Nothing -- error "you want the NetCrypto-PingMachine, but is it started?" | ||
353 | , ncOutgoingQueue = pktoq | 357 | , ncOutgoingQueue = pktoq |
354 | } | 358 | } |
359 | -- launch dequeue thread | ||
355 | threadid <- forkIO $ do | 360 | threadid <- forkIO $ do |
356 | tid <- myThreadId | 361 | tid <- myThreadId |
357 | labelThread tid ("NetCryptoDequeue." ++ show (key2id remotePublicKey)) | 362 | labelThread tid ("NetCryptoDequeue." ++ show (key2id remotePublicKey)) |
@@ -359,7 +364,12 @@ freshCryptoSession sessions | |||
359 | cd <- atomically $ PQ.dequeue pktq | 364 | cd <- atomically $ PQ.dequeue pktq |
360 | _ <- runCryptoHook (netCryptoSession0 {ncDequeueThread=Just tid}) cd | 365 | _ <- runCryptoHook (netCryptoSession0 {ncDequeueThread=Just tid}) cd |
361 | loop | 366 | loop |
362 | let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid} | 367 | -- launch ping thread |
368 | fuzz <- randomRIO (0,2000) | ||
369 | pingMachine <- forkPingMachine ("NetCrypto." ++ show (key2id remotePublicKey)) (15000 + fuzz) 2000 | ||
370 | -- update session with thread ids | ||
371 | let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid, ncPingMachine=Just pingMachine} | ||
372 | -- add this session to the lookup maps | ||
363 | atomically $ do | 373 | atomically $ do |
364 | modifyTVar allsessions (Map.insert addr netCryptoSession) | 374 | modifyTVar allsessions (Map.insert addr netCryptoSession) |
365 | byKeyResult <- readTVar allsessionsByKey >>= return . Map.lookup remotePublicKey | 375 | byKeyResult <- readTVar allsessionsByKey >>= return . Map.lookup remotePublicKey |
@@ -459,7 +469,9 @@ cryptoNetHandler sessions addr (NetCrypto (CryptoPacket nonce16 encrypted)) = do | |||
459 | -- Handle Encrypted Message | 469 | -- Handle Encrypted Message |
460 | case Map.lookup addr sessionsmap of | 470 | case Map.lookup addr sessionsmap of |
461 | Nothing -> return Nothing -- drop packet, we have no session | 471 | Nothing -> return Nothing -- drop packet, we have no session |
462 | Just session@(NCrypto {ncIncomingTypeArray, ncState, ncPacketQueue, ncHooks,ncSessionSecret,ncTheirSessionPublic,ncTheirBaseNonce}) -> do | 472 | Just session@(NCrypto { ncIncomingTypeArray, ncState, ncPacketQueue, ncHooks, |
473 | ncSessionSecret, ncTheirSessionPublic, ncTheirBaseNonce, | ||
474 | ncPingMachine}) -> do | ||
463 | theirBaseNonce <- atomically $ readTVar ncTheirBaseNonce | 475 | theirBaseNonce <- atomically $ readTVar ncTheirBaseNonce |
464 | -- Try to decrypt message | 476 | -- Try to decrypt message |
465 | let diff :: Word16 | 477 | let diff :: Word16 |
@@ -488,6 +500,10 @@ cryptoNetHandler sessions addr (NetCrypto (CryptoPacket nonce16 encrypted)) = do | |||
488 | writeTVar ncTheirBaseNonce y | 500 | writeTVar ncTheirBaseNonce y |
489 | -- then set session confirmed, | 501 | -- then set session confirmed, |
490 | atomically $ writeTVar ncState Confirmed | 502 | atomically $ writeTVar ncState Confirmed |
503 | -- bump ping machine | ||
504 | case ncPingMachine of | ||
505 | Just pingMachine -> pingBump pingMachine | ||
506 | Nothing -> return () | ||
491 | msgTypes <- atomically $ readTVar ncIncomingTypeArray | 507 | msgTypes <- atomically $ readTVar ncIncomingTypeArray |
492 | let msgTyp = cd ^. messageType | 508 | let msgTyp = cd ^. messageType |
493 | msgTypMapped16 = msgTypes A.! fromEnum8 (msgID cm) | 509 | msgTypMapped16 = msgTypes A.! fromEnum8 (msgID cm) |