Skip to content

Commit b4bcfd3

Browse files
authored
agent: better handling errors during connection handshake retries (#1578)
* agent: handle invitation connection handshake errors * fix/test retries for connecting via address
1 parent 976bd3a commit b4bcfd3

File tree

8 files changed

+293
-75
lines changed

8 files changed

+293
-75
lines changed

src/Simplex/Messaging/Agent.hs

Lines changed: 72 additions & 40 deletions
Large diffs are not rendered by default.

src/Simplex/Messaging/Agent/Client.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ newProtocolClient c tSess@(userId, srv, entityId_) clients connectClient v =
867867
Right client -> do
868868
logInfo . decodeUtf8 $ "Agent connected to " <> showServer srv <> " (user " <> bshow userId <> maybe "" (" for entity " <>) entityId_ <> ")"
869869
atomically $ putTMVar (sessionVar v) (Right client)
870-
atomically $ writeTBQueue (subQ c) ("", "", AEvt SAENone $ hostEvent CONNECT client)
870+
liftIO $ nonBlockingWriteTBQueue (subQ c) ("", "", AEvt SAENone $ hostEvent CONNECT client)
871871
pure client
872872
Left e -> do
873873
ei <- asks $ persistErrorInterval . config
@@ -2126,12 +2126,12 @@ withStoreBatch' c actions = withStoreBatch c (fmap (fmap Right) . actions)
21262126

21272127
storeError :: StoreError -> AgentErrorType
21282128
storeError = \case
2129-
SEConnNotFound -> CONN NOT_FOUND
2129+
SEConnNotFound -> CONN NOT_FOUND ""
21302130
SEUserNotFound -> NO_USER
2131-
SERatchetNotFound -> CONN NOT_FOUND
2132-
SEConnDuplicate -> CONN DUPLICATE
2133-
SEBadConnType CRcv -> CONN SIMPLEX
2134-
SEBadConnType CSnd -> CONN SIMPLEX
2131+
SERatchetNotFound -> CONN NOT_FOUND ""
2132+
SEConnDuplicate -> CONN DUPLICATE ""
2133+
SEBadConnType cxt CRcv -> CONN SIMPLEX cxt
2134+
SEBadConnType cxt CSnd -> CONN SIMPLEX cxt
21352135
SEInvitationNotFound cxt invId -> CMD PROHIBITED $ "SEInvitationNotFound " <> cxt <> ", invitationId = " <> show invId
21362136
-- this error is never reported as store error,
21372137
-- it is used to wrap agent operations when "transaction-like" store access is needed

src/Simplex/Messaging/Agent/Protocol.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,7 @@ data AgentErrorType
18371837
= -- | command or response error
18381838
CMD {cmdErr :: CommandErrorType, errContext :: String}
18391839
| -- | connection errors
1840-
CONN {connErr :: ConnectionErrorType}
1840+
CONN {connErr :: ConnectionErrorType, errContext :: String}
18411841
| -- | user not found in database
18421842
NO_USER
18431843
| -- | SMP protocol errors forwarded to agent clients

src/Simplex/Messaging/Agent/Store.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ rcvQueueInfo :: RcvQueue -> RcvQueueInfo
119119
rcvQueueInfo rq@RcvQueue {server, rcvSwchStatus} =
120120
RcvQueueInfo {rcvServer = server, rcvSwitchStatus = rcvSwchStatus, canAbortSwitch = canAbortRcvSwitch rq}
121121

122+
rcvSMPQueueAddress :: RcvQueue -> SMPQueueAddress
123+
rcvSMPQueueAddress RcvQueue {server, sndId, e2ePrivKey, queueMode} =
124+
SMPQueueAddress server sndId (C.publicKey e2ePrivKey) queueMode
125+
122126
canAbortRcvSwitch :: RcvQueue -> Bool
123127
canAbortRcvSwitch = maybe False canAbort . rcvSwchStatus
124128
where
@@ -662,7 +666,7 @@ data StoreError
662666
SESndQueueExists
663667
| -- | Wrong connection type, e.g. "send" connection when "receive" or "duplex" is expected, or vice versa.
664668
-- 'upgradeRcvConnToDuplex' and 'upgradeSndConnToDuplex' do not allow duplex connections - they would also return this error.
665-
SEBadConnType ConnType
669+
SEBadConnType String ConnType
666670
| -- | Confirmation not found.
667671
SEConfirmationNotFound
668672
| -- | Invitation not found

src/Simplex/Messaging/Agent/Store/AgentStore.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ updateNewConnRcv db connId rq =
387387
getConn db connId $>>= \case
388388
(SomeConn _ NewConnection {}) -> updateConn
389389
(SomeConn _ RcvConnection {}) -> updateConn -- to allow retries
390-
(SomeConn c _) -> pure . Left . SEBadConnType $ connType c
390+
(SomeConn c _) -> pure . Left . SEBadConnType "updateNewConnRcv" $ connType c
391391
where
392392
updateConn :: IO (Either StoreError RcvQueue)
393393
updateConn = Right <$> addConnRcvQueue_ db connId rq
@@ -396,7 +396,7 @@ updateNewConnSnd :: DB.Connection -> ConnId -> NewSndQueue -> IO (Either StoreEr
396396
updateNewConnSnd db connId sq =
397397
getConn db connId $>>= \case
398398
(SomeConn _ NewConnection {}) -> updateConn
399-
(SomeConn c _) -> pure . Left . SEBadConnType $ connType c
399+
(SomeConn c _) -> pure . Left . SEBadConnType "updateNewConnSnd" $ connType c
400400
where
401401
updateConn :: IO (Either StoreError SndQueue)
402402
updateConn = Right <$> addConnSndQueue_ db connId sq
@@ -472,22 +472,22 @@ upgradeRcvConnToDuplex :: DB.Connection -> ConnId -> NewSndQueue -> IO (Either S
472472
upgradeRcvConnToDuplex db connId sq =
473473
getConn db connId $>>= \case
474474
(SomeConn _ RcvConnection {}) -> Right <$> addConnSndQueue_ db connId sq
475-
(SomeConn c _) -> pure . Left . SEBadConnType $ connType c
475+
(SomeConn c _) -> pure . Left . SEBadConnType "upgradeRcvConnToDuplex" $ connType c
476476

477477
-- TODO [certs rcv] store clientServiceId from NewRcvQueue
478478
upgradeSndConnToDuplex :: DB.Connection -> ConnId -> NewRcvQueue -> IO (Either StoreError RcvQueue)
479479
upgradeSndConnToDuplex db connId rq =
480480
getConn db connId >>= \case
481481
Right (SomeConn _ SndConnection {}) -> Right <$> addConnRcvQueue_ db connId rq
482-
Right (SomeConn c _) -> pure . Left . SEBadConnType $ connType c
482+
Right (SomeConn c _) -> pure . Left . SEBadConnType "upgradeSndConnToDuplex" $ connType c
483483
_ -> pure $ Left SEConnNotFound
484484

485485
-- TODO [certs rcv] store clientServiceId from NewRcvQueue
486486
addConnRcvQueue :: DB.Connection -> ConnId -> NewRcvQueue -> IO (Either StoreError RcvQueue)
487487
addConnRcvQueue db connId rq =
488488
getConn db connId >>= \case
489489
Right (SomeConn _ DuplexConnection {}) -> Right <$> addConnRcvQueue_ db connId rq
490-
Right (SomeConn c _) -> pure . Left . SEBadConnType $ connType c
490+
Right (SomeConn c _) -> pure . Left . SEBadConnType "addConnRcvQueue" $ connType c
491491
_ -> pure $ Left SEConnNotFound
492492

493493
addConnRcvQueue_ :: DB.Connection -> ConnId -> NewRcvQueue -> IO RcvQueue
@@ -499,7 +499,7 @@ addConnSndQueue :: DB.Connection -> ConnId -> NewSndQueue -> IO (Either StoreErr
499499
addConnSndQueue db connId sq =
500500
getConn db connId >>= \case
501501
Right (SomeConn _ DuplexConnection {}) -> Right <$> addConnSndQueue_ db connId sq
502-
Right (SomeConn c _) -> pure . Left . SEBadConnType $ connType c
502+
Right (SomeConn c _) -> pure . Left . SEBadConnType "addConnSndQueue" $ connType c
503503
_ -> pure $ Left SEConnNotFound
504504

505505
addConnSndQueue_ :: DB.Connection -> ConnId -> NewSndQueue -> IO SndQueue

src/Simplex/Messaging/Crypto/Ratchet.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ module Simplex.Messaging.Crypto.Ratchet
5555
supportedE2EEncryptVRange,
5656
generateRcvE2EParams,
5757
generateSndE2EParams,
58+
mkRcvE2ERatchetParams,
5859
initialPQEncryption,
5960
connPQEncryption,
6061
joinContactInitialKeys,
@@ -196,6 +197,8 @@ data ARKEMParams = forall s. RatchetKEMStateI s => ARKP (SRatchetKEMState s) (RK
196197

197198
deriving instance Show ARKEMParams
198199

200+
type RcvRKEMParams = RKEMParams 'RKSProposed
201+
199202
instance RatchetKEMStateI s => Encoding (RKEMParams s) where
200203
smpEncode = \case
201204
RKParamsProposed k -> smpEncode ('P', k)
@@ -406,6 +409,12 @@ data UseKEM (s :: RatchetKEMState) where
406409

407410
data AUseKEM = forall s. RatchetKEMStateI s => AUseKEM (SRatchetKEMState s) (UseKEM s)
408411

412+
mkRcvE2ERatchetParams :: VersionE2E -> (PrivateKey a, PrivateKey a, Maybe RcvPrivRKEMParams) -> RcvE2ERatchetParams a
413+
mkRcvE2ERatchetParams v (pk1, pk2, pKem) = E2ERatchetParams v (publicKey pk1) (publicKey pk2) (mkKem <$> pKem)
414+
where
415+
mkKem :: RcvPrivRKEMParams -> RcvRKEMParams
416+
mkKem (PrivateRKParamsProposed (k, _)) = RKParamsProposed k
417+
409418
generateE2EParams :: forall s a. (AlgorithmI a, DhAlgorithm a) => TVar ChaChaDRG -> VersionE2E -> Maybe (UseKEM s) -> IO (PrivateKey a, PrivateKey a, Maybe (PrivRKEMParams s), E2ERatchetParams s a)
410419
generateE2EParams g v useKEM_ = do
411420
(k1, pk1) <- atomically $ generateKeyPair g

0 commit comments

Comments
 (0)