]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add Proxy-State if requested
authorAlan T. DeKok <aland@freeradius.org>
Sun, 19 May 2024 14:40:44 +0000 (10:40 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 21 May 2024 22:20:57 +0000 (18:20 -0400)
src/protocols/radius/client.c
src/protocols/radius/client.h

index d45bb2e9fbbea33d782300510f97418fcbf4b535..b6057ef9b9c4c09a06cab7168ae7c89d6e0dbe1d 100644 (file)
@@ -29,6 +29,8 @@ RCSID("$Id$")
 #include <freeradius-devel/radius/client_tcp.h>
 #include <freeradius-devel/radius/client_priv.h>
 
+#include <freeradius-devel/protocol/radius/rfc2865.h>
+
 static void radius_client_retry_sent(fr_bio_t *bio, void *packet_ctx, const void *buffer, UNUSED size_t size,
                                     fr_bio_retry_entry_t *retry_ctx);
 static bool radius_client_retry_response(fr_bio_t *bio, fr_bio_retry_entry_t **retry_ctx_p, UNUSED void *packet_ctx, const void *buffer, UNUSED size_t size);
@@ -131,6 +133,7 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t
 int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *request_ctx, fr_packet_t *packet, fr_pair_list_t *list)
 {
        ssize_t slen;
+       uint8_t *end;
        fr_radius_id_ctx_t *id_ctx;
 
        fr_assert(!packet->data);
@@ -184,7 +187,26 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *request_c
                fr_radius_code_id_push(my->codes, packet);
                return fr_bio_error(GENERIC);
        }
-       packet->data_len = (size_t) slen;
+
+       end = my->buffer + slen;
+
+       /*
+        *      Add our own Proxy-State if requested.
+        *
+        *      @todo - don't add Proxy-State for status checks, which could also be Access-Request or
+        *      Accounting-Request.  Note also that Status-Server packets should bypass the normal write
+        *      routines, and instead be run by internal timers.
+        */
+       if (my->cfg.add_proxy_state && (packet->code != FR_RADIUS_CODE_STATUS_SERVER) && ((end + 6) < (my->buffer + sizeof(my->buffer)))) {
+               end[0] = FR_PROXY_STATE;
+               end[1] = 6;
+               memcpy(&end[2], &my->cfg.proxy_state, sizeof(my->cfg.proxy_state));
+
+               end += 6;
+       }
+
+       packet->data_len = end - my->buffer;
+       fr_nbo_from_uint64(my->buffer + 2, packet->data_len);
 
        packet->data = talloc_array(packet, uint8_t, packet->data_len);
        if (!packet->data) goto fail;
@@ -259,6 +281,7 @@ static void radius_client_retry_sent(fr_bio_t *bio, void *packet_ctx, const void
 //     if (buffer[0] != FR_RADIUS_CODE_ACCOUNTING_REQUEST) return;
 }
 
+
 static bool radius_client_retry_response(fr_bio_t *bio, fr_bio_retry_entry_t **retry_ctx_p, void *packet_ctx, const void *buffer, UNUSED size_t size)
 {
        fr_radius_client_fd_bio_t *my = talloc_get_type_abort(bio->uctx, fr_radius_client_fd_bio_t);
index a995ca8fc1a32b008c63001cc243913ad443df16..caae5860926f91aacbbf9429e59953d11cb78b80 100644 (file)
@@ -40,6 +40,9 @@ typedef struct {
 
        fr_bio_packet_cb_funcs_t pause_resume_cfg;
 
+       bool                    add_proxy_state;
+       uint32_t                proxy_state;
+
        bool                    outgoing[FR_RADIUS_CODE_MAX];   //!< allowed outgoing packet types
 
        fr_retry_config_t       retry[FR_RADIUS_CODE_MAX];      //!< default retry configuration for each packet type