diff options
-rw-r--r-- | main/dns.c | 2 | ||||
-rw-r--r-- | main/dns_system_resolver.c | 535 |
2 files changed, 269 insertions, 268 deletions
diff --git a/main/dns.c b/main/dns.c index e338d768b..96227949e 100644 --- a/main/dns.c +++ b/main/dns.c @@ -558,7 +558,7 @@ enum ast_dns_search_result ast_search_dns_ex(void *context, const char *dname, i sizeof(dns_response)); if (dns_response_len < 0) { - ast_log(LOG_ERROR, "DNS search failed for %s\n", dname); + ast_debug(1, "DNS search failed for %s\n", dname); response_handler(context, (unsigned char *)"", 0, ns_r_nxdomain); return AST_DNS_SEARCH_FAILURE; } diff --git a/main/dns_system_resolver.c b/main/dns_system_resolver.c index a5ac77127..d57814874 100644 --- a/main/dns_system_resolver.c +++ b/main/dns_system_resolver.c @@ -1,267 +1,268 @@ -/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2015, Digium, Inc.
- *
- * Ashley Sanders <asanders@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief The default DNS resolver for Asterisk.
- *
- * \arg See also \ref res_resolver_unbound
- *
- * \author Ashley Sanders <asanders@digium.com>
- */
-
-#include "asterisk.h"
-
-ASTERISK_REGISTER_FILE()
-
-#include "asterisk/_private.h"
-#include "asterisk/astobj2.h"
-#include "asterisk/dns.h"
-#include "asterisk/dns_core.h"
-#include "asterisk/dns_resolver.h"
-#include "asterisk/linkedlists.h"
-#include "asterisk/taskprocessor.h"
-
-/*! \brief The consideration priority for this resolver implementation. */
-#define DNS_SYSTEM_RESOLVER_PRIORITY INT_MAX
-
-/*! \brief Resolver return code upon success. */
-#define DNS_SYSTEM_RESOLVER_SUCCESS 0
-
-/*! \brief Resolver return code upon failure. */
-#define DNS_SYSTEM_RESOLVER_FAILURE -1
-
-
-static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl);
-static int dns_system_resolver_cancel(struct ast_dns_query *query);
-static void dns_system_resolver_destroy(void);
-static int dns_system_resolver_process_query(void *data);
-static int dns_system_resolver_resolve(struct ast_dns_query *query);
-static int dns_system_resolver_set_response(void *context, unsigned char *dns_response, int dns_response_len, int rcode);
-
-
-/*! \brief The task processor to use for making DNS searches asynchronous. */
-static struct ast_taskprocessor *dns_system_resolver_tp;
-
-/*! \brief The base definition for the dns_system_resolver */
-struct ast_dns_resolver dns_system_resolver_base = {
- .name = "system",
- .priority = DNS_SYSTEM_RESOLVER_PRIORITY,
- .resolve = dns_system_resolver_resolve,
- .cancel = dns_system_resolver_cancel,
-};
-
-/*!
- * \brief Callback to handle processing resource records.
- *
- * \details Adds an individual resource record discovered with ast_search_dns_ex to the
- * ast_dns_query currently being resolved.
- *
- * \internal
- *
- * \param context A void pointer to the ast_dns_query being processed.
- * \param record An individual resource record discovered during the DNS search.
- * \param record_len The length of the resource record.
- * \param ttl The resource record's expiration time limit (time to live).
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl)
-{
- struct ast_dns_query *query = context;
-
- /* Add the record to the query.*/
- return ast_dns_resolver_add_record(query,
- ast_dns_query_get_rr_type(query),
- ast_dns_query_get_rr_class(query),
- ttl,
- (const char*) record,
- record_len);
-}
-
-/*!
- * \brief Cancels processing resolution for a given query.
- *
- * \note The system API calls block so there is no way to cancel them. Therefore, this function always
- * returns failure when invoked.
- *
- * \internal
- *
- * \param query The ast_dns_query to cancel.
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-static int dns_system_resolver_cancel(struct ast_dns_query *query)
-{
- return DNS_SYSTEM_RESOLVER_FAILURE;
-}
-
-/*!
- * \brief Destructor.
- *
- * \internal
- */
-static void dns_system_resolver_destroy(void)
-{
- /* Unreference the task processor */
- dns_system_resolver_tp = ast_taskprocessor_unreference(dns_system_resolver_tp);
-
- /* Unregister the base resolver */
- ast_dns_resolver_unregister(&dns_system_resolver_base);
-}
-
-/*!
- * \brief Callback to handle processing the query from the ast_taskprocessor instance.
- *
- * \internal
- *
- * \param data A void pointer to the ast_dns_query being processed.
- *
- * \retval -1 on search failure
- * \retval 0 on no records found
- * \retval 1 on success
- */
-static int dns_system_resolver_process_query(void *data)
-{
- struct ast_dns_query *query = data;
-
- /* Perform the DNS search */
- enum ast_dns_search_result res = ast_search_dns_ex(query,
- ast_dns_query_get_name(query),
- ast_dns_query_get_rr_class(query),
- ast_dns_query_get_rr_type(query),
- dns_system_resolver_set_response,
- dns_system_resolver_add_record);
-
- /* Handle the possible return values from the DNS search */
- if (res == AST_DNS_SEARCH_FAILURE) {
- ast_log(LOG_ERROR, "DNS search failed for query: '%s'\n",
- ast_dns_query_get_name(query));
- } else if (res == AST_DNS_SEARCH_NO_RECORDS) {
- ast_log(LOG_WARNING, "DNS search failed to yield any results for query: '%s'\n",
- ast_dns_query_get_name(query));
- }
-
- /* Mark the query as complete */
- ast_dns_resolver_completed(query);
-
- /* Reduce the reference count on the query object */
- ao2_ref(query, -1);
-
- return res;
-}
-
-/*!
- * \brief Resolves a DNS query.
- *
- * \internal
- *
- * \param query The ast_dns_query to resolve.
- *
- * \retval 0 on successful load of query handler to the ast_taskprocessor instance
- * \retval -1 on failure to load the query handler to the ast_taskprocessor instance
- */
-static int dns_system_resolver_resolve(struct ast_dns_query *query)
-{
- /* Add query processing handler to the task processor */
- int res = ast_taskprocessor_push(dns_system_resolver_tp,
- dns_system_resolver_process_query,
- ao2_bump(query));
-
- /* The query processing handler was not added to the task processor */
- if (res < 0) {
- ast_log(LOG_ERROR, "Failed to perform async DNS resolution of '%s'\n",
- ast_dns_query_get_name(query));
- ao2_ref(query, -1);
- }
-
- /* Return the result of adding the query processing handler to the task processor */
- return res;
-}
-
-/*!
- * \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 Initializes the resolver.
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-int ast_dns_system_resolver_init(void)
-{
- /* Register the base resolver */
- int res = ast_dns_resolver_register(&dns_system_resolver_base);
-
- if (res) {
- return DNS_SYSTEM_RESOLVER_FAILURE;
- }
-
- /* Instantiate the task processor */
- dns_system_resolver_tp = ast_taskprocessor_get("dns_system_resolver_tp",
- TPS_REF_DEFAULT);
-
- /* Return error if the task processor failed to instantiate */
- if (!dns_system_resolver_tp) {
- dns_system_resolver_destroy();
- return DNS_SYSTEM_RESOLVER_FAILURE;
- }
-
- /* Register the cleanup function */
- ast_register_cleanup(dns_system_resolver_destroy);
-
- return DNS_SYSTEM_RESOLVER_SUCCESS;
-}
+/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2015, Digium, Inc. + * + * Ashley Sanders <asanders@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief The default DNS resolver for Asterisk. + * + * \arg See also \ref res_resolver_unbound + * + * \author Ashley Sanders <asanders@digium.com> + */ + +#include "asterisk.h" + +ASTERISK_REGISTER_FILE() + +#include "asterisk/_private.h" +#include "asterisk/astobj2.h" +#include "asterisk/dns.h" +#include "asterisk/dns_core.h" +#include "asterisk/dns_resolver.h" +#include "asterisk/linkedlists.h" +#include "asterisk/taskprocessor.h" +#include "asterisk/utils.h" + +/*! \brief The consideration priority for this resolver implementation. */ +#define DNS_SYSTEM_RESOLVER_PRIORITY INT_MAX + +/*! \brief Resolver return code upon success. */ +#define DNS_SYSTEM_RESOLVER_SUCCESS 0 + +/*! \brief Resolver return code upon failure. */ +#define DNS_SYSTEM_RESOLVER_FAILURE -1 + + +static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl); +static int dns_system_resolver_cancel(struct ast_dns_query *query); +static void dns_system_resolver_destroy(void); +static int dns_system_resolver_process_query(void *data); +static int dns_system_resolver_resolve(struct ast_dns_query *query); +static int dns_system_resolver_set_response(void *context, unsigned char *dns_response, int dns_response_len, int rcode); + + +/*! \brief The task processor to use for making DNS searches asynchronous. */ +static struct ast_taskprocessor *dns_system_resolver_tp; + +/*! \brief The base definition for the dns_system_resolver */ +struct ast_dns_resolver dns_system_resolver_base = { + .name = "system", + .priority = DNS_SYSTEM_RESOLVER_PRIORITY, + .resolve = dns_system_resolver_resolve, + .cancel = dns_system_resolver_cancel, +}; + +/*! + * \brief Callback to handle processing resource records. + * + * \details Adds an individual resource record discovered with ast_search_dns_ex to the + * ast_dns_query currently being resolved. + * + * \internal + * + * \param context A void pointer to the ast_dns_query being processed. + * \param record An individual resource record discovered during the DNS search. + * \param record_len The length of the resource record. + * \param ttl The resource record's expiration time limit (time to live). + * + * \retval 0 on success + * \retval -1 on failure + */ +static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl) +{ + struct ast_dns_query *query = context; + + /* Add the record to the query.*/ + return ast_dns_resolver_add_record(query, + ast_dns_query_get_rr_type(query), + ast_dns_query_get_rr_class(query), + ttl, + (const char*) record, + record_len); +} + +/*! + * \brief Cancels processing resolution for a given query. + * + * \note The system API calls block so there is no way to cancel them. Therefore, this function always + * returns failure when invoked. + * + * \internal + * + * \param query The ast_dns_query to cancel. + * + * \retval 0 on success + * \retval -1 on failure + */ +static int dns_system_resolver_cancel(struct ast_dns_query *query) +{ + return DNS_SYSTEM_RESOLVER_FAILURE; +} + +/*! + * \brief Destructor. + * + * \internal + */ +static void dns_system_resolver_destroy(void) +{ + /* Unreference the task processor */ + dns_system_resolver_tp = ast_taskprocessor_unreference(dns_system_resolver_tp); + + /* Unregister the base resolver */ + ast_dns_resolver_unregister(&dns_system_resolver_base); +} + +/*! + * \brief Callback to handle processing the query from the ast_taskprocessor instance. + * + * \internal + * + * \param data A void pointer to the ast_dns_query being processed. + * + * \retval -1 on search failure + * \retval 0 on no records found + * \retval 1 on success + */ +static int dns_system_resolver_process_query(void *data) +{ + struct ast_dns_query *query = data; + + /* Perform the DNS search */ + enum ast_dns_search_result res = ast_search_dns_ex(query, + ast_dns_query_get_name(query), + ast_dns_query_get_rr_class(query), + ast_dns_query_get_rr_type(query), + dns_system_resolver_set_response, + dns_system_resolver_add_record); + + /* Handle the possible return values from the DNS search */ + if (res == AST_DNS_SEARCH_FAILURE) { + ast_debug(1, "DNS search failed for query: '%s'\n", + ast_dns_query_get_name(query)); + } else if (res == AST_DNS_SEARCH_NO_RECORDS) { + ast_debug(1, "DNS search failed to yield any results for query: '%s'\n", + ast_dns_query_get_name(query)); + } + + /* Mark the query as complete */ + ast_dns_resolver_completed(query); + + /* Reduce the reference count on the query object */ + ao2_ref(query, -1); + + return res; +} + +/*! + * \brief Resolves a DNS query. + * + * \internal + * + * \param query The ast_dns_query to resolve. + * + * \retval 0 on successful load of query handler to the ast_taskprocessor instance + * \retval -1 on failure to load the query handler to the ast_taskprocessor instance + */ +static int dns_system_resolver_resolve(struct ast_dns_query *query) +{ + /* Add query processing handler to the task processor */ + int res = ast_taskprocessor_push(dns_system_resolver_tp, + dns_system_resolver_process_query, + ao2_bump(query)); + + /* The query processing handler was not added to the task processor */ + if (res < 0) { + ast_log(LOG_ERROR, "Failed to perform async DNS resolution of '%s'\n", + ast_dns_query_get_name(query)); + ao2_ref(query, -1); + } + + /* Return the result of adding the query processing handler to the task processor */ + return res; +} + +/*! + * \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 Initializes the resolver. + * + * \retval 0 on success + * \retval -1 on failure + */ +int ast_dns_system_resolver_init(void) +{ + /* Register the base resolver */ + int res = ast_dns_resolver_register(&dns_system_resolver_base); + + if (res) { + return DNS_SYSTEM_RESOLVER_FAILURE; + } + + /* Instantiate the task processor */ + dns_system_resolver_tp = ast_taskprocessor_get("dns_system_resolver_tp", + TPS_REF_DEFAULT); + + /* Return error if the task processor failed to instantiate */ + if (!dns_system_resolver_tp) { + dns_system_resolver_destroy(); + return DNS_SYSTEM_RESOLVER_FAILURE; + } + + /* Register the cleanup function */ + ast_register_cleanup(dns_system_resolver_destroy); + + return DNS_SYSTEM_RESOLVER_SUCCESS; +} |