diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Data/Word64RangeMap.hs | 7 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Handlers.hs | 46 |
2 files changed, 32 insertions, 21 deletions
diff --git a/src/Data/Word64RangeMap.hs b/src/Data/Word64RangeMap.hs index b5cbe9d1..c754c226 100644 --- a/src/Data/Word64RangeMap.hs +++ b/src/Data/Word64RangeMap.hs | |||
@@ -15,6 +15,8 @@ import Data.Array.MArray (MArray(..)) | |||
15 | import qualified Data.Array.Base as Base | 15 | import qualified Data.Array.Base as Base |
16 | import Data.Reference | 16 | import Data.Reference |
17 | import Debug.Trace | 17 | import Debug.Trace |
18 | import Control.Concurrent.STM | ||
19 | import Control.Concurrent.STM.TArray | ||
18 | import Data.Array.IO | 20 | import Data.Array.IO |
19 | import Data.IORef | 21 | import Data.IORef |
20 | 22 | ||
@@ -58,6 +60,11 @@ instance (Reference r m, MArray ma e m) => MArray (RefArray r ma) e m where | |||
58 | unsafeWrite (RefArray r) i e = modifyRef r (\x -> Base.unsafeWrite x i e >> return (x,())) | 60 | unsafeWrite (RefArray r) i e = modifyRef r (\x -> Base.unsafeWrite x i e >> return (x,())) |
59 | -} | 61 | -} |
60 | 62 | ||
63 | emptySTMRangeMap :: STM (RangeMap TArray Word8 TVar) | ||
64 | emptySTMRangeMap = RefArray <$> | ||
65 | (newTVar =<< | ||
66 | newListArray (0,-1) []) | ||
67 | |||
61 | -- | a sample RangeMap for easier debugging | 68 | -- | a sample RangeMap for easier debugging |
62 | getX :: IO (RangeMap IOArray Word8 IORef) | 69 | getX :: IO (RangeMap IOArray Word8 IORef) |
63 | getX = RefArray <$> | 70 | getX = RefArray <$> |
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs index 59e78213..f4b79272 100644 --- a/src/Network/Tox/Crypto/Handlers.hs +++ b/src/Network/Tox/Crypto/Handlers.hs | |||
@@ -25,6 +25,7 @@ import qualified Data.PacketQueue as PQ | |||
25 | import Data.Serialize as S | 25 | import Data.Serialize as S |
26 | import Data.Word | 26 | import Data.Word |
27 | import qualified Data.Word64Map as W64 | 27 | import qualified Data.Word64Map as W64 |
28 | import Data.Word64RangeMap | ||
28 | import qualified Data.Set as Set | 29 | import qualified Data.Set as Set |
29 | import qualified Data.Array.Unboxed as A | 30 | import qualified Data.Array.Unboxed as A |
30 | import SensibleDir | 31 | import SensibleDir |
@@ -48,12 +49,12 @@ data NetCryptoSessionStatus = Unaccepted | Accepted | Confirmed | |||
48 | 49 | ||
49 | type IOHook addr x = addr -> x -> IO (Maybe (x -> x)) | 50 | type IOHook addr x = addr -> x -> IO (Maybe (x -> x)) |
50 | type NetCryptoHook = IOHook NetCryptoSession CryptoData | 51 | type NetCryptoHook = IOHook NetCryptoSession CryptoData |
51 | type MsgTypeArray = A.UArray Word8 Word16 | 52 | type MsgTypeArray = A.UArray Word8 Word64 |
52 | type MsgOutMap = W64.Word64Map Word8 | 53 | -- type MsgOutMap = RangeMap STArray Word8 STRef |
54 | -- type MsgOutMap = W64.Word64Map Word8 | ||
53 | -- type MsgOutMap = A.UArray Word64 Word8 -- if above is too slow, switch to this, but use reasonable bounds | 55 | -- type MsgOutMap = A.UArray Word64 Word8 -- if above is too slow, switch to this, but use reasonable bounds |
54 | 56 | -- msgOutMapLookup :: Word64 -> MsgOutMap -> STM (Maybe Word8) | |
55 | msgOutMapLookup :: Word64 -> MsgOutMap -> Maybe Word8 | 57 | -- msgOutMapLookup k mp = return (W64.lookup k mp) |
56 | msgOutMapLookup = W64.lookup | ||
57 | 58 | ||
58 | -- | Information, that may be made visible in multiple sessions, as well | 59 | -- | Information, that may be made visible in multiple sessions, as well |
59 | -- as displayed in some way to the user via mutiple views. | 60 | -- as displayed in some way to the user via mutiple views. |
@@ -101,7 +102,7 @@ data NetCryptoSession = NCrypto | |||
101 | -- may not be in ncHooks yet, but they should appear | 102 | -- may not be in ncHooks yet, but they should appear |
102 | -- here if ncUnrecognizedHook will add them to ncHooks | 103 | -- here if ncUnrecognizedHook will add them to ncHooks |
103 | -- on an as-need basis. | 104 | -- on an as-need basis. |
104 | , ncOutgoingIdMap :: TVar MsgOutMap | 105 | , ncOutgoingIdMap :: RangeMap TArray Word8 TVar |
105 | , ncAllSessions :: NetCryptoSessions -- ^ may be needed if one net-crypto session | 106 | , ncAllSessions :: NetCryptoSessions -- ^ may be needed if one net-crypto session |
106 | -- needs to possibly start another, as is | 107 | -- needs to possibly start another, as is |
107 | -- the case in group chats | 108 | -- the case in group chats |
@@ -110,7 +111,7 @@ data NetCryptoSession = NCrypto | |||
110 | , ncBufferStart :: TVar Word32 | 111 | , ncBufferStart :: TVar Word32 |
111 | , ncDequeueThread :: Maybe ThreadId | 112 | , ncDequeueThread :: Maybe ThreadId |
112 | , ncPingMachine :: Maybe PingMachine | 113 | , ncPingMachine :: Maybe PingMachine |
113 | , ncOutgoingQueue :: PQ.PacketOutQueue (State,Nonce24,TVar MsgOutMap) | 114 | , ncOutgoingQueue :: PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 TVar) |
114 | CryptoMessage | 115 | CryptoMessage |
115 | (CryptoPacket Encrypted) | 116 | (CryptoPacket Encrypted) |
116 | CryptoData | 117 | CryptoData |
@@ -187,7 +188,7 @@ newSessionsState crypto unrechook hooks = do | |||
187 | , svConfigDir = configdir | 188 | , svConfigDir = configdir |
188 | , svDownloadDir = svDownloadDir0 | 189 | , svDownloadDir = svDownloadDir0 |
189 | } | 190 | } |
190 | , msgTypeArray = allMsgTypes -- todo make this a parameter | 191 | , msgTypeArray = allMsgTypes id -- todo make this a parameter |
191 | , inboundQueueCapacity = 200 | 192 | , inboundQueueCapacity = 200 |
192 | , outboundQueueCapacity = 400 | 193 | , outboundQueueCapacity = 400 |
193 | , nextSessionId = nextSessionId0 | 194 | , nextSessionId = nextSessionId0 |
@@ -235,7 +236,7 @@ newHandShakeData crypto basenonce (HParam {hpOtherCookie,hpMySecretKey,hpCookieR | |||
235 | 236 | ||
236 | type XMessage = CryptoMessage -- todo | 237 | type XMessage = CryptoMessage -- todo |
237 | 238 | ||
238 | ncToWire :: STM (State,Nonce24,TVar MsgOutMap) | 239 | ncToWire :: STM (State,Nonce24,RangeMap TArray Word8 TVar) |
239 | -> Word32{- packet number we expect to recieve -} | 240 | -> Word32{- packet number we expect to recieve -} |
240 | -> Word32{- buffer_end -} | 241 | -> Word32{- buffer_end -} |
241 | -> Word32{- packet number -} | 242 | -> Word32{- packet number -} |
@@ -250,8 +251,9 @@ ncToWire getState seqno bufend pktno msg = do | |||
250 | GrpMsg KnownLossy _ -> Lossy | 251 | GrpMsg KnownLossy _ -> Lossy |
251 | GrpMsg KnownLossless _ -> Lossless | 252 | GrpMsg KnownLossless _ -> Lossless |
252 | (state,n24,msgOutMapVar) <- getState | 253 | (state,n24,msgOutMapVar) <- getState |
253 | msgOutMap <- readTVar msgOutMapVar | 254 | -- msgOutMap <- readTVar msgOutMapVar |
254 | case msgOutMapLookup typ64 msgOutMap of | 255 | result1 <- lookupInRangeMap typ64 msgOutMapVar |
256 | case result1 of -- msgOutMapLookup typ64 msgOutMap of | ||
255 | Just outid -> do | 257 | Just outid -> do |
256 | let setMessageId (OneByte _) mid = OneByte (toEnum8 mid) | 258 | let setMessageId (OneByte _) mid = OneByte (toEnum8 mid) |
257 | setMessageId (TwoByte _ x) mid = TwoByte (toEnum8 mid) x | 259 | setMessageId (TwoByte _ x) mid = TwoByte (toEnum8 mid) x |
@@ -323,7 +325,7 @@ freshCryptoSession sessions | |||
323 | ncUnrecognizedHook0 <- atomically $ newTVar (defaultUnrecognizedHook sessions) | 325 | ncUnrecognizedHook0 <- atomically $ newTVar (defaultUnrecognizedHook sessions) |
324 | ncIncomingTypeArray0 <- atomically $ newTVar (msgTypeArray sessions) | 326 | ncIncomingTypeArray0 <- atomically $ newTVar (msgTypeArray sessions) |
325 | let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255]) | 327 | let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255]) |
326 | ncOutgoingIdMap0 <- atomically $ newTVar idMap | 328 | ncOutgoingIdMap0 <- atomically $ emptySTMRangeMap -- atomically $ newTVar idMap |
327 | ncView0 <- atomically $ newTVar (sessionView sessions) | 329 | ncView0 <- atomically $ newTVar (sessionView sessions) |
328 | pktq <- atomically $ PQ.new (inboundQueueCapacity sessions) 0 | 330 | pktq <- atomically $ PQ.new (inboundQueueCapacity sessions) 0 |
329 | bufstart <- atomically $ newTVar 0 | 331 | bufstart <- atomically $ newTVar 0 |
@@ -516,8 +518,8 @@ cryptoNetHandler sessions addr (NetCrypto (CryptoPacket nonce16 encrypted)) = do | |||
516 | Nothing -> return () | 518 | Nothing -> return () |
517 | msgTypes <- atomically $ readTVar ncIncomingTypeArray | 519 | msgTypes <- atomically $ readTVar ncIncomingTypeArray |
518 | let msgTyp = cd ^. messageType | 520 | let msgTyp = cd ^. messageType |
519 | msgTypMapped16 = msgTypes A.! fromEnum8 (msgID cm) | 521 | msgTypMapped64 = msgTypes A.! fromEnum8 (msgID cm) |
520 | msgTypMapped = fromWord16 $ msgTypMapped16 | 522 | msgTypMapped = fromWord64 $ msgTypMapped64 |
521 | isLossy (GrpMsg KnownLossy _) = True | 523 | isLossy (GrpMsg KnownLossy _) = True |
522 | isLossy (Msg mid) | lossyness mid == Lossy = True | 524 | isLossy (Msg mid) | lossyness mid == Lossy = True |
523 | isLossy _ = False | 525 | isLossy _ = False |
@@ -542,9 +544,9 @@ runCryptoHook session@(NCrypto {ncState, ncHooks,ncSessionSecret,ncTheirSessionP | |||
542 | flip fix (cd,hookmap) $ \lookupAgain (cd,hookmap) -> do | 544 | flip fix (cd,hookmap) $ \lookupAgain (cd,hookmap) -> do |
543 | msgTypes <- atomically $ readTVar ncIncomingTypeArray | 545 | msgTypes <- atomically $ readTVar ncIncomingTypeArray |
544 | let msgTyp = cd ^. messageType | 546 | let msgTyp = cd ^. messageType |
545 | msgTypMapped16 = msgTypes A.! fromEnum8 (msgID cm) | 547 | msgTypMapped64 = msgTypes A.! fromEnum8 (msgID cm) |
546 | msgTypMapped = fromWord16 $ msgTypMapped16 | 548 | msgTypMapped = fromWord64 $ msgTypMapped64 |
547 | if msgTypMapped16 == 0 | 549 | if msgTypMapped64 == 0 |
548 | then return Nothing | 550 | then return Nothing |
549 | else | 551 | else |
550 | case Map.lookup msgTypMapped hookmap of | 552 | case Map.lookup msgTypMapped hookmap of |
@@ -574,17 +576,19 @@ runCryptoHook session@(NCrypto {ncState, ncHooks,ncSessionSecret,ncTheirSessionP | |||
574 | -- in the MessageId space if they have such a thing. | 576 | -- in the MessageId space if they have such a thing. |
575 | mkMsgTypes :: [MessageType] -> MsgTypeArray | 577 | mkMsgTypes :: [MessageType] -> MsgTypeArray |
576 | mkMsgTypes msgs = let zeros = A.listArray (0,255) (replicate 256 0) | 578 | mkMsgTypes msgs = let zeros = A.listArray (0,255) (replicate 256 0) |
577 | in zeros A.// map (\x -> (toIndex x,toWord16 x)) msgs | 579 | in zeros A.// map (\x -> (toIndex x,toWord64 x)) msgs |
578 | where | 580 | where |
579 | toIndex (Msg mid) = fromIntegral . fromEnum $ mid | 581 | toIndex (Msg mid) = fromIntegral . fromEnum $ mid |
580 | toIndex (GrpMsg KnownLossless nam) = 0x63 -- fromEnum MESSAGE_GROUPCHAT | 582 | toIndex (GrpMsg KnownLossless nam) = 0x63 -- fromEnum MESSAGE_GROUPCHAT |
581 | toIndex (GrpMsg KnownLossy nam) = 0xC7 -- fromEnum LOSSY_GROUPCHAT | 583 | toIndex (GrpMsg KnownLossy nam) = 0xC7 -- fromEnum LOSSY_GROUPCHAT |
582 | 584 | ||
583 | -- | Handle all Tox messages that this code base is aware of. | 585 | -- | Handle all Tox messages that this code base is aware of. |
584 | allMsgTypes :: MsgTypeArray | 586 | -- The first parameter is a function which is applied to get the values |
585 | allMsgTypes = A.listArray (minBound,maxBound) (0:knownMsgs) | 587 | -- for keys of unknown nature. Could be either 'id' or 'const 0' |
588 | allMsgTypes :: (Word64 -> Word64) -> MsgTypeArray | ||
589 | allMsgTypes fDefault = A.listArray (minBound,maxBound) (0:knownMsgs) | ||
586 | where | 590 | where |
587 | knownMsgs :: [Word16] | 591 | knownMsgs :: [Word64] |
588 | knownMsgs = | 592 | knownMsgs = |
589 | concat [ map (fromIntegral . fromEnum) [ PacketRequest .. KillPacket ] | 593 | concat [ map (fromIntegral . fromEnum) [ PacketRequest .. KillPacket ] |
590 | , map (const 0) [ 3 .. 15 ] -- UnspecifiedPacket | 594 | , map (const 0) [ 3 .. 15 ] -- UnspecifiedPacket |