diff options
author | Joshua Colp <jcolp@digium.com> | 2015-04-13 10:47:01 -0300 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2015-04-15 10:47:53 -0300 |
commit | a3cec44a0a415e803057a11ab11d80e4f93e10cf (patch) | |
tree | 550c4a127eae12504f06ae3c7a96927173b0bbb6 /include | |
parent | 60d1911482c1dcf44d34e30f252857d75f5d5d77 (diff) |
res_pjsip: Add external PJSIP resolver implementation using core DNS API.
This change adds the following:
1. A query set implementation. This is an API that allows queries to be executed in parallel and once all have completed a callback is invoked.
2. Unit tests for the query set implementation.
3. An external PJSIP resolver which uses the DNS core API to do NAPTR, SRV, AAAA, and A lookups.
For the resolver it will do NAPTR, SRV, and AAAA/A lookups in parallel. If NAPTR or SRV
are available it will then do more queries. And so on. Preference is NAPTR > SRV > AAAA/A,
with IPv6 preferred over IPv4. For transport it will prefer TLS > TCP > UDP if no explicit
transport has been provided. Configured transports on the system are taken into account to
eliminate resolved addresses which have no hope of completing.
ASTERISK-24947 #close
Reported by: Joshua Colp
Change-Id: I56cb03ce4f9d3d600776f36928e0b3e379b5d71e
Diffstat (limited to 'include')
-rw-r--r-- | include/asterisk/autoconfig.h.in | 4 | ||||
-rw-r--r-- | include/asterisk/dns_core.h | 9 | ||||
-rw-r--r-- | include/asterisk/dns_internal.h | 52 | ||||
-rw-r--r-- | include/asterisk/dns_query_set.h | 20 |
4 files changed, 75 insertions, 10 deletions
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in index 8c7ead499..474fb8c31 100644 --- a/include/asterisk/autoconfig.h.in +++ b/include/asterisk/autoconfig.h.in @@ -578,6 +578,10 @@ /* Define if your system has the PJPROJECT libraries. */ #undef HAVE_PJPROJECT +/* Define to 1 if PJPROJECT has the PJSIP External Resolver Support feature. + */ +#undef HAVE_PJSIP_EXTERNAL_RESOLVER + /* Define to 1 if PJPROJECT has the pjsip_get_dest_info support feature. */ #undef HAVE_PJSIP_GET_DEST_INFO diff --git a/include/asterisk/dns_core.h b/include/asterisk/dns_core.h index 1f67bb803..fe67e340d 100644 --- a/include/asterisk/dns_core.h +++ b/include/asterisk/dns_core.h @@ -205,6 +205,15 @@ int ast_dns_record_get_ttl(const struct ast_dns_record *record); const char *ast_dns_record_get_data(const struct ast_dns_record *record); /*! + * \brief Retrieve the size of the raw DNS record + * + * \param record The DNS record + * + * \return the size of the raw DNS record + */ +size_t ast_dns_record_get_data_size(const struct ast_dns_record *record); + +/*! * \brief Get the next DNS record * * \param record The current DNS record diff --git a/include/asterisk/dns_internal.h b/include/asterisk/dns_internal.h index d518f9066..be8794ba9 100644 --- a/include/asterisk/dns_internal.h +++ b/include/asterisk/dns_internal.h @@ -23,6 +23,12 @@ * \author Joshua Colp <jcolp@digium.com> */ +/*! \brief For AST_VECTOR */ +#include "asterisk/vector.h" + +/*! \brief For ast_dns_query_set_callback */ +#include "asterisk/dns_query_set.h" + /*! \brief Generic DNS record information */ struct ast_dns_record { /*! \brief Resource record type */ @@ -151,6 +157,30 @@ struct ast_dns_query_recurring { char name[0]; }; +/*! \brief A DNS query set query, which includes its state */ +struct dns_query_set_query { + /*! \brief Whether the query started successfully or not */ + unsigned int started; + /*! \brief THe query itself */ + struct ast_dns_query *query; +}; + +/*! \brief A set of DNS queries */ +struct ast_dns_query_set { + /*! \brief DNS queries */ + AST_VECTOR(, struct dns_query_set_query) queries; + /* \brief Whether the query set is in progress or not */ + int in_progress; + /*! \brief The total number of completed queries */ + int queries_completed; + /*! \brief The total number of cancelled queries */ + int queries_cancelled; + /*! \brief Callback to invoke upon completion */ + ast_dns_query_set_callback callback; + /*! \brief User-specific data */ + void *user_data; +}; + /*! \brief An active DNS query */ struct ast_dns_query_active { /*! \brief The underlying DNS query */ @@ -241,3 +271,25 @@ int dns_parse_short(unsigned char *cur, uint16_t *val); * \return The number of bytes consumed while parsing */ int dns_parse_string(char *cur, uint8_t *size, char **val); + +/*! + * \brief Allocate a DNS query (but do not start resolution) + * + * \param name The name of what to resolve + * \param rr_type Resource record type + * \param rr_class Resource record class + * \param callback The callback to invoke upon completion + * \param data User data to make available on the query + * + * \retval non-NULL success + * \retval NULL failure + * + * \note The result passed to the callback does not need to be freed + * + * \note The user data MUST be an ao2 object + * + * \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 *dns_query_alloc(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data); diff --git a/include/asterisk/dns_query_set.h b/include/asterisk/dns_query_set.h index c89fdfde7..fac732ae0 100644 --- a/include/asterisk/dns_query_set.h +++ b/include/asterisk/dns_query_set.h @@ -43,6 +43,8 @@ typedef void (*ast_dns_query_set_callback)(const struct ast_dns_query_set *query * * \retval non-NULL success * \retval NULL failure + * + * \note The query set must be released upon cancellation or completion using ao2_ref */ struct ast_dns_query_set *ast_dns_query_set_create(void); @@ -76,6 +78,8 @@ size_t ast_dns_query_set_num_queries(const struct ast_dns_query_set *query_set); * * \retval non-NULL success * \retval NULL failure + * + * \note The returned query is only valid for the lifetime of the query set itself */ struct ast_dns_query *ast_dns_query_set_get(const struct ast_dns_query_set *query_set, unsigned int index); @@ -106,29 +110,25 @@ void ast_dns_query_set_resolve_async(struct ast_dns_query_set *query_set, ast_dn * * \param query_set The query set * + * \retval 0 success + * \retval -1 failure + * * \note This function will return when all queries have been completed */ -void ast_query_set_resolve(struct ast_dns_query_set *query_set); +int ast_query_set_resolve(struct ast_dns_query_set *query_set); /*! * \brief Cancel an asynchronous DNS query set resolution * * \param query_set The DNS query set * - * \retval 0 success - * \retval -1 failure + * \retval 0 success (all queries have been cancelled) + * \retval -1 failure (some queries could not be cancelled) * * \note If successfully cancelled the callback will not be invoked */ int ast_dns_query_set_resolve_cancel(struct ast_dns_query_set *query_set); -/*! - * \brief Free a query set - * - * \param query_set A DNS query set - */ -void ast_dns_query_set_free(struct ast_dns_query_set *query_set); - #if defined(__cplusplus) || defined(c_plusplus) } #endif |