Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ntf: smp to ntf push plan wip #1388

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion rfcs/2024-09-25-ios-notifications-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,12 @@ NKEY :: NtfPublicAuthKey -> RcvNtfPublicDhKey -> Maybe NtfServerRequest -> Comma
-- NotifierID is passed in entity ID field of the transmission
```

2. Notification server will need to support an additional command to receive "proxied" subscription commands, `SFWD`, that would include `NtfServerRequest`. This command can include both `SNEW` and `SDEL` commands.
Instead of client generating keys for request, SMP server could generate them itself before forwarding request to notifications server.

2. SMP server has to differentiate legacy queues and queues using new notifications protocol, for example by saving notifications server on queue record.

For sending notifications, subscriptions mechanism could be replaced with direct push to notifications protocol.

3. Notification server will need to support an additional command to receive "proxied" subscription commands, `SFWD`, that would include `NtfServerRequest`. This command can include both `SNEW` and `SDEL` commands.

Notifications server has to process NMSG in form of forwarded request from SMP server (in addition to processing it in subscriptions loop). Notifications "subscription" record in that case would be used only for bookkeeping, for example, finding token (not for making subscriptions to SMP server via NSUB).
3 changes: 3 additions & 0 deletions src/Simplex/Messaging/Agent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-}

Check warning on line 18 in src/Simplex/Messaging/Agent.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-8.10.7

unrecognised warning flag: -fno-warn-ambiguous-fields

-- |
-- Module : Simplex.Messaging.Agent
Expand Down Expand Up @@ -771,10 +771,12 @@
_ -> pure ()
AgentConfig {smpClientVRange, smpAgentVRange, e2eEncryptVRange} <- asks config
let sndSecure = case cMode of SCMInvitation -> True; SCMContact -> False
-- [ntf] enableNtfs to newRcvQueue
(rq, qUri, tSess, sessId) <- newRcvQueue c userId connId srvWithAuth smpClientVRange subMode sndSecure `catchAgentError` \e -> liftIO (print e) >> throwE e
atomically $ incSMPServerStat c userId srv connCreated
rq' <- withStore c $ \db -> updateNewConnRcv db connId rq
lift . when (subMode == SMSubscribe) $ addNewQueueSubscription c rq' tSess sessId
-- [ntf] don't create subscription in client
when enableNtfs $ do
ns <- asks ntfSupervisor
atomically $ sendNtfSubCommand ns (NSCCreate, [connId])
Expand Down Expand Up @@ -2083,6 +2085,7 @@
connIds <- liftIO $ S.toList <$> getSubscriptions c
rs <- lift $ withStoreBatch' c (\db -> map (getConnData db) connIds)
let (connIds', cErrs) = enabledNtfConns (zip connIds rs)
-- [ntf] send NKEY to smp servers instead of creating via smp supervisor
forM_ (L.nonEmpty connIds') $ \connIds'' ->
atomically $ writeTBQueue (ntfSubQ ns) (cmd, connIds'')
unless (null cErrs) $ atomically $ writeTBQueue (subQ c) ("", "", AEvt SAENone $ ERRS cErrs)
Expand Down
1 change: 1 addition & 0 deletions src/Simplex/Messaging/Agent/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,7 @@ newRcvQueue c userId connId (ProtoServerWithAuth srv auth) vRange subMode sender
(e2eDhKey, e2ePrivKey) <- atomically $ C.generateKeyPair g
logServer "-->" c srv NoEntity "NEW"
tSess <- mkTransportSession c userId srv connId
-- [ntf] generate notifier id (if enableNtfs), other data from token
(sessId, QIK {rcvId, sndId, rcvPublicDhKey, sndSecure}) <-
withClient c tSess $ \(SMPConnectedClient smp _) ->
(sessionId $ thParams smp,) <$> createSMPQueue smp rKeys dhKey auth subMode senderCanSecure
Expand Down
5 changes: 5 additions & 0 deletions src/Simplex/Messaging/Notifications/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,11 @@ client NtfServerClient {rcvQ, sndQ} NtfSubscriber {newSubQ, smpAgent = ca} NtfPu
intervalNotifier delay = forever $ do
liftIO $ threadDelay' delay
atomically $ writeTBQueue pushQ (tkn, PNCheckMessages)
-- [ntf] should process forwarded commands
-- SNEW, SDEL
-- should process pushed messages (outside of subscription mechanism) - NMSG
-- - find token by notifier id sent by smp server
-- - push last ntfs to apns for token (PNMessageData - NMSG data, notifier id)
NtfReqNew corrId (ANE SSubscription newSub) -> do
logDebug "SNEW - new subscription"
st <- asks store
Expand Down
15 changes: 13 additions & 2 deletions src/Simplex/Messaging/Protocol.hs
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,10 @@
-- v6 of SMP servers only support signature algorithm for command authorization.
-- v7 of SMP servers additionally support additional layer of authenticated encryption.
-- RcvPublicAuthKey is defined as C.APublicKey - it can be either signature or DH public keys.
NEW :: RcvPublicAuthKey -> RcvPublicDhKey -> Maybe BasicAuth -> SubscriptionMode -> SenderCanSecure -> Command Recipient
NEW :: RcvPublicAuthKey -> RcvPublicDhKey -> Maybe BasicAuth -> SubscriptionMode -> SenderCanSecure -> Maybe NtfRequest -> Command Recipient
SUB :: Command Recipient
KEY :: SndPublicAuthKey -> Command Recipient
NKEY :: NtfPublicAuthKey -> RcvNtfPublicDhKey -> Command Recipient
NKEY :: NtfPublicAuthKey -> RcvNtfPublicDhKey -> Maybe NtfServerRequest -> Command Recipient
NDEL :: Command Recipient
GET :: Command Recipient
-- ACK v1 has to be supported for encoding/decoding
Expand Down Expand Up @@ -427,6 +427,17 @@

deriving instance Show (Command p)

-- [ntf]
-- why does client need to include pass into commands?
-- client doesn't have to pass them to ntf server, so smp server could generate them itself.
-- does ntf server even need NtfPublicAuthKey it if it won't be making subscription? - only RcvNtfPublicDhKey for ecryption?
data NtfRequest = NtfRequest NotifierId NtfPublicAuthKey RcvNtfPublicDhKey NtfServerRequest

data NtfServerRequest = NtfServerRequest NtfServer EncSingedNtfCmd

-- EncSingedNtfCmd should contain device token
type EncSingedNtfCmd = ByteString

data SubscriptionMode = SMSubscribe | SMOnlyCreate
deriving (Eq, Show)

Expand Down Expand Up @@ -1309,7 +1320,7 @@
instance PartyI p => ProtocolEncoding SMPVersion ErrorType (Command p) where
type Tag (Command p) = CommandTag p
encodeProtocol v = \case
NEW rKey dhKey auth_ subMode sndSecure

Check failure on line 1323 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-8.10.7

• The constructor ‘NEW’ should have 6 arguments, but has been given 5

Check failure on line 1323 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

• The constructor ‘NEW’ should have 6 arguments, but has been given 5

Check failure on line 1323 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

• The constructor ‘NEW’ should have 6 arguments, but has been given 5
| v >= sndAuthKeySMPVersion -> new <> e (auth_, subMode, sndSecure)
| v >= subModeSMPVersion -> new <> auth <> e subMode
| v == basicAuthSMPVersion -> new <> auth
Expand Down Expand Up @@ -1381,16 +1392,16 @@
CT SRecipient tag ->
Cmd SRecipient <$> case tag of
NEW_
| v >= sndAuthKeySMPVersion -> new <*> smpP <*> smpP <*> smpP

Check failure on line 1395 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient

Check failure on line 1395 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient
| v >= subModeSMPVersion -> new <*> auth <*> smpP <*> pure False

Check failure on line 1396 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient

Check failure on line 1396 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient
| v == basicAuthSMPVersion -> new <*> auth <*> pure SMSubscribe <*> pure False

Check failure on line 1397 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient

Check failure on line 1397 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient
| otherwise -> new <*> pure Nothing <*> pure SMSubscribe <*> pure False

Check failure on line 1398 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient

Check failure on line 1398 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

• Couldn't match type: Maybe NtfRequest -> Command Recipient
where
new = NEW <$> _smpP <*> smpP
auth = optional (A.char 'A' *> smpP)
SUB_ -> pure SUB
KEY_ -> KEY <$> _smpP
NKEY_ -> NKEY <$> _smpP <*> smpP

Check failure on line 1404 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

• Couldn't match type: Maybe NtfServerRequest -> Command Recipient

Check failure on line 1404 in src/Simplex/Messaging/Protocol.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

• Couldn't match type: Maybe NtfServerRequest -> Command Recipient
NDEL_ -> pure NDEL
GET_ -> pure GET
ACK_ -> ACK <$> _smpP
Expand Down
9 changes: 9 additions & 0 deletions src/Simplex/Messaging/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ smpServer started cfg@ServerConfig {transports, transportConfig = tCfg} attachHT
stats <- asks serverStats
liftIO $ forever $ do
threadDelay ntfInt
-- [ntf] in addition to subscribed ntf clients (legacy), should push itself for queues with ntf server saved
readTVarIO ntfSubClients >>= mapM_ (deliverNtfs ns stats)
where
deliverNtfs ns stats Client {clientId, ntfSubscriptions, sndQ, connected} =
Expand Down Expand Up @@ -1221,6 +1222,14 @@ client thParams' clnt@Client {clientId, subscriptions, ntfSubscriptions, rcvQ, s
incStat $ qSecured stats
liftIO $ either ERR (const OK) <$> secureQueue st rId sKey

-- [ntf]
-- take notifier id (Maybe for backwards compatibility).
-- if id is passed:
-- - response to client would be OK
-- - if it already exists, response would be AUTH / duplicate error?
-- - forward notifier id, EncSingedNtfCmd and dhKey for encryption negotiation to ntf server to create "subscription" record.
-- smp server should differentiate on queue record whether it expects ntf subscriptions or
-- it should push notifications to ntf server itself. - store ntf server on queue record.
addQueueNotifier_ :: QueueStore -> NtfPublicAuthKey -> RcvNtfPublicDhKey -> M (Transmission BrokerMsg)
addQueueNotifier_ st notifierKey dhKey = time "NKEY" $ do
(rcvPublicDhKey, privDhKey) <- atomically . C.generateKeyPair =<< asks random
Expand Down
Loading