on master help sign in
Fix four bugs: SendMessage mailbox full, evicted acks retry, RecvGossip trust check expiry
commitfa38fa75b9acc1ed749693d9cec80663f8e148c6 authoriko <mail@iko.soy> dateTue 31 Mar 2026, 16:23 (7 months ago) parentadeccc3
1 file changed+18−10
server.knot+18−10
server.knot+18−10
@@ -741,6 +741,7 @@ serve = \req -> case req of
741741 let status = case session of
742742 Nothing {} -> "unauthorized"
743743 _ -> if not validInput then "invalid"
744+ else if recipientMsgCount >= maxMessagesPerRecipient then "rejected"
744745 else if localOnline then "delivered"
745746 else if count remoteServers > 0 then "federated"
746747 else "queued"
@@ -751,15 +752,15 @@ serve = \req -> case req of
751752 else forwards
752753 yield {status: status, remoteServers: remoteServers, fromKey: fromKey, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, forwardsAtCapacity: forwardsAtCapacity}
753754 let finalStatus = if result.status == "federated" && (federationSecret == "" || result.forwardsAtCapacity) then "queued" else result.status
754− respond {status: finalStatus, messageId: (if result.status == "unauthorized" then "" else if result.status == "invalid" then "" else msgId)}
755− if count result.remoteServers > 0 && not (result.status == "unauthorized") && not (result.status == "invalid") && not (federationSecret == "")
755+ respond {status: finalStatus, messageId: (if result.status == "unauthorized" then "" else if result.status == "invalid" then "" else if result.status == "rejected" then "" else msgId)}
756+ if count result.remoteServers > 0 && not (result.status == "unauthorized") && not (result.status == "invalid") && not (result.status == "rejected") && not (federationSecret == "")
756757 then sendToEach result.remoteServers (\server ->
757758 fetch (federationScheme ++ server) (ForwardMessage {
758759 toKey: to, fromKey: result.fromKey, encryptedBlob: encryptedBlob,
759760 timestamp: clampedTs, originServer: serverHostN, messageId: msgId,
760761 authorization: "Bearer " ++ federationSecret}))
761762 else yield {}
762− if result.forwardsAtCapacity && count result.remoteServers > 0 && not (result.status == "unauthorized") && not (result.status == "invalid")
763+ if result.forwardsAtCapacity && count result.remoteServers > 0 && not (result.status == "unauthorized") && not (result.status == "invalid") && not (result.status == "rejected")
763764 then println ("sendMessage: forwards at capacity (" ++ show maxForwardsEntries ++ "), skipping forward tracking")
764765 else yield {}
765766 broadcastOfflineGossip t result.peerServers result.expiredLocal
@@ -830,10 +831,17 @@ serve = \req -> case req of
830831 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
831832 else union acc [a.originServer]) [] result.evictedEntries
832833 sendToEach evictedOriginServers (\server ->
833− fetch (federationScheme ++ server) (FederationAck {
834− authorization: "Bearer " ++ federationSecret,
835− messageIds: (do a <- result.evictedEntries; where a.originServer == server; yield a.messageId),
836− originServer: server, fromServer: serverHostN}))
834+ catch (do
835+ fetch (federationScheme ++ server) (FederationAck {
836+ authorization: "Bearer " ++ federationSecret,
837+ messageIds: (do a <- result.evictedEntries; where a.originServer == server; yield a.messageId),
838+ originServer: server, fromServer: serverHostN})
839+ yield {}) (\err -> do
840+ println ("federation: error sending evicted ack to " ++ server ++ ": " ++ show err)
841+ atomic do
842+ ackedIds <- *ackedIds
843+ let reinsert = do a <- result.evictedEntries; where a.originServer == server; yield a
844+ set *ackedIds = union ackedIds reinsert))
837845 else yield {}
838846 broadcastOfflineGossip t result.peerServers result.expiredLocal
839847
@@ -936,14 +944,14 @@ serve = \req -> case req of
936944 gossipResult <- atomic do
937945 pr <- maybePrune t
938946 presence <- *presence
939− let fromServerTrusted = count (do p <- presence; where p.server == fromServer; yield p) > 0
947+ let fromServerTrusted = count (do p <- presence; where p.server == fromServer; where p.expiresAt > t; yield p) > 0
940948 let trustedDeduped = do
941949 e <- deduped
942− where e.server == fromServer || fromServerTrusted || count (do p <- presence; where p.server == e.server; yield p) > 0
950+ where e.server == fromServer || fromServerTrusted || count (do p <- presence; where p.server == e.server; where p.expiresAt > t; yield p) > 0
943951 yield e
944952 let trustedOffline = do
945953 e <- offlineEntries
946− where e.server == fromServer || fromServerTrusted || count (do p <- presence; where p.server == e.server; yield p) > 0
954+ where e.server == fromServer || fromServerTrusted || count (do p <- presence; where p.server == e.server; where p.expiresAt > t; yield p) > 0
947955 yield e
948956 let appliedOnline = do
949957 e <- trustedDeduped