Module: kamailio Branch: master Commit: 48f0e7fc9bd95b509e8fb619d8aafb59c125d2c8 URL: https://github.com/kamailio/kamailio/commit/48f0e7fc9bd95b509e8fb619d8aafb59c125d2c8
Author: Morten Tryfoss <[email protected]> Committer: Daniel-Constantin Mierla <[email protected]> Date: 2023-11-22T09:37:08+01:00 cdp: Avoid deadlock for callback on diameter timeout Callback function might do an operation which creates a new transaction, which will result in a deadlock. Fixes #3641 --- Modified: src/modules/cdp/transaction.c --- Diff: https://github.com/kamailio/kamailio/commit/48f0e7fc9bd95b509e8fb619d8aafb59c125d2c8.diff Patch: https://github.com/kamailio/kamailio/commit/48f0e7fc9bd95b509e8fb619d8aafb59c125d2c8.patch --- diff --git a/src/modules/cdp/transaction.c b/src/modules/cdp/transaction.c index 5680e5b59c6..bba7e27fcc8 100644 --- a/src/modules/cdp/transaction.c +++ b/src/modules/cdp/transaction.c @@ -206,6 +206,15 @@ void cdp_free_trans(cdp_trans_t *x) int cdp_trans_timer(time_t now, void *ptr) { cdp_trans_t *x, *n; + cdp_trans_list_t *cb_queue = 0; + cb_queue = pkg_malloc(sizeof(cdp_trans_list_t)); + if(!cb_queue) { + LOG_NO_MEM("pkg", sizeof(cdp_trans_list_t)); + return 0; + } + cb_queue->head = 0; + cb_queue->tail = 0; + lock_get(trans_list->lock); x = trans_list->head; while(x) { @@ -215,9 +224,6 @@ int cdp_trans_timer(time_t now, void *ptr) .timeout); //Transaction has timed out waiting for response x->ans = 0; - if(x->cb) { - (x->cb)(1, *(x->ptr), 0, (now - x->expires)); - } n = x->next; if(x->prev) @@ -228,7 +234,17 @@ int cdp_trans_timer(time_t now, void *ptr) x->next->prev = x->prev; else trans_list->tail = x->prev; - if(x->auto_drop) + + if(x->cb) { + /* queue cb to be done after list unlock */ + x->next = 0; + x->prev = cb_queue->tail; + if(cb_queue->tail) + cb_queue->tail->next = x; + cb_queue->tail = x; + if(!cb_queue->head) + cb_queue->head = x; + } else if(x->auto_drop) /* if no callback, auto drop here */ cdp_free_trans(x); x = n; @@ -236,6 +252,17 @@ int cdp_trans_timer(time_t now, void *ptr) x = x->next; } lock_release(trans_list->lock); + + /* do all queued callbacks */ + x = cb_queue->head; + while(x) { + (x->cb)(1, *(x->ptr), 0, (now - x->expires)); + if(x->auto_drop) + cdp_free_trans(x); + x = x->next; + } + pkg_free(cb_queue); + return 1; } _______________________________________________ Kamailio (SER) - Development Mailing List To unsubscribe send an email to [email protected]
