mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	dns: Change lookup failures from LOG_ERROR to debug 1.
dns.c and dns_system_resolver.c were spitting out errors for lookup failures for things like not finding a SRV record even though there was an A record. Those have been changed to debug messages. Logging not finding ANY record is left to the higher level caller. Also, dns_system_resolver was using Windows line endings so I converted them to Unix style. The actual log changes are on lines 156 and 159. Change-Id: I65be16ea15304b96f9dcb4d289dbd3e2286fc094
This commit is contained in:
		| @@ -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; | ||||
| 	} | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user