mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-10-23 23:52:40 +00:00
add agent SWITCH event, update DH e2e key in reply queue address
This commit is contained in:
1 parent
02b81ae2fe
commit
0152832f8e
2 files changed
+57
-18
No files matched your search
@@ -836,14 +836,18 @@ deleteConnection' c connId =
|
||||
atomically $ writeTBQueue (ntfSubQ ns) (connId, NSCDelete)
|
||||
|
||||
getConnectionServers' :: AgentMonad m => AgentClient -> ConnId -> m ConnectionStats
|
||||
getConnectionServers' c connId = connServers <$> withStore c (`getConn` connId)
|
||||
getConnectionServers' c connId = do
|
||||
SomeConn _ conn <- withStore c (`getConn` connId)
|
||||
-- TODO load next queues
|
||||
pure $ connectionStats conn Nothing Nothing
|
||||
|
||||
connectionStats :: Connection c -> Maybe RcvQueue -> Maybe SndQueue -> ConnectionStats
|
||||
connectionStats conn nextRq_ nextSq_ = case conn of
|
||||
RcvConnection _ rq -> ConnectionStats {rcvServers = rcvSrvs rq, sndServers = [], nextRcvServers = [], nextSndServers = []}
|
||||
SndConnection _ sq -> ConnectionStats {rcvServers = [], sndServers = sndSrvs sq, nextRcvServers = [], nextSndServers = []}
|
||||
DuplexConnection _ rq sq -> ConnectionStats {rcvServers = rcvSrvs rq, sndServers = sndSrvs sq, nextRcvServers = maybe [] rcvSrvs nextRq_, nextSndServers = maybe [] sndSrvs nextSq_}
|
||||
ContactConnection _ rq -> ConnectionStats {rcvServers = rcvSrvs rq, sndServers = [], nextRcvServers = [], nextSndServers = []}
|
||||
where
|
||||
connServers :: SomeConn -> ConnectionStats
|
||||
connServers = \case
|
||||
SomeConn _ (RcvConnection _ rq) -> ConnectionStats {rcvServers = rcvSrvs rq, sndServers = []}
|
||||
SomeConn _ (SndConnection _ sq) -> ConnectionStats {rcvServers = [], sndServers = sndSrvs sq}
|
||||
SomeConn _ (DuplexConnection _ rq sq) -> ConnectionStats {rcvServers = rcvSrvs rq, sndServers = sndSrvs sq}
|
||||
SomeConn _ (ContactConnection _ rq) -> ConnectionStats {rcvServers = rcvSrvs rq, sndServers = []}
|
||||
rcvSrvs RcvQueue {server} = [server]
|
||||
sndSrvs SndQueue {server} = [server]
|
||||
|
||||
@@ -1296,16 +1300,19 @@ processSMPTransmission c@AgentClient {smpClients, subQ} (srv, v, sessId, rId, cm
|
||||
-- processed by queue sender
|
||||
rqNewMsg :: (SMPServer, SMP.SenderId) -> SMPQueueUri -> m ()
|
||||
rqNewMsg _currAddr nextQUri = case conn of
|
||||
DuplexConnection _ _ sq -> do
|
||||
DuplexConnection _ rq sq -> do
|
||||
clientVRange <- asks $ smpClientVRange . config
|
||||
case (nextQUri `compatibleVersion` clientVRange) of
|
||||
Just qInfo@(Compatible nextQueueInfo) -> do
|
||||
sq'@SndQueue {sndPublicKey} <- newSndQueue qInfo
|
||||
Just qInfo@(Compatible nextQInfo) -> do
|
||||
sq'@SndQueue {sndPublicKey, e2ePubKey} <- newSndQueue qInfo
|
||||
withStore' c $ \db -> dbCreateNextSndQueue db sq sq'
|
||||
case sndPublicKey of
|
||||
Just nextSenderKey ->
|
||||
rq' <- withStore' c (`getNextRcvQueue` dbNextRcvQueueId rq)
|
||||
case (sndPublicKey, e2ePubKey) of
|
||||
(Just nextSenderKey, Just dhPublicKey) -> do
|
||||
let qAddr = (queueAddress (nextQInfo :: SMPQueueInfo)) {dhPublicKey}
|
||||
nextQueueInfo = (nextQInfo :: SMPQueueInfo) {queueAddress = qAddr}
|
||||
void . enqueueMessage c cData sq SMP.noMsgFlags $ QKEYS {nextSenderKey, nextQueueInfo}
|
||||
-- TODO possibly, notify user that send queue is rotating
|
||||
notify . SWITCH SPStarted $ connectionStats conn rq' (Just sq')
|
||||
_ -> do
|
||||
-- TODO notify user: internal error
|
||||
pure ()
|
||||
@@ -1318,7 +1325,12 @@ processSMPTransmission c@AgentClient {smpClients, subQ} (srv, v, sessId, rId, cm
|
||||
|
||||
-- processed by queue recipient
|
||||
rqKeys :: SndPublicVerifyKey -> SMPQueueInfo -> m () -> m ()
|
||||
rqKeys _sKey _nextQInfo ackDelete = do
|
||||
rqKeys _sKey (SMPQueueInfo v SMPQueueAddress {smpServer, senderId, dhPublicKey}) ackDelete = do
|
||||
-- withStore c (`getNextRcvQueue` dbNextRcvQueueId rq) >>= \case
|
||||
-- Just rq'
|
||||
-- | -> do
|
||||
-- | otherwise
|
||||
|
||||
-- store sender keys
|
||||
-- new rcv queue status = Confirmed
|
||||
-- old rcv_queue_action = RQASecureNewQueue
|
||||
|
||||
@@ -45,6 +45,7 @@ module Simplex.Messaging.Agent.Protocol
|
||||
SAParty (..),
|
||||
MsgHash,
|
||||
MsgMeta (..),
|
||||
SwitchPhase (..),
|
||||
ConnectionStats (..),
|
||||
SMPConfirmation (..),
|
||||
AgentMsgEnvelope (..),
|
||||
@@ -235,6 +236,7 @@ data ACommand (p :: AParty) where
|
||||
DISCONNECT :: AProtocolType -> TransportHost -> ACommand Agent
|
||||
DOWN :: SMPServer -> [ConnId] -> ACommand Agent
|
||||
UP :: SMPServer -> [ConnId] -> ACommand Agent
|
||||
SWITCH :: SwitchPhase -> ConnectionStats -> ACommand Agent
|
||||
SEND :: MsgFlags -> MsgBody -> ACommand Client
|
||||
MID :: AgentMsgId -> ACommand Agent
|
||||
SENT :: AgentMsgId -> ACommand Agent
|
||||
@@ -253,19 +255,41 @@ deriving instance Eq (ACommand p)
|
||||
|
||||
deriving instance Show (ACommand p)
|
||||
|
||||
data SwitchPhase = SPStarted | SPCompleted
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance StrEncoding SwitchPhase where
|
||||
strEncode = \case
|
||||
SPStarted -> "started"
|
||||
SPCompleted -> "completed"
|
||||
strP =
|
||||
A.takeTill (== ' ') >>= \case
|
||||
"started" -> pure SPStarted
|
||||
"completed" -> pure SPCompleted
|
||||
_ -> fail "bad SwitchPhase"
|
||||
|
||||
data ConnectionStats = ConnectionStats
|
||||
{ rcvServers :: [SMPServer],
|
||||
sndServers :: [SMPServer]
|
||||
sndServers :: [SMPServer],
|
||||
nextRcvServers :: [SMPServer],
|
||||
nextSndServers :: [SMPServer]
|
||||
}
|
||||
deriving (Eq, Show, Generic)
|
||||
|
||||
instance StrEncoding ConnectionStats where
|
||||
strEncode ConnectionStats {rcvServers, sndServers} =
|
||||
"rcv=" <> strEncodeList rcvServers <> " snd=" <> strEncodeList sndServers
|
||||
strEncode s =
|
||||
B.unwords
|
||||
[ "rcv=" <> strEncodeList (rcvServers s),
|
||||
"snd=" <> strEncodeList (sndServers s),
|
||||
"next_rcv=" <> strEncodeList (nextRcvServers s),
|
||||
"next_snd=" <> strEncodeList (nextSndServers s)
|
||||
]
|
||||
strP = do
|
||||
rcvServers <- "rcv=" *> strListP
|
||||
sndServers <- " snd=" *> strListP
|
||||
pure ConnectionStats {rcvServers, sndServers}
|
||||
nextRcvServers <- " next_rcv=" *> strListP
|
||||
nextSndServers <- " next_snd=" *> strListP
|
||||
pure ConnectionStats {rcvServers, sndServers, nextRcvServers, nextSndServers}
|
||||
|
||||
instance ToJSON ConnectionStats where toEncoding = J.genericToEncoding J.defaultOptions
|
||||
|
||||
@@ -1010,6 +1034,7 @@ commandP =
|
||||
<|> "DISCONNECT " *> disconnectResp
|
||||
<|> "DOWN " *> downResp
|
||||
<|> "UP " *> upResp
|
||||
<|> "SWITCH " *> switchResp
|
||||
<|> "SEND " *> sendCmd
|
||||
<|> "MID " *> msgIdResp
|
||||
<|> "SENT " *> sentResp
|
||||
@@ -1037,6 +1062,7 @@ commandP =
|
||||
disconnectResp = ACmd SAgent .: DISCONNECT <$> strP_ <*> strP
|
||||
downResp = ACmd SAgent .: DOWN <$> strP_ <*> connections
|
||||
upResp = ACmd SAgent .: UP <$> strP_ <*> connections
|
||||
switchResp = ACmd SAgent .: SWITCH <$> strP_ <*> strP
|
||||
sendCmd = ACmd SClient .: SEND <$> smpP <* A.space <*> A.takeByteString
|
||||
msgIdResp = ACmd SAgent . MID <$> A.decimal
|
||||
sentResp = ACmd SAgent . SENT <$> A.decimal
|
||||
@@ -1075,6 +1101,7 @@ serializeCommand = \case
|
||||
DISCONNECT p h -> B.unwords ["DISCONNECT", strEncode p, strEncode h]
|
||||
DOWN srv conns -> B.unwords ["DOWN", strEncode srv, connections conns]
|
||||
UP srv conns -> B.unwords ["UP", strEncode srv, connections conns]
|
||||
SWITCH phase srvs -> B.unwords ["SWITCH", strEncode phase, strEncode srvs]
|
||||
SEND msgFlags msgBody -> "SEND " <> smpEncode msgFlags <> " " <> serializeBinary msgBody
|
||||
MID mId -> "MID " <> bshow mId
|
||||
SENT mId -> "SENT " <> bshow mId
|
||||
|
||||
Reference in new issue
Block a user