From 8ba219a520bf0333c304c04b4d5442c18e27c68b Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Wed, 8 Apr 2015 10:10:44 +0000 Subject: Re #1838: Enable application to provide its own external resolver implementation. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5055 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsip/sip_endpoint.h | 18 +++++++++++++ pjsip/include/pjsip/sip_resolve.h | 55 ++++++++++++++++++++++++++++++++++++++ pjsip/src/pjsip/sip_endpoint.c | 9 +++++++ pjsip/src/pjsip/sip_resolve.c | 27 +++++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/pjsip/include/pjsip/sip_endpoint.h b/pjsip/include/pjsip/sip_endpoint.h index 265b7f23..cb3d90fb 100644 --- a/pjsip/include/pjsip/sip_endpoint.h +++ b/pjsip/include/pjsip/sip_endpoint.h @@ -390,6 +390,24 @@ PJ_DECL(pj_status_t) pjsip_endpt_create_resolver(pjsip_endpoint *endpt, PJ_DECL(pj_status_t) pjsip_endpt_set_resolver(pjsip_endpoint *endpt, pj_dns_resolver *resv); +/** + * Set the DNS external resolver implementation to use in the SIP resolver. + * + * Note that naturally when implementing its own resolver, application would not + * need the internal resolver, hence this function will also destroy the + * PJLIB-UTIL DNS resolver if any (e.g: set using #pjsip_endpt_set_resolver()). + * Application that needs it, still be able create its own instance. + * + * @param res The SIP resolver engine. + * @param ext_res The external resolver implementation callback. This argument + * can be NULL to reset the whole external implementation. + * However, it is prohibited to reset individual callback. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsip_endpt_set_ext_resolver(pjsip_endpoint *endpt, + pjsip_ext_resolver *ext_res); + /** * Get the DNS resolver being used by the SIP resolver. * diff --git a/pjsip/include/pjsip/sip_resolve.h b/pjsip/include/pjsip/sip_resolve.h index 5a12cf78..188cd315 100644 --- a/pjsip/include/pjsip/sip_resolve.h +++ b/pjsip/include/pjsip/sip_resolve.h @@ -118,6 +118,7 @@ PJ_BEGIN_DECL * - The PJLIB-UTIL DNS resolver provides additional functionality such as * response caching, query aggregation, parallel nameservers, fallback * nameserver, etc., which will be described below. + * - Enable application to provide its own resolver implementation. * * * \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features @@ -155,6 +156,14 @@ PJ_BEGIN_DECL * Once the resolver is set, it will be used automatically by PJSIP everytime * PJSIP needs to send SIP request/response messages. * + * \section PJSIP_RESOLVE_EXT_RESOLVER External Resolver + * + * As an alternative to enabling PJLIB-UTIL DNS resolver, application can + * provide its own resolver implementation by defining the callback in + * pjsip_ext_resolver and pass the callback to + * #pjsip_resolver_set_ext_resolver() function. Please note that if the + * implementation needs feature from PJLIB-UTL DNS resolver, it has to create + * its own PJLIB-UTL DNS resolver instance. * * \section PJSIP_RESOLVE_REFERENCE Reference * @@ -206,6 +215,30 @@ typedef void pjsip_resolver_callback(pj_status_t status, void *token, const struct pjsip_server_addresses *addr); +/** + * This structure describes application callback to receive various event from + * the SIP resolver engine. Application can use this for its own resolver + * implementation. + */ +typedef struct pjsip_ext_resolver +{ + /** + * Notify application when the resolution should begin. + * + * @param resolver The resolver engine. + * @param pool The pool to allocate resolver job. + * @param target The target specification to be resolved. + * @param token A user defined token to be passed back to callback + * function. + * @param cb The callback function. + */ + void (*resolve) (pjsip_resolver_t *resolver, pj_pool_t *pool, + const pjsip_host_info *target, void *token, + pjsip_resolver_callback *cb); + +} pjsip_ext_resolver; + + /** * Create SIP resolver engine. Note that this function is normally called * internally by pjsip_endpoint instance. @@ -237,6 +270,28 @@ PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res, pj_dns_resolver *dns_res); +/** + * Set the DNS external resolver implementation to use in the SIP resolver + * engine. Naturally when implementing its own resolver, application would not + * need the internal resolver, hence this function will also destroy the + * PJLIB-UTIL DNS resolver if any (e.g: set using + * #pjsip_resolver_set_resolver()). Application that needs it, still be able + * create its own instance. + * + * Note that application normally will use #pjsip_endpt_set_ext_resolver() + * instead since it does not normally have access to the SIP resolver instance. + * + * @param res The SIP resolver engine. + * @param ext_res The external resolver implementation callback. This argument + * can be NULL to reset the whole external implementation. + * However, it is prohibited to reset individual callback. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsip_resolver_set_ext_resolver( + pjsip_resolver_t *res, + pjsip_ext_resolver *ext_res); + /** * Get the DNS resolver instance of the SIP resolver engine. * diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c index d1f66b8c..b2094268 100644 --- a/pjsip/src/pjsip/sip_endpoint.c +++ b/pjsip/src/pjsip/sip_endpoint.c @@ -1127,6 +1127,15 @@ PJ_DEF(pj_status_t) pjsip_endpt_set_resolver( pjsip_endpoint *endpt, return pjsip_resolver_set_resolver(endpt->resolver, resv); } +/* + * Set DNS external resolver implementation to be used by the SIP resolver. + */ +PJ_DEF(pj_status_t) pjsip_endpt_set_ext_resolver(pjsip_endpoint *endpt, + pjsip_ext_resolver *ext_res) +{ + return pjsip_resolver_set_ext_resolver(endpt->resolver, ext_res); +} + /* * Get the DNS resolver being used by the SIP resolver. */ diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c index 03413ab8..943fb3c4 100644 --- a/pjsip/src/pjsip/sip_resolve.c +++ b/pjsip/src/pjsip/sip_resolve.c @@ -70,6 +70,7 @@ struct query struct pjsip_resolver_t { pj_dns_resolver *res; + pjsip_ext_resolver *ext_res; }; @@ -114,6 +115,26 @@ PJ_DEF(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res, #endif } +/* + * Public API to set the DNS external resolver implementation for the SIP + * resolver. + */ +PJ_DEF(pj_status_t) pjsip_resolver_set_ext_resolver(pjsip_resolver_t *res, + pjsip_ext_resolver *ext_res) +{ + if (ext_res && !ext_res->resolve) + return PJ_EINVAL; + + if (ext_res && res->res) { +#if PJSIP_HAS_RESOLVER + pj_dns_resolver_destroy(res->res, PJ_FALSE); +#endif + res->res = NULL; + } + res->ext_res = ext_res; + return PJ_SUCCESS; +} + /* * Public API to get the internal DNS resolver. @@ -175,6 +196,12 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, struct query *query; pjsip_transport_type_e type = target->type; + /* If an external implementation has been provided use it instead */ + if (resolver->ext_res) { + (*resolver->ext_res->resolve)(resolver, pool, target, token, cb); + return; + } + /* Is it IP address or hostname? And if it's an IP, which version? */ ip_addr_ver = get_ip_addr_ver(&target->addr.host); -- cgit v1.2.3