From ce6be5df61ee49f672a1cc940f8dc2ef7f97aff8 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Wed, 25 May 2022 16:28:45 +0200 Subject: [PATCH] Reputation was synced correctly on IP basis (and thus the databases) across servers if they differed, however the individual IP of users was not updated until next add_scores() run. So, there would be an up to 5 minute delay during which scores for individual users were possibly too low, with all the effects that it could possibly have nowadays such as restrict-commands, more stringent flood limits, etc. If your servers are all linked all the time then you would not have noticed this issue. It mostly matters if you are linking in a new server or if the server has been delinked or out of order for days or weeks. --- doc/RELEASE-NOTES.md | 2 ++ src/modules/reputation.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md index 6d7eb63c5..ea2bed7b0 100644 --- a/doc/RELEASE-NOTES.md +++ b/doc/RELEASE-NOTES.md @@ -89,6 +89,8 @@ about UnrealIRCd 6. * [`set::modes-on-join`](https://www.unrealircd.org/docs/Set_block#set::modes-on-join) did not work with `+f` + timed bans properly, eg `[3t#b1]:10` * Several log messages were missing some information. +* Reputation syncing across servers had a small glitch. Fix is mostly + useful for servers that were not linked to the network for days or weeks. ### Changes: * Clarified that UnrealIRCd is licensed as "GPLv2 or later" diff --git a/src/modules/reputation.c b/src/modules/reputation.c index b509d2a9a..ca9a58087 100644 --- a/src/modules/reputation.c +++ b/src/modules/reputation.c @@ -918,6 +918,24 @@ static inline int is_reputation_expired(ReputationEntry *e) return 0; } +/** If the reputation changed (due to server syncing) then update the + * individual users reputation score as well. + */ +void reputation_changed_update_users(ReputationEntry *e) +{ + Client *client; + + list_for_each_entry(client, &client_list, client_node) + { + if (client->ip && !strcmp(e->ip, client->ip)) + { + /* With some (possibly unneeded) care to only go forward */ + if (Reputation(client) < e->score) + Reputation(client) = e->score; + } + } +} + EVENT(delete_old_records) { int i; @@ -1279,6 +1297,7 @@ CMD_FUNC(reputation_server_cmd) log_data_integer("score", e->score)); #endif e->score = score; + reputation_changed_update_users(e); } /* If we don't have any entry for this IP, add it now. */ @@ -1296,6 +1315,7 @@ CMD_FUNC(reputation_server_cmd) e->score = score; e->last_seen = TStime(); add_reputation_entry(e); + reputation_changed_update_users(e); } /* Propagate to the non-client direction (score may be updated) */