smp-server: drop relay session after timeouts

This commit is contained in:
shum
2026-09-30 11:33:02 +00:00
parent 35767d74c5
commit ad694af988
3 changed files with 14 additions and 5 deletions
+8 -2
View File
@@ -35,6 +35,7 @@ module Simplex.Messaging.Client
ProxiedRelay (..),
getProtocolClient,
closeProtocolClient,
closeTimedOutClient,
pClientSentCommandsCount,
protocolClientServer,
protocolClientServer',
@@ -660,10 +661,9 @@ getProtocolClient g nm transportSession@(_, srv, _) cfg@ProtocolClientConfig {qS
responseErr = atomically . putTMVar responseVar . Left . PCETransportError
receive :: Transport c => ProtocolClient v err msg -> THandle v c 'TClient -> IO ()
receive ProtocolClient {client_ = PClient {rcvQ, lastReceived, timeoutErrorCount}} h = forever $ do
receive ProtocolClient {client_ = PClient {rcvQ, lastReceived}} h = forever $ do
tGetClient h >>= atomically . writeTBQueue rcvQ
getCurrentTime >>= atomically . writeTVar lastReceived
atomically $ writeTVar timeoutErrorCount 0
monitor :: ProtocolClient v err msg -> IO ()
monitor c@ProtocolClient {client_ = PClient {sendPings, lastReceived, timeoutErrorCount}} = loop smpPingInterval
@@ -752,6 +752,12 @@ closeProtocolClient :: ProtocolClient v err msg -> IO ()
closeProtocolClient = mapM_ (deRefWeak >=> mapM_ killThread) . action
{-# INLINE closeProtocolClient #-}
-- | Disconnects client when maxCnt commands in a row timed out, 0 to disable.
closeTimedOutClient :: Int -> ProtocolClient v err msg -> IO ()
closeTimedOutClient maxCnt c@ProtocolClient {client_ = PClient {timeoutErrorCount}} = do
cnt <- readTVarIO timeoutErrorCount
when (maxCnt > 0 && cnt >= maxCnt) $ closeProtocolClient c
pClientSentCommandsCount :: ProtocolClient v err msg -> IO Int
pClientSentCommandsCount ProtocolClient {client_ = PClient {sentCommands}} = M.size <$> readTVarIO sentCommands
+5 -2
View File
@@ -98,8 +98,8 @@ import Network.Socket (ServiceName, Socket, socketToHandle)
import qualified Network.TLS as TLS
import Numeric.Natural (Natural)
import Simplex.Messaging.Agent.Lock
import Simplex.Messaging.Client (ProtocolClient (thParams), ProtocolClientError (..), SMPClient, SMPClientError, clientHandlers, forwardSMPTransmission, smpProxyError, temporaryClientError)
import Simplex.Messaging.Client.Agent (OwnServer, SMPClientAgent (..), SMPClientAgentEvent (..), closeSMPClientAgent, getSMPServerClient'', isOwnServer, lookupSMPServerClient, getConnectedSMPServerClient)
import Simplex.Messaging.Client (NetworkConfig (..), ProtocolClient (thParams), ProtocolClientConfig (..), ProtocolClientError (..), SMPClient, SMPClientError, clientHandlers, closeTimedOutClient, forwardSMPTransmission, smpProxyError, temporaryClientError)
import Simplex.Messaging.Client.Agent (OwnServer, SMPClientAgent (..), SMPClientAgentConfig (..), SMPClientAgentEvent (..), closeSMPClientAgent, getSMPServerClient'', isOwnServer, lookupSMPServerClient, getConnectedSMPServerClient)
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Encoding
import Simplex.Messaging.Encoding.String
@@ -1465,6 +1465,9 @@ client
Right r -> PRES r <$ inc own pSuccesses
Left e -> ERR (smpProxyError e) <$ case e of
PCEProtocolError {} -> inc own pSuccesses
PCEResponseTimeout -> do
inc own pErrorsOther
liftIO $ closeTimedOutClient (smpPingCount $ networkConfig $ smpCfg $ agentCfg a) smp
_ -> inc own pErrorsOther
Nothing -> inc False pRequests >> inc False pErrorsConnect $> Just (ERR $ PROXY NO_SESSION)
where
+1 -1
View File
@@ -64,7 +64,7 @@ smpProxyTests = do
testProxyRecoversWithoutDisconnect
it "reconnects to relay after sender disconnects mid-connection" $ \_ ->
testProxyReconnectAfterRelayRestart
xit "must drop a stuck relay session after forward timeouts" $ \_ ->
it "must drop a stuck relay session after forward timeouts" $ \_ ->
testProxyForwardTimeoutStuckSession
it "does not keep oversized forwarded command" $ \_ ->
testForwardOversizedNotKept