[asterisk-commits] file: branch group/dns r432997 - in /team/group/dns: include/asterisk/ main/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 16 10:55:41 CDT 2015


Author: file
Date: Mon Mar 16 10:55:38 2015
New Revision: 432997

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=432997
Log:
Hide an asynchronous query behind an opaque structure so results can not be retrieved until the callback is invoked.

Modified:
    team/group/dns/include/asterisk/dns_core.h
    team/group/dns/include/asterisk/dns_internal.h
    team/group/dns/main/dns_core.c
    team/group/dns/main/dns_recurring.c
    team/group/dns/res/res_resolver_unbound.c
    team/group/dns/tests/test_dns.c

Modified: team/group/dns/include/asterisk/dns_core.h
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/include/asterisk/dns_core.h?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/include/asterisk/dns_core.h (original)
+++ team/group/dns/include/asterisk/dns_core.h Mon Mar 16 10:55:38 2015
@@ -28,6 +28,9 @@
 extern "C" {
 #endif
 
+/*! \brief Opaque structure for an active DNS query */
+struct ast_dns_query_active;
+
 /*! \brief Opaque structure for a DNS query */
 struct ast_dns_query;
 
@@ -220,21 +223,21 @@
  *
  * \note This function increments the reference count of the user data, it does NOT steal
  *
- * \note The query must be released upon completion or cancellation using ao2_ref
- */
-struct ast_dns_query *ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data);
+ * \note The active query must be released upon completion or cancellation using ao2_ref
+ */
+struct ast_dns_query_active *ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data);
 
 /*!
  * \brief Cancel an asynchronous DNS resolution
  *
- * \param query The DNS query returned from ast_dns_resolve_async
+ * \param active The active DNS query returned from ast_dns_resolve_async
  *
  * \retval 0 success
  * \retval -1 failure
  *
  * \note If successfully cancelled the callback will not be invoked
  */
-int ast_dns_resolve_cancel(struct ast_dns_query *query);
+int ast_dns_resolve_cancel(struct ast_dns_query_active *active);
 
 /*!
  * \brief Synchronously resolve a DNS query

Modified: team/group/dns/include/asterisk/dns_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/include/asterisk/dns_internal.h?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/include/asterisk/dns_internal.h (original)
+++ team/group/dns/include/asterisk/dns_internal.h Mon Mar 16 10:55:38 2015
@@ -106,14 +106,13 @@
 };
 
 /*! \brief A recurring DNS query */
-struct ast_dns_query_recurring
-{
+struct ast_dns_query_recurring {
 	/*! \brief Callback to invoke upon completion */
 	ast_dns_resolve_callback callback;
 	/*! \brief User-specific data */
 	void *user_data;
 	/*! \brief Current active query */
-	struct ast_dns_query *query;
+	struct ast_dns_query_active *active;
 	/*! \brief The recurring query has been cancelled */
 	unsigned int cancelled;
 	/*! \brief Scheduled timer for next resolution */
@@ -126,6 +125,12 @@
 	char name[0];
 };
 
+/*! \brief An active DNS query */
+struct ast_dns_query_active {
+	/*! \brief The underlying DNS query */
+	struct ast_dns_query *query;
+};
+
 struct ast_sched_context;
 
 /*!

Modified: team/group/dns/main/dns_core.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_core.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/main/dns_core.c (original)
+++ team/group/dns/main/dns_core.c Mon Mar 16 10:55:38 2015
@@ -162,6 +162,14 @@
 	return AST_LIST_NEXT(record, list);
 }
 
+/*! \brief Destructor for an active DNS query */
+static void dns_query_active_destroy(void *data)
+{
+	struct ast_dns_query_active *active = data;
+
+	ao2_cleanup(active->query);
+}
+
 /*! \brief \brief Destructor for a DNS query */
 static void dns_query_destroy(void *data)
 {
@@ -172,9 +180,9 @@
 	ast_dns_result_free(query->result);
 }
 
-struct ast_dns_query *ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
-{
-	struct ast_dns_query *query;
+struct ast_dns_query_active *ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
+{
+	struct ast_dns_query_active *active;
 
 	if (ast_strlen_zero(name)) {
 		ast_log(LOG_WARNING, "Could not perform asynchronous resolution, no name provided\n");
@@ -201,41 +209,46 @@
 		return NULL;
 	}
 
-	query = ao2_alloc_options(sizeof(*query) + strlen(name) + 1, dns_query_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
-	if (!query) {
-		return NULL;
-	}
-
-	query->callback = callback;
-	query->user_data = ao2_bump(data);
-	query->rr_type = rr_type;
-	query->rr_class = rr_class;
-	strcpy(query->name, name); /* SAFE */
+	active = ao2_alloc_options(sizeof(*active), dns_query_active_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	if (!active) {
+		return NULL;
+	}
+
+	active->query = ao2_alloc_options(sizeof(*active->query) + strlen(name) + 1, dns_query_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	if (!active->query) {
+		return NULL;
+	}
+
+	active->query->callback = callback;
+	active->query->user_data = ao2_bump(data);
+	active->query->rr_type = rr_type;
+	active->query->rr_class = rr_class;
+	strcpy(active->query->name, name); /* SAFE */
 
 	AST_RWLIST_RDLOCK(&resolvers);
-	query->resolver = AST_RWLIST_FIRST(&resolvers);
+	active->query->resolver = AST_RWLIST_FIRST(&resolvers);
 	AST_RWLIST_UNLOCK(&resolvers);
 
-	if (!query->resolver) {
+	if (!active->query->resolver) {
 		ast_log(LOG_ERROR, "Attempted to do a DNS query for '%s' of class '%d' and type '%d' but no resolver is available\n",
 			name, rr_class, rr_type);
-		ao2_ref(query, -1);
-		return NULL;
-	}
-
-	if (query->resolver->resolve(query)) {
+		ao2_ref(active, -1);
+		return NULL;
+	}
+
+	if (active->query->resolver->resolve(active->query)) {
 		ast_log(LOG_ERROR, "Resolver '%s' returned an error when resolving '%s' of class '%d' and type '%d'\n",
-			query->resolver->name, name, rr_class, rr_type);
-		ao2_ref(query, -1);
-		return NULL;
-	}
-
-	return query;
-}
-
-int ast_dns_resolve_cancel(struct ast_dns_query *query)
-{
-	return query->resolver->cancel(query);
+			active->query->resolver->name, name, rr_class, rr_type);
+		ao2_ref(active, -1);
+		return NULL;
+	}
+
+	return active;
+}
+
+int ast_dns_resolve_cancel(struct ast_dns_query_active *active)
+{
+	return active->query->resolver->cancel(active->query);
 }
 
 /*! \brief Structure used for signaling back for synchronous resolution completion */
@@ -278,7 +291,7 @@
 int ast_dns_resolve(const char *name, int rr_type, int rr_class, struct ast_dns_result **result)
 {
 	struct dns_synchronous_resolve *synchronous;
-	struct ast_dns_query *query;
+	struct ast_dns_query_active *active;
 
 	if (ast_strlen_zero(name)) {
 		ast_log(LOG_WARNING, "Could not perform synchronous resolution, no name provided\n");
@@ -313,15 +326,15 @@
 	ast_mutex_init(&synchronous->lock);
 	ast_cond_init(&synchronous->cond, NULL);
 
-	query = ast_dns_resolve_async(name, rr_type, rr_class, dns_synchronous_resolve_callback, synchronous);
-	if (query) {
+	active = ast_dns_resolve_async(name, rr_type, rr_class, dns_synchronous_resolve_callback, synchronous);
+	if (active) {
 		/* Wait for resolution to complete */
 		ast_mutex_lock(&synchronous->lock);
 		while (!synchronous->completed) {
 			ast_cond_wait(&synchronous->cond, &synchronous->lock);
 		}
 		ast_mutex_unlock(&synchronous->lock);
-		ao2_ref(query, -1);
+		ao2_ref(active, -1);
 	}
 
 	*result = synchronous->result;

Modified: team/group/dns/main/dns_recurring.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_recurring.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/main/dns_recurring.c (original)
+++ team/group/dns/main/dns_recurring.c Mon Mar 16 10:55:38 2015
@@ -59,7 +59,7 @@
 	ao2_lock(recurring);
 	recurring->timer = -1;
 	if (!recurring->cancelled) {
-		recurring->query = ast_dns_resolve_async(recurring->name, recurring->rr_type, recurring->rr_class, dns_query_recurring_resolution_callback,
+		recurring->active = ast_dns_resolve_async(recurring->name, recurring->rr_type, recurring->rr_class, dns_query_recurring_resolution_callback,
 			recurring);
 	}
 	ao2_unlock(recurring);
@@ -93,7 +93,7 @@
 		}
 	}
 
-	ao2_replace(recurring->query, NULL);
+	ao2_replace(recurring->active, NULL);
 	ao2_unlock(recurring);
 
 	/* Since we stole the reference from the query we need to drop it ourselves */
@@ -120,8 +120,8 @@
 	recurring->rr_class = rr_class;
 	strcpy(recurring->name, name); /* SAFE */
 
-	recurring->query = ast_dns_resolve_async(name, rr_type, rr_class, dns_query_recurring_resolution_callback, recurring);
-	if (!recurring->query) {
+	recurring->active = ast_dns_resolve_async(name, rr_type, rr_class, dns_query_recurring_resolution_callback, recurring);
+	if (!recurring->active) {
 		ao2_ref(recurring, -1);
 		return NULL;
 	}
@@ -138,9 +138,9 @@
 	recurring->cancelled = 1;
 	AST_SCHED_DEL_UNREF(ast_dns_get_sched(), recurring->timer, ao2_ref(recurring, -1));
 
-	if (recurring->query) {
-		res = ast_dns_resolve_cancel(recurring->query);
-		ao2_replace(recurring->query, NULL);
+	if (recurring->active) {
+		res = ast_dns_resolve_cancel(recurring->active);
+		ao2_replace(recurring->active, NULL);
 	}
 
 	ao2_unlock(recurring);

Modified: team/group/dns/res/res_resolver_unbound.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/res/res_resolver_unbound.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/res/res_resolver_unbound.c (original)
+++ team/group/dns/res/res_resolver_unbound.c Mon Mar 16 10:55:38 2015
@@ -681,7 +681,7 @@
 static int async_run(struct ast_test *test, const char *domain, int rr_type,
 		int rr_class, struct dns_record *records, size_t num_records)
 {
-	RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
 	RAII_VAR(struct async_data *, adata, NULL, ao2_cleanup);
 	int i;
 
@@ -698,8 +698,8 @@
 
 	ast_test_status_update(test, "Performing DNS query '%s', type %d\n", domain, rr_type);
 
-	query = ast_dns_resolve_async(domain, rr_type, rr_class, async_callback, adata);
-	if (!query) {
+	active = ast_dns_resolve_async(domain, rr_type, rr_class, async_callback, adata);
+	if (!active) {
 		ast_test_status_update(test, "Failed to perform asynchronous resolution of domain %s\n", domain);
 		return -1;
 	}

Modified: team/group/dns/tests/test_dns.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/tests/test_dns.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/tests/test_dns.c (original)
+++ team/group/dns/tests/test_dns.c Mon Mar 16 10:55:38 2015
@@ -1005,7 +1005,7 @@
 AST_TEST_DEFINE(resolver_resolve_async)
 {
 	RAII_VAR(struct async_resolution_data *, async_data, NULL, ao2_cleanup);
-	RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
 	struct ast_dns_result *result;
 	enum ast_test_result_state res = AST_TEST_PASS;
 	struct timespec timeout;
@@ -1039,8 +1039,8 @@
 		goto cleanup;
 	}
 
-	query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, async_callback, async_data);
-	if (!query) {
+	active = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, async_callback, async_data);
+	if (!active) {
 		ast_test_status_update(test, "Asynchronous resolution of address failed\n");
 		res = AST_TEST_FAIL;
 		goto cleanup;
@@ -1080,7 +1080,7 @@
 		goto cleanup;
 	}
 
-	result = ast_dns_query_get_result(query);
+	result = ast_dns_query_get_result(active->query);
 	if (!result) {
 		ast_test_status_update(test, "Asynchronous resolution yielded no result\n");
 		res = AST_TEST_FAIL;
@@ -1128,7 +1128,7 @@
 		{ "asterisk.org", ns_t_a,       ns_c_in,      NULL },
 	};
 
-	struct ast_dns_query *query;
+	struct ast_dns_query_active *active;
 	enum ast_test_result_state res = AST_TEST_PASS;
 	int i;
 
@@ -1155,11 +1155,11 @@
 	}
 
 	for (i = 0; i < ARRAY_LEN(resolves); ++i) {
-		query = ast_dns_resolve_async(resolves[i].name, resolves[i].rr_type, resolves[i].rr_class,
+		active = ast_dns_resolve_async(resolves[i].name, resolves[i].rr_type, resolves[i].rr_class,
 				resolves[i].callback, NULL);
-		if (query) {
+		if (active) {
 			ast_test_status_update(test, "Successfully performed asynchronous resolution with invalid data\n");
-			ao2_ref(query, -1);
+			ao2_ref(active, -1);
 			res = AST_TEST_FAIL;
 		}
 	}
@@ -1171,13 +1171,13 @@
 		return AST_TEST_FAIL;
 	}
 
-	query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, stub_callback, NULL);
+	active = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, stub_callback, NULL);
 
 	ast_dns_resolver_unregister(&terrible_resolver);
 
-	if (query) {
+	if (active) {
 		ast_test_status_update(test, "Successfully performed asynchronous resolution with invalid data\n");
-		ao2_ref(query, -1);
+		ao2_ref(active, -1);
 		return AST_TEST_FAIL;
 	}
 
@@ -1187,7 +1187,7 @@
 AST_TEST_DEFINE(resolver_resolve_async_cancel)
 {
 	RAII_VAR(struct async_resolution_data *, async_data, NULL, ao2_cleanup);
-	RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
 	struct ast_dns_result *result;
 	enum ast_test_result_state res = AST_TEST_PASS;
 	struct timespec timeout;
@@ -1221,8 +1221,8 @@
 		goto cleanup;
 	}
 
-	query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, async_callback, async_data);
-	if (!query) {
+	active = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, async_callback, async_data);
+	if (!active) {
 		ast_test_status_update(test, "Asynchronous resolution of address failed\n");
 		res = AST_TEST_FAIL;
 		goto cleanup;
@@ -1240,7 +1240,7 @@
 		goto cleanup;
 	}
 
-	ast_dns_resolve_cancel(query);
+	ast_dns_resolve_cancel(active);
 
 	if (!test_resolver_data.canceled) {
 		ast_test_status_update(test, "Resolver's cancel() method was not called\n");
@@ -1270,7 +1270,7 @@
 		goto cleanup;
 	}
 
-	result = ast_dns_query_get_result(query);
+	result = ast_dns_query_get_result(active->query);
 	if (result) {
 		ast_test_status_update(test, "Canceled resolution had a result\n");
 		res = AST_TEST_FAIL;




More information about the asterisk-commits mailing list