mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 03:50:31 +00:00
DNS: Fix some corner cases.
* Fix query_set destruction before we are done kicking the queries off. * Fixed no queries requested handling. * Add empty queries request unit test. * Added missing allocation check in ast_dns_query_set_add(). * Made initial pjsip resolving query vector slightly larger. ASTERISK-25115 Reported by: John Bigelow Change-Id: Ie8be8347d0992e93946d72b6e7b1299727b038f2
This commit is contained in:
@@ -130,7 +130,10 @@ int ast_dns_query_set_add(struct ast_dns_query_set *query_set, const char *name,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_VECTOR_APPEND(&query_set->queries, query);
|
if (AST_VECTOR_APPEND(&query_set->queries, query)) {
|
||||||
|
ao2_ref(query.query, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -175,6 +178,11 @@ void ast_dns_query_set_resolve_async(struct ast_dns_query_set *query_set, ast_dn
|
|||||||
query_set->callback = callback;
|
query_set->callback = callback;
|
||||||
query_set->user_data = ao2_bump(data);
|
query_set->user_data = ao2_bump(data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bump the query_set ref in case all queries complete
|
||||||
|
* before we are done kicking them off.
|
||||||
|
*/
|
||||||
|
ao2_ref(query_set, +1);
|
||||||
for (idx = 0; idx < AST_VECTOR_SIZE(&query_set->queries); ++idx) {
|
for (idx = 0; idx < AST_VECTOR_SIZE(&query_set->queries); ++idx) {
|
||||||
struct dns_query_set_query *query = AST_VECTOR_GET_ADDR(&query_set->queries, idx);
|
struct dns_query_set_query *query = AST_VECTOR_GET_ADDR(&query_set->queries, idx);
|
||||||
|
|
||||||
@@ -187,6 +195,17 @@ void ast_dns_query_set_resolve_async(struct ast_dns_query_set *query_set, ast_dn
|
|||||||
|
|
||||||
dns_query_set_callback(query->query);
|
dns_query_set_callback(query->query);
|
||||||
}
|
}
|
||||||
|
if (!idx) {
|
||||||
|
/*
|
||||||
|
* There were no queries in the set;
|
||||||
|
* therefore all queries are "completed".
|
||||||
|
* Invoke the final callback.
|
||||||
|
*/
|
||||||
|
query_set->callback(query_set);
|
||||||
|
ao2_cleanup(query_set->user_data);
|
||||||
|
query_set->user_data = NULL;
|
||||||
|
}
|
||||||
|
ao2_ref(query_set, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Structure used for signaling back for synchronous resolution completion */
|
/*! \brief Structure used for signaling back for synchronous resolution completion */
|
||||||
|
@@ -516,7 +516,7 @@ static void sip_resolve(pjsip_resolver_t *resolver, pj_pool_t *pool, const pjsip
|
|||||||
resolve->callback = cb;
|
resolve->callback = cb;
|
||||||
resolve->token = token;
|
resolve->token = token;
|
||||||
|
|
||||||
if (AST_VECTOR_INIT(&resolve->resolving, 2)) {
|
if (AST_VECTOR_INIT(&resolve->resolving, 4)) {
|
||||||
ao2_ref(resolve, -1);
|
ao2_ref(resolve, -1);
|
||||||
cb(PJ_ENOMEM, token, NULL);
|
cb(PJ_ENOMEM, token, NULL);
|
||||||
return;
|
return;
|
||||||
@@ -565,6 +565,12 @@ static void sip_resolve(pjsip_resolver_t *resolver, pj_pool_t *pool, const pjsip
|
|||||||
cb(PJ_ENOMEM, token, NULL);
|
cb(PJ_ENOMEM, token, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!resolve->queries) {
|
||||||
|
ast_debug(2, "[%p] No resolution queries for target '%s'\n", resolve, host);
|
||||||
|
ao2_ref(resolve, -1);
|
||||||
|
cb(PJLIB_UTIL_EDNSNOANSWERREC, token, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ast_debug(2, "[%p] Starting initial resolution using parallel queries for target '%s'\n", resolve, host);
|
ast_debug(2, "[%p] Starting initial resolution using parallel queries for target '%s'\n", resolve, host);
|
||||||
ast_dns_query_set_resolve_async(resolve->queries, sip_resolve_callback, resolve);
|
ast_dns_query_set_resolve_async(resolve->queries, sip_resolve_callback, resolve);
|
||||||
|
@@ -306,6 +306,26 @@ AST_TEST_DEFINE(query_set)
|
|||||||
return query_set_test(test, 4, 0);
|
return query_set_test(test, 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_TEST_DEFINE(query_set_empty)
|
||||||
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case TEST_INIT:
|
||||||
|
info->name = "query_set_empty";
|
||||||
|
info->category = "/main/dns/query_set/";
|
||||||
|
info->summary = "Test nominal asynchronous empty DNS query set";
|
||||||
|
info->description =
|
||||||
|
"This tests nominal query set in the following ways:\n"
|
||||||
|
"\t* No queries are added to a query set\n"
|
||||||
|
"\t* Asynchronous resolution of the query set is started\n"
|
||||||
|
"\t* We ensure that the query set callback is invoked upon completion";
|
||||||
|
return AST_TEST_NOT_RUN;
|
||||||
|
case TEST_EXECUTE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return query_set_test(test, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
AST_TEST_DEFINE(query_set_nominal_cancel)
|
AST_TEST_DEFINE(query_set_nominal_cancel)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@@ -352,6 +372,7 @@ AST_TEST_DEFINE(query_set_off_nominal_cancel)
|
|||||||
static int unload_module(void)
|
static int unload_module(void)
|
||||||
{
|
{
|
||||||
AST_TEST_UNREGISTER(query_set);
|
AST_TEST_UNREGISTER(query_set);
|
||||||
|
AST_TEST_UNREGISTER(query_set_empty);
|
||||||
AST_TEST_UNREGISTER(query_set_nominal_cancel);
|
AST_TEST_UNREGISTER(query_set_nominal_cancel);
|
||||||
AST_TEST_UNREGISTER(query_set_off_nominal_cancel);
|
AST_TEST_UNREGISTER(query_set_off_nominal_cancel);
|
||||||
|
|
||||||
@@ -361,6 +382,7 @@ static int unload_module(void)
|
|||||||
static int load_module(void)
|
static int load_module(void)
|
||||||
{
|
{
|
||||||
AST_TEST_REGISTER(query_set);
|
AST_TEST_REGISTER(query_set);
|
||||||
|
AST_TEST_REGISTER(query_set_empty);
|
||||||
AST_TEST_REGISTER(query_set_nominal_cancel);
|
AST_TEST_REGISTER(query_set_nominal_cancel);
|
||||||
AST_TEST_REGISTER(query_set_off_nominal_cancel);
|
AST_TEST_REGISTER(query_set_off_nominal_cancel);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user