mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 00:04:53 +00:00
res_pjsip: Enable PJSIP DNS client support.
This change enables DNS client support within PJSIP. System nameservers are automatically discovered using res_init or res_ninit. If this fails then PJSIP will resort to using gethostbyname for resolution. By enabling this support we gain SRV support, failover, and weight support. (closes issue ASTERISK-23435) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/3343/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@410795 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
7
CHANGES
7
CHANGES
@@ -160,6 +160,13 @@ res_mwi_external
|
|||||||
and other modules that depend on it cannot be built or loaded with
|
and other modules that depend on it cannot be built or loaded with
|
||||||
app_voicemail present.
|
app_voicemail present.
|
||||||
|
|
||||||
|
res_pjsip
|
||||||
|
------------------
|
||||||
|
* DNS functionality will now automatically be enabled if the system configured
|
||||||
|
nameservers can be retrieved. If the system configured nameservers can not be
|
||||||
|
retrieved the functionality will resort to using system resolution. Functionalty
|
||||||
|
such as SRV records and failover will not be available if system resolution
|
||||||
|
is in use.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
--- Functionality changes from Asterisk 11 to Asterisk 12 --------------------
|
--- Functionality changes from Asterisk 11 to Asterisk 12 --------------------
|
||||||
|
@@ -36,4 +36,7 @@
|
|||||||
int ast_search_dns(void *context, const char *dname, int class, int type,
|
int ast_search_dns(void *context, const char *dname, int class, int type,
|
||||||
int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer));
|
int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer));
|
||||||
|
|
||||||
|
/*! \brief Retrieve the configured nameservers of the system */
|
||||||
|
struct ao2_container *ast_dns_get_nameservers(void);
|
||||||
|
|
||||||
#endif /* _ASTERISK_DNS_H */
|
#endif /* _ASTERISK_DNS_H */
|
||||||
|
44
main/dns.c
44
main/dns.c
@@ -296,3 +296,47 @@ int ast_search_dns(void *context,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ao2_container *ast_dns_get_nameservers(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_RES_NINIT
|
||||||
|
struct __res_state dnsstate;
|
||||||
|
#endif
|
||||||
|
struct __res_state *state;
|
||||||
|
struct ao2_container *nameservers;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nameservers = ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 3);
|
||||||
|
if (!nameservers) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_RES_NINIT
|
||||||
|
memset(&dnsstate, 0, sizeof(dnsstate));
|
||||||
|
res_ninit(&dnsstate);
|
||||||
|
state = &dnsstate;
|
||||||
|
#else
|
||||||
|
ast_mutex_lock(&res_lock);
|
||||||
|
res_init();
|
||||||
|
state = &_res;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < state->nscount; i++) {
|
||||||
|
ast_str_container_add(nameservers, ast_inet_ntoa(state->nsaddr_list[i].sin_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_RES_NINIT
|
||||||
|
#ifdef HAVE_RES_NDESTROY
|
||||||
|
res_ndestroy(&dnsstate);
|
||||||
|
#else
|
||||||
|
res_nclose(&dnsstate);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_RES_CLOSE
|
||||||
|
res_close();
|
||||||
|
#endif
|
||||||
|
ast_mutex_unlock(&res_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return nameservers;
|
||||||
|
}
|
@@ -2305,6 +2305,8 @@ static int load_module(void)
|
|||||||
return AST_MODULE_LOAD_DECLINE;
|
return AST_MODULE_LOAD_DECLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast_sip_initialize_dns();
|
||||||
|
|
||||||
pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
|
pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
|
||||||
pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
|
pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
|
||||||
|
|
||||||
@@ -2395,6 +2397,7 @@ static int reload_module(void)
|
|||||||
return AST_MODULE_LOAD_DECLINE;
|
return AST_MODULE_LOAD_DECLINE;
|
||||||
}
|
}
|
||||||
ast_res_pjsip_init_options_handling(1);
|
ast_res_pjsip_init_options_handling(1);
|
||||||
|
ast_sip_initialize_dns();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "asterisk/sorcery.h"
|
#include "asterisk/sorcery.h"
|
||||||
#include "include/res_pjsip_private.h"
|
#include "include/res_pjsip_private.h"
|
||||||
#include "asterisk/threadpool.h"
|
#include "asterisk/threadpool.h"
|
||||||
|
#include "asterisk/dns.h"
|
||||||
|
|
||||||
#define TIMER_T1_MIN 100
|
#define TIMER_T1_MIN 100
|
||||||
#define DEFAULT_TIMER_T1 500
|
#define DEFAULT_TIMER_T1 500
|
||||||
@@ -174,3 +175,70 @@ void ast_sip_destroy_system(void)
|
|||||||
ast_sorcery_unref(system_sorcery);
|
ast_sorcery_unref(system_sorcery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int system_create_resolver_and_set_nameservers(void *data)
|
||||||
|
{
|
||||||
|
struct ao2_container *discovered_nameservers;
|
||||||
|
struct ao2_iterator it_nameservers;
|
||||||
|
char *nameserver;
|
||||||
|
pj_status_t status;
|
||||||
|
pj_dns_resolver *resolver;
|
||||||
|
pj_str_t nameservers[PJ_DNS_RESOLVER_MAX_NS];
|
||||||
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
discovered_nameservers = ast_dns_get_nameservers();
|
||||||
|
if (!discovered_nameservers) {
|
||||||
|
ast_log(LOG_ERROR, "Could not retrieve local system nameservers, resorting to system resolution\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ao2_container_count(discovered_nameservers)) {
|
||||||
|
ast_log(LOG_ERROR, "There are no local system nameservers configured, resorting to system resolution\n");
|
||||||
|
ao2_ref(discovered_nameservers, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(resolver = pjsip_endpt_get_resolver(ast_sip_get_pjsip_endpoint()))) {
|
||||||
|
status = pjsip_endpt_create_resolver(ast_sip_get_pjsip_endpoint(), &resolver);
|
||||||
|
if (status != PJ_SUCCESS) {
|
||||||
|
ast_log(LOG_ERROR, "Could not create DNS resolver(%d), resorting to system resolution\n", status);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it_nameservers = ao2_iterator_init(discovered_nameservers, 0);
|
||||||
|
while ((nameserver = ao2_iterator_next(&it_nameservers))) {
|
||||||
|
pj_strset2(&nameservers[count++], nameserver);
|
||||||
|
ao2_ref(nameserver, -1);
|
||||||
|
|
||||||
|
if (count == (PJ_DNS_RESOLVER_MAX_NS - 1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ao2_iterator_destroy(&it_nameservers);
|
||||||
|
|
||||||
|
status = pj_dns_resolver_set_ns(resolver, count, nameservers, NULL);
|
||||||
|
|
||||||
|
/* Since we no longer need the nameservers we can drop the list of them */
|
||||||
|
ao2_ref(discovered_nameservers, -1);
|
||||||
|
|
||||||
|
if (status != PJ_SUCCESS) {
|
||||||
|
ast_log(LOG_ERROR, "Could not set nameservers on DNS resolver in PJSIP(%d), resorting to system resolution\n",
|
||||||
|
status);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pjsip_endpt_get_resolver(ast_sip_get_pjsip_endpoint())) {
|
||||||
|
status = pjsip_endpt_set_resolver(ast_sip_get_pjsip_endpoint(), resolver);
|
||||||
|
if (status != PJ_SUCCESS) {
|
||||||
|
ast_log(LOG_ERROR, "Could not set DNS resolver in PJSIP(%d), resorting to system resolution\n", status);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_sip_initialize_dns(void)
|
||||||
|
{
|
||||||
|
ast_sip_push_task_synchronous(NULL, system_create_resolver_and_set_nameservers, NULL);
|
||||||
|
}
|
@@ -72,6 +72,11 @@ int ast_sip_initialize_system(void);
|
|||||||
*/
|
*/
|
||||||
void ast_sip_destroy_system(void);
|
void ast_sip_destroy_system(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initialize nameserver configuration
|
||||||
|
*/
|
||||||
|
void ast_sip_initialize_dns(void);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Initialize global configuration
|
* \brief Initialize global configuration
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user