From: Arran Cudbard-Bell Date: Thu, 12 Jul 2018 18:26:24 +0000 (-0400) Subject: Add talloc validation to dlists X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7aa98c2da03e1be09e61369fb1a5dd6880c3c2e0;p=thirdparty%2Ffreeradius-server.git Add talloc validation to dlists --- diff --git a/src/lib/io/schedule.c b/src/lib/io/schedule.c index 55808bbb16b..5c0a4a1195f 100644 --- a/src/lib/io/schedule.c +++ b/src/lib/io/schedule.c @@ -439,7 +439,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el, /* * Create the list which holds the workers. */ - fr_dlist_init(&sc->workers, offsetof(fr_schedule_worker_t, entry)); + fr_dlist_init(&sc->workers, fr_schedule_worker_t, entry); memset(&sc->semaphore, 0, sizeof(sc->semaphore)); if (sem_init(&sc->semaphore, 0, SEMAPHORE_LOCKED) != 0) { @@ -512,7 +512,7 @@ fr_schedule_t *fr_schedule_create(TALLOC_CTX *ctx, fr_event_list_t *el, /* * See if all of the workers have started. */ - for (sw = fr_dlist_first(&sc->workers); + for (sw = fr_dlist_head(&sc->workers); sw != NULL; sw = next) { @@ -585,7 +585,7 @@ int fr_schedule_destroy(fr_schedule_t *sc) /* * Signal all of the workers to exit. */ - for (sw = fr_dlist_first(&sc->workers); + for (sw = fr_dlist_head(&sc->workers); sw != NULL; sw = fr_dlist_next(&sc->workers, sw)) { fr_worker_exit(sw->worker); @@ -604,7 +604,7 @@ int fr_schedule_destroy(fr_schedule_t *sc) /* * Clean up the exited workers. */ - while ((sw = fr_dlist_first(&sc->workers)) != NULL) { + while ((sw = fr_dlist_head(&sc->workers)) != NULL) { sc->num_workers--; fr_dlist_remove(&sc->workers, sw); diff --git a/src/lib/io/time.c b/src/lib/io/time.c index db4f8c35365..848aab3bceb 100644 --- a/src/lib/io/time.c +++ b/src/lib/io/time.c @@ -157,7 +157,7 @@ void fr_time_tracking_start(fr_time_tracking_t *tt, fr_time_t when, fr_time_trac tt->start = when; tt->resumed = when; - fr_dlist_init(&(worker->list), offsetof(fr_time_tracking_t, list.entry)); + fr_dlist_init(&(worker->list), fr_time_tracking_t, list.entry); fr_dlist_entry_init(&tt->list.entry); } diff --git a/src/lib/io/worker.c b/src/lib/io/worker.c index 3bf55e47988..d043c9026e8 100644 --- a/src/lib/io/worker.c +++ b/src/lib/io/worker.c @@ -166,7 +166,7 @@ static void fr_worker_post_event(fr_event_list_t *el, struct timeval *now, void * the same code. */ #define WORKER_HEAP_INIT(_name, _func) do { \ - fr_dlist_init(&worker->_name.list, offsetof(fr_channel_data_t, request.entry)); \ + fr_dlist_init(&worker->_name.list, fr_channel_data_t, request.entry); \ worker->_name.heap = fr_heap_create(worker, _func, fr_channel_data_t, channel.heap_id); \ if (!worker->_name.heap) { \ (void) fr_event_user_delete(worker->el, fr_worker_evfilt_user, worker); \ @@ -1307,7 +1307,7 @@ nomem: * the worker thread is running. */ memset(&worker->tracking, 0, sizeof(worker->tracking)); - fr_dlist_init(&worker->tracking.list, offsetof(fr_time_tracking_t, list.entry)); + fr_dlist_init(&worker->tracking.list, fr_time_tracking_t, list.entry); worker->kq = fr_event_list_kq(worker->el); rad_assert(worker->kq >= 0); diff --git a/src/lib/util/dlist.h b/src/lib/util/dlist.h index d11cfdcff5d..60f1c52b8ac 100644 --- a/src/lib/util/dlist.h +++ b/src/lib/util/dlist.h @@ -25,37 +25,105 @@ */ RCSIDH(dlist_h, "$Id$") -/** - * A doubly linked list. +/** Entry in a doubly linked list + * */ -typedef struct fr_dlist_t { - struct fr_dlist_t *prev; - struct fr_dlist_t *next; +typedef struct fr_dlist { + struct fr_dlist *prev; + struct fr_dlist *next; } fr_dlist_t; -typedef struct fr_dlist_head_t { - size_t offset; - fr_dlist_t entry; +/** Head of a doubly linked list + * + * Holds additional information about the list items, + * like at which offset the next/prev pointers can be found. + */ +typedef struct { + size_t offset; //!< Positive offset from start of structure to #fr_dlist_t. + char const *type; //!< of items contained within the list. Used for talloc + ///< validation. + fr_dlist_t entry; //!< Struct holding the head and fail of the list. } fr_dlist_head_t; -/* - * Functions to manage a doubly linked list. +/** Initialise a linked list without metadata + * */ static inline void fr_dlist_entry_init(fr_dlist_t *entry) { entry->prev = entry->next = entry; } -static inline void fr_dlist_init(fr_dlist_head_t *head, size_t offset) +/** Initialise the head structure of a doubly linked list + * + * @note This variant does not perform talloc validation. + * + @code{.c} + typedef struct { + fr_dlist_t dlist; + char const *field_a; + int *field_b; + ... + } my_struct_t; + + int my_func(my_struct_t *a, my_struct_t *b) + { + fr_dlist_head_t head; + + fr_dlist_init(&head, my_struct_t, dlist); + fr_dlist_insert_head(&head, a); + fr_dlist_insert_head(&head, b); + } + @endcode + * + * @param[in] _head structure to initialise. + * @param[in] _type of structure being stored in the list, + * e.g. fr_value_box_t, fr_dict_attr_t etc... + * @param[in] _field Containing the #fr_dlist_t structure within + * structure being stored. + */ +#define fr_dlist_init(_head, _type, _field) _fr_dlist_init(_head, offsetof(_type, _field), NULL) + +/** Initialise the head structure of a doubly linked list + * + * @note This variant *DOES* perform talloc validation. All items inserted + * into the list must be allocated with talloc. + * + * @copybrief fr_dlist_init. + * + * @param[in] _head structure to initialise. + * @param[in] _type of structure being stored in the list, + * e.g. fr_value_box_t, fr_dict_attr_t etc... + * @param[in] _field Containing the #fr_dlist_t within + * structure being stored. + */ +#define fr_dlist_talloc_init(_head, _type, _field) _fr_dlist_init(_head, offsetof(_type, _field), STRINGIFY(_type)) + +static inline void _fr_dlist_init(fr_dlist_head_t *head, size_t offset, char const *type) { fr_dlist_entry_init(&head->entry); head->offset = offset; + head->type = type; } +/** Insert an item into the head of the list + * + * @note If #fr_dlist_talloc_init was used to initialise #fr_dlist_head_t + * ptr must be a talloced chunk of the type passed to #fr_dlist_talloc_init. + * + * @param[in] list_head to insert ptr into. + * @param[in] ptr to insert. + */ static inline void fr_dlist_insert_head(fr_dlist_head_t *list_head, void *ptr) { - fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); - fr_dlist_t *head = &(list_head->entry); + fr_dlist_t *entry; + fr_dlist_t *head; + +#ifndef TALLOC_GET_TYPE_ABORT_NOOP + if (list_head->type) ptr = _talloc_get_type_abort(ptr, list_head->type, __location__); +#endif + + entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + head = &(list_head->entry); if (!fr_cond_assert(head->next != NULL)) return; if (!fr_cond_assert(head->prev != NULL)) return; @@ -66,10 +134,25 @@ static inline void fr_dlist_insert_head(fr_dlist_head_t *list_head, void *ptr) head->next = entry; } +/** Insert an item into the tail of the list + * + * @note If #fr_dlist_talloc_init was used to initialise #fr_dlist_head_t + * ptr must be a talloced chunk of the type passed to #fr_dlist_talloc_init. + * + * @param[in] list_head to insert ptr into. + * @param[in] ptr to insert. + */ static inline void fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr) { - fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); - fr_dlist_t *head = &(list_head->entry); + fr_dlist_t *entry; + fr_dlist_t *head; + +#ifndef TALLOC_GET_TYPE_ABORT_NOOP + if (list_head->type) ptr = _talloc_get_type_abort(ptr, list_head->type, __location__); +#endif + + entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + head = &(list_head->entry); if (!fr_cond_assert(head->next != NULL)) return; if (!fr_cond_assert(head->prev != NULL)) return; @@ -80,86 +163,143 @@ static inline void fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr) head->prev = entry; } -#if 0 -/* - * Insert one list into the tail of another +/** Return the HEAD item of a list or NULL if the list is empty + * + * @param[in] list_head to return the HEAD item from. + * @return + * - The HEAD item. + * - NULL if no items exist in the list. */ -static inline void fr_dlist_insert_tail_list(fr_dlist_head_t *list_head, fr_dlist_t *list) +static inline void *fr_dlist_head(fr_dlist_head_t *list_head) { fr_dlist_t *head = &(list_head->entry); - if (!fr_cond_assert(head->next != NULL)) return; - if (!fr_cond_assert(head->prev != NULL)) return; - - list->prev->next = head; - list->next->prev = head->prev; + if (head->next == head) return NULL; - head->prev->next = list->next; - head->prev = list->prev; + return (void *) (((uint8_t *) head->next) - list_head->offset); - list->prev = list->next = &list; } -#endif -static inline void fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr) +/** Return the TAIL item of a list or NULL if the list is empty + * + * @param[in] list_head to return the HEAD item from. + * @return + * - The TAIL item. + * - NULL if no items exist in the list. + */ +static inline void *fr_dlist_tail(fr_dlist_head_t *list_head) { - fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + fr_dlist_t *head = &(list_head->entry); - if (!fr_cond_assert(entry->next != NULL)) return; - if (!fr_cond_assert(entry->prev != NULL)) return; + if (head->prev == head) return NULL; + + return (void *) (((uint8_t *) head->prev) - list_head->offset); - entry->prev->next = entry->next; - entry->next->prev = entry->prev; - entry->prev = entry->next = entry; } +/** Get the next item in a list + * + * @note If #fr_dlist_talloc_init was used to initialise #fr_dlist_head_t + * ptr must be a talloced chunk of the type passed to #fr_dlist_talloc_init. + * + * @param[in] list_head containing ptr. + * @param[in] ptr to retrieve the next item from. + */ static inline void *fr_dlist_next(fr_dlist_head_t *list_head, void *ptr) { - fr_dlist_t *entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); - fr_dlist_t *head = &(list_head->entry); + fr_dlist_t *entry; + fr_dlist_t *head; + +#ifndef TALLOC_GET_TYPE_ABORT_NOOP + if (list_head->type) ptr = _talloc_get_type_abort(ptr, list_head->type, __location__); +#endif + + entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + head = &(list_head->entry); if (entry->next == head) return NULL; entry = entry->next; return (void *) (((uint8_t *) entry) - list_head->offset); } -static inline void *fr_dlist_first(fr_dlist_head_t *list_head) +/** Remove an item from the list + * + * @note If #fr_dlist_talloc_init was used to initialise #fr_dlist_head_t + * ptr must be a talloced chunk of the type passed to #fr_dlist_talloc_init. + * + * @param[in] list_head to remove ptr from. + * @param[in] ptr to remove. + */ +static inline void fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr) { - fr_dlist_t *head = &(list_head->entry); + fr_dlist_t *entry; - if (head->next == head) return NULL; +#ifndef TALLOC_GET_TYPE_ABORT_NOOP + if (list_head->type) ptr = _talloc_get_type_abort(ptr, list_head->type, __location__); +#endif - return (void *) (((uint8_t *) head->next) - list_head->offset); + entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + + if (!fr_cond_assert(entry->next != NULL)) return; + if (!fr_cond_assert(entry->prev != NULL)) return; + entry->prev->next = entry->next; + entry->next->prev = entry->prev; + entry->prev = entry->next = entry; } -static inline void *fr_dlist_tail(fr_dlist_head_t *list_head) +/** Check all items in the list are valid + * + * Checks item talloc headers and types to ensure they're consistent + * with what we expect. + * + * Does nothing if the list was not initialised with #fr_dlist_talloc_init. + */ +#ifndef TALLOC_GET_TYPE_ABORT_NOOP +static inline void fr_dlist_verify(fr_dlist_head_t *list_head) { - fr_dlist_t *head = &(list_head->entry); - - if (head->prev == head) return NULL; + void *item; - return (void *) (((uint8_t *) head->prev) - list_head->offset); + if (!list_head->type) return; + for (item = fr_dlist_head(list_head); + item; + item = fr_dlist_next(list_head, item)) { + item = _talloc_get_type_abort(item, list_head->type, __location__); + } } - -#if 0 -#ifdef WITH_VERIFY_PTR -# define FR_DLIST_VERIFY(_head, _type, _member) \ -do { \ - fr_dlist_t *_next; \ - for (_next = FR_DLIST_FIRST(_head); \ - _next; \ - _next = FR_DLIST_NEXT(_head, _next)) { \ - (void)talloc_get_type_abort(fr_ptr_to_type(_type, _member, _next), _type); \ - } \ -} while(0) #else -# define FR_DLIST_VERIFY(_head, _type, _member) -#endif +# define fr_list_verify(_head) #endif -/** Convert a pointer to a member into a pointer to the parent structure. +/** Merge two lists, inserting the tail of one into the other * */ -#define fr_ptr_to_type(TYPE, MEMBER, PTR) (TYPE *) (((char *)PTR) - offsetof(TYPE, MEMBER)) +static inline void fr_dlist_insert_tail_list(fr_dlist_head_t *list_head_a, fr_dlist_head_t *list_head_b) +{ + fr_dlist_t *head_a = &(list_head_a->entry); + fr_dlist_t *head_b = &(list_head_b->entry); + +#ifdef WITH_VERIFY_PTR + /* + * Must be both talloced or both not + */ + if (!fr_cond_assert(list_head_a->type == list_head_b->type)) return; + + /* + * Must be of the same type + */ + if (!fr_cond_assert(!list_head_a->type) || (strcmp(list_head_a->type, list_head_b->type) == 0)) return; +#endif + + if (!fr_cond_assert(head_a->next != NULL)) return; + if (!fr_cond_assert(head_a->prev != NULL)) return; + + head_b->prev->next = head_a; + head_b->next->prev = head_a->prev; + + head_a->prev->next = head_b->next; + head_a->prev = head_b->prev; + + head_b->prev = head_b->next = head_b; +} diff --git a/src/lib/util/event.c b/src/lib/util/event.c index 692a9a198ec..c5fc9e7fd53 100644 --- a/src/lib/util/event.c +++ b/src/lib/util/event.c @@ -1213,7 +1213,7 @@ int fr_event_user_delete(fr_event_list_t *el, fr_event_user_handler_t callback, { fr_event_user_t *user, *next; - for (user = fr_dlist_first(&el->user_callbacks); + for (user = fr_dlist_head(&el->user_callbacks); user != NULL; user = next) { next = fr_dlist_next(&el->user_callbacks, user); @@ -1267,7 +1267,7 @@ int fr_event_pre_delete(fr_event_list_t *el, fr_event_status_cb_t callback, void { fr_event_pre_t *pre, *next; - for (pre = fr_dlist_first(&el->pre_callbacks); + for (pre = fr_dlist_head(&el->pre_callbacks); pre != NULL; pre = next) { next = fr_dlist_next(&el->pre_callbacks, pre); @@ -1321,7 +1321,7 @@ int fr_event_post_delete(fr_event_list_t *el, fr_event_cb_t callback, void *uctx { fr_event_post_t *post, *next; - for (post = fr_dlist_first(&el->post_callbacks); + for (post = fr_dlist_head(&el->post_callbacks); post != NULL; post = next) { next = fr_dlist_next(&el->post_callbacks, post); @@ -1452,7 +1452,7 @@ int fr_event_corral(fr_event_list_t *el, bool wait) * application has more work to do, in which case we * re-set the timeout to be instant. */ - for (pre = fr_dlist_first(&el->pre_callbacks); + for (pre = fr_dlist_head(&el->pre_callbacks); pre != NULL; pre = fr_dlist_next(&el->pre_callbacks, pre)) { if (pre->callback(pre->uctx, wake) > 0) { @@ -1712,7 +1712,7 @@ service: /* * Run all of the post-processing events. */ - for (post = fr_dlist_first(&el->post_callbacks); + for (post = fr_dlist_head(&el->post_callbacks); post != NULL; post = fr_dlist_next(&el->post_callbacks, post)) { when = el->now; @@ -1833,9 +1833,9 @@ fr_event_list_t *fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t statu goto error; } - fr_dlist_init(&el->pre_callbacks, offsetof(fr_event_pre_t, entry)); - fr_dlist_init(&el->post_callbacks, offsetof(fr_event_post_t, entry)); - fr_dlist_init(&el->user_callbacks, offsetof(fr_event_user_t, entry)); + fr_dlist_init(&el->pre_callbacks, fr_event_pre_t, entry); + fr_dlist_init(&el->post_callbacks, fr_event_post_t, entry); + fr_dlist_init(&el->user_callbacks, fr_event_user_t, entry); if (status) (void) fr_event_pre_insert(el, status, status_uctx); diff --git a/src/main/exec.c b/src/main/exec.c index 8216ef2fa71..778c3018b50 100644 --- a/src/main/exec.c +++ b/src/main/exec.c @@ -129,7 +129,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait, return -1; } - fr_dlist_init(list, offsetof(fr_child_t, entry)); + fr_dlist_init(list, fr_child_t, entry); fr_thread_local_set_destructor(fr_children, _fr_children_free, list); } else { @@ -139,7 +139,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait, * Clean up the children. ALL of them. This is * slow as heck, but correct. :( */ - for (child = fr_dlist_first(fr_children); + for (child = fr_dlist_head(fr_children); child != NULL; child = next) { int status; diff --git a/src/main/state.c b/src/main/state.c index 2acd2787339..f31f9d8ca11 100644 --- a/src/main/state.c +++ b/src/main/state.c @@ -152,7 +152,7 @@ static int _state_tree_free(fr_state_tree_t *state) DEBUG4("Freeing state tree %p", state); - while ((entry = fr_dlist_first(&state->to_expire))) { + while ((entry = fr_dlist_head(&state->to_expire))) { state_entry_unlink(state, entry); talloc_free(entry); } @@ -202,7 +202,7 @@ fr_state_tree_t *fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, b return NULL; } - fr_dlist_init(&state->to_expire, offsetof(fr_state_entry_t, list)); + fr_dlist_init(&state->to_expire, fr_state_entry_t, list); /* * We need to do controlled freeing of the @@ -297,12 +297,12 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req bool too_many = false; fr_dlist_head_t to_free; - fr_dlist_init(&to_free, offsetof(fr_state_entry_t, list)); + fr_dlist_init(&to_free, fr_state_entry_t, list); /* * Clean up old entries. */ - for (entry = fr_dlist_first(&state->to_expire); + for (entry = fr_dlist_head(&state->to_expire); entry != NULL; entry = next) { (void)talloc_get_type_abort(entry, fr_state_entry_t); /* Allow examination */ @@ -361,7 +361,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, REQUEST *req * be freed also, and it may have complex destructors associated * with it. */ - while ((entry = fr_dlist_first(&to_free)) != NULL) { + while ((entry = fr_dlist_head(&to_free)) != NULL) { fr_dlist_remove(&to_free, entry); talloc_free(entry); } diff --git a/src/modules/proto_detail/proto_detail_work.c b/src/modules/proto_detail/proto_detail_work.c index 6d7b7cd9e2f..e0fcfe8db6d 100644 --- a/src/modules/proto_detail/proto_detail_work.c +++ b/src/modules/proto_detail/proto_detail_work.c @@ -155,7 +155,7 @@ static ssize_t mod_read(void *instance, void **packet_ctx, fr_time_t **recv_time * Process retransmissions before anything else in the * file. */ - track = fr_dlist_first(&inst->list); + track = fr_dlist_head(&inst->list); if (track) { fr_dlist_remove(&inst->list, track); @@ -814,7 +814,7 @@ static int mod_instantiate(void *instance, UNUSED CONF_SECTION *cs) proto_detail_work_t *inst = talloc_get_type_abort(instance, proto_detail_work_t); RADCLIENT *client; - fr_dlist_init(&inst->list, offsetof(fr_detail_entry_t, entry)); + fr_dlist_init(&inst->list, fr_detail_entry_t, entry); client = inst->client = talloc_zero(inst, RADCLIENT); if (!inst->client) return 0; diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index bbad3f34e3c..f4bf0935849 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -819,7 +819,7 @@ static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, void *instance, t->inst = instance; t->el = el; - fr_dlist_init(&t->running, offsetof(rlm_radius_link_t, entry)); + fr_dlist_init(&t->running, rlm_radius_link_t, entry); /* * Allocate thread-specific data. The connections should @@ -866,7 +866,7 @@ static int mod_thread_detach(fr_event_list_t *el, void *thread) * marked DONE, and (in an ideal world) resumed / cleaned * up before this memory is freed. */ - if (fr_dlist_first(&t->running) != NULL) { + if (fr_dlist_head(&t->running) != NULL) { ERROR("Module still has running requests!"); return -1; } diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index 2f660810b16..54752a11089 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -299,7 +299,7 @@ static void conn_check_idle(rlm_radius_udp_connection_t *c) /* * No outstanding packets, we're idle. */ - if (fr_dlist_first(&c->sent) == NULL) { + if (fr_dlist_head(&c->sent) == NULL) { break; } @@ -2002,7 +2002,7 @@ static fr_connection_state_t _conn_failed(UNUSED int fd, fr_connection_state_t s /* * Move "sent" packets back to the thread queue, */ - while ((u = fr_dlist_first(&c->sent)) != NULL) { + while ((u = fr_dlist_head(&c->sent)) != NULL) { state_transition(u, PACKET_STATE_THREAD); } } @@ -2044,7 +2044,7 @@ static fr_connection_state_t _conn_open(UNUSED fr_event_list_t *el, int fd, void rad_assert(c->zombie_ev == NULL); memset(&c->zombie_start, 0, sizeof(c->zombie_start)); - fr_dlist_init(&c->sent, offsetof(rlm_radius_udp_request_t, entry)); + fr_dlist_init(&c->sent, rlm_radius_udp_request_t, entry); /* * Status-Server checks. Manually build the packet, and @@ -2250,7 +2250,7 @@ static int _conn_free(rlm_radius_udp_connection_t *c) /* * Move "sent" packets back to the main thread queue */ - while ((u = fr_dlist_first(&c->sent)) != NULL) { + while ((u = fr_dlist_head(&c->sent)) != NULL) { rad_assert(u->state == PACKET_STATE_SENT); rad_assert(u->c == c); @@ -2333,7 +2333,7 @@ static void conn_alloc(rlm_radius_udp_t *inst, rlm_radius_udp_thread_t *t) talloc_free(c); return; } - fr_dlist_init(&c->sent, offsetof(rlm_radius_udp_request_t, entry)); + fr_dlist_init(&c->sent, rlm_radius_udp_request_t, entry); c->conn = fr_connection_alloc(c, t->el, &inst->parent->connection_timeout, &inst->parent->reconnection_delay, _conn_init, @@ -2452,7 +2452,7 @@ static rlm_rcode_t mod_push(void *instance, REQUEST *request, rlm_radius_link_t /* * Only open one new connection at a time. */ - if (!fr_dlist_first(&t->opening)) conn_alloc(inst, t); + if (!fr_dlist_head(&t->opening)) conn_alloc(inst, t); /* * Add the request to the backlog. It will be @@ -2615,10 +2615,10 @@ static int mod_thread_instantiate(UNUSED CONF_SECTION const *cs, void *instance, t->el = el; t->queued = fr_heap_talloc_create(t, queue_cmp, rlm_radius_udp_request_t, heap_id); - fr_dlist_init(&t->blocked, offsetof(rlm_radius_udp_connection_t, entry)); - fr_dlist_init(&t->full, offsetof(rlm_radius_udp_connection_t, entry)); - fr_dlist_init(&t->zombie, offsetof(rlm_radius_udp_connection_t, entry)); - fr_dlist_init(&t->opening, offsetof(rlm_radius_udp_connection_t, entry)); + fr_dlist_init(&t->blocked, rlm_radius_udp_connection_t, entry); + fr_dlist_init(&t->full, rlm_radius_udp_connection_t, entry); + fr_dlist_init(&t->zombie, rlm_radius_udp_connection_t, entry); + fr_dlist_init(&t->opening, rlm_radius_udp_connection_t, entry); t->active = fr_heap_talloc_create(t, conn_cmp, rlm_radius_udp_connection_t, heap_id); @@ -2644,7 +2644,7 @@ static int mod_thread_detach(UNUSED fr_event_list_t *el, void *thread) */ talloc_free_children(t); - if (fr_dlist_first(&t->opening) != NULL) { + if (fr_dlist_head(&t->opening) != NULL) { ERROR("There are still partially open sockets"); return -1; } diff --git a/src/modules/rlm_radius/track.c b/src/modules/rlm_radius/track.c index 84e82f38a54..e1c28fb40e2 100644 --- a/src/modules/rlm_radius/track.c +++ b/src/modules/rlm_radius/track.c @@ -68,7 +68,7 @@ rlm_radius_id_t *rr_track_create(TALLOC_CTX *ctx) id = talloc_zero(ctx, rlm_radius_id_t); if (!id) return NULL; - fr_dlist_init(&id->free_list, offsetof(rlm_radius_request_t, entry)); + fr_dlist_init(&id->free_list, rlm_radius_request_t, entry); for (i = 0; i < 256; i++) { id->id[i].id = i; @@ -112,7 +112,7 @@ rlm_radius_request_t *rr_track_alloc(rlm_radius_id_t *id, REQUEST *request, int rlm_radius_request_t *rr; retry: - rr = fr_dlist_first(&id->free_list); + rr = fr_dlist_head(&id->free_list); if (rr) { rad_assert(id->num_free > 0); diff --git a/src/modules/rlm_stats/rlm_stats.c b/src/modules/rlm_stats/rlm_stats.c index b0995d69004..01b0b00257d 100644 --- a/src/modules/rlm_stats/rlm_stats.c +++ b/src/modules/rlm_stats/rlm_stats.c @@ -140,7 +140,7 @@ static void coalesce(uint64_t final_stats[FR_MAX_PACKET_CODE], rlm_stats_thread_ * Loop over all of the other thread instances, locking * them, and adding their statistics in. */ - for (other = fr_dlist_first(&t->inst->list); + for (other = fr_dlist_head(&t->inst->list); other != NULL; other = fr_dlist_next(&t->inst->list, other)) { int i; @@ -421,7 +421,7 @@ static int mod_instantiate(void *instance, UNUSED CONF_SECTION *conf) pthread_mutex_init(&inst->mutex, NULL); #endif - fr_dlist_init(&inst->list, offsetof(rlm_stats_thread_t, entry)); + fr_dlist_init(&inst->list, rlm_stats_thread_t, entry); return 0; } diff --git a/src/unlang/op.c b/src/unlang/op.c index ea0eaaf48fa..aef5747eaa7 100644 --- a/src/unlang/op.c +++ b/src/unlang/op.c @@ -529,7 +529,7 @@ static REQUEST *unlang_child_alloc(REQUEST *request, unlang_t *instruction, rlm_ * Instead, all of it is done in the context of the * parent. */ - fr_dlist_init(&child->async->tracking.list, 0); + fr_dlist_init(&child->async->tracking.list, fr_time_tracking_t, list.entry); /* * create {...} creates an empty copy.