<p>Sébastien Duthil has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16167">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_rtp_asterisk: Automatically refresh stunaddr from DNS<br><br>This allows the STUN server to change its IP address without having to<br>reload the res_rtp_asterisk module.<br><br>The refresh of the name resolution occurs first when the module is<br>loaded, then recurringly, slightly after the previous DNS answer TTL<br>expires.<br><br>Change-Id: I7955a046293f913ba121bbd82153b04439e3465f<br>---<br>M configs/samples/rtp.conf.sample<br>A doc/CHANGES-staging/res_rtp_asterisk_stunaddr_recurring_resolution.txt<br>M main/dns_recurring.c<br>M res/res_rtp_asterisk.c<br>4 files changed, 161 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/67/16167/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample</span><br><span>index 1207c78..3027b95 100644</span><br><span>--- a/configs/samples/rtp.conf.sample</span><br><span>+++ b/configs/samples/rtp.conf.sample</span><br><span>@@ -63,7 +63,8 @@</span><br><span> ; Hostname or address for the STUN server used when determining the external</span><br><span> ; IP address and port an RTP session can be reached at. The port number is</span><br><span> ; optional. If omitted the default value of 3478 will be used. This option is</span><br><span style="color: hsl(0, 100%, 40%);">-; disabled by default.</span><br><span style="color: hsl(120, 100%, 40%);">+; disabled by default. Name resolution will occur at load time, and if DNS is</span><br><span style="color: hsl(120, 100%, 40%);">+; used, name resolution will occur repeatedly after the TTL expires.</span><br><span> ;</span><br><span> ; e.g. stundaddr=mystun.server.com:3478</span><br><span> ;</span><br><span>diff --git a/doc/CHANGES-staging/res_rtp_asterisk_stunaddr_recurring_resolution.txt b/doc/CHANGES-staging/res_rtp_asterisk_stunaddr_recurring_resolution.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..c78f4f5</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/res_rtp_asterisk_stunaddr_recurring_resolution.txt</span><br><span>@@ -0,0 +1,6 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_rtp_asterisk</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+When the address of the STUN server (stunaddr) is a name resolved via DNS, the</span><br><span style="color: hsl(120, 100%, 40%);">+stunaddr will be recurringly resolved when the DNS answer Time-To-Live (TTL)</span><br><span style="color: hsl(120, 100%, 40%);">+expires. This allows the STUN server to change its IP address without having to</span><br><span style="color: hsl(120, 100%, 40%);">+reload the res_rtp_asterisk module.</span><br><span>diff --git a/main/dns_recurring.c b/main/dns_recurring.c</span><br><span>index 294438f..6a953fa 100644</span><br><span>--- a/main/dns_recurring.c</span><br><span>+++ b/main/dns_recurring.c</span><br><span>@@ -39,6 +39,11 @@</span><br><span> </span><br><span> #include <arpa/nameser.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* \brief Delay between TTL expiration and the next DNS query, to make sure the</span><br><span style="color: hsl(120, 100%, 40%);">+resolver cache really expired. */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EXTRA_TTL 2</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_TTL ((INT_MAX - EXTRA_TTL) / 1000)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Destructor for a DNS query */</span><br><span> static void dns_query_recurring_destroy(void *data)</span><br><span> {</span><br><span>@@ -91,10 +96,10 @@</span><br><span> /* So.. if something has not externally cancelled this we can reschedule based on the TTL */</span><br><span> if (!recurring->cancelled) {</span><br><span> const struct ast_dns_result *result = ast_dns_query_get_result(query);</span><br><span style="color: hsl(0, 100%, 40%);">- int ttl = MIN(ast_dns_result_get_lowest_ttl(result), INT_MAX / 1000);</span><br><span style="color: hsl(120, 100%, 40%);">+ int ttl = MIN(ast_dns_result_get_lowest_ttl(result), MAX_TTL);</span><br><span> </span><br><span> if (ttl) {</span><br><span style="color: hsl(0, 100%, 40%);">- recurring->timer = ast_sched_add(ast_dns_get_sched(), ttl * 1000, dns_query_recurring_scheduled_callback, ao2_bump(recurring));</span><br><span style="color: hsl(120, 100%, 40%);">+ recurring->timer = ast_sched_add(ast_dns_get_sched(), (ttl + EXTRA_TTL) * 1000, dns_query_recurring_scheduled_callback, ao2_bump(recurring));</span><br><span> if (recurring->timer < 0) {</span><br><span> /* It is impossible for this to be the last reference as the query has a reference to it */</span><br><span> ao2_ref(recurring, -1);</span><br><span>diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c</span><br><span>index e5bef24..f1aed85 100644</span><br><span>--- a/res/res_rtp_asterisk.c</span><br><span>+++ b/res/res_rtp_asterisk.c</span><br><span>@@ -36,6 +36,11 @@</span><br><span> </span><br><span> #include "asterisk.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <arpa/nameser.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/dns_core.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/dns_internal.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/dns_recurring.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <sys/time.h></span><br><span> #include <signal.h></span><br><span> #include <fcntl.h></span><br><span>@@ -213,7 +218,7 @@</span><br><span> #ifdef HAVE_PJPROJECT</span><br><span> static int icesupport = DEFAULT_ICESUPPORT;</span><br><span> static int stun_software_attribute = DEFAULT_STUN_SOFTWARE_ATTRIBUTE;</span><br><span style="color: hsl(0, 100%, 40%);">-static struct sockaddr_in stunaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sockaddr stunaddr;</span><br><span> static pj_str_t turnaddr;</span><br><span> static int turnport = DEFAULT_TURN_PORT;</span><br><span> static pj_str_t turnusername;</span><br><span>@@ -229,6 +234,11 @@</span><br><span> static struct ast_acl_list *stun_acl = NULL;</span><br><span> static ast_rwlock_t stun_acl_lock = AST_RWLOCK_INIT_VALUE;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! stunaddr recurring resolution */</span><br><span style="color: hsl(120, 100%, 40%);">+static ast_rwlock_t stunaddr_lock = AST_RWLOCK_INIT_VALUE;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct stunaddr_resolve_data *stunaddr_resolve_data;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_dns_query_recurring *stunaddr_resolver = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Pool factory used by pjlib to allocate memory. */</span><br><span> static pj_caching_pool cachingpool;</span><br><span> </span><br><span>@@ -645,6 +655,12 @@</span><br><span> </span><br><span> static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *via_ice, int use_srtp);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct stunaddr_resolve_data {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t port;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+void stunaddr_resolve_callback(const struct ast_dns_query *query);</span><br><span style="color: hsl(120, 100%, 40%);">+int store_stunaddr_resolved(const struct ast_dns_query *query);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)</span><br><span> static int dtls_bio_new(BIO *bio)</span><br><span> {</span><br><span>@@ -3528,6 +3544,7 @@</span><br><span> pj_sockaddr pjtmp;</span><br><span> struct ast_ice_host_candidate *candidate;</span><br><span> int af_inet_ok = 0, af_inet6_ok = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sockaddr *stunaddr_pointer = NULL;</span><br><span> </span><br><span> if (ast_sockaddr_is_ipv4(addr)) {</span><br><span> af_inet_ok = 1;</span><br><span>@@ -3637,12 +3654,17 @@</span><br><span> freeifaddrs(ifa);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_rdlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_pointer = &stunaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_unlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* If configured to use a STUN server to get our external mapped address do so */</span><br><span style="color: hsl(0, 100%, 40%);">- if (stunaddr.sin_addr.s_addr && !stun_address_is_blacklisted(addr) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_sockaddr_isnull(stunaddr_pointer) && !stun_address_is_blacklisted(addr) &&</span><br><span> (ast_sockaddr_is_ipv4(addr) || ast_sockaddr_is_any(addr)) &&</span><br><span> count < PJ_ICE_MAX_CAND) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct sockaddr_in answer;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in answer, stun_sin;</span><br><span> int rsp;</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_to_sin(stunaddr_pointer, &stun_sin);</span><br><span> </span><br><span> ast_debug_category(3, AST_DEBUG_CATEGORY_ICE | AST_DEBUG_CATEGORY_STUN,</span><br><span> "(%p) ICE request STUN %s %s candidate\n", instance,</span><br><span>@@ -3655,7 +3677,7 @@</span><br><span> */</span><br><span> ao2_unlock(instance);</span><br><span> rsp = ast_stun_request(component == AST_RTP_ICE_COMPONENT_RTCP</span><br><span style="color: hsl(0, 100%, 40%);">- ? rtp->rtcp->s : rtp->s, &stunaddr, NULL, &answer);</span><br><span style="color: hsl(120, 100%, 40%);">+ ? rtp->rtcp->s : rtp->s, &stun_sin, NULL, &answer);</span><br><span> ao2_lock(instance);</span><br><span> if (!rsp) {</span><br><span> struct ast_rtp_engine_ice_candidate *candidate;</span><br><span>@@ -9008,6 +9030,72 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void stunaddr_resolve_callback(const struct ast_dns_query *query)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const int lowest_ttl = ast_dns_result_get_lowest_ttl(ast_dns_query_get_result(query));</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *stunaddr_name = ast_dns_query_get_name(query);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!store_stunaddr_resolved(query)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Failed to resolve stunaddr '%s'. Cancelling recurring resolution.\n", stunaddr_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug_stun(2, "Resolved stunaddr '%s' to '%s'. Lowest TTL = %d.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_stringify(&stunaddr),</span><br><span style="color: hsl(120, 100%, 40%);">+ lowest_ttl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!lowest_ttl) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Resolution for stunaddr '%s' returned TTL = 0. Recurring resolution was cancelled.\n", ast_dns_query_get_name(query));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int store_stunaddr_resolved(const struct ast_dns_query *query)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ast_dns_result *result = ast_dns_query_get_result(query);</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ast_dns_record *record;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct stunaddr_resolve_data *data = ast_dns_query_get_data(query);</span><br><span style="color: hsl(120, 100%, 40%);">+ const in_port_t in_port = htons(data->port);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ const size_t data_size = ast_dns_record_get_data_size(record);</span><br><span style="color: hsl(120, 100%, 40%);">+ const unsigned char *data = (unsigned char *)ast_dns_record_get_data(record);</span><br><span style="color: hsl(120, 100%, 40%);">+ const int rr_type = ast_dns_record_get_rr_type(record);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rr_type == ns_t_aaaa && data_size == 16) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in6 sin6 = { 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sin6.sin6_port = in_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&sin6.sin6_addr, data, data_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ sin6.sin6_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_wrlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&stunaddr.ss, &sin6, sizeof(sin6));</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr.len = sizeof(sin6);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_unlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (rr_type == ns_t_a && data_size == 4) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in sin4 = { 0, };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sin4.sin_port = in_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&sin4.sin_addr, data, data_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ sin4.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_wrlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_from_sin(&stunaddr, &sin4);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_unlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug_stun(3, "Unrecognized rr_type '%u' or data_size '%zu' from DNS query for stunaddr '%s'\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rr_type, data_size, ast_dns_query_get_name(query));</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)</span><br><span> /*! \pre instance is locked */</span><br><span> static int ast_rtp_activate(struct ast_rtp_instance *instance)</span><br><span>@@ -9137,6 +9225,7 @@</span><br><span> ast_cli(a->fd, " Replay Protect: %s\n", AST_CLI_YESNO(srtp_replay_protection));</span><br><span> #ifdef HAVE_PJPROJECT</span><br><span> ast_cli(a->fd, " ICE support: %s\n", AST_CLI_YESNO(icesupport));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_cli(a->fd, " STUN address: %s\n", ast_sockaddr_stringify(&stunaddr));</span><br><span> #endif</span><br><span> return CLI_SUCCESS;</span><br><span> }</span><br><span>@@ -9385,7 +9474,9 @@</span><br><span> icesupport = DEFAULT_ICESUPPORT;</span><br><span> stun_software_attribute = DEFAULT_STUN_SOFTWARE_ATTRIBUTE;</span><br><span> turnport = DEFAULT_TURN_PORT;</span><br><span style="color: hsl(0, 100%, 40%);">- memset(&stunaddr, 0, sizeof(stunaddr));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_wrlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_setnull(&stunaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_unlock(&stunaddr_lock);</span><br><span> turnaddr = pj_str(NULL);</span><br><span> turnusername = pj_str(NULL);</span><br><span> turnpassword = pj_str(NULL);</span><br><span>@@ -9463,9 +9554,46 @@</span><br><span> stun_software_attribute = ast_true(s);</span><br><span> }</span><br><span> if ((s = ast_variable_retrieve(cfg, "general", "stunaddr"))) {</span><br><span style="color: hsl(0, 100%, 40%);">- stunaddr.sin_port = htons(STANDARD_STUN_PORT);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_parse_arg(s, PARSE_INADDR, &stunaddr)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", s);</span><br><span style="color: hsl(120, 100%, 40%);">+ char *hostport, *host, *port;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int port_parsed = STANDARD_STUN_PORT;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sockaddr stunaddr_parsed;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (stunaddr_resolver) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_dns_resolve_recurring_cancel(stunaddr_resolver)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Failed to cancel recurring DNS resolution of previous stunaddr.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(stunaddr_resolver, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_resolver = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_cleanup(stunaddr_resolve_data);</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_resolve_data = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hostport = ast_strdupa(s);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_parse_arg(hostport, PARSE_ADDR, &stunaddr_parsed)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug_stun(3, "stunaddr = '%s' does not need name resolution\n", ast_sockaddr_stringify_host(&stunaddr_parsed));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_sockaddr_port(&stunaddr_parsed)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_set_port(&stunaddr_parsed, STANDARD_STUN_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_wrlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_copy(&stunaddr, &stunaddr_parsed);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_rwlock_unlock(&stunaddr_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ast_sockaddr_split_hostport(hostport, &host, &port, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (port) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_parse_arg(port, PARSE_UINT32|PARSE_IN_RANGE, &port_parsed, 1, 65535);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!(stunaddr_resolve_data = ao2_alloc(sizeof(*stunaddr_resolve_data), NULL))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Failed to allocate STUN resolution data.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_resolve_data->port = port_parsed;</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_resolver = ast_dns_resolve_recurring(host, T_A, C_IN, &stunaddr_resolve_callback, stunaddr_resolve_data);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!stunaddr_resolver) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Failed to setup recurring DNS resolution of stunaddr '%s'", host);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Failed to parse stunaddr '%s'", hostport);</span><br><span> }</span><br><span> }</span><br><span> if ((s = ast_variable_retrieve(cfg, "general", "turnaddr"))) {</span><br><span>@@ -9725,6 +9853,16 @@</span><br><span> acl_change_sub = stasis_unsubscribe_and_join(acl_change_sub);</span><br><span> rtp_unload_acl(&ice_acl_lock, &ice_acl);</span><br><span> rtp_unload_acl(&stun_acl_lock, &stun_acl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (stunaddr_resolver) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_dns_resolve_recurring_cancel(stunaddr_resolver)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "Failed to cancel recurring DNS resolution of previous stunaddr.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(stunaddr_resolver, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_resolver = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_cleanup(stunaddr_resolve_data);</span><br><span style="color: hsl(120, 100%, 40%);">+ stunaddr_resolve_data = NULL;</span><br><span> #endif</span><br><span> </span><br><span> return 0;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16167">change 16167</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/16167"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: I7955a046293f913ba121bbd82153b04439e3465f </div>
<div style="display:none"> Gerrit-Change-Number: 16167 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sébastien Duthil <sduthil@wazo.community> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>