]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add a timed event to retry "load Cookie" on failure
authorNick Porter <nick@portercomputing.co.uk>
Mon, 11 Dec 2023 12:03:17 +0000 (12:03 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Mon, 11 Dec 2023 12:15:23 +0000 (12:15 +0000)
src/listen/ldap_sync/proto_ldap_sync.h
src/listen/ldap_sync/proto_ldap_sync_ldap.c

index b6aa7d8e4d203928ae6a8920e082f3f26b0a17c8..97d2b5f0ab7a34d6f542238504d98ee0a1eee47a 100644 (file)
@@ -132,6 +132,8 @@ struct sync_config_s {
        CONF_SECTION            *cs;                    //!< Config section where this sync was defined.
                                                        //!< Used for logging.
 
+       fr_event_timer_t const  *ev;                    //!< Event for retrying cookie load
+
        /*
         *      Callbacks for various events
         */
index 27b6b8002d3febc3f3a9730d33cc0237500e4518..6f80b2fc6bdd5a6efb4aabf64a3afefbc4b33cac 100644 (file)
@@ -121,6 +121,14 @@ typedef struct {
        int                     msgid;
 } proto_ldap_dir_ctx;
 
+/** Context for "load Cookie" retry timed event
+ */
+typedef struct {
+       proto_ldap_sync_ldap_thread_t   *thread;
+       proto_ldap_sync_ldap_t const    *inst;
+       size_t                          sync_no;
+} proto_ldap_cookie_load_retry_ctx;
+
 /** Compare two sync state structures on msgid
  *
  * @param[in] one first sync to compare.
@@ -840,6 +848,26 @@ static int proto_ldap_cookie_load_send(TALLOC_CTX *ctx, proto_ldap_sync_ldap_t c
        return 0;
 }
 
+/** Timer event to retry running "load Cookie" on failures
+ *
+ */
+static void proto_ldap_cookie_load_retry(fr_event_list_t *el, UNUSED fr_time_t now, void *uctx) {
+       proto_ldap_cookie_load_retry_ctx  *retry_ctx = talloc_get_type_abort(uctx, proto_ldap_cookie_load_retry_ctx);
+
+       DEBUG2("Retrying \"load Cookie\" for sync no %ld", retry_ctx->sync_no);
+       if (proto_ldap_cookie_load_send(retry_ctx, retry_ctx->inst, retry_ctx->sync_no,
+                                       retry_ctx->thread) < 0) {
+               ERROR("Failed retrying \"load Cookie\".  Will try again in %pV seconds",
+                     fr_box_time_delta(retry_ctx->inst->handle_config.reconnection_delay));
+               (void) fr_event_timer_in(retry_ctx->thread->conn->h, el,
+                                        &retry_ctx->inst->parent->sync_config[retry_ctx->sync_no]->ev,
+                                        retry_ctx->inst->handle_config.reconnection_delay,
+                                        proto_ldap_cookie_load_retry, retry_ctx);
+               return;
+       }
+       talloc_free(retry_ctx);
+}
+
 /** LDAP sync mod_write for child listener
  *
  * Handle any returned data after the worker has processed the packet and,
@@ -930,6 +958,26 @@ static ssize_t proto_ldap_child_mod_write(fr_listen_t *li, void *packet_ctx, UNU
        }
                break;
 
+       case FR_LDAP_SYNC_CODE_COOKIE_LOAD_FAIL:
+       {
+               proto_ldap_cookie_load_retry_ctx *retry_ctx;
+
+               ERROR("Load Cookie failed for sync %d, retrying in %pV seconds", packet_id,
+                     fr_box_time_delta(inst->handle_config.reconnection_delay));
+
+               MEM(retry_ctx = talloc(thread, proto_ldap_cookie_load_retry_ctx));
+               *retry_ctx = (proto_ldap_cookie_load_retry_ctx){
+                       .thread = thread,
+                       .inst = inst,
+                       .sync_no = packet_id,
+               };
+
+               (void) fr_event_timer_in(thread->conn->h, thread->el, &inst->parent->sync_config[packet_id]->ev,
+                                        inst->handle_config.reconnection_delay,
+                                        proto_ldap_cookie_load_retry, retry_ctx);
+       }
+               break;
+
        default:
                ERROR("Invalid packet type returned %d", pcode);
                break;