]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Some minor tweaks to expose problems in rlm_rest
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 16 May 2024 22:00:28 +0000 (16:00 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 16 May 2024 22:00:28 +0000 (16:00 -0600)
src/lib/curl/io.c
src/modules/rlm_rest/rlm_rest.c

index 64e2a30adc41d96cd08d271bf1d8fbc19ba29eda..b72064bb98a3e1e49d61f15f5941c5cb9465dbc7 100644 (file)
@@ -58,7 +58,7 @@ static inline void _fr_curl_io_demux(fr_curl_handle_t *mhandle, CURLM *mandle)
                case CURLMSG_DONE:
                {
                        fr_curl_io_request_t    *randle;
-                       request_t                       *request = NULL;
+                       request_t               *request = NULL;
                        CURL                    *candle = m->easy_handle;
                        CURLcode                ret;
 
@@ -67,6 +67,17 @@ static inline void _fr_curl_io_demux(fr_curl_handle_t *mhandle, CURLM *mandle)
                        mhandle->transfers--;
 
                        ret = curl_easy_getinfo(candle, CURLINFO_PRIVATE, &randle);
+                       /*
+                        *      In curl 7.61 we got bad request data returned
+                        *      here after cancellations were processed.
+                        *
+                        *      For debug builds if the value is equal to
+                        *      0xdeadc341, we know the request was cancelled.
+                        *
+                        *      There is no good work around for this other than
+                        *      upgrading to a newer version of curl.
+                        */
+                       talloc_get_type_abort(randle, fr_curl_io_request_t);
                        if (!fr_cond_assert_msg(ret == CURLE_OK,
                                                "Failed retrieving request data from CURL easy handle (candle)")) {
                                curl_multi_remove_handle(mandle, candle);
@@ -86,8 +97,8 @@ static inline void _fr_curl_io_demux(fr_curl_handle_t *mhandle, CURLM *mandle)
                        randle->result = m->data.result;
 
                        /*
-                        *      Looks like this needs to be done last,
-                        *      else m->data.result ends up being junk.
+                        *      This needs to be done last, else m->data.result
+                        *      ends up being junk.
                         */
                        curl_multi_remove_handle(mandle, candle);
 
@@ -491,6 +502,11 @@ int fr_curl_io_request_enqueue(fr_curl_handle_t *mhandle, request_t *request, fr
         *      Stick the current request in the curl handle's
         *      private data.  This makes it simple to resume
         *      the request in the demux function later...
+        *
+        *      Note: If you get 0xdeadc341 in the private data
+        *      in the demux function, the result for the easy
+        *      handle was erroneously delivered after a
+        *      cancellation.
         */
        ret = curl_easy_setopt(randle->candle, CURLOPT_PRIVATE, randle);
        if (ret != CURLE_OK) {
index afe3a55443d359a9a0e8d118dcadaf429bf59eb5..179507b851a8521152197ebfaa04a542864e4136 100644 (file)
@@ -1177,12 +1177,6 @@ static int parse_sub_section(rlm_rest_t *inst, CONF_SECTION *parent, conf_parser
        return 0;
 }
 
-static int _mod_conn_free(fr_curl_io_request_t *randle)
-{
-       curl_easy_cleanup(randle->candle);
-       return 0;
-}
-
 /** Cleans up after a REST request.
  *
  * Resets all options associated with a CURL handle, and frees any headers
@@ -1194,7 +1188,7 @@ static int _mod_conn_free(fr_curl_io_request_t *randle)
  * @param[in] randle to cleanup.
  * @param[in] uctx unused.
  */
-static int rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
+static int _rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
 {
        rlm_rest_curl_context_t *ctx = talloc_get_type_abort(randle->uctx, rlm_rest_curl_context_t);
        CURL                    *candle = randle->candle;
@@ -1212,6 +1206,15 @@ static int rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
                ctx->headers = NULL;
        }
 
+#ifndef NDEBUG
+       /*
+        *  With curl 7.61 when a request in cancelled we get a result
+        *  with a NULL (invalid) pointer to private data.  This lets
+        *  us know that it was request returned to the slab.
+        */
+       curl_easy_setopt(candle, CURLOPT_PRIVATE, (void *)0xdeadc341);
+#endif
+
        /*
         *  Free response data
         */
@@ -1225,6 +1228,12 @@ static int rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
        return 0;
 }
 
+static int _mod_conn_free(fr_curl_io_request_t *randle)
+{
+       curl_easy_cleanup(randle->candle);
+       return 0;
+}
+
 static int rest_conn_alloc(fr_curl_io_request_t *randle, void *uctx)
 {
        rlm_rest_t const        *inst = talloc_get_type_abort(uctx, rlm_rest_t);
@@ -1244,7 +1253,7 @@ static int rest_conn_alloc(fr_curl_io_request_t *randle, void *uctx)
        randle->uctx = curl_ctx;
        talloc_set_destructor(randle, _mod_conn_free);
 
-       rest_slab_element_set_destructor(randle, rest_request_cleanup, NULL);
+       rest_slab_element_set_destructor(randle,  _rest_request_cleanup, NULL);
 
        return 0;
 }