]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add cancellation function for rest xlats
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 27 Jan 2018 15:38:15 +0000 (08:38 -0700)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 27 Jan 2018 15:49:06 +0000 (08:49 -0700)
src/include/xlat.h
src/modules/rlm_rest/io.c
src/modules/rlm_rest/rest.h
src/modules/rlm_rest/rlm_rest.c

index 1380aff72f063fa3519c2b0f52f18c8d8fd70436..0fd218754feba2c12928d6c69d60e346c1f0861d 100644 (file)
@@ -30,6 +30,7 @@ extern "C" {
 #endif
 
 #include <freeradius-devel/cf_util.h>
+#include <freeradius-devel/signal.h>
 
 typedef struct xlat_exp xlat_exp_t;
 
@@ -140,7 +141,7 @@ typedef xlat_action_t (*xlat_func_resume_t)(TALLOC_CTX *ctx, fr_cursor_t *out,
  * @param[in] action           which is signalling the request.
  */
 typedef void (*xlat_func_signal_t)(REQUEST *request, void *instance, void *thread,
-                                  void *rctx, int action);
+                                  void *rctx, fr_state_signal_t action);
 
 /** Allocate new instance data for an xlat instance
  *
index ab22a61d455189a989ee3b00303263e9632e67b9..240e70f86cb41b6e36763428c4e29ac9af0a8d6e 100644 (file)
@@ -300,7 +300,7 @@ static int _rest_io_event_modify(UNUSED CURL *easy, curl_socket_t fd, int what,
                                       _rest_io_service_errored,
                                       thread) < 0) {
                        PERROR("multi-handle %p registration failed for read+write+error events on FD %i",
-                             thread->mandle, fd);
+                              thread->mandle, fd);
                        return -1;
                }
                DEBUG4("multi-handle %p registered for read+write+error events on FD %i", thread->mandle, fd);
@@ -333,9 +333,9 @@ static int _rest_io_event_modify(UNUSED CURL *easy, curl_socket_t fd, int what,
  * @param[in] ctx      rlm_rest_handle_t currently used by the request.
  * @param[in] action   What happened.
  */
-void rest_io_action(REQUEST *request, void *instance, void *thread, void *ctx, fr_state_signal_t action)
+void rest_io_module_action(REQUEST *request, void *instance, void *thread, void *rctx, fr_state_signal_t action)
 {
-       rlm_rest_handle_t       *randle = talloc_get_type_abort(ctx, rlm_rest_handle_t);
+       rlm_rest_handle_t       *randle = talloc_get_type_abort(rctx, rlm_rest_handle_t);
        rlm_rest_thread_t       *t = thread;
        CURLMcode               ret;
 
@@ -354,6 +354,29 @@ void rest_io_action(REQUEST *request, void *instance, void *thread, void *ctx, f
        fr_pool_connection_release(t->pool, request, randle);
 }
 
+/** Handle asynchronous cancellation of a request
+ *
+ * If we're signalled that the request has been cancelled (FR_SIGNAL_DONE).
+ * Cleanup any pending state and release the connection handle back into the pool.
+ *
+ * @param[in] request  being cancelled.
+ * @param[in] instance of rlm_rest.
+ * @param[in] thread   Thread specific module instance.
+ * @param[in] ctx      rlm_rest_handle_t currently used by the request.
+ * @param[in] action   What happened.
+ */
+void rest_io_xlat_action(REQUEST *request, UNUSED void *instance, void *thread, void *rctx, fr_state_signal_t action)
+{
+       rest_xlat_thread_inst_t         *xti = talloc_get_type_abort(thread, rest_xlat_thread_inst_t);
+       rlm_rest_t                      *mod_inst = xti->inst;
+       rlm_rest_thread_t               *t = xti->t;
+
+       rlm_rest_xlat_rctx_t            *our_rctx = talloc_get_type_abort(rctx, rlm_rest_xlat_rctx_t);
+       rlm_rest_handle_t               *randle = talloc_get_type_abort(our_rctx->handle, rlm_rest_handle_t);
+
+       rest_io_module_action(request, mod_inst, t, randle, action);
+}
+
 /** Sends a REST (HTTP) request.
  *
  * Send the actual REST request to the server. The response will be handled by
index 4b2248dbff04f651e5211eaf570b134e91ab4382..c5308649bfa05e8c1d60c67d1980e6e714f0a0ac 100644 (file)
@@ -147,7 +147,7 @@ typedef struct {
 
        char const              *connect_proxy; //!< Send request via this proxy.
 
-       fr_pool_t       *pool;          //!< Pointer to the connection pool.
+       fr_pool_t       *pool;                  //!< Pointer to the connection pool.
 
        rlm_rest_section_t      xlat;           //!< Configuration specific to xlat.
        rlm_rest_section_t      authorize;      //!< Configuration specific to authorisation.
@@ -176,7 +176,7 @@ typedef struct {
  *
  */
 typedef struct {
-       rlm_rest_t const        *inst;          //!< Instance of rlm_rest.
+       rlm_rest_t              *inst;          //!< Instance of rlm_rest.
        rlm_rest_thread_t       *t;             //!< rlm_rest thread instance.
 } rest_xlat_thread_inst_t;
 
@@ -257,6 +257,14 @@ typedef struct {
        rlm_rest_curl_context_t *ctx;           //!< Context, re-initialised after each request.
 } rlm_rest_handle_t;
 
+/** Stores the state of a yielded xlat
+ *
+ */
+typedef struct {
+       rlm_rest_section_t              section;        //!< Our mutated section config.
+       rlm_rest_handle_t               *handle;        //!< curl easy handle servicing our request.
+} rlm_rest_xlat_rctx_t;
+
 /*
  *     Function prototype for rest_read_wrapper. Matches CURL's
  *     CURLOPT_READFUNCTION prototype.
@@ -304,7 +312,8 @@ ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t const *mod_inst, RE
 /*
  *     Async IO helpers
  */
-void rest_io_action(REQUEST *request, void *instance, void *thread, void *ctx, fr_state_signal_t action);
+void rest_io_module_action(REQUEST *request, void *instance, void *thread, void *rctx, fr_state_signal_t action);
+void rest_io_xlat_action(REQUEST *request, void *instance, void *thread, void *rctx, fr_state_signal_t action);
 int rest_io_request_enqueue(rlm_rest_thread_t *thread, REQUEST *request, void *handle);
 int rest_io_init(rlm_rest_thread_t *thread);
 
index c2fe080328386e7d26dcd6a45da2187adfca6f81..121419565e25e73f48d0e2fa674e8dd3d575870d 100644 (file)
@@ -174,14 +174,6 @@ static int rlm_rest_perform(rlm_rest_t const *instance, rlm_rest_thread_t *threa
        return 0;
 }
 
-/** Stores the state of a yielded xlat
- *
- */
-typedef struct {
-       rlm_rest_section_t              section;        //!< Our mutated section config.
-       rlm_rest_handle_t               *handle;        //!< curl easy handle servicing our request.
-} rlm_rest_xlat_rctx_t;
-
 static xlat_action_t rest_xlat_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
                                      REQUEST *request, UNUSED void const *xlat_inst, void *xlat_thread_inst,
                                      UNUSED fr_value_box_t **in, void *rctx)
@@ -380,7 +372,7 @@ static xlat_action_t rest_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_cursor_t *out,
        ret = rest_io_request_enqueue(t, request, handle);
        if (ret < 0) goto error;
 
-       return xlat_unlang_yield(request, rest_xlat_resume, NULL, rctx);
+       return xlat_unlang_yield(request, rest_xlat_resume, rest_io_xlat_action, rctx);
 }
 
 static rlm_rcode_t mod_authorize_result(REQUEST *request, void *instance, void *thread, void *ctx)
@@ -493,7 +485,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, void *thread,
                return RLM_MODULE_FAIL;
        }
 
-       return unlang_module_yield(request, mod_authorize_result, rest_io_action, handle);
+       return unlang_module_yield(request, mod_authorize_result, rest_io_module_action, handle);
 }
 
 static rlm_rcode_t mod_authenticate_result(REQUEST *request, void *instance, void *thread, void *ctx)