@@ -102,9 +102,10 @@ type PresenceEntry = {pubkey: PubkeyHex, server: AnyServerName, expiresAt: Times
102type ForwardEntry = {messageId: MessageIdHex, toServer: ServerName, createdAt: Timestamp, toKey: PubkeyHex, fromKey: PubkeyHex, encryptedBlob: BlobHex, timestamp: Timestamp}
102type ForwardEntry = {messageId: MessageIdHex, toServer: ServerName, createdAt: Timestamp, toKey: PubkeyHex, fromKey: PubkeyHex, encryptedBlob: BlobHex, timestamp: Timestamp}
103type AckedEntry = {messageId: MessageIdHex, toKey: PubkeyHex, ackedAt: Timestamp, originServer: ServerName}
103type AckedEntry = {messageId: MessageIdHex, toKey: PubkeyHex, ackedAt: Timestamp, originServer: ServerName}
104type AuthResult = Authorized {pubkey: PubkeyHex} | Unauthorized {}
104type AuthResult = Authorized {pubkey: PubkeyHex} | Unauthorized {}
105−type SendResult = SendFailed {status: MessageStatus} | SendDone {status: MessageStatus, remoteServers: [ServerName], fromKey: PubkeyHex}
105+type SendResult = SendUnauthorized {} | SendRejected {} | SendDone {status: MessageStatus, remoteServers: [ServerName], fromKey: PubkeyHex}
106type VerifyResult = VerifyFailed {} | VerifyOk {peerServers: [ServerName]}
106type VerifyResult = VerifyFailed {} | VerifyOk {peerServers: [ServerName]}
107type AckResult = AckUnauthorized {} | AckDone {pendingAcks: [AckedEntry], evictedEntries: [AckedEntry]}
107type AckResult = AckUnauthorized {} | AckDone {pendingAcks: [AckedEntry], evictedEntries: [AckedEntry]}
108+type LookupResult = LookupUnauthorized {} | LookupDone {server: AnyServerName}
110-- ============================================
111-- ============================================
@@ -815,11 +816,11 @@ serve = \req -> case req of
815 auth <- authenticateRequest authorization t
816 auth <- authenticateRequest authorization t
816 case auth of
817 case auth of
817 Unauthorized {} ->
818 Unauthorized {} ->
818− yield {pr: pr, send: SendFailed {status: MsUnauthorized {}}}
819+ yield {pr: pr, send: SendUnauthorized {}}
819 Authorized {pubkey: fromKey} -> do
820 Authorized {pubkey: fromKey} -> do
820 messages <- *messages
821 messages <- *messages
821 if countMessagesFor messages to t >= maxMessagesPerRecipient
822 if countMessagesFor messages to t >= maxMessagesPerRecipient
822− then yield {pr: pr, send: SendFailed {status: MsRejected {}}}
823+ then yield {pr: pr, send: SendRejected {}}
824 presence <- *presence
825 presence <- *presence
825 seqCounter <- *seqCounter
826 seqCounter <- *seqCounter
@@ -857,7 +858,8 @@ serve = \req -> case req of
857 _ -> yield {}
858 _ -> yield {}
858 broadcastOfflineGossip t result.pr.peerServers result.pr.expiredLocal)
859 broadcastOfflineGossip t result.pr.peerServers result.pr.expiredLocal)
859 yield (case result.send of
860 yield (case result.send of
860− SendFailed {status} -> respond {status: status, messageId: ""}
861+ SendUnauthorized {} -> respond {status: MsUnauthorized {}, messageId: ""}
862+ SendRejected {} -> respond {status: MsRejected {}, messageId: ""}
861 SendDone {status} -> respond {status: status, messageId: msgId})
863 SendDone {status} -> respond {status: status, messageId: msgId})
863 AckMessages {messageIds, authorization, respond} -> do
865 AckMessages {messageIds, authorization, respond} -> do
@@ -906,7 +908,7 @@ serve = \req -> case req of
906 auth <- authenticateRequest authorization t
908 auth <- authenticateRequest authorization t
907 case auth of
909 case auth of
908 Unauthorized {} ->
910 Unauthorized {} ->
909− yield {pr: pr, authorized: False {}, foundServer: ""}
911+ yield {pr: pr, lookup: LookupUnauthorized {}}
910 Authorized _ -> do
912 Authorized _ -> do
911 presence <- *presence
913 presence <- *presence
912 let valid = do
914 let valid = do
@@ -914,11 +916,14 @@ serve = \req -> case req of
914 where p.pubkey == pubkey && p.expiresAt > t
916 where p.pubkey == pubkey && p.expiresAt > t
916 let localOnline = any valid (\p -> p.server == serverHostN)
918 let localOnline = any valid (\p -> p.server == serverHostN)
919+ let remoteValid = do p <- valid; where p.server != serverHostN; yield p
917− let bestRemote = (fold (\acc p -> if p.server != serverHostN && p.expiresAt > acc.best then {server: p.server, best: p.expiresAt} else acc) {server: "", best: 0} valid).server
920+ let bestRemote = (fold (\acc p -> if p.expiresAt > acc.best then {server: p.server, best: p.expiresAt} else acc) {server: "", best: 0} remoteValid).server
918 let foundServer = if localOnline then serverHostN else bestRemote
921 let foundServer = if localOnline then serverHostN else bestRemote
919− yield {pr: pr, authorized: True {}, foundServer: foundServer}
922+ yield {pr: pr, lookup: LookupDone {server: foundServer}}
920 forkBroadcastOffline t result.pr
923 forkBroadcastOffline t result.pr
921− yield (respond {online: result.foundServer != "", server: result.foundServer, authorized: result.authorized})
924+ yield (case result.lookup of
925+ LookupUnauthorized {} -> respond {online: False {}, server: "", authorized: False {}}
926+ LookupDone {server} -> respond {online: server != "", server: server, authorized: True {}})
923 RecvGossip {events, hopsRemaining, fromServer, authorization, respond} -> do
928 RecvGossip {events, hopsRemaining, fromServer, authorization, respond} -> do