]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/journal/journald-rate-limit.c
dns-domain: add code for verifying validity of DNS-SD service names and types
[thirdparty/systemd.git] / src / journal / journald-rate-limit.c
index 8bd68476a39764e13eb1ff16afc218266af43cb8..1c406aef8ebd2e5e9bcc6351e03ad2ff7757d228 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <string.h>
 #include <errno.h>
+#include <string.h>
 
+#include "alloc-util.h"
+#include "hashmap.h"
 #include "journald-rate-limit.h"
 #include "list.h"
+#include "random-util.h"
+#include "string-util.h"
 #include "util.h"
-#include "hashmap.h"
 
 #define POOLS_MAX 5
 #define BUCKETS_MAX 127
@@ -56,7 +59,7 @@ struct JournalRateLimitGroup {
 
         char *id;
         JournalRateLimitPool pools[POOLS_MAX];
-        unsigned hash;
+        uint64_t hash;
 
         LIST_FIELDS(JournalRateLimitGroup, bucket);
         LIST_FIELDS(JournalRateLimitGroup, lru);
@@ -70,6 +73,8 @@ struct JournalRateLimit {
         JournalRateLimitGroup *lru, *lru_tail;
 
         unsigned n_groups;
+
+        uint8_t hash_key[16];
 };
 
 JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
@@ -84,6 +89,8 @@ JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
         r->interval = interval;
         r->burst = burst;
 
+        random_bytes(r->hash_key, sizeof(r->hash_key));
+
         return r;
 }
 
@@ -96,8 +103,8 @@ static void journal_rate_limit_group_free(JournalRateLimitGroup *g) {
                 if (g->parent->lru_tail == g)
                         g->parent->lru_tail = g->lru_prev;
 
-                LIST_REMOVE(JournalRateLimitGroup, lru, g->parent->lru, g);
-                LIST_REMOVE(JournalRateLimitGroup, bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
+                LIST_REMOVE(lru, g->parent->lru, g);
+                LIST_REMOVE(bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
 
                 g->parent->n_groups --;
         }
@@ -115,7 +122,7 @@ void journal_rate_limit_free(JournalRateLimit *r) {
         free(r);
 }
 
-static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) {
+_pure_ static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) {
         unsigned i;
 
         assert(g);
@@ -140,6 +147,7 @@ static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) {
 
 static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
         JournalRateLimitGroup *g;
+        struct siphash state;
 
         assert(r);
         assert(id);
@@ -152,12 +160,14 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
         if (!g->id)
                 goto fail;
 
-        g->hash = string_hash_func(g->id);
+        siphash24_init(&state, r->hash_key);
+        string_hash_func(g->id, &state);
+        g->hash = siphash24_finalize(&state);
 
         journal_rate_limit_vacuum(r, ts);
 
-        LIST_PREPEND(JournalRateLimitGroup, bucket, r->buckets[g->hash % BUCKETS_MAX], g);
-        LIST_PREPEND(JournalRateLimitGroup, lru, r->lru, g);
+        LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g);
+        LIST_PREPEND(lru, r->lru, g);
         if (!g->lru_next)
                 r->lru_tail = g;
         r->n_groups ++;
@@ -170,21 +180,6 @@ fail:
         return NULL;
 }
 
-static uint64_t u64log2(uint64_t n) {
-        unsigned r;
-
-        if (n <= 1)
-                return 0;
-
-        r = 0;
-        for (;;) {
-                n = n >> 1;
-                if (!n)
-                        return r;
-                r++;
-        }
-}
-
 static unsigned burst_modulate(unsigned burst, uint64_t available) {
         unsigned k;
 
@@ -214,9 +209,10 @@ static unsigned burst_modulate(unsigned burst, uint64_t available) {
 }
 
 int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
-        unsigned h;
+        uint64_t h;
         JournalRateLimitGroup *g;
         JournalRateLimitPool *p;
+        struct siphash state;
         unsigned burst;
         usec_t ts;
 
@@ -232,7 +228,9 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
 
         ts = now(CLOCK_MONOTONIC);
 
-        h = string_hash_func(id);
+        siphash24_init(&state, r->hash_key);
+        string_hash_func(id, &state);
+        h = siphash24_finalize(&state);
         g = r->buckets[h % BUCKETS_MAX];
 
         LIST_FOREACH(bucket, g, g)