Skip to content

Commit 08b84de

Browse files
authored
agent: option to use web port by default for preset servers only (#1523)
* agent: option to use web port by default for preset servers only * shorten/restore short links in agent, add encodings for SMP web port setting * decouple preset domains from preset servers for short links * refactor, rename
1 parent ec5a604 commit 08b84de

File tree

7 files changed

+52
-19
lines changed

7 files changed

+52
-19
lines changed

src/Simplex/Messaging/Agent/Client.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ data AgentClient = AgentClient
326326
xftpServers :: TMap UserId (UserServers 'PXFTP),
327327
xftpClients :: TMap XFTPTransportSession XFTPClientVar,
328328
useNetworkConfig :: TVar (NetworkConfig, NetworkConfig), -- (slow, fast) networks
329+
presetSMPDomains :: [HostName],
329330
userNetworkInfo :: TVar UserNetworkInfo,
330331
userNetworkUpdated :: TVar (Maybe UTCTime),
331332
subscrConns :: TVar (Set ConnId),
@@ -478,7 +479,7 @@ data UserNetworkType = UNNone | UNCellular | UNWifi | UNEthernet | UNOther
478479

479480
-- | Creates an SMP agent client instance that receives commands and sends responses via 'TBQueue's.
480481
newAgentClient :: Int -> InitialAgentServers -> UTCTime -> Env -> IO AgentClient
481-
newAgentClient clientId InitialAgentServers {smp, ntf, xftp, netCfg} currentTs agentEnv = do
482+
newAgentClient clientId InitialAgentServers {smp, ntf, xftp, netCfg, presetDomains} currentTs agentEnv = do
482483
let cfg = config agentEnv
483484
qSize = tbqSize cfg
484485
proxySessTs <- newTVarIO =<< getCurrentTime
@@ -532,6 +533,7 @@ newAgentClient clientId InitialAgentServers {smp, ntf, xftp, netCfg} currentTs a
532533
xftpServers,
533534
xftpClients,
534535
useNetworkConfig,
536+
presetSMPDomains = presetDomains,
535537
userNetworkInfo,
536538
userNetworkUpdated,
537539
subscrConns,
@@ -690,7 +692,7 @@ smpConnectClient c@AgentClient {smpClients, msgQ, proxySessTs} tSess@(_, srv, _)
690692
env <- ask
691693
liftError (protocolClientError SMP $ B.unpack $ strEncode srv) $ do
692694
ts <- readTVarIO proxySessTs
693-
smp <- ExceptT $ getProtocolClient g tSess cfg (Just msgQ) ts $ smpClientDisconnected c tSess env v' prs
695+
smp <- ExceptT $ getProtocolClient g tSess cfg (presetSMPDomains c) (Just msgQ) ts $ smpClientDisconnected c tSess env v' prs
694696
pure SMPConnectedClient {connectedClient = smp, proxiedRelays = prs}
695697

696698
smpClientDisconnected :: AgentClient -> SMPTransportSession -> Env -> SMPClientVar -> TMap SMPServer ProxiedRelayVar -> SMPClient -> IO ()
@@ -793,7 +795,7 @@ getNtfServerClient c@AgentClient {active, ntfClients, workerSeq, proxySessTs} tS
793795
g <- asks random
794796
ts <- readTVarIO proxySessTs
795797
liftError' (protocolClientError NTF $ B.unpack $ strEncode srv) $
796-
getProtocolClient g tSess cfg Nothing ts $
798+
getProtocolClient g tSess cfg [] Nothing ts $
797799
clientDisconnected v
798800

799801
clientDisconnected :: NtfClientVar -> NtfClient -> IO ()
@@ -1225,7 +1227,7 @@ runSMPServerTest c userId (ProtoServerWithAuth srv auth) = do
12251227
liftIO $ do
12261228
let tSess = (userId, srv, Nothing)
12271229
ts <- readTVarIO $ proxySessTs c
1228-
getProtocolClient g tSess cfg Nothing ts (\_ -> pure ()) >>= \case
1230+
getProtocolClient g tSess cfg (presetSMPDomains c) Nothing ts (\_ -> pure ()) >>= \case
12291231
Right smp -> do
12301232
rKeys@(_, rpKey) <- atomically $ C.generateAuthKeyPair ra g
12311233
(sKey, spKey) <- atomically $ C.generateAuthKeyPair sa g
@@ -1302,7 +1304,7 @@ runNTFServerTest c userId (ProtoServerWithAuth srv _) = do
13021304
liftIO $ do
13031305
let tSess = (userId, srv, Nothing)
13041306
ts <- readTVarIO $ proxySessTs c
1305-
getProtocolClient g tSess cfg Nothing ts (\_ -> pure ()) >>= \case
1307+
getProtocolClient g tSess cfg [] Nothing ts (\_ -> pure ()) >>= \case
13061308
Right ntf -> do
13071309
(nKey, npKey) <- atomically $ C.generateAuthKeyPair a g
13081310
(dhKey, _) <- atomically $ C.generateKeyPair g

src/Simplex/Messaging/Agent/Env/SQLite.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ data InitialAgentServers = InitialAgentServers
9696
{ smp :: Map UserId (NonEmpty (ServerCfg 'PSMP)),
9797
ntf :: [NtfServer],
9898
xftp :: Map UserId (NonEmpty (ServerCfg 'PXFTP)),
99-
netCfg :: NetworkConfig
99+
netCfg :: NetworkConfig,
100+
presetDomains :: [HostName]
100101
}
101102

102103
data ServerCfg p = ServerCfg

src/Simplex/Messaging/Client.hs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ module Simplex.Messaging.Client
8484
SocksMode (..),
8585
SMPProxyMode (..),
8686
SMPProxyFallback (..),
87+
SMPWebPortServers (..),
8788
defaultClientConfig,
8889
defaultSMPClientConfig,
8990
defaultNetworkConfig,
@@ -129,7 +130,7 @@ import qualified Data.ByteString.Char8 as B
129130
import qualified Data.ByteString.Base64 as B64
130131
import Data.Functor (($>))
131132
import Data.Int (Int64)
132-
import Data.List (find)
133+
import Data.List (find, isSuffixOf)
133134
import Data.List.NonEmpty (NonEmpty (..))
134135
import qualified Data.List.NonEmpty as L
135136
import Data.Maybe (catMaybes, fromMaybe)
@@ -138,7 +139,7 @@ import qualified Data.Text as T
138139
import Data.Time.Clock (UTCTime (..), diffUTCTime, getCurrentTime)
139140
import qualified Data.X509 as X
140141
import qualified Data.X509.Validation as XV
141-
import Network.Socket (ServiceName)
142+
import Network.Socket (HostName, ServiceName)
142143
import Network.Socks5 (SocksCredentials (..))
143144
import Numeric.Natural
144145
import qualified Simplex.Messaging.Crypto as C
@@ -291,7 +292,7 @@ data NetworkConfig = NetworkConfig
291292
-- | Fallback to direct connection when destination SMP relay does not support SMP proxy protocol extensions
292293
smpProxyFallback :: SMPProxyFallback,
293294
-- | use web port 443 for SMP protocol
294-
smpWebPort :: Bool,
295+
smpWebPortServers :: SMPWebPortServers,
295296
-- | timeout for the initial client TCP/TLS connection (microseconds)
296297
tcpConnectTimeout :: Int,
297298
-- | timeout of protocol commands (microseconds)
@@ -327,6 +328,12 @@ data SMPProxyFallback
327328
| SPFProhibit -- prohibit direct connection to destination relay.
328329
deriving (Eq, Show)
329330

331+
data SMPWebPortServers
332+
= SWPAll
333+
| SWPPreset
334+
| SWPOff
335+
deriving (Eq, Show)
336+
330337
instance StrEncoding SMPProxyMode where
331338
strEncode = \case
332339
SPMAlways -> "always"
@@ -353,6 +360,18 @@ instance StrEncoding SMPProxyFallback where
353360
"no" -> pure SPFProhibit
354361
_ -> fail "Invalid SMP proxy fallback mode"
355362

363+
instance StrEncoding SMPWebPortServers where
364+
strEncode = \case
365+
SWPAll -> "all"
366+
SWPPreset -> "preset"
367+
SWPOff -> "off"
368+
strP =
369+
A.takeTill (== ' ') >>= \case
370+
"all" -> pure SWPAll
371+
"preset" -> pure SWPPreset
372+
"off" -> pure SWPOff
373+
_ -> fail "Invalid SMP wep port setting"
374+
356375
defaultNetworkConfig :: NetworkConfig
357376
defaultNetworkConfig =
358377
NetworkConfig
@@ -363,7 +382,7 @@ defaultNetworkConfig =
363382
sessionMode = TSMSession,
364383
smpProxyMode = SPMNever,
365384
smpProxyFallback = SPFAllow,
366-
smpWebPort = False,
385+
smpWebPortServers = SWPPreset,
367386
tcpConnectTimeout = defaultTcpConnectTimeout,
368387
tcpTimeout = 15_000_000,
369388
tcpTimeoutPerKb = 5_000,
@@ -498,15 +517,15 @@ type TransportSession msg = (UserId, ProtoServer msg, Maybe ByteString)
498517
--
499518
-- A single queue can be used for multiple 'SMPClient' instances,
500519
-- as 'SMPServerTransmission' includes server information.
501-
getProtocolClient :: forall v err msg. Protocol v err msg => TVar ChaChaDRG -> TransportSession msg -> ProtocolClientConfig v -> Maybe (TBQueue (ServerTransmissionBatch v err msg)) -> UTCTime -> (ProtocolClient v err msg -> IO ()) -> IO (Either (ProtocolClientError err) (ProtocolClient v err msg))
502-
getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize, networkConfig, clientALPN, serverVRange, agreeSecret, proxyServer, useSNI} msgQ proxySessTs disconnected = do
520+
getProtocolClient :: forall v err msg. Protocol v err msg => TVar ChaChaDRG -> TransportSession msg -> ProtocolClientConfig v -> [HostName] -> Maybe (TBQueue (ServerTransmissionBatch v err msg)) -> UTCTime -> (ProtocolClient v err msg -> IO ()) -> IO (Either (ProtocolClientError err) (ProtocolClient v err msg))
521+
getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize, networkConfig, clientALPN, serverVRange, agreeSecret, proxyServer, useSNI} presetDomains msgQ proxySessTs disconnected = do
503522
case chooseTransportHost networkConfig (host srv) of
504523
Right useHost ->
505524
(getCurrentTime >>= mkProtocolClient useHost >>= runClient useTransport useHost)
506525
`catch` \(e :: IOException) -> pure . Left $ PCEIOError e
507526
Left e -> pure $ Left e
508527
where
509-
NetworkConfig {smpWebPort, tcpConnectTimeout, tcpTimeout, smpPingInterval} = networkConfig
528+
NetworkConfig {smpWebPortServers, tcpConnectTimeout, tcpTimeout, smpPingInterval} = networkConfig
510529
mkProtocolClient :: TransportHost -> UTCTime -> IO (PClient v err msg)
511530
mkProtocolClient transportHost ts = do
512531
connected <- newTVarIO False
@@ -554,6 +573,13 @@ getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize
554573
SPSMP | smpWebPort -> ("443", transport @TLS)
555574
_ -> defaultTransport cfg
556575
p -> (p, transport @TLS)
576+
where
577+
smpWebPort = case smpWebPortServers of
578+
SWPAll -> True
579+
SWPPreset -> case srv of
580+
ProtocolServer {host = THDomainName h :| _} -> any (`isSuffixOf` h) presetDomains
581+
_ -> False
582+
SWPOff -> False
557583

558584
client :: forall c. Transport c => TProxy c -> PClient v err msg -> TMVar (Either (ProtocolClientError err) (ProtocolClient v err msg)) -> c -> IO ()
559585
client _ c cVar h = do
@@ -1262,6 +1288,8 @@ $(J.deriveJSON (enumJSON $ dropPrefix "SPM") ''SMPProxyMode)
12621288

12631289
$(J.deriveJSON (enumJSON $ dropPrefix "SPF") ''SMPProxyFallback)
12641290

1291+
$(J.deriveJSON (enumJSON $ dropPrefix "SWP") ''SMPWebPortServers)
1292+
12651293
$(J.deriveJSON defaultJSON ''NetworkConfig)
12661294

12671295
$(J.deriveJSON (sumTypeJSON $ dropPrefix "Proxy") ''ProxyClientError)

src/Simplex/Messaging/Client/Agent.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ isOwnServer SMPClientAgent {agentCfg} ProtocolServer {host} =
198198
-- | Run an SMP client for SMPClientVar
199199
connectClient :: SMPClientAgent -> SMPServer -> SMPClientVar -> IO (Either SMPClientError SMPClient)
200200
connectClient ca@SMPClientAgent {agentCfg, smpClients, smpSessions, msgQ, randomDrg, startedAt} srv v =
201-
getProtocolClient randomDrg (1, srv, Nothing) (smpCfg agentCfg) (Just msgQ) startedAt clientDisconnected
201+
getProtocolClient randomDrg (1, srv, Nothing) (smpCfg agentCfg) [] (Just msgQ) startedAt clientDisconnected
202202
where
203203
clientDisconnected :: SMPClient -> IO ()
204204
clientDisconnected smp = do

tests/AgentTests/ServerChoice.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ initServers =
6161
{ smp = M.fromList [(1, testSMPServers)],
6262
ntf = [testNtfServer],
6363
xftp = userServers [testXFTPServer],
64-
netCfg = defaultNetworkConfig
64+
netCfg = defaultNetworkConfig,
65+
presetDomains = []
6566
}
6667

6768
testChooseDifferentOperator :: IO ()

tests/SMPAgentClient.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ initAgentServers =
6565
{ smp = userServers [testSMPServer],
6666
ntf = [testNtfServer],
6767
xftp = userServers [testXFTPServer],
68-
netCfg = defaultNetworkConfig {tcpTimeout = 500_000, tcpConnectTimeout = 500_000}
68+
netCfg = defaultNetworkConfig {tcpTimeout = 500_000, tcpConnectTimeout = 500_000},
69+
presetDomains = []
6970
}
7071

7172
initAgentServers2 :: InitialAgentServers

tests/SMPProxyTests.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,12 @@ deliverMessagesViaProxy proxyServ relayServ alg unsecuredMsgs securedMsgs = do
167167
g <- C.newRandom
168168
-- set up proxy
169169
ts <- getCurrentTime
170-
pc' <- getProtocolClient g (1, proxyServ, Nothing) defaultSMPClientConfig {serverVRange = mkVersionRange minServerSMPRelayVersion currentClientSMPRelayVersion} Nothing ts (\_ -> pure ())
170+
pc' <- getProtocolClient g (1, proxyServ, Nothing) defaultSMPClientConfig {serverVRange = mkVersionRange minServerSMPRelayVersion currentClientSMPRelayVersion} [] Nothing ts (\_ -> pure ())
171171
pc <- either (fail . show) pure pc'
172172
THAuthClient {} <- maybe (fail "getProtocolClient returned no thAuth") pure $ thAuth $ thParams pc
173173
-- set up relay
174174
msgQ <- newTBQueueIO 1024
175-
rc' <- getProtocolClient g (2, relayServ, Nothing) defaultSMPClientConfig {serverVRange = mkVersionRange minServerSMPRelayVersion authCmdsSMPVersion} (Just msgQ) ts (\_ -> pure ())
175+
rc' <- getProtocolClient g (2, relayServ, Nothing) defaultSMPClientConfig {serverVRange = mkVersionRange minServerSMPRelayVersion authCmdsSMPVersion} [] (Just msgQ) ts (\_ -> pure ())
176176
rc <- either (fail . show) pure rc'
177177
-- prepare receiving queue
178178
(rPub, rPriv) <- atomically $ C.generateAuthKeyPair alg g
@@ -210,7 +210,7 @@ proxyConnectDeadRelay n d proxyServ = do
210210
g <- C.newRandom
211211
-- set up proxy
212212
ts <- getCurrentTime
213-
pc' <- getProtocolClient g (1, proxyServ, Nothing) defaultSMPClientConfig {serverVRange = mkVersionRange minServerSMPRelayVersion sendingProxySMPVersion} Nothing ts (\_ -> pure ())
213+
pc' <- getProtocolClient g (1, proxyServ, Nothing) defaultSMPClientConfig {serverVRange = mkVersionRange minServerSMPRelayVersion sendingProxySMPVersion} [] Nothing ts (\_ -> pure ())
214214
pc <- either (fail . show) pure pc'
215215
THAuthClient {} <- maybe (fail "getProtocolClient returned no thAuth") pure $ thAuth $ thParams pc
216216
-- get proxy session

0 commit comments

Comments
 (0)