Skip to content
Permalink
Browse files

Add cancellation function for rest xlats

  • Loading branch information...
arr2036 committed Jan 27, 2018
1 parent 9075a35 commit 64ffa5ee2054391b5358aa7f3ea7d68d7641dda9
Showing with 42 additions and 17 deletions.
  1. +2 −1 src/include/xlat.h
  2. +26 −3 src/modules/rlm_rest/io.c
  3. +12 −3 src/modules/rlm_rest/rest.h
  4. +2 −10 src/modules/rlm_rest/rlm_rest.c
@@ -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
*
@@ -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
@@ -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);

@@ -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)

0 comments on commit 64ffa5e

Please sign in to comment.
You can’t perform that action at this time.