+ * Return a 32-bit random number.
+ */
+static uint32_t eap_rand(fr_randctx *ctx)
+{
+ uint32_t num;
+
+ num = ctx->randrsl[ctx->randcnt++];
+ if (ctx->randcnt >= 256) {
+ ctx->randcnt = 0;
+ fr_isaac(ctx);
+ }
+
+ return num;
+}
+
+
+static EAP_HANDLER *eaplist_delete(rlm_eap_t *inst, EAP_HANDLER *handler)
+{
+ rbnode_t *node;
+
+ node = rbtree_find(inst->session_tree, handler);
+ if (!node) return NULL;
+
+ handler = rbtree_node2data(inst->session_tree, node);
+
+ /*
+ * Delete old handler from the tree.
+ */
+ rbtree_delete(inst->session_tree, node);
+
+ /*
+ * And unsplice it from the linked list.
+ */
+ if (handler->prev) {
+ handler->prev->next = handler->next;
+ } else {
+ inst->session_head = handler->next;
+ }
+ if (handler->next) {
+ handler->next->prev = handler->prev;
+ } else {
+ inst->session_tail = handler->prev;
+ }
+ handler->prev = handler->next = NULL;
+
+ return handler;
+}
+
+
+static void eaplist_expire(rlm_eap_t *inst, time_t timestamp)
+{
+ int i;
+ EAP_HANDLER *handler;
+
+ /*
+ * Check the first few handlers in the list, and delete
+ * them if they're too old. We don't need to check them
+ * all, as incoming requests will quickly cause older
+ * handlers to be deleted.
+ *
+ */
+ for (i = 0; i < 3; i++) {
+ handler = inst->session_head;
+ if (!handler) break;
+
+ /*
+ * Expire entries from the start of the list.
+ * They should be the oldest ones.
+ */
+ if ((timestamp - handler->timestamp) > inst->timer_limit) {
+ rbnode_t *node;
+ node = rbtree_find(inst->session_tree, handler);
+ rad_assert(node != NULL);
+ rbtree_delete(inst->session_tree, node);
+
+ /*
+ * handler == inst->session_head
+ */
+ inst->session_head = handler->next;
+ if (handler->next) {
+ handler->next->prev = NULL;
+ } else {
+ inst->session_head = NULL;
+ inst->session_tail = NULL;
+ }
+ eap_handler_free(inst, handler);
+ }
+ }
+}
+
+/*