summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Jordan <mjordan@digium.com>2015-07-02 09:43:09 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2015-07-02 09:43:09 -0500
commit45b8a2be31176c217c3a3f53d3c7ae552d723a08 (patch)
treeabc1d22b0754d0158ceed7f57483c46aac031eff
parenta889cfa0b9b6ddaee98336a25d7e4d9d59f25e4d (diff)
parentf18436642b90487a53b8818ef853205620960c29 (diff)
Merge "dns: Fix crash when invoking cancel in DNS recurring unit test."
-rw-r--r--main/dns_recurring.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/main/dns_recurring.c b/main/dns_recurring.c
index 855273f10..992575507 100644
--- a/main/dns_recurring.c
+++ b/main/dns_recurring.c
@@ -73,10 +73,21 @@ static int dns_query_recurring_scheduled_callback(const void *data)
static void dns_query_recurring_resolution_callback(const struct ast_dns_query *query)
{
struct ast_dns_query_recurring *recurring = ast_dns_query_get_data(query);
-
- /* Replace the user data so the actual callback sees what it provided */
- ((struct ast_dns_query*)query)->user_data = ao2_bump(recurring->user_data);
- recurring->callback(query);
+ struct ast_dns_query *callback_query;
+
+ /* Create a separate query to invoke the user specific callback on as the
+ * recurring query user data may get used externally (by the unit test)
+ * and thus changing it is problematic
+ */
+ callback_query = dns_query_alloc(query->name, query->rr_type, query->rr_class,
+ recurring->callback, recurring->user_data);
+ if (callback_query) {
+ /* The result is immutable at this point and can be safely provided */
+ callback_query->result = query->result;
+ callback_query->callback(callback_query);
+ callback_query->result = NULL;
+ ao2_ref(callback_query, -1);
+ }
ao2_lock(recurring);
/* So.. if something has not externally cancelled this we can reschedule based on the TTL */
@@ -87,7 +98,7 @@ static void dns_query_recurring_resolution_callback(const struct ast_dns_query *
if (ttl) {
recurring->timer = ast_sched_add(ast_dns_get_sched(), ttl * 1000, dns_query_recurring_scheduled_callback, ao2_bump(recurring));
if (recurring->timer < 0) {
- /* It is impossible for this to be the last reference as this callback function holds a reference itself */
+ /* It is impossible for this to be the last reference as the query has a reference to it */
ao2_ref(recurring, -1);
}
}
@@ -95,9 +106,6 @@ static void dns_query_recurring_resolution_callback(const struct ast_dns_query *
ao2_replace(recurring->active, NULL);
ao2_unlock(recurring);
-
- /* Since we stole the reference from the query we need to drop it ourselves */
- ao2_ref(recurring, -1);
}
struct ast_dns_query_recurring *ast_dns_resolve_recurring(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)