@@ -482,12 +482,10 @@ addServerToList = \listRef server -> atomic do
482-- Remove `server` from the named list ref. Returns whether it was present.
482-- Remove `server` from the named list ref. Returns whether it was present.
483removeServerFromList = \listRef server -> atomic do
483removeServerFromList = \listRef server -> atomic do
484 current <- *listRef
484 current <- *listRef
485− pruneRef listRef (\x -> x != server)
485+ set *listRef = removeWhere current (\x -> x == server)
486 yield (elem current server)
486 yield (elem current server)
488−headOf = \items -> fold (\acc x -> case acc of
488+headOf = \items -> fold (\_ x -> Just {value: x}) Nothing {} (take 1 items)
489− Nothing {} -> Just {value: x}
490− _ -> acc) Nothing {} items
492-- Sort then take head: O(n log n) but no fold-with-Maybe boilerplate.
490-- Sort then take head: O(n log n) but no fold-with-Maybe boilerplate.
493minBy = \items getKey -> headOf (sortBy getKey items)
491minBy = \items getKey -> headOf (sortBy getKey items)
@@ -560,18 +558,13 @@ tooLong : Text -> Int -> Bool
560tooLong = \s maxLen -> count (chars s) > maxLen
558tooLong = \s maxLen -> count (chars s) > maxLen
562isValidHex : Text -> Bool
560isValidHex : Text -> Bool
566− n > 0 && mod n 2 == 0 && all cs (\c -> contains c "0123456789abcdef")
561+isValidHex = \s -> let cs = chars s in count cs > 0 && mod (count cs) 2 == 0 && all cs (\c -> contains c "0123456789abcdef")
568normalizeHex : Text -> Text
563normalizeHex : Text -> Text
569normalizeHex = \s -> bytesToHex (bytesFromHex s)
564normalizeHex = \s -> bytesToHex (bytesFromHex s)
571stripTrailingDot : Text -> Text
566stripTrailingDot : Text -> Text
572−stripTrailingDot = \s ->
573− let n = count (chars s) in
574− if n > 0 && drop (n - 1) s == "." then stripTrailingDot (take (n - 1) s) else s
567+stripTrailingDot = \s -> if containsSuffix "." s then stripTrailingDot (take (count (chars s) - 1) s) else s
576normalizeServerName : Text -> Text
569normalizeServerName : Text -> Text
577normalizeServerName = \s -> toLower (stripTrailingDot s)
570normalizeServerName = \s -> toLower (stripTrailingDot s)
@@ -581,6 +574,9 @@ serverHostN = normalizeServerName serverHost
581isLocalServer : Text -> Bool
574isLocalServer : Text -> Bool
582isLocalServer = \s -> s == serverHostN
575isLocalServer = \s -> s == serverHostN
577+hasPrefix : Text -> Text -> Bool
578+hasPrefix = \pre s -> take (count (chars pre)) s == pre
584containsSuffix : Text -> Text -> Bool
580containsSuffix : Text -> Text -> Bool
585containsSuffix = \suffix s ->
581containsSuffix = \suffix s ->
586 let d = count (chars s) - count (chars suffix) in
582 let d = count (chars s) - count (chars suffix) in
@@ -592,8 +588,8 @@ isBadServerName : Text -> Bool
592isBadServerName = \sn ->
588isBadServerName = \sn ->
593 sn == "" || sn == "localhost"
589 sn == "" || sn == "localhost"
594 || not (all (chars sn) (\c -> contains c "0123456789abcdefghijklmnopqrstuvwxyz-.:"))
590 || not (all (chars sn) (\c -> contains c "0123456789abcdefghijklmnopqrstuvwxyz-.:"))
595− || any [".", ":", "[", "127.", "10.", "192.168.", "169.254.", "0.", "::"] (\pre -> take (count (chars pre)) sn == pre)
591+ || any [".", ":", "[", "127.", "10.", "192.168.", "169.254.", "0.", "::"] (\p -> hasPrefix p sn)
596− || any [".localhost", ".local", ".internal", ".arpa", ".onion"] (\suf -> containsSuffix suf sn)
592+ || any [".localhost", ".local", ".internal", ".arpa", ".onion"] (\s -> containsSuffix s sn)
598-- ============================================
594-- ============================================
599-- Auth helpers
595-- Auth helpers
@@ -890,10 +886,9 @@ recordAcksAndDeliveries = \toAck t -> do
890applyCancel = \msgs matches to mid t -> do
886applyCancel = \msgs matches to mid t -> do
891 set *messages = removeWhere msgs matches
887 set *messages = removeWhere msgs matches
892 fwds <- *forwards
888 fwds <- *forwards
893− let fwdServers = collectPeers (filter fwds matches) (\f -> f.toServer)
889+ set *forwards = removeWhere fwds matches
894− pruneRef forwards (\f -> not (matches f))
895 appendCapped cancelNotifications [{toKey: to, messageId: mid, cancelledAt: t}] 10000 (\c -> c.cancelledAt)
890 appendCapped cancelNotifications [{toKey: to, messageId: mid, cancelledAt: t}] 10000 (\c -> c.cancelledAt)
896− yield fwdServers
891+ yield (collectPeers (filter fwds matches) (\f -> f.toServer))
898sendBatchedGossip = \peers events hops -> forEach peers id (\server -> do
893sendBatchedGossip = \peers events hops -> forEach peers id (\server -> do