]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
use new BIO packet APIs.
authorAlan T. DeKok <aland@freeradius.org>
Tue, 12 Nov 2024 18:39:30 +0000 (13:39 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 12 Nov 2024 19:33:01 +0000 (14:33 -0500)
src/bin/radclient-ng.c
src/lib/bio/packet.c
src/protocols/radius/client.c
src/protocols/radius/client.h
src/protocols/radius/client_priv.h

index ea610227f559c401bcf108c4ae85633862c429ac..55dfc93959f97d5fe5a1a64a56969346cbb6b558 100644 (file)
@@ -1756,13 +1756,14 @@ int main(int argc, char **argv)
         *
         ***********************************************************************/
 
-       client_config.retry_cfg.el = fr_event_list_alloc(autofree,
-                                                        (fr_debug_lvl >= 2) ? _loop_status : NULL,
-                                                        NULL);
-       if (!client_config.retry_cfg.el) {
+       client_config.el = fr_event_list_alloc(autofree,
+                                              (fr_debug_lvl >= 2) ? _loop_status : NULL,
+                                              NULL);
+       if (!client_config.el) {
                ERROR("Failed opening event list: %s", fr_strerror());
                fr_exit_now(EXIT_FAILURE);
        }
+       client_config.retry_cfg.el = client_config.el;
 
        /*
         *      Set callbacks so that the socket is automatically
index d3260f26ffc19c1fc6b443060cceffc0d1890de5..9d7cc7534eb0cdcc6eb230ef04acea10d7e6d7e9 100644 (file)
@@ -168,9 +168,8 @@ void fr_bio_packet_connected(fr_bio_t *bio)
        my->cb.connected(my);
 }
 
-static void fr_bio_packet_shutdown(fr_bio_t *bio)
+static void fr_bio_packet_shutdown(UNUSED fr_bio_t *bio)
 {
-       fr_assert(bio);
 }
 
 static void fr_bio_packet_eof(fr_bio_t *bio)
@@ -180,9 +179,8 @@ static void fr_bio_packet_eof(fr_bio_t *bio)
        if (my->cb.eof) my->cb.eof(my);
 }
 
-static void fr_bio_packet_failed(fr_bio_t *bio)
+static void fr_bio_packet_failed(UNUSED fr_bio_t *bio)
 {
-       fr_assert(bio);
 }
 
 
index 630e7179d79f46efc32c4dda268ff5c8fe8d0a12..7f8aab3f8a75c54077bed48ae18e2d3647dc3f3f 100644 (file)
@@ -143,15 +143,15 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t
 
        my->cfg = *cfg;
 
+       /*
+        *      Inform the packet BIO about our application callbacks.
+        */
+       my->common.cb = cfg->packet_cb_cfg;
 
        /*
-        *      Inform all BIOs about the write pause / resume callbacks
-        *
-        *      @todo - these callbacks are set AFTER the BIOs have been initialized, so the connected()
-        *      callback is never set, and therefore is never run.  We should add all of the callbacks to the
-        *      various bio "cfg" data structures.
+        *      Initialize the packet handlers in each BIO.
         */
-       fr_radius_client_bio_cb_set(&my->common, &cfg->packet_cb_cfg);
+       fr_bio_packet_init(&my->common);
 
        talloc_set_destructor(my, _radius_client_fd_bio_free);
 
@@ -166,7 +166,7 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t
         */
        if ((my->info.fd_info->type == FR_BIO_FD_CONNECTED) && !my->info.connected &&
            fr_time_delta_ispos(cfg->connection_timeout) && cfg->retry_cfg.el) {
-               if (fr_event_timer_in(my, cfg->retry_cfg.el, &my->ev, cfg->connection_timeout, fr_radius_client_bio_connect_timer, my) < 0) {
+               if (fr_event_timer_in(my, cfg->el, &my->common.ev, cfg->connection_timeout, fr_radius_client_bio_connect_timer, my) < 0) {
                        talloc_free(my);
                        return NULL;
                }
@@ -210,6 +210,9 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *pctx, fr_
                all_ids_used:
                        my->all_ids_used = true;
 
+                       /*
+                        *      Tell the application to stop writing data to the BIO.
+                        */
                        if (my->common.cb.write_blocked) my->common.cb.write_blocked(&my->common);
 
                        fr_strerror_const("All IDs are in use");
@@ -539,13 +542,15 @@ static void radius_client_retry_release(fr_bio_t *bio, fr_bio_retry_entry_t *ret
        my->info.outstanding--;
 
        /*
-        *      IO was blocked due to IDs.  We now have a free ID, so perhaps we can resume writes.  But only
-        *      if the IO handlers didn't mark us as "write blocked".
+        *      IO was blocked due to IDs.  We now have a free ID, so we resume the normal write process.
         */
        if (my->all_ids_used) {
                my->all_ids_used = false;
 
-               if (!my->common.write_blocked && my->common.cb.write_resume) my->common.cb.write_resume(&my->common);
+               /*
+                *      Tell the application to resume writing to the BIO.
+                */
+               if (my->common.cb.write_resume) my->common.cb.write_resume(&my->common);
 
        } else if (!my->info.outstanding) {
                my->info.last_idle = fr_time();
@@ -680,35 +685,6 @@ int fr_radius_client_bio_force_id(fr_bio_packet_t *bio, int code, int id)
        return fr_radius_code_id_force(my->codes, code, id);
 }
 
-static void fr_radius_client_bio_eof(fr_bio_t *bio)
-{
-       fr_radius_client_fd_bio_t *my = bio->uctx;
-
-       if (my->common.cb.eof) my->common.cb.eof(&my->common);
-}
-
-/** Callback for when the FD is connected, and the application can use it
- *
- */
-static void fr_radius_client_bio_connected(fr_bio_t *bio)
-{
-       fr_radius_client_fd_bio_t *my = bio->uctx;
-
-       fr_assert(!my->info.connected);
-
-       my->info.connected = true;
-
-       /*
-        *      Stop any connection timeout.
-        */
-       if (my->ev) talloc_const_free(&my->ev);
-
-       /*
-        *      Tell the application that the connection has been connected, and is now usable.
-        */
-       my->common.cb.connected(&my->common);
-}
-
 /** We failed to connect in the given timeout, the connection is dead.
  *
  */
@@ -718,8 +694,6 @@ static void fr_radius_client_bio_connect_timer(NDEBUG_UNUSED fr_event_list_t *el
 
        fr_assert(!my->retry || (my->info.retry_info->el == el));
 
-       if (my->ev) talloc_const_free(&my->ev);
-
        if (my->common.cb.failed) my->common.cb.failed(&my->common);
 }
 
@@ -744,7 +718,7 @@ void fr_radius_client_bio_connect(NDEBUG_UNUSED fr_event_list_t *el, NDEBUG_UNUS
         *      As a result, we have to check if the FD is open, and then call it ourselves.
         */
        if (my->info.fd_info->state == FR_BIO_FD_STATE_OPEN) {
-               fr_radius_client_bio_connected(my->fd);
+               fr_bio_packet_connected(my->fd);
                return;
        }
 
@@ -756,131 +730,3 @@ void fr_radius_client_bio_connect(NDEBUG_UNUSED fr_event_list_t *el, NDEBUG_UNUS
         */
        (void) fr_bio_fd_connect(my->fd);
 }
-
-
-
-/** Callback for when the writes are blocked.
- *
- */
-static int fr_radius_client_bio_write_blocked(fr_bio_t *bio)
-{
-       fr_radius_client_fd_bio_t *my = bio->uctx;
-       int rcode;
-
-       /*
-        *      This function must be callable multiple times, as different portions of the BIOs can block at
-        *      different times.
-        */
-       if (my->common.write_blocked) return 1;
-
-       /*
-        *      Mark the retry code as blocked, so that it stops trying to write packets.
-        */
-       if (my->retry) {
-               rcode = fr_bio_retry_write_blocked(my->retry);
-               if (rcode < 0) return rcode;
-       }
-
-       /*
-        *      The application doesn't want to know that it's blocked, so we just return.
-        */
-       if (!my->common.cb.write_blocked) {
-               my->common.write_blocked = true;
-               return 1;
-       }
-
-       /*
-        *      Tell the application that IO is blocked.
-        */
-       rcode = my->common.cb.write_blocked(&my->common);
-       if (rcode <= 0) return rcode;
-
-       my->common.write_blocked = true;
-       return 1;
-}
-
-
-/** Callback for when the writes can be resumed
- *
- */
-static int fr_radius_client_bio_write_resume(fr_bio_t *bio)
-{
-       fr_radius_client_fd_bio_t *my = bio->uctx;
-       int rcode;
-
-       /*
-        *      This function must be callable multiple times, as different portions of the BIOs can block or
-        *      resume at different times.
-        */
-       if (!my->common.write_blocked) return 1;
-
-       /*
-        *      Flush the outgoing memory buffers.
-        */
-       rcode = fr_bio_mem_write_resume(my->mem);
-       if (rcode <= 0) return rcode;
-
-       /*
-        *      Flush the packets which should have been retried, but weren't due to blocking.
-        */
-       if (my->retry) {
-               rcode = fr_bio_retry_write_resume(my->retry);
-               if (rcode <= 0) return rcode;
-       }
-
-       /*
-        *      IO is unblocked, but we don't have any free IDs.  So
-        *      we can't yet resume application-layer writes.
-        */
-       if (my->all_ids_used) return 0;
-
-       /*
-        *      The application doesn't want to know that it's resumed, so we just return.
-        */
-       if (!my->common.cb.write_resume) {
-               my->common.write_blocked = false;
-               return 1;
-       }
-
-       /*
-        *      Tell the application that IO has resumed.
-        */
-       rcode = my->common.cb.write_resume(&my->common);
-       if (rcode <= 0) return rcode;
-
-       my->common.write_blocked = false;
-       return 1;
-}
-
-void fr_radius_client_bio_cb_set(fr_bio_packet_t *bio, fr_bio_packet_cb_funcs_t const *cb)
-{
-       fr_radius_client_fd_bio_t *my = talloc_get_type_abort(bio, fr_radius_client_fd_bio_t);
-       fr_bio_cb_funcs_t bio_cb = {};
-
-       /*
-        *      If we have a "blocked" function, we must have a "resume" function, and vice versa.
-        */
-       fr_assert((cb->write_blocked != NULL) == (cb->write_resume != NULL));
-       fr_assert((cb->read_blocked != NULL) == (cb->read_resume != NULL));
-
-       bio_cb.connected = fr_radius_client_bio_connected;
-       bio_cb.write_blocked = fr_radius_client_bio_write_blocked;
-       bio_cb.write_resume = fr_radius_client_bio_write_resume;
-
-#undef SET
-#define SET(_x) if (cb->_x) bio_cb._x = fr_bio_packet_ ## _x
-
-       SET(read_blocked);
-       SET(read_resume);
-
-       my->common.cb = *cb;
-
-       fr_bio_cb_set(my->mem, &bio_cb);
-       if (my->retry) fr_bio_cb_set(my->retry, &bio_cb);
-
-       /*
-        *      Only the FD bio gets an EOF callback.
-        */
-       bio_cb.eof = fr_radius_client_bio_eof;
-       fr_bio_cb_set(my->fd, &bio_cb);
-}
index a65c9eea1f34b134a39c4afae016d5ad392145ae..c5fd9bb799851ac25e770eea71cfe918c8306e07 100644 (file)
@@ -32,6 +32,7 @@ RCSIDH(radius_client_h, "$Id$")
 #include <freeradius-devel/bio/retry.h>
 
 typedef struct {
+       fr_event_list_t         *el;
        fr_log_t                *log;
 
        fr_radius_bio_verify_t  verify;
@@ -76,6 +77,4 @@ size_t                fr_radius_client_bio_outstanding(fr_bio_packet_t *bio) CC_HINT(nonnull);
 
 int            fr_radius_client_bio_force_id(fr_bio_packet_t *bio, int code, int id);
 
-void           fr_radius_client_bio_cb_set(fr_bio_packet_t *bio, fr_bio_packet_cb_funcs_t const *cb);
-
 void           fr_radius_client_bio_connect(fr_event_list_t *el, int fd, int flags, void *uctx);
index 19e784cbbf1692e433b34a98a0bbc0c0d4b6357c..f216f36d57335667083f68ec36cdf67c8ebc4878 100644 (file)
@@ -46,8 +46,6 @@ typedef struct {
        fr_bio_t                *mem;
        fr_bio_t                *fd;
 
-       fr_event_timer_t const  *ev;
-
        /*
         *      @todo - this blocks on _any_ ID space being full.  So if we send auth+acct and auth blocks,
         *      then acct is also blocked.  Perhaps we want to track these individually, which means having