Author: file Date: Fri Mar 13 10:34:23 2015 New Revision: 432887 URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=432887 Log: Incorporate review feedback.
1. Split higher level concepts out into their own files 2. Improve documentation detailing behavior 3. Fix overflow bug with high TTL 4. Fix bug where a record TTL of 0 could override non-zero Added: team/group/dns/main/dns_naptr.c (with props) team/group/dns/main/dns_recurring.c (with props) team/group/dns/main/dns_srv.c (with props) team/group/dns/main/dns_tlsa.c (with props) Modified: team/group/dns/include/asterisk/dns_core.h team/group/dns/include/asterisk/dns_internal.h team/group/dns/include/asterisk/dns_recurring.h team/group/dns/main/dns_core.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=432887&r1=432886&r2=432887 ============================================================================== --- team/group/dns/include/asterisk/dns_core.h (original) +++ team/group/dns/include/asterisk/dns_core.h Fri Mar 13 10:34:23 2015 @@ -126,6 +126,18 @@ */ const struct ast_dns_record *ast_dns_result_get_records(const struct ast_dns_result *result); + +/*! + * \brief Retrieve the lowest TTL from a result + * + * \param result The DNS result + * + * \return the lowest TTL + * + * \note If no records exist this function will return a TTL of 0 + */ +int ast_dns_result_get_lowest_ttl(const struct ast_dns_result *result); + /*! * \brief Free the DNS result information * 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=432887&r1=432886&r2=432887 ============================================================================== --- team/group/dns/include/asterisk/dns_internal.h (original) +++ team/group/dns/include/asterisk/dns_internal.h Fri Mar 13 10:34:23 2015 @@ -125,3 +125,12 @@ /*! \brief The name of what is being resolved */ char name[0]; }; + +struct ast_sched_context; + +/*! + * \brief Retrieve the DNS scheduler context + * + * \return scheduler context + */ +struct ast_sched_context *ast_dns_get_sched(void); Modified: team/group/dns/include/asterisk/dns_recurring.h URL: http://svnview.digium.com/svn/asterisk/team/group/dns/include/asterisk/dns_recurring.h?view=diff&rev=432887&r1=432886&r2=432887 ============================================================================== --- team/group/dns/include/asterisk/dns_recurring.h (original) +++ team/group/dns/include/asterisk/dns_recurring.h Fri Mar 13 10:34:23 2015 @@ -45,9 +45,15 @@ * * \note The user data passed in to this function must be ao2 allocated * - * \note This query will continue to happen according to the lowest TTL unless cancelled using ast_dns_resolve_cancel + * \note This query will continue to happen according to the lowest TTL unless cancelled using ast_dns_resolve_recurring_cancel * * \note It is NOT possible for the callback to be invoked concurrently for the query multiple times + * + * \note The query will occur when the TTL expires, not before. This means that there is a period of time where the previous + * information can be considered stale. + * + * \note If the TTL is determined to be 0 (the record specifies 0, or no records exist) this will cease doing a recurring query. + * It is the responsibility of the caller to resume querying at an interval they determine. */ struct ast_dns_query_recurring *ast_dns_resolve_recurring(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data); @@ -56,8 +62,8 @@ * * \param query The DNS query returned from ast_dns_resolve_recurring * - * \retval 0 success - * \retval -1 failure + * \retval 0 success - any active query has been cancelled and the query will no longer occur + * \retval -1 failure - an active query was in progress and could not be cancelled * * \note If successfully cancelled the callback will not be invoked */ 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=432887&r1=432886&r2=432887 ============================================================================== --- team/group/dns/main/dns_core.c (original) +++ team/group/dns/main/dns_core.c Fri Mar 13 10:34:23 2015 @@ -37,7 +37,6 @@ #include "asterisk/strings.h" #include "asterisk/sched.h" #include "asterisk/dns_core.h" -#include "asterisk/dns_naptr.h" #include "asterisk/dns_srv.h" #include "asterisk/dns_tlsa.h" #include "asterisk/dns_recurring.h" @@ -50,6 +49,11 @@ static struct ast_sched_context *sched; +struct ast_sched_context *ast_dns_get_sched(void) +{ + return sched; +} + const char *ast_dns_query_get_name(const struct ast_dns_query *query) { return query->name; @@ -98,6 +102,24 @@ const struct ast_dns_record *ast_dns_result_get_records(const struct ast_dns_result *result) { return AST_LIST_FIRST(&result->records); +} + +int ast_dns_result_get_lowest_ttl(const struct ast_dns_result *result) +{ + int ttl = 0; + const struct ast_dns_record *record; + + if (ast_dns_result_get_rcode(result) == ns_r_nxdomain) { + return 0; + } + + for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) { + if (!ttl || (ast_dns_record_get_ttl(record) && (ast_dns_record_get_ttl(record) < ttl))) { + ttl = ast_dns_record_get_ttl(record); + } + } + + return ttl; } void ast_dns_result_free(struct ast_dns_result *result) @@ -297,76 +319,6 @@ return *result ? 0 : -1; } -const char *ast_dns_naptr_get_flags(const struct ast_dns_record *record) -{ - return NULL; -} - -const char *ast_dns_naptr_get_service(const struct ast_dns_record *record) -{ - return NULL; -} - -const char *ast_dns_naptr_get_regexp(const struct ast_dns_record *record) -{ - return NULL; -} - -const char *ast_dns_naptr_get_replacement(const struct ast_dns_record *record) -{ - return NULL; -} - -unsigned short ast_dns_naptr_get_order(const struct ast_dns_record *record) -{ - return 0; -} - -unsigned short ast_dns_naptr_get_preference(const struct ast_dns_record *record) -{ - return 0; -} - -const char *ast_dns_srv_get_host(const struct ast_dns_record *record) -{ - return NULL; -} - -unsigned short ast_dns_srv_get_priority(const struct ast_dns_record *record) -{ - return 0; -} - -unsigned short ast_dns_srv_get_weight(const struct ast_dns_record *record) -{ - return 0; -} - -unsigned short ast_dns_srv_get_port(const struct ast_dns_record *record) -{ - return 0; -} - -unsigned int ast_dns_tlsa_get_usage(const struct ast_dns_record *record) -{ - return 0; -} - -unsigned int ast_dns_tlsa_get_selector(const struct ast_dns_record *record) -{ - return 0; -} - -unsigned int ast_dns_tlsa_get_matching_type(const struct ast_dns_record *record) -{ - return 0; -} - -const char *ast_dns_tlsa_get_association_data(const struct ast_dns_record *record) -{ - return NULL; -} - int ast_dns_resolver_set_data(struct ast_dns_query *query, void *data) { if (query->resolver_data) { @@ -479,130 +431,6 @@ void ast_dns_resolver_completed(struct ast_dns_query *query) { query->callback(query); -} - -/*! \brief Destructor for a DNS query */ -static void dns_query_recurring_destroy(void *data) -{ - struct ast_dns_query_recurring *recurring = data; - - ao2_cleanup(recurring->user_data); -} - -/*! \brief Determine the TTL to use when scheduling recurring resolution */ -static int dns_query_recurring_get_ttl(const struct ast_dns_query *query) -{ - int ttl = 0; - const struct ast_dns_result *result = ast_dns_query_get_result(query); - const struct ast_dns_record *record; - - if (ast_dns_result_get_rcode(result) == ns_r_nxdomain) { - return 0; - } - - for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) { - if (!ttl || (ast_dns_record_get_ttl(record) < ttl)) { - ttl = ast_dns_record_get_ttl(record); - } - } - - return ttl; -} - -static void dns_query_recurring_resolution_callback(const struct ast_dns_query *query); - -/*! \brief Scheduled recurring query callback */ -static int dns_query_recurring_scheduled_callback(const void *data) -{ - struct ast_dns_query_recurring *recurring = (struct ast_dns_query_recurring *)data; - - 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); - } - ao2_unlock(recurring); - - ao2_ref(recurring, -1); - - return 0; -} - -/*! \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); - - /* Replace the user data so the actual callback sees what it provided */ - ((struct ast_dns_query*)query)->user_data = ao2_bump(recurring->user_data); - recurring->callback(query); - - ao2_lock(recurring); - /* So.. if something has not externally cancelled this we can reschedule based on the TTL */ - if (!recurring->cancelled) { - int ttl = dns_query_recurring_get_ttl(query); - - if (ttl) { - recurring->timer = ast_sched_add(sched, ttl * 1000, dns_query_recurring_scheduled_callback, ao2_bump(recurring)); - if (recurring->timer < 0) { - ao2_ref(recurring, -1); - } - } - } - - ao2_replace(recurring->query, NULL); - ao2_unlock(recurring); - - /* Since we stole the reference from the query we need to drop it ourselves */ - ao2_ref(recurring, -1); -} - -struct ast_dns_query_recurring *ast_dns_resolve_recurring(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data) -{ - struct ast_dns_query_recurring *recurring; - - if (ast_strlen_zero(name) || !callback) { - return NULL; - } - - recurring = ao2_alloc(sizeof(*recurring) + strlen(name) + 1, dns_query_recurring_destroy); - if (!recurring) { - return NULL; - } - - recurring->callback = callback; - recurring->user_data = ao2_bump(data); - recurring->timer = -1; - recurring->rr_type = rr_type; - recurring->rr_class = rr_class; - strcpy(recurring->name, name); /* SAFE */ - - /* The scheduler callback expects a reference, so bump it up */ - recurring->query = ast_dns_resolve_async(name, rr_type, rr_class, dns_query_recurring_resolution_callback, recurring); - if (!recurring->query) { - ao2_ref(recurring, -1); - return NULL; - } - - return recurring; -} - -int ast_dns_resolve_recurring_cancel(struct ast_dns_query_recurring *recurring) -{ - ao2_lock(recurring); - - recurring->cancelled = 1; - AST_SCHED_DEL_UNREF(sched, recurring->timer, ao2_ref(recurring, -1)); - - if (recurring->query) { - ast_dns_resolve_cancel(recurring->query); - ao2_replace(recurring->query, NULL); - } - - ao2_unlock(recurring); - - return 0; } static void dns_shutdown(void) Added: team/group/dns/main/dns_naptr.c URL: http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_naptr.c?view=auto&rev=432887 ============================================================================== --- team/group/dns/main/dns_naptr.c (added) +++ team/group/dns/main/dns_naptr.c Fri Mar 13 10:34:23 2015 @@ -1,0 +1,65 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2015, Digium, Inc. + * + * Joshua Colp <jc...@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 DNS NAPTR Record Support + * + * \author Joshua Colp <jc...@digium.com> + */ + +/*** MODULEINFO + <support_level>core</support_level> + ***/ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/dns_core.h" +#include "asterisk/dns_naptr.h" + +const char *ast_dns_naptr_get_flags(const struct ast_dns_record *record) +{ + return NULL; +} + +const char *ast_dns_naptr_get_service(const struct ast_dns_record *record) +{ + return NULL; +} + +const char *ast_dns_naptr_get_regexp(const struct ast_dns_record *record) +{ + return NULL; +} + +const char *ast_dns_naptr_get_replacement(const struct ast_dns_record *record) +{ + return NULL; +} + +unsigned short ast_dns_naptr_get_order(const struct ast_dns_record *record) +{ + return 0; +} + +unsigned short ast_dns_naptr_get_preference(const struct ast_dns_record *record) +{ + return 0; +} Propchange: team/group/dns/main/dns_naptr.c ------------------------------------------------------------------------------ svn:eol-style = native Propchange: team/group/dns/main/dns_naptr.c ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: team/group/dns/main/dns_naptr.c ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: team/group/dns/main/dns_recurring.c URL: http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_recurring.c?view=auto&rev=432887 ============================================================================== --- team/group/dns/main/dns_recurring.c (added) +++ team/group/dns/main/dns_recurring.c Fri Mar 13 10:34:23 2015 @@ -1,0 +1,149 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2015, Digium, Inc. + * + * Joshua Colp <jc...@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 DNS Recurring Query Support + * + * \author Joshua Colp <jc...@digium.com> + */ + +/*** MODULEINFO + <support_level>core</support_level> + ***/ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/astobj2.h" +#include "asterisk/linkedlists.h" +#include "asterisk/sched.h" +#include "asterisk/strings.h" +#include "asterisk/dns_core.h" +#include "asterisk/dns_recurring.h" +#include "asterisk/dns_internal.h" + +#include <arpa/nameser.h> + +/*! \brief Destructor for a DNS query */ +static void dns_query_recurring_destroy(void *data) +{ + struct ast_dns_query_recurring *recurring = data; + + ao2_cleanup(recurring->user_data); +} + +static void dns_query_recurring_resolution_callback(const struct ast_dns_query *query); + +/*! \brief Scheduled recurring query callback */ +static int dns_query_recurring_scheduled_callback(const void *data) +{ + struct ast_dns_query_recurring *recurring = (struct ast_dns_query_recurring *)data; + + 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); + } + ao2_unlock(recurring); + + ao2_ref(recurring, -1); + + return 0; +} + +/*! \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); + + /* Replace the user data so the actual callback sees what it provided */ + ((struct ast_dns_query*)query)->user_data = ao2_bump(recurring->user_data); + recurring->callback(query); + + 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) { + ao2_ref(recurring, -1); + } + } + } + + ao2_replace(recurring->query, NULL); + ao2_unlock(recurring); + + /* Since we stole the reference from the query we need to drop it ourselves */ + ao2_ref(recurring, -1); +} + +struct ast_dns_query_recurring *ast_dns_resolve_recurring(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data) +{ + struct ast_dns_query_recurring *recurring; + + if (ast_strlen_zero(name) || !callback || !ast_dns_get_sched()) { + return NULL; + } + + recurring = ao2_alloc(sizeof(*recurring) + strlen(name) + 1, dns_query_recurring_destroy); + if (!recurring) { + return NULL; + } + + recurring->callback = callback; + recurring->user_data = ao2_bump(data); + recurring->timer = -1; + recurring->rr_type = rr_type; + recurring->rr_class = rr_class; + strcpy(recurring->name, name); /* SAFE */ + + /* The resolution callback expects a reference, so bump it up */ + recurring->query = ast_dns_resolve_async(name, rr_type, rr_class, dns_query_recurring_resolution_callback, ao2_bump(recurring)); + if (!recurring->query) { + ao2_ref(recurring, -1); + return NULL; + } + + return recurring; +} + +int ast_dns_resolve_recurring_cancel(struct ast_dns_query_recurring *recurring) +{ + int res = 0; + + ao2_lock(recurring); + + 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); + } + + ao2_unlock(recurring); + + return res; +} Propchange: team/group/dns/main/dns_recurring.c ------------------------------------------------------------------------------ svn:eol-style = native Propchange: team/group/dns/main/dns_recurring.c ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: team/group/dns/main/dns_recurring.c ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: team/group/dns/main/dns_srv.c URL: http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_srv.c?view=auto&rev=432887 ============================================================================== --- team/group/dns/main/dns_srv.c (added) +++ team/group/dns/main/dns_srv.c Fri Mar 13 10:34:23 2015 @@ -1,0 +1,55 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2015, Digium, Inc. + * + * Joshua Colp <jc...@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 DNS SRV Record Support + * + * \author Joshua Colp <jc...@digium.com> + */ + +/*** MODULEINFO + <support_level>core</support_level> + ***/ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/dns_core.h" +#include "asterisk/dns_srv.h" + +const char *ast_dns_srv_get_host(const struct ast_dns_record *record) +{ + return NULL; +} + +unsigned short ast_dns_srv_get_priority(const struct ast_dns_record *record) +{ + return 0; +} + +unsigned short ast_dns_srv_get_weight(const struct ast_dns_record *record) +{ + return 0; +} + +unsigned short ast_dns_srv_get_port(const struct ast_dns_record *record) +{ + return 0; +} Propchange: team/group/dns/main/dns_srv.c ------------------------------------------------------------------------------ svn:eol-style = native Propchange: team/group/dns/main/dns_srv.c ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: team/group/dns/main/dns_srv.c ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: team/group/dns/main/dns_tlsa.c URL: http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_tlsa.c?view=auto&rev=432887 ============================================================================== --- team/group/dns/main/dns_tlsa.c (added) +++ team/group/dns/main/dns_tlsa.c Fri Mar 13 10:34:23 2015 @@ -1,0 +1,55 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2015, Digium, Inc. + * + * Joshua Colp <jc...@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 DNS TLSA Record Support + * + * \author Joshua Colp <jc...@digium.com> + */ + +/*** MODULEINFO + <support_level>core</support_level> + ***/ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/dns_core.h" +#include "asterisk/dns_tlsa.h" + +unsigned int ast_dns_tlsa_get_usage(const struct ast_dns_record *record) +{ + return 0; +} + +unsigned int ast_dns_tlsa_get_selector(const struct ast_dns_record *record) +{ + return 0; +} + +unsigned int ast_dns_tlsa_get_matching_type(const struct ast_dns_record *record) +{ + return 0; +} + +const char *ast_dns_tlsa_get_association_data(const struct ast_dns_record *record) +{ + return NULL; +} Propchange: team/group/dns/main/dns_tlsa.c ------------------------------------------------------------------------------ svn:eol-style = native Propchange: team/group/dns/main/dns_tlsa.c ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: team/group/dns/main/dns_tlsa.c ------------------------------------------------------------------------------ svn:mime-type = text/plain -- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- svn-commits mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/svn-commits