/*! * \brief Callback to handle initializing the results field. * * \internal * * \param dns_response The full DNS response. * \param dns_response The length of the full DNS response. * \param rcode The DNS response code. * * \retval 0 on success * \retval -1 on failure */ static int dns_system_resolver_set_response(void *context, unsigned char *dns_response, int dns_response_len, int rcode) { struct ast_dns_query *query = context; int res; /* Instantiate the query's result field (if necessary). */ if (!ast_dns_query_get_result(query)) { res = ast_dns_resolver_set_result(query, 0, 0, rcode, ast_dns_query_get_name(query), (const char*) dns_response, dns_response_len); if (res) { /* There was a problem instantiating the results field. */ ast_log(LOG_ERROR, "Could not instantiate the results field for query: '%s'\n", ast_dns_query_get_name(query)); } } else { res = DNS_SYSTEM_RESOLVER_SUCCESS; } return res; }
/*! \brief Query resolution callback */ 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); 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 */ if (!recurring->cancelled) { const struct ast_dns_result *result = ast_dns_query_get_result(query); int ttl = MIN(ast_dns_result_get_lowest_ttl(result), INT_MAX / 1000); 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 the query has a reference to it */ ao2_ref(recurring, -1); } } } ao2_replace(recurring->active, NULL); ao2_unlock(recurring); }