@@ -506,7 +506,11 @@ sendAcksAndClean = \pendingAcks servers ->
506 originServer: server, fromServer: serverHostN})
506 originServer: server, fromServer: serverHostN})
507 atomic do
507 atomic do
508 ackedIds <- *ackedIds
508 ackedIds <- *ackedIds
509+ let ackMsgIds = do a <- serverAcks; yield a.messageId
509− set *ackedIds = diff ackedIds serverAcks) (\err ->
510+ set *ackedIds = do
512+ where not (a.originServer == server && count (do mid <- ackMsgIds; where mid == a.messageId; yield mid) > 0)
510 println ("federation: error sending ack to " ++ server ++ ": " ++ show err))
514 println ("federation: error sending ack to " ++ server ++ ": " ++ show err))
511 sendAcksAndClean pendingAcks rest
515 sendAcksAndClean pendingAcks rest
@@ -635,12 +639,14 @@ serve = \req -> case req of
635 else if not (isValidHex pubkey) || not (isValidHex signature)
639 else if not (isValidHex pubkey) || not (isValidHex signature)
636 then False {}
640 then False {}
637 else verify (bytesFromHex pubkey) (textToBytes challenge) (bytesFromHex signature)
641 else verify (bytesFromHex pubkey) (textToBytes challenge) (bytesFromHex signature)
642+ set *challenges = if sigValid
638− set *challenges = case matched of
643+ then (case matched of
639− Just {value: _} -> do
644+ Just {value: _} -> do
640− c <- challenges
645+ c <- challenges
641− where not (c.pubkey == pubkey && c.challenge == challenge)
646+ where not (c.pubkey == pubkey && c.challenge == challenge)
643− Nothing {} -> challenges
648+ Nothing {} -> challenges)
644 let existingForKey = do
650 let existingForKey = do
645 s <- sessions
651 s <- sessions
646 where s.pubkey == pubkey
652 where s.pubkey == pubkey
@@ -654,15 +660,16 @@ serve = \req -> case req of
654 let sessionsCapped = if count existingForKey >= maxSessionsPerKey && oldestExpiry >= 0
660 let sessionsCapped = if count existingForKey >= maxSessionsPerKey && oldestExpiry >= 0
655 then cappedFold.sessions
661 then cappedFold.sessions
656 else sessions
662 else sessions
663+ let activeSessionsCapped = do s <- sessionsCapped; where s.expiresAt > t; yield s
657− let globalOldestSessionExpiry = if count sessionsCapped >= maxSessions
664+ let globalOldestSessionExpiry = if count activeSessionsCapped >= maxSessions
658− then fold (\acc s -> if acc == -1 || s.expiresAt < acc then s.expiresAt else acc) -1 sessionsCapped
665+ then fold (\acc s -> if acc == -1 || s.expiresAt < acc then s.expiresAt else acc) -1 activeSessionsCapped
660 let globalSessionsCapped = if globalOldestSessionExpiry >= 0
667 let globalSessionsCapped = if globalOldestSessionExpiry >= 0
661 then (fold (\acc s ->
668 then (fold (\acc s ->
662 if not acc.removed && s.expiresAt == globalOldestSessionExpiry
669 if not acc.removed && s.expiresAt == globalOldestSessionExpiry
663 then {removed: True {}, items: acc.items}
670 then {removed: True {}, items: acc.items}
664− else {removed: acc.removed, items: union acc.items [s]}) {removed: False {}, items: []} sessionsCapped).items
671+ else {removed: acc.removed, items: union acc.items [s]}) {removed: False {}, items: []} activeSessionsCapped).items
665− else sessionsCapped
672+ else activeSessionsCapped
666 set *sessions = if sigValid
673 set *sessions = if sigValid
667 then union globalSessionsCapped [{token: token, pubkey: pubkey, expiresAt: expiry}]
674 then union globalSessionsCapped [{token: token, pubkey: pubkey, expiresAt: expiry}]
668 else sessions
675 else sessions
@@ -829,18 +836,11 @@ serve = \req -> case req of
829 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
836 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
830 ackedIds <- *ackedIds
837 ackedIds <- *ackedIds
831 let combinedAckedIds = union ackedIds ackedFederated
838 let combinedAckedIds = union ackedIds ackedFederated
832− let excessCount = count combinedAckedIds - maxAckedIds
833− let afterEviction = if excessCount <= 0
834− then combinedAckedIds
835− else evictOldestAckedIds combinedAckedIds excessCount
836− let evictedEntries = if excessCount <= 0
838− else diff combinedAckedIds afterEviction
839− set *ackedIds = afterEviction
839+ set *ackedIds = combinedAckedIds
840 let ok = case session of
840 let ok = case session of
841 Nothing {} -> False {}
841 Nothing {} -> False {}
842 _ -> True {}
842 _ -> True {}
843− yield {ok: ok, ackedMessages: ackedMessages, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, evictedEntries: evictedEntries}
843+ yield {ok: ok, ackedMessages: ackedMessages, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers}
844 let fedMessages = do
844 let fedMessages = do
845 m <- result.ackedMessages
845 m <- result.ackedMessages
846 where not (m.originServer == "")
846 where not (m.originServer == "")
@@ -857,8 +857,18 @@ serve = \req -> case req of
857 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
857 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
858 sendAcksAndClean pendingAcks originServers
858 sendAcksAndClean pendingAcks originServers
859 else yield {}
859 else yield {}
860+ evictedEntries <- atomic do
861+ ackedIds <- *ackedIds
862+ let excessCount = count ackedIds - maxAckedIds
866+ let afterEviction = evictOldestAckedIds ackedIds excessCount
867+ let evicted = diff ackedIds afterEviction
868+ set *ackedIds = afterEviction
860 let evictedToRetry = do
870 let evictedToRetry = do
861− a <- result.evictedEntries
871+ a <- evictedEntries
862 where count (do m <- fedMessages; where m.messageId == a.messageId; where m.toKey == a.toKey; yield m) == 0
872 where count (do m <- fedMessages; where m.messageId == a.messageId; where m.toKey == a.toKey; yield m) == 0
864 if count evictedToRetry > 0 && not (federationSecret == "")
874 if count evictedToRetry > 0 && not (federationSecret == "")
@@ -1031,7 +1041,7 @@ serve = \req -> case req of
1031 o <- trustedOffline
1041 o <- trustedOffline
1032 where o.pubkey == k.pubkey
1042 where o.pubkey == k.pubkey
1033 where o.server == k.server
1043 where o.server == k.server
1034− where o.timestamp > p.timestamp
1044+ where (if o.timestamp > t then t else o.timestamp) > p.timestamp
1035 yield o) > 0
1045 yield o) > 0
1036 yield p) > 0
1046 yield p) > 0
1037 yield {pubkey: k.pubkey, server: k.server}
1047 yield {pubkey: k.pubkey, server: k.server}
@@ -1044,7 +1054,7 @@ serve = \req -> case req of
1044 o <- trustedOffline
1054 o <- trustedOffline
1045 where o.pubkey == k.pubkey
1055 where o.pubkey == k.pubkey
1046 where o.server == k.server
1056 where o.server == k.server
1047− where o.timestamp > p.timestamp
1057+ where (if o.timestamp > t then t else o.timestamp) > p.timestamp
1048 yield o) > 0
1058 yield o) > 0
1049 yield p)
1059 yield p)
1050 let withinCapacity = count afterOffline <= maxPresenceEntries
1060 let withinCapacity = count afterOffline <= maxPresenceEntries
@@ -1075,7 +1085,7 @@ serve = \req -> case req of
1075 o <- trustedOffline
1085 o <- trustedOffline
1076 where o.pubkey == k.pubkey
1086 where o.pubkey == k.pubkey
1077 where o.server == k.server
1087 where o.server == k.server
1078− where o.timestamp > p.timestamp
1088+ where (if o.timestamp > t then t else o.timestamp) > p.timestamp
1079 yield o) > 0
1089 yield o) > 0
1080 yield p)
1090 yield p)
1081 let reclaimCapacity = if withinCapacity then 0 else maxPresenceEntries - count updatesOnlyAfterOffline
1091 let reclaimCapacity = if withinCapacity then 0 else maxPresenceEntries - count updatesOnlyAfterOffline
@@ -1259,17 +1269,20 @@ serve = \req -> case req of
1260 yield {expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, pendingForwards: pendingForwards, pendingAcks: pendingAcks}
1270 yield {expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, pendingForwards: pendingForwards, pendingAcks: pendingAcks}
1261 respond {ok: True {}}
1271 respond {ok: True {}}
1262− broadcastOfflineGossip t result.peerServers result.expiredLocal
1272+ catch (broadcastOfflineGossip t result.peerServers result.expiredLocal) (\err ->
1273+ println ("prune: gossip failed: " ++ show err))
1263− if not (federationSecret == "") && count result.pendingForwards > 0
1274+ catch (if not (federationSecret == "") && count result.pendingForwards > 0
1264 then retryPendingForwards result.pendingForwards
1275 then retryPendingForwards result.pendingForwards
1265− else yield {}
1276+ else yield {}) (\err ->
1277+ println ("prune: forward retry failed: " ++ show err))
1266− if not (federationSecret == "") && count result.pendingAcks > 0
1278+ catch (if not (federationSecret == "") && count result.pendingAcks > 0
1268 let ackOriginServers = fold (\acc a ->
1280 let ackOriginServers = fold (\acc a ->
1269 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
1281 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
1270 else union acc [a.originServer]) [] result.pendingAcks
1282 else union acc [a.originServer]) [] result.pendingAcks
1271 sendAcksAndClean result.pendingAcks ackOriginServers
1283 sendAcksAndClean result.pendingAcks ackOriginServers
1272− else yield {}
1284+ else yield {}) (\err ->
1285+ println ("prune: ack send failed: " ++ show err))
1273 else respond {ok: False {}}
1286 else respond {ok: False {}}
1275-- ============================================
1288-- ============================================
@@ -1294,17 +1307,20 @@ backgroundPrune = do
1294 where not (a.originServer == serverHostN)
1307 where not (a.originServer == serverHostN)
1296 yield {expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, pendingForwards: pendingForwards, pendingAcks: pendingAcks}
1309 yield {expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, pendingForwards: pendingForwards, pendingAcks: pendingAcks}
1297− broadcastOfflineGossip t result.peerServers result.expiredLocal
1310+ catch (broadcastOfflineGossip t result.peerServers result.expiredLocal) (\err ->
1311+ println ("background prune: gossip failed: " ++ show err))
1298− if not (federationSecret == "") && count result.pendingForwards > 0
1312+ catch (if not (federationSecret == "") && count result.pendingForwards > 0
1299 then retryPendingForwards result.pendingForwards
1313 then retryPendingForwards result.pendingForwards
1300− else yield {}
1314+ else yield {}) (\err ->
1315+ println ("background prune: forward retry failed: " ++ show err))
1301− if not (federationSecret == "") && count result.pendingAcks > 0
1316+ catch (if not (federationSecret == "") && count result.pendingAcks > 0
1303 let ackOriginServers = fold (\acc a ->
1318 let ackOriginServers = fold (\acc a ->
1304 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
1319 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
1305 else union acc [a.originServer]) [] result.pendingAcks
1320 else union acc [a.originServer]) [] result.pendingAcks
1306 sendAcksAndClean result.pendingAcks ackOriginServers
1321 sendAcksAndClean result.pendingAcks ackOriginServers
1307 else yield {}) (\err ->
1322 else yield {}) (\err ->
1323+ println ("background prune: ack send failed: " ++ show err))) (\err ->
1308 println ("background prune: " ++ show err))
1324 println ("background prune: " ++ show err))
1309 backgroundPrune
1325 backgroundPrune