]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add home_server_lifetime, and update docs
authorAlan T. DeKok <aland@freeradius.org>
Wed, 12 Feb 2025 15:58:50 +0000 (10:58 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 12 Feb 2025 15:59:12 +0000 (10:59 -0500)
raddb/mods-available/radius
src/modules/rlm_radius/bio.c
src/modules/rlm_radius/rlm_radius.c
src/modules/rlm_radius/rlm_radius.h

index 770d33cf767988144e0fccc9941451eff8fc3619..4923950e7b72a37c955a506fb8e648ae99ec4f95 100644 (file)
@@ -587,7 +587,7 @@ radius {
        #
 
        #
-       #  ### Access requests packets
+       #  ### Access Request packets
        #
        Access-Request {
                #
@@ -767,14 +767,42 @@ radius replicate {
 }
 
 #
-#  A dynamic proxy module
+#  ## Dynamic Proxying
+#
+#  This module supports dynamic proxying via a run-time function:
+#
+#      %proxy.sendto.ipaddr(127.0.0.1, 1812, "testing123")
+#
+#  The first part of the function name (e.g. `proxy`) is taken from
+#  the module name.  The rest is fixed as `sendto.ipaddr()`
+#
+#  The arguments to the function are:
+#
+#  * destination IP address.
+#  * destination port
+#  * shared secret
+#
+#  The function will return the type of response packet if it receives
+#  as a response, or else the function all will fail.
+#
+#      if (%proxy.sendto.ipaddr(127.0.0.1, 1812, "testing123") == 'Access-Accept') {
+#        ...
+#      }
+#
+#  The packet name must be a quoted string.
+#
+#  The proxying is done asynchronously.  i.e. the packet is sent, and
+#  the server goes on to do other work.  At some point in the future,
+#  a response is received, the module processes it, and the server
+#  continues.
+#
+#  The timeouts are controlled as described above.
 #
 radius proxy {
        type = Access-Request
 
        #
-       #  We are not opening a socket from our server to their
-       #  server.  We are replicating packets.
+       #  The mode.
        #
        mode = dynamic-proxy
 
@@ -813,12 +841,12 @@ radius proxy {
                #  These two configuratiuon items can only be used for
                #  UDP sockets.
                #
-#              src_port_start = 10000
+               src_port_start = 10000
 
                #
                #  src_port_end:: End of source port range.
                #
-#              src_port_end = 11000
+               src_port_end = 11000
 
                #
                #  `src_port` cannot be used.  If it is used here, the
@@ -830,6 +858,55 @@ radius proxy {
                #
        }
 
+       #
+       #  Dynamic proxying does *not* support the `status_check`
+       #  section.
+       #
+
+       #
+       #  home_server_lifetime:: The lifetime of the home server.
+       #
+       #  When a new dynamic home server is used, the module caches
+       #  information about it.  So long as the home server is still
+       #  being used, it will not expire.  But if it has received all
+       #  expected responses (or timeouts), _and_ it has reached its
+       #  expected lifetime, then the home server will be deleted.
+       #
+       #  This process allows for the secret to change over time.
+       #  However, the secret can only be changed if there are no
+       #  outstanding packets.  Otherwise, changing the secret would
+       #  involve having multiple packets outstanding which have
+       #  different secrets.  That doesn't work, and can't be fixed
+       #  through any code changes on the server.
+       #
+       #  The solution to that is to switch to using TLS.
+       #
+       home_server_lifetime = 3600
+
+       #
+       #  These are allowed, but are less useful.  If the home server
+       #  doesn't respond, it will often just hit the home server
+       #  lifetime, and be deleted.
+       #
+       response_window = 15
+       zombie_period = 10
+       revive_interval = 3600
+
+
+       #
+       #  ## Timeouts
+       #
+       #  Timeouts for proxying are controlled in sections named for
+       #  the packet type.  See the examples above for full
+       #  documentation.
+       #
+       Access-Request {
+               initial_rtx_time = 2
+               max_rtx_time = 16
+               max_rtx_count = 5
+               max_rtx_duration = 30
+       }
+
        #
        #  ## Connection trunking
        #
index 5c6c120b9b7fcb30cda76e4ad0209ed49eb7d5c7..3a1a4c99de8812375a26dfe405b4d3060e968862 100644 (file)
@@ -2439,11 +2439,8 @@ static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
 
        switch (inst->mode) {
        case RLM_RADIUS_MODE_XLAT_PROXY:
-               /*
-                *      @todo - make lifetime configurable?
-                */
                fr_rb_expire_inline_talloc_init(&thread->bio.expires, home_server_t, expire, home_server_cmp, home_server_free,
-                                               fr_time_delta_from_sec(60));
+                                               inst->home_server_lifetime);
                FALL_THROUGH;
 
        default:
index 48e081d32c449fe6794222d5815c3b4b4a225c46..f7eadc37bf521a7f086fb6bcdb2ceb26a5e52a46 100644 (file)
@@ -162,6 +162,8 @@ static conf_parser_t const module_config[] = {
 
        { FR_CONF_OFFSET("revive_interval", rlm_radius_t, revive_interval) },
 
+       { FR_CONF_OFFSET("home_server_lifetime", rlm_radius_t, home_server_lifetime) },
+
        CONF_PARSER_TERMINATOR
 };
 
@@ -721,6 +723,12 @@ check_others:
                FR_INTEGER_BOUND_CHECK("trunk.per_connection_max", inst->trunk_conf.max_req_per_conn, >=, 2);
                FR_INTEGER_BOUND_CHECK("trunk.per_connection_max", inst->trunk_conf.max_req_per_conn, <=, 255);
                FR_INTEGER_BOUND_CHECK("trunk.per_connection_target", inst->trunk_conf.target_req_per_conn, <=, inst->trunk_conf.max_req_per_conn / 2);
+
+               /*
+                *      This only applies for XLAT_PROXY, but what the heck.
+                */
+               FR_TIME_DELTA_BOUND_CHECK("home_server_lifetime", inst->home_server_lifetime, >=, fr_time_delta_from_sec(10));
+               FR_TIME_DELTA_BOUND_CHECK("home_server_lifetime", inst->home_server_lifetime, <=, fr_time_delta_from_sec(3600));
                break;
 
        case RLM_RADIUS_MODE_UNCONNECTED_REPLICATE:
index 8d6a2f9195f19ac2d64b48cd522e7b0e47c57e1e..02b3b3e0925a31f42a62da3667f219330fe3848c 100644 (file)
@@ -59,6 +59,8 @@ struct rlm_radius_s {
        fr_time_delta_t         zombie_period;
        fr_time_delta_t         revive_interval;
 
+       fr_time_delta_t         home_server_lifetime;   //!< for XLAT_PROXY
+
        char const              *secret;                //!< Shared secret.
 
        uint32_t                max_packet_size;        //!< Maximum packet size.