From d920a2504b6d4653748da7d297cb13cd0a0f1f48 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:48:54 +0400 Subject: [PATCH] agent: check confirmed snd queue doesn't exist before replacing (#871) --- src/Simplex/Messaging/Agent/Store.hs | 2 ++ src/Simplex/Messaging/Agent/Store/SQLite.hs | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Simplex/Messaging/Agent/Store.hs b/src/Simplex/Messaging/Agent/Store.hs index dda6c7c65..27b193693 100644 --- a/src/Simplex/Messaging/Agent/Store.hs +++ b/src/Simplex/Messaging/Agent/Store.hs @@ -576,6 +576,8 @@ data StoreError SEServerNotFound | -- | Connection already used. SEConnDuplicate + | -- | Confirmed snd queue already exists. + SESndQueueExists | -- | Wrong connection type, e.g. "send" connection when "receive" or "duplex" is expected, or vice versa. -- 'upgradeRcvConnToDuplex' and 'upgradeSndConnToDuplex' do not allow duplex connections - they would also return this error. SEBadConnType ConnType diff --git a/src/Simplex/Messaging/Agent/Store/SQLite.hs b/src/Simplex/Messaging/Agent/Store/SQLite.hs index 59d05df32..ab2c294d8 100644 --- a/src/Simplex/Messaging/Agent/Store/SQLite.hs +++ b/src/Simplex/Messaging/Agent/Store/SQLite.hs @@ -560,10 +560,23 @@ createRcvConn db gVar cData@ConnData {userId, connAgentVersion, enableNtfs, dupl createSndConn :: DB.Connection -> TVar ChaChaDRG -> ConnData -> SndQueue -> IO (Either StoreError ConnId) createSndConn db gVar cData@ConnData {userId, connAgentVersion, enableNtfs, duplexHandshake} q@SndQueue {server} = - createConn_ gVar cData $ \connId -> do - serverKeyHash_ <- createServer_ db server - DB.execute db "INSERT INTO connections (user_id, conn_id, conn_mode, smp_agent_version, enable_ntfs, duplex_handshake) VALUES (?,?,?,?,?,?)" (userId, connId, SCMInvitation, connAgentVersion, enableNtfs, duplexHandshake) - void $ insertSndQueue_ db connId q serverKeyHash_ + -- check confirmed snd queue doesn't already exist, to prevent it being deleted by REPLACE in insertSndQueue_ + ifM (liftIO $ checkConfirmedSndQueueExists_ db q) (pure $ Left SESndQueueExists) $ + createConn_ gVar cData $ \connId -> do + serverKeyHash_ <- createServer_ db server + DB.execute db "INSERT INTO connections (user_id, conn_id, conn_mode, smp_agent_version, enable_ntfs, duplex_handshake) VALUES (?,?,?,?,?,?)" (userId, connId, SCMInvitation, connAgentVersion, enableNtfs, duplexHandshake) + void $ insertSndQueue_ db connId q serverKeyHash_ + +checkConfirmedSndQueueExists_ :: DB.Connection -> SndQueue -> IO Bool +checkConfirmedSndQueueExists_ db SndQueue {server, sndId} = do + fromMaybe False + <$> maybeFirstRow + fromOnly + ( DB.query + db + "SELECT 1 FROM snd_queues WHERE host = ? AND port = ? AND snd_id = ? AND status != ? LIMIT 1" + (host server, port server, sndId, New) + ) getRcvConn :: DB.Connection -> SMPServer -> SMP.RecipientId -> IO (Either StoreError (RcvQueue, SomeConn)) getRcvConn db ProtocolServer {host, port} rcvId = runExceptT $ do