ntf: smp to ntf push plan wip

This commit is contained in:
spaced4ndy
2024-10-25 21:53:07 +04:00
parent 3860341584
commit a14a799cca
6 changed files with 40 additions and 3 deletions
+9 -1
View File
@@ -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
View File
@@ -771,10 +771,12 @@ newRcvConnSrv c userId connId enableNtfs cMode clientData pqInitKeys subMode srv
_ -> 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])
@@ -2083,6 +2085,7 @@ sendNtfConnCommands c cmd = do
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)
+1
View File
@@ -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
@@ -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
+13 -2
View File
@@ -393,10 +393,10 @@ data Command (p :: Party) where
-- 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
@@ -427,6 +427,17 @@ data Command (p :: Party) where
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)
+9
View File
@@ -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} =
@@ -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