summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Data/Word64RangeMap.hs6
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs139
2 files changed, 97 insertions, 48 deletions
diff --git a/src/Data/Word64RangeMap.hs b/src/Data/Word64RangeMap.hs
index f4736d59..2e4cc8b7 100644
--- a/src/Data/Word64RangeMap.hs
+++ b/src/Data/Word64RangeMap.hs
@@ -20,14 +20,14 @@ import Data.IORef
20 20
21type OuterIndex = Int 21type OuterIndex = Int
22type Index = Word64 22type Index = Word64
23type InnerArray b = UArray Index b 23type InnerArray b = Array Index b
24 24
25-- | Although this type includes a parameter for index, the code assumes bounds start at 0 25-- | Although this type includes a parameter for index, the code assumes bounds start at 0
26-- and the index has 'Integral', and 'Num' instances. 26-- and the index has 'Integral', and 'Num' instances.
27newtype RefArray r ma i e = RefArray (r (ma i e)) 27newtype RefArray r ma i e = RefArray (r (ma i e))
28 28
29-- convenient contraint kind 29-- convenient contraint kind
30type RangeArray rangeArray m b ref = (IArray UArray b, MArray rangeArray (InnerArray b) m, Reference ref m) 30type RangeArray rangeArray m b ref = (MArray rangeArray (InnerArray b) m, Reference ref m)
31-- The RangeMap type, to be used with the above constraint 31-- The RangeMap type, to be used with the above constraint
32type RangeMap rangeArray b ref = RefArray ref rangeArray OuterIndex (InnerArray b) 32type RangeMap rangeArray b ref = RefArray ref rangeArray OuterIndex (InnerArray b)
33 33
@@ -64,7 +64,7 @@ instance (Reference r m, MArray ma e m) => MArray (RefArray r ma) e m where
64 unsafeWrite (RefArray r) i e = modifyRef r (\x -> Base.unsafeWrite x i e >> return (x,())) 64 unsafeWrite (RefArray r) i e = modifyRef r (\x -> Base.unsafeWrite x i e >> return (x,()))
65-} 65-}
66 66
67emptySTMRangeMap :: STM (RangeMap TArray Word8 TVar) 67emptySTMRangeMap :: STM (RangeMap TArray a TVar)
68emptySTMRangeMap = RefArray <$> 68emptySTMRangeMap = RefArray <$>
69 (newTVar =<< 69 (newTVar =<<
70 newListArray (0,-1) []) 70 newListArray (0,-1) [])
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index d5a49816..fabbf21d 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -32,7 +32,9 @@ import Data.Maybe
32import qualified Data.Word64Map as W64 32import qualified Data.Word64Map as W64
33import Data.Word64RangeMap 33import Data.Word64RangeMap
34import qualified Data.Set as Set 34import qualified Data.Set as Set
35import qualified Data.Array.Unboxed as A 35import qualified Data.Word64RangeMap.Unboxed as U
36import qualified Data.Array.Unboxed as U
37import qualified Data.Array as A
36import SensibleDir 38import SensibleDir
37import System.FilePath 39import System.FilePath
38import System.Environment 40import System.Environment
@@ -189,7 +191,7 @@ type NetCryptoHook = IOHook NetCryptoSession CryptoMessage
189-- | Convert an id byte to it's type (in Word64 format) 191-- | Convert an id byte to it's type (in Word64 format)
190-- Although the type doesn't enforce it, MsgTypeArray 192-- Although the type doesn't enforce it, MsgTypeArray
191-- should always have 256 entries. 193-- should always have 256 entries.
192type MsgTypeArray = A.UArray Word8 Word64 194type MsgTypeArray = U.UArray Word8 Word64
193 195
194-- | Information, that may be made visible in multiple sessions, as well 196-- | Information, that may be made visible in multiple sessions, as well
195-- as displayed in some way to the user via mutiple views. 197-- as displayed in some way to the user via mutiple views.
@@ -302,6 +304,9 @@ data NetCryptoSession = NCrypto
302 -- The remaining fields correspond to implementation specific state -- 304 -- The remaining fields correspond to implementation specific state --
303 -- where as the prior fields will be used in any implementation -- 305 -- where as the prior fields will be used in any implementation --
304 , ncHooks :: TVar (Map.Map MessageType [NetCryptoHook]) 306 , ncHooks :: TVar (Map.Map MessageType [NetCryptoHook])
307 , ncOutHooks :: RangeMap TArray
308 (TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted)))
309 TVar
305 , ncUnrecognizedHook :: TVar (MessageType -> NetCryptoHook) 310 , ncUnrecognizedHook :: TVar (MessageType -> NetCryptoHook)
306 , ncIdleEventHooks :: TVar [(Int,NetCryptoSession -> IO ())] 311 , ncIdleEventHooks :: TVar [(Int,NetCryptoSession -> IO ())]
307 , ncIncomingTypeArray :: TVar MsgTypeArray 312 , ncIncomingTypeArray :: TVar MsgTypeArray
@@ -315,7 +320,7 @@ data NetCryptoSession = NCrypto
315 -- always escapes. 320 -- always escapes.
316 -- 321 --
317 -- Currently, the values at these indices are ignored. 322 -- Currently, the values at these indices are ignored.
318 , ncOutgoingIdMap :: RangeMap TArray Word8 TVar 323 , ncOutgoingIdMap :: U.RangeMap TArray Word8 TVar
319 -- ^ used to lookup the outgoing id for a type when sending an outoing message 324 -- ^ used to lookup the outgoing id for a type when sending an outoing message
320 , ncOutgoingIdMapEscapedLossy :: TVar (A.Array Word8 Word8) 325 , ncOutgoingIdMapEscapedLossy :: TVar (A.Array Word8 Word8)
321 -- ^ mapping of secondary id, when primary id is 0xC7 326 -- ^ mapping of secondary id, when primary id is 0xC7
@@ -363,7 +368,7 @@ data NetCryptoSession = NCrypto
363 , ncOutgoingQueue :: TVar 368 , ncOutgoingQueue :: TVar
364 (UponHandshake 369 (UponHandshake
365 (PQ.PacketOutQueue 370 (PQ.PacketOutQueue
366 (State,Nonce24,RangeMap TArray Word8 TVar) 371 (State,Nonce24,U.RangeMap TArray Word8 TVar)
367 CryptoMessage 372 CryptoMessage
368 (CryptoPacket Encrypted) 373 (CryptoPacket Encrypted)
369 CryptoData)) 374 CryptoData))
@@ -495,7 +500,7 @@ type XMessage = CryptoMessage -- todo
495-- rangemap <- readTVar (ncOutgoingIdMap session) 500-- rangemap <- readTVar (ncOutgoingIdMap session)
496-- return (state,n24,rangemap) 501-- return (state,n24,rangemap)
497 502
498ncToWire :: STM (State,Nonce24,RangeMap TArray Word8 TVar) 503ncToWire :: STM (State,Nonce24,U.RangeMap TArray Word8 TVar)
499 -> Word32{- packet number we expect to recieve -} 504 -> Word32{- packet number we expect to recieve -}
500 -> Word32{- buffer_end -} 505 -> Word32{- buffer_end -}
501 -> Word32{- packet number -} 506 -> Word32{- packet number -}
@@ -512,7 +517,7 @@ ncToWire getState seqno bufend pktno msg = do
512 (state,n24,msgOutMapVar) <- getState 517 (state,n24,msgOutMapVar) <- getState
513 -- msgOutMap <- readTVar msgOutMapVar 518 -- msgOutMap <- readTVar msgOutMapVar
514 result1 <- dtrace XNetCrypto ("lookupInRangeMap typ64=" ++ show typ64 ++ " " ++ show typ ++ show msg) 519 result1 <- dtrace XNetCrypto ("lookupInRangeMap typ64=" ++ show typ64 ++ " " ++ show typ ++ show msg)
515 $ lookupInRangeMap typ64 msgOutMapVar 520 $ U.lookupInRangeMap typ64 msgOutMapVar
516 case result1 of -- msgOutMapLookup typ64 msgOutMap of 521 case result1 of -- msgOutMapLookup typ64 msgOutMap of
517 Nothing -> dtrace XNetCrypto "lookupInRangeMap gave Nothing!" $ return Nothing 522 Nothing -> dtrace XNetCrypto "lookupInRangeMap gave Nothing!" $ return Nothing
518 Just outid -> dtrace XNetCrypto ("encrypting packet with Nonce: " ++ show n24) $ do 523 Just outid -> dtrace XNetCrypto ("encrypting packet with Nonce: " ++ show n24) $ do
@@ -589,18 +594,26 @@ freshCryptoSession sessions
589 ncIdleEventHooks0 <- newTVar (defaultIdleEventHooks sessions) 594 ncIdleEventHooks0 <- newTVar (defaultIdleEventHooks sessions)
590 ncIncomingTypeArray0 <- newTVar (msgTypeArray sessions) 595 ncIncomingTypeArray0 <- newTVar (msgTypeArray sessions)
591 let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255]) 596 let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255])
592 (ncOutgoingIdMap0,lossyEscapeIdMap,losslessEscapeIdMap) <- do 597 (ncOutgoingIdMap0,lossyEscapeIdMap,losslessEscapeIdMap,ncOutHooks0) <- do
593 idmap <- emptySTMRangeMap 598 idmap <- U.emptySTMRangeMap
594 insertArrayAt idmap 0 (A.listArray (0,255) [0 .. 255]) 599 U.insertArrayAt idmap 0 (U.listArray (0,255) [0 .. 255])
595 -- the 2 escape ranges are adjacent, so put them in one array: 600 -- the 2 escape ranges are adjacent, so put them in one array:
596 insertArrayAt idmap 512 (A.listArray (512,1023) ( replicate 256 0xC7 -- lossy escaped 601 U.insertArrayAt idmap 512 (U.listArray (512,1023) ( replicate 256 0xC7 -- lossy escaped
597 ++ replicate 256 0x63 -- lossless escapped 602 ++ replicate 256 0x63 -- lossless escapped
598 )) 603 ))
599 -- lossless as separate range could have been done: 604 -- lossless as separate range could have been done:
600 -- > insertArrayAt idmap 768 (A.listArray (768,1023) (replicate 256 0x63)) 605 -- > insertArrayAt idmap 768 (A.listArray (768,1023) (replicate 256 0x63))
601 lossyEsc <- newTVar $ A.listArray (0,255) [0 .. 255] 606 lossyEsc <- newTVar $ U.listArray (0,255) [0 .. 255]
602 losslessEsc <- newTVar $ A.listArray (0,255) [0 .. 255] 607 losslessEsc <- newTVar $ U.listArray (0,255) [0 .. 255]
603 return (idmap,lossyEsc,losslessEsc) 608 outHooks <- emptySTMRangeMap
609 mapM_ ($ outHooks) -- TODO: combine into larger ranges for faster lookup
610 [ insertWhereItGoes (A.listArray (2,2) [sendKillHook])
611 , insertWhereItGoes (A.listArray (16,16) [sendLossless{-Ping-}])
612 , insertWhereItGoes (A.listArray (24,25) [sendOnlineHook,sendLossless{-Offline-}])
613 , insertWhereItGoes (A.listArray (48,51) [sendNickHook,sendStatusMsgHook,sendStatusHook,sendTypingHook])
614 , insertWhereItGoes (A.listArray (63,64) [sendMessageHook, sendMessageHook])
615 ]
616 return (idmap,lossyEsc,losslessEsc,outHooks)
604 ncView0 <- newTVar (sessionView sessions) 617 ncView0 <- newTVar (sessionView sessions)
605 pktq <- PQ.new (inboundQueueCapacity sessions) 0 618 pktq <- PQ.new (inboundQueueCapacity sessions) 0
606 bufstart <- newTVar 0 619 bufstart <- newTVar 0
@@ -645,6 +658,7 @@ freshCryptoSession sessions
645 , ncSessionSecret = newsession 658 , ncSessionSecret = newsession
646 , ncSockAddr = HaveDHTKey addr 659 , ncSockAddr = HaveDHTKey addr
647 , ncHooks = ncHooks0 660 , ncHooks = ncHooks0
661 , ncOutHooks = ncOutHooks0
648 , ncUnrecognizedHook = ncUnrecognizedHook0 662 , ncUnrecognizedHook = ncUnrecognizedHook0
649 , ncIdleEventHooks = ncIdleEventHooks0 663 , ncIdleEventHooks = ncIdleEventHooks0
650 , ncAllSessions = sessions 664 , ncAllSessions = sessions
@@ -677,13 +691,13 @@ freshCryptoSession sessions
677 HaveHandshake pktoq -> return (runUponHandshake netCryptoSession0 addr pktoq) 691 HaveHandshake pktoq -> return (runUponHandshake netCryptoSession0 addr pktoq)
678 return (myhandshake,maybeLaunchMissles) 692 return (myhandshake,maybeLaunchMissles)
679 693
680type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 TVar) 694type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,U.RangeMap TArray Word8 TVar)
681 CryptoMessage 695 CryptoMessage
682 (CryptoPacket Encrypted) 696 (CryptoPacket Encrypted)
683 CryptoData 697 CryptoData
684 698
685createNetCryptoOutQueue :: NetCryptoSessions -> SecretKey -> PublicKey -> PacketQueue CryptoData 699createNetCryptoOutQueue :: NetCryptoSessions -> SecretKey -> PublicKey -> PacketQueue CryptoData
686 -> TVar Nonce24 -> RangeMap TArray Word8 TVar -> STM (UponHandshake NetCryptoOutQueue) 700 -> TVar Nonce24 -> U.RangeMap TArray Word8 TVar -> STM (UponHandshake NetCryptoOutQueue)
687createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 = do 701createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 = do
688 let crypto = transportCrypto sessions 702 let crypto = transportCrypto sessions
689 let toWireIO = do 703 let toWireIO = do
@@ -1084,7 +1098,7 @@ sessionPacketH sessions addrRaw (CryptoPacket nonce16 encrypted) = do
1084 Nothing -> return () 1098 Nothing -> return ()
1085 msgTypes <- atomically $ readTVar ncIncomingTypeArray 1099 msgTypes <- atomically $ readTVar ncIncomingTypeArray
1086 let msgTyp = cd ^. messageType 1100 let msgTyp = cd ^. messageType
1087 msgTypMapped64 = msgTypes A.! fromEnum8 (msgID cm) 1101 msgTypMapped64 = msgTypes U.! fromEnum8 (msgID cm)
1088 msgTypMapped = fromWord64 $ msgTypMapped64 1102 msgTypMapped = fromWord64 $ msgTypMapped64
1089 isLossy (GrpMsg KnownLossy _) = True 1103 isLossy (GrpMsg KnownLossy _) = True
1090 isLossy (Msg mid) | lossyness mid == Lossy = True 1104 isLossy (Msg mid) | lossyness mid == Lossy = True
@@ -1116,7 +1130,7 @@ runCryptoHook session@(NCrypto {ncState, ncHooks,ncSessionSecret,ncTheirSessionP
1116 flip fix (cm,hookmap) $ \lookupAgain (cm,hookmap) -> do 1130 flip fix (cm,hookmap) $ \lookupAgain (cm,hookmap) -> do
1117 msgTypes <- atomically $ readTVar ncIncomingTypeArray 1131 msgTypes <- atomically $ readTVar ncIncomingTypeArray
1118 let msgTyp = cm ^. messageType 1132 let msgTyp = cm ^. messageType
1119 msgTypMapped64 = msgTypes A.! fromEnum8 (msgID cm) 1133 msgTypMapped64 = msgTypes U.! fromEnum8 (msgID cm)
1120 msgTypMapped = fromWord64 $ msgTypMapped64 1134 msgTypMapped = fromWord64 $ msgTypMapped64
1121 if msgTypMapped64 == 0 1135 if msgTypMapped64 == 0
1122 then return Nothing 1136 then return Nothing
@@ -1147,8 +1161,8 @@ runCryptoHook session@(NCrypto {ncState, ncHooks,ncSessionSecret,ncTheirSessionP
1147-- | construct a 'MsgTypeArray' for specified types, using their known common positions 1161-- | construct a 'MsgTypeArray' for specified types, using their known common positions
1148-- in the MessageId space if they have such a thing. 1162-- in the MessageId space if they have such a thing.
1149mkMsgTypes :: [MessageType] -> MsgTypeArray 1163mkMsgTypes :: [MessageType] -> MsgTypeArray
1150mkMsgTypes msgs = let zeros = A.listArray (0,255) (replicate 256 0) 1164mkMsgTypes msgs = let zeros = U.listArray (0,255) (replicate 256 0)
1151 in zeros A.// map (\x -> (toIndex x,toWord64 x)) msgs 1165 in zeros U.// map (\x -> (toIndex x,toWord64 x)) msgs
1152 where 1166 where
1153 toIndex (Msg mid) = fromIntegral . fromEnum $ mid 1167 toIndex (Msg mid) = fromIntegral . fromEnum $ mid
1154 toIndex (GrpMsg KnownLossless nam) = 0x63 -- fromEnum MESSAGE_GROUPCHAT 1168 toIndex (GrpMsg KnownLossless nam) = 0x63 -- fromEnum MESSAGE_GROUPCHAT
@@ -1189,10 +1203,10 @@ pattern PACKET_ID_LOSSY_RANGE_SIZE = 63
1189-- The first parameter is a function which is applied to get the values 1203-- The first parameter is a function which is applied to get the values
1190-- for keys of unknown nature. Could be either 'id' or 'const 0' 1204-- for keys of unknown nature. Could be either 'id' or 'const 0'
1191allMsgTypes :: (Word64 -> Word64) -> MsgTypeArray 1205allMsgTypes :: (Word64 -> Word64) -> MsgTypeArray
1192allMsgTypes fDefault = A.listArray (minBound,maxBound) (0:knownMsgs) 1206allMsgTypes fDefault = U.listArray (minBound,maxBound) (0:knownMsgs)
1193 where 1207
1194 knownMsgs :: [Word64] 1208knownMsgs :: [Word64]
1195 knownMsgs = 1209knownMsgs =
1196 concat [ map (fromIntegral . fromEnum) [ PacketRequest .. KillPacket ] 1210 concat [ map (fromIntegral . fromEnum) [ PacketRequest .. KillPacket ]
1197 , map (const 0) [ 3 .. 15 ] -- UnspecifiedPacket 1211 , map (const 0) [ 3 .. 15 ] -- UnspecifiedPacket
1198 , map (const 0) [ 16 .. 23 ] -- MessengerLoseless 1212 , map (const 0) [ 16 .. 23 ] -- MessengerLoseless
@@ -1236,6 +1250,10 @@ sendPing crypto session = do
1236sendOnline :: TransportCrypto -> NetCryptoSession -> IO (Either String (CryptoPacket Encrypted)) 1250sendOnline :: TransportCrypto -> NetCryptoSession -> IO (Either String (CryptoPacket Encrypted))
1237sendOnline crypto session = do 1251sendOnline crypto session = do
1238 let cm=OneByte ONLINE 1252 let cm=OneByte ONLINE
1253 sendOnlineHook crypto session cm
1254
1255sendOnlineHook :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1256sendOnlineHook crypto session cm = do
1239 addMsgToLastN False (cm ^. messageType) session (Out cm) 1257 addMsgToLastN False (cm ^. messageType) session (Out cm)
1240 result <- sendCrypto crypto session (return ()) (OneByte ONLINE) 1258 result <- sendCrypto crypto session (return ()) (OneByte ONLINE)
1241 -- double this packet 1259 -- double this packet
@@ -1252,49 +1270,61 @@ sendOnline crypto session = do
1252sendOffline :: TransportCrypto -> NetCryptoSession -> IO (Either String (CryptoPacket Encrypted)) 1270sendOffline :: TransportCrypto -> NetCryptoSession -> IO (Either String (CryptoPacket Encrypted))
1253sendOffline crypto session = do 1271sendOffline crypto session = do
1254 let cm=OneByte OFFLINE 1272 let cm=OneByte OFFLINE
1273 sendLossless crypto session cm
1274
1275sendLossless :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1276sendLossless crypto session cm = do
1255 addMsgToLastN False (cm ^. messageType) session (Out cm) 1277 addMsgToLastN False (cm ^. messageType) session (Out cm)
1256 sendCrypto crypto session (return ()) (OneByte OFFLINE) 1278 sendCrypto crypto session (return ()) (OneByte OFFLINE)
1257 1279
1280sendLossy :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1281sendLossy crypto session cm = sendCryptoLossy crypto session (return ()) cm
1258 1282
1259sendKill :: TransportCrypto -> NetCryptoSession -> IO (Either String (CryptoPacket Encrypted)) 1283sendKill :: TransportCrypto -> NetCryptoSession -> IO (Either String (CryptoPacket Encrypted))
1260sendKill crypto session = do 1284sendKill crypto session = do
1261 let cm=OneByte KillPacket 1285 let cm=OneByte KillPacket
1286 sendKillHook crypto session cm
1287
1288sendKillHook :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1289sendKillHook crypto session cm = sendCryptoLossy crypto session (destroySession session) cm
1290
1291sendCryptoLossy :: TransportCrypto -> NetCryptoSession -> (IO ()) -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1292sendCryptoLossy crypto session updateLocal cm = do
1262 mbOutQ <- atomically $ readTVar (ncOutgoingQueue session) 1293 mbOutQ <- atomically $ readTVar (ncOutgoingQueue session)
1263 case mbOutQ of 1294 case mbOutQ of
1264 NeedHandshake -> do 1295 NeedHandshake -> do
1265 let errmsg="NetCrypto NOT SENDING Kill packet (sessionid: " ++ show (ncSessionId session) ++ ") since no handshake yet" 1296 let errmsg = "Error sending lossy packet! (sessionid: " ++ show (ncSessionId session) ++ ") Need the Handshake first!"
1266 dput XNetCrypto errmsg 1297 updateLocal
1267 dput XNetCrypto $ "Destroying session anyway"
1268 destroySession session
1269 return (Left errmsg) 1298 return (Left errmsg)
1270 HaveHandshake outq -> do 1299 HaveHandshake outq -> do
1271 dput XNetCrypto $ "NetCrypto sending Kill packet (sessionid: " ++ show (ncSessionId session) ++ ")"
1272 getOutGoingParam <- PQ.readyOutGoing outq 1300 getOutGoingParam <- PQ.readyOutGoing outq
1273 mbPkt <- atomically $ PQ.peekPacket getOutGoingParam outq cm 1301 mbPkt <- atomically $ PQ.peekPacket getOutGoingParam outq cm
1274 case mbPkt of 1302 case mbPkt of
1275 Nothing -> do 1303 Nothing -> do
1276 let errmsg = "Error sending kill packet! (sessionid: " ++ show (ncSessionId session) ++ ")" 1304 let errmsg = "Error sending lossy packet! (sessionid: " ++ show (ncSessionId session) ++ ") " ++ show cm
1277 dput XNetCrypto errmsg 1305 updateLocal
1278 dput XNetCrypto $ "Destroying session anyway"
1279 Right <$> destroySession session
1280 return (Left errmsg) 1306 return (Left errmsg)
1281 Just (pkt,seqno) -> do 1307 Just (pkt,seqno) -> do
1282 case (ncSockAddr session) of 1308 case (ncSockAddr session) of
1283 NeedDHTKey -> do 1309 NeedDHTKey -> do
1284 let errmsg= "NetCrypto NOT SENDING Kill packet (sessionid: " ++ show (ncSessionId session) ++ ") since no DHTkey(sockaddr) yet" 1310 let errmsg= "NetCrypto NOT SENDING Lossy packet (sessionid: " ++ show (ncSessionId session) ++ ") since no DHTkey(sockaddr) yet"
1285 dput XNetCrypto errmsg 1311 updateLocal
1286 dput XNetCrypto $ "Destroying session anyway"
1287 Right <$> destroySession session
1288 return (Left errmsg) 1312 return (Left errmsg)
1289 HaveDHTKey saddr -> do 1313 HaveDHTKey saddr -> do
1290 sendSessionPacket (ncAllSessions session) saddr pkt 1314 sendSessionPacket (ncAllSessions session) saddr pkt
1291 dput XNetCrypto $ "sent kill packet (sessionid: " ++ show (ncSessionId session) ++ ")... now destroying session..." 1315 dput XNetCrypto $ "sent lossy packet (sessionid: " ++ show (ncSessionId session) ++ ") " ++ take 40 (show cm) ++ "..."
1292 destroySession session 1316 updateLocal
1293 return (Right pkt) 1317 return (Right pkt)
1294 1318
1295setNick :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String (CryptoPacket Encrypted)) 1319setNick :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String (CryptoPacket Encrypted))
1296setNick crypto session nick = do 1320setNick crypto session nick = do
1321 let cm = UpToN NICKNAME nick
1322 sendNickHook crypto session cm
1323
1324sendNickHook :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1325sendNickHook crypto session cm = do
1297 let Just (_,maxlen) = msgSizeParam NICKNAME 1326 let Just (_,maxlen) = msgSizeParam NICKNAME
1327 let nick = msgBytes cm
1298 if B.length nick > maxlen 1328 if B.length nick > maxlen
1299 then return (Left $ "nickname must not exceed " ++ show maxlen ++ " bytes.") 1329 then return (Left $ "nickname must not exceed " ++ show maxlen ++ " bytes.")
1300 else do 1330 else do
@@ -1302,16 +1332,20 @@ setNick crypto session nick = do
1302 let viewVar = ncView session 1332 let viewVar = ncView session
1303 view <- readTVar viewVar 1333 view <- readTVar viewVar
1304 writeTVar (svNick view) nick 1334 writeTVar (svNick view) nick
1305 let cm = UpToN NICKNAME nick
1306 addMsgToLastN False (cm ^. messageType) session (Out cm) 1335 addMsgToLastN False (cm ^. messageType) session (Out cm)
1307 sendCrypto crypto session updateLocal cm 1336 sendCrypto crypto session updateLocal cm
1308 1337
1309setTyping :: TransportCrypto -> NetCryptoSession -> TypingStatus -> IO (Either String (CryptoPacket Encrypted)) 1338setTyping :: TransportCrypto -> NetCryptoSession -> TypingStatus -> IO (Either String (CryptoPacket Encrypted))
1310setTyping crypto session status = do 1339setTyping crypto session status = do
1340 let cm = TwoByte TYPING (fromEnum8 status)
1341 sendTypingHook crypto session cm
1342
1343sendTypingHook:: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1344sendTypingHook crypto session cm = do
1345 let status = toEnum8 (msgByte cm)
1311 let updateLocal = do 1346 let updateLocal = do
1312 view <- readTVar (ncView session) 1347 view <- readTVar (ncView session)
1313 writeTVar (svTyping view) status 1348 writeTVar (svTyping view) status
1314 let cm = TwoByte TYPING (fromEnum8 status)
1315 addMsgToLastN False (cm ^. messageType) session (Out cm) 1349 addMsgToLastN False (cm ^. messageType) session (Out cm)
1316 sendCrypto crypto session updateLocal cm 1350 sendCrypto crypto session updateLocal cm
1317 1351
@@ -1325,36 +1359,51 @@ setNoSpam crypto session mbnospam = do
1325 1359
1326setStatus :: TransportCrypto -> NetCryptoSession -> UserStatus -> IO (Either String (CryptoPacket Encrypted)) 1360setStatus :: TransportCrypto -> NetCryptoSession -> UserStatus -> IO (Either String (CryptoPacket Encrypted))
1327setStatus crypto session status = do 1361setStatus crypto session status = do
1362 let cm = TwoByte USERSTATUS (fromEnum8 status)
1363 sendStatusHook crypto session cm
1364
1365sendStatusHook :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1366sendStatusHook crypto session cm = do
1367 let status = toEnum8 (msgByte cm)
1328 let updateLocal = do 1368 let updateLocal = do
1329 view <- readTVar (ncView session) 1369 view <- readTVar (ncView session)
1330 writeTVar (svStatus view) status 1370 writeTVar (svStatus view) status
1331 let cm = TwoByte USERSTATUS (fromEnum8 status)
1332 addMsgToLastN False (cm ^. messageType) session (Out cm) 1371 addMsgToLastN False (cm ^. messageType) session (Out cm)
1333 sendCrypto crypto session updateLocal cm 1372 sendCrypto crypto session updateLocal cm
1334 1373
1335setStatusMsg :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String (CryptoPacket Encrypted)) 1374setStatusMsg :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String (CryptoPacket Encrypted))
1336setStatusMsg crypto session msg = do 1375setStatusMsg crypto session msg = do
1376 let cm = UpToN STATUSMESSAGE msg
1377 sendStatusMsgHook crypto session cm
1378
1379sendStatusMsgHook :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1380sendStatusMsgHook crypto session cm = do
1337 let Just (_,maxlen) = msgSizeParam STATUSMESSAGE 1381 let Just (_,maxlen) = msgSizeParam STATUSMESSAGE
1382 let msg = msgBytes cm
1338 if B.length msg > maxlen 1383 if B.length msg > maxlen
1339 then return (Left $ "status message must not exceed " ++ show maxlen ++ " bytes.") 1384 then return (Left $ "status message must not exceed " ++ show maxlen ++ " bytes.")
1340 else do 1385 else do
1341 let updateLocal = do 1386 let updateLocal = do
1342 view <- readTVar (ncView session) 1387 view <- readTVar (ncView session)
1343 writeTVar (svStatusMsg view) msg 1388 writeTVar (svStatusMsg view) msg
1344 let cm = UpToN STATUSMESSAGE msg
1345 addMsgToLastN False (cm ^. messageType) session (Out cm) 1389 addMsgToLastN False (cm ^. messageType) session (Out cm)
1346 sendCrypto crypto session updateLocal cm 1390 sendCrypto crypto session updateLocal cm
1347 1391
1348sendChatMsg :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String (CryptoPacket Encrypted)) 1392sendChatMsg :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String (CryptoPacket Encrypted))
1349sendChatMsg crypto session msg = do 1393sendChatMsg crypto session msg = do
1394 let cm = UpToN MESSAGE msg
1395 sendMessageHook crypto session cm
1396
1397sendMessageHook :: TransportCrypto -> NetCryptoSession -> CryptoMessage -> IO (Either String (CryptoPacket Encrypted))
1398sendMessageHook crypto session cm = do
1350 let Just (_,maxlen) = msgSizeParam MESSAGE 1399 let Just (_,maxlen) = msgSizeParam MESSAGE
1400 let msg = msgBytes cm
1351 if B.length msg > maxlen 1401 if B.length msg > maxlen
1352 then return (Left $ "status message must not exceed " ++ show maxlen ++ " bytes.") 1402 then return (Left $ "status message must not exceed " ++ show maxlen ++ " bytes.")
1353 else do 1403 else do
1354 let updateLocal = do 1404 let updateLocal = do
1355 view <- readTVar (ncView session) 1405 view <- readTVar (ncView session)
1356 writeTVar (svStatusMsg view) msg 1406 writeTVar (svStatusMsg view) msg
1357 let cm = UpToN MESSAGE msg
1358 addMsgToLastN False (cm ^. messageType) session (Out cm) 1407 addMsgToLastN False (cm ^. messageType) session (Out cm)
1359 sendCrypto crypto session updateLocal cm 1408 sendCrypto crypto session updateLocal cm
1360 1409