]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow it to be listed in the "authorize" section
authorAlan T. DeKok <aland@freeradius.org>
Fri, 6 Jun 2025 13:25:46 +0000 (09:25 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 6 Jun 2025 13:25:46 +0000 (09:25 -0400)
doc/ChangeLog
raddb/mods-available/proxy_rate_limit
src/modules/rlm_proxy_rate_limit/rlm_proxy_rate_limit.c

index eb1a47e0a164928f3e2a26723ffa986a886d8d94..6a05abbdab04867a6d0514a9408371b8fd94a4db 100644 (file)
@@ -33,6 +33,8 @@ FreeRADIUS 3.2.8 Fri 31 Jan 2025 12:00:00 UTC urgency=low
        * Add delay_proxy_rejects, and ensure that reject_delay
          will delay for at least that time, and does not always
          add a delay.
+       * The proxy_rate_limit module can now be listed in the
+         "authorize" section.
 
        Bug fixes
        * Move assertion in thread / queue code, which only affects
index e7db410a8c3d300e9552731c037fa55186137290..4471734a0a628ba42c844d7bb71ca3cff847491b 100644 (file)
 #              ...
 #      }
 #
+#  The module can also be listed in the "authorize" section.  Listing
+#  it there as the first module allows the server to reject bad
+#  packets as quickly as possible, while doing zero additional work
+#  for policies, database lookups, etc.
+#
+#  If it is listed in the "authorize" section, then it should not be
+#  listed in the "pre-proxy" section.
+#
 
 #
 #  The module configuration.
index 1fe5bcc7415247e903312b91b8b9c24b9b13ee41..1f8b348dc4802ecc7cde5f95e2cc96ccc0f7302d 100644 (file)
@@ -190,29 +190,28 @@ static rlm_proxy_rate_limit_table_t* derive_key_and_table(rlm_proxy_rate_limit_t
  *     Check whether we have recently seen repeated Access-Rejects for this username
  *      and calling station, and if this is a new request then issue an Access-Reject
  */
-static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void * instance, REQUEST *request)
+static int CC_HINT(nonnull) mod_common(void * instance, REQUEST *request)
 {
        rlm_proxy_rate_limit_t          *inst = instance;
        char                            key[512];
        size_t                          key_len = sizeof(key);
        rlm_proxy_rate_limit_table_t    *table;
        rlm_proxy_rate_limit_entry_t    *entry, my_entry;
-       VALUE_PAIR                      *vp;
 
        if (!(table = derive_key_and_table(inst, request, key, &key_len)))
-               return RLM_MODULE_OK;
+               return 0;
 
        my_entry.key = key;
        my_entry.key_len = key_len;
        entry = rbtree_finddata(table->tree, &my_entry);
 
        if (!entry)
-               return RLM_MODULE_OK;
+               return 0;
 
        if (entry->expires <= request->timestamp) {
                RDEBUG3("Rate limit entry %.*s (%d) has expired", 6, entry->key, entry->table->id);
                rbtree_deletebydata(table->tree, entry);
-               return RLM_MODULE_OK;
+               return 0;
        };
 
        /*
@@ -224,7 +223,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void * instance, REQUEST *requ
         *      retransmissions.
         */
        if (!entry->active || entry->last_id == request->packet->id)
-               return RLM_MODULE_OK;
+               return 0;
 
        RDEBUG("Active rate limit entry %.*s (%d) matched for new request. Cancelling proxy "
                "and sending Access-Reject. Instance %d.", 6, entry->key, entry->table->id, entry->count);
@@ -252,6 +251,14 @@ static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void * instance, REQUEST *requ
 
        entry->last_request = request->timestamp;
        entry->count++;
+       return -1;
+}
+
+static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void * instance, REQUEST *request)
+{
+       VALUE_PAIR                      *vp;
+
+       if (mod_common(instance, request) == 0) return RLM_MODULE_NOOP;
 
        /*
         *  This new request arrived within the suppression interval. Don't proxy but
@@ -269,7 +276,21 @@ static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void * instance, REQUEST *requ
                REDEBUG("Failed creating Reply-Message");
 
        return RLM_MODULE_FAIL;
+}
+
+static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void * instance, REQUEST *request)
+{
+       VALUE_PAIR                      *vp;
+
+       if (mod_common(instance, request) == 0) return RLM_MODULE_NOOP;
+
+       fr_pair_list_free(&request->reply->vps);
+
+       vp = pair_make_reply("Reply-Message", "Proxy rate limit exceeded", T_OP_EQ);
+       if (!vp)
+               REDEBUG("Failed creating Reply-Message");
 
+       return RLM_MODULE_REJECT;
 }
 
 /*
@@ -506,6 +527,7 @@ module_t rlm_proxy_rate_limit = {
        .instantiate    = mod_instantiate,
        .detach         = mod_detach,
        .methods = {
+               [MOD_AUTHORIZE]         = mod_authorize,
                [MOD_PRE_PROXY]         = mod_pre_proxy,
                [MOD_POST_PROXY]        = mod_post_proxy,
        },