aboutsummaryrefslogtreecommitdiffstats
path: root/main/asterisk
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2012-03-08 09:07:17 +0200
committerTimo Teräs <timo.teras@iki.fi>2012-03-08 09:07:17 +0200
commitea858919b459042138958b7b669816a84026546a (patch)
tree76b98caf29aefb6d6f3038227a0edae2f36d13f4 /main/asterisk
parent56944b2879124e49973505bab5561eecda1dee28 (diff)
downloadaports-ea858919b459042138958b7b669816a84026546a.tar.bz2
aports-ea858919b459042138958b7b669816a84026546a.tar.xz
main/asterisk: upgrade to 10.2.0
remove patches merged upstream
Diffstat (limited to 'main/asterisk')
-rw-r--r--main/asterisk/APKBUILD8
-rw-r--r--main/asterisk/ASTERISK-18976.patch142
-rw-r--r--main/asterisk/ASTERISK-19106.patch442
3 files changed, 2 insertions, 590 deletions
diff --git a/main/asterisk/APKBUILD b/main/asterisk/APKBUILD
index c9079c1e24..51124dd536 100644
--- a/main/asterisk/APKBUILD
+++ b/main/asterisk/APKBUILD
@@ -1,7 +1,7 @@
# Contributor: Timo Teras <timo.teras@iki.fi>
# Maintainer: Timo Teras <timo.teras@iki.fi>
pkgname=asterisk
-pkgver=10.1.3
+pkgver=10.2.0
pkgrel=0
pkgdesc="Asterisk: A Module Open Source PBX System"
pkgusers="asterisk"
@@ -23,10 +23,8 @@ source="http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-$
101-caps-uclibc.patch
400-bug-227.patch
900-tryinclude.patch
- ASTERISK-18976.patch
ASTERISK-18977.patch
ASTERISK-18995.patch
- ASTERISK-19106.patch
ASTERISK-19109.patch
asterisk.initd
asterisk.confd
@@ -174,15 +172,13 @@ sound_en() {
chown -R asterisk:asterisk "$subpkgdir"/var/*/asterisk
}
-md5sums="74722496822e4fcee56c24016c1a8c1d asterisk-10.1.3.tar.gz
+md5sums="b8d4d435ea050cc9856261d4f610377e asterisk-10.2.0.tar.gz
b00c9d98ce2ad445501248a197c6e436 100-uclibc-daemon.patch
6e1129e30c4fd2c25c86c81685a485a9 101-caps-uclibc.patch
79e9634b5054bceb3b8dc246654bb243 400-bug-227.patch
b794636266cc573f0dda730fba634567 900-tryinclude.patch
-da5a3c500192dee4275aae5235d25f97 ASTERISK-18976.patch
1ddadef41aa7120e168738b6f3ed8917 ASTERISK-18977.patch
bc6713f5434e07b79d3afdd155461d72 ASTERISK-18995.patch
-cbe5e2363570c5417c9edc68ed849b0d ASTERISK-19106.patch
a22bb1d513d026564cb40ec213b1ae7f ASTERISK-19109.patch
74cd25a5638a94ef51e9f4ede2fd28f2 asterisk.initd
ed31d7ba37bcf8b0346dcf8593c395f0 asterisk.confd
diff --git a/main/asterisk/ASTERISK-18976.patch b/main/asterisk/ASTERISK-18976.patch
deleted file mode 100644
index 36c613ff4f..0000000000
--- a/main/asterisk/ASTERISK-18976.patch
+++ /dev/null
@@ -1,142 +0,0 @@
---- a/pbx/pbx_lua.c.orig 2011-12-08 08:28:31.000000000 +0200
-+++ b/pbx/pbx_lua.c 2011-12-08 08:54:22.000000000 +0200
-@@ -94,7 +94,6 @@
- static void lua_create_application_metatable(lua_State *L);
- static void lua_create_autoservice_functions(lua_State *L);
- static void lua_create_hangup_function(lua_State *L);
--static void lua_detect_goto(lua_State *L);
- static void lua_concat_args(lua_State *L, int start, int nargs);
-
- static void lua_state_destroy(void *data);
-@@ -213,19 +212,10 @@
- chan = lua_touserdata(L, -1);
- lua_pop(L, 1);
-
-+ context = ast_strdupa(chan->context);
-+ exten = ast_strdupa(chan->exten);
-+ priority = chan->priority;
-
-- lua_getfield(L, LUA_REGISTRYINDEX, "context");
-- context = ast_strdupa(lua_tostring(L, -1));
-- lua_pop(L, 1);
--
-- lua_getfield(L, LUA_REGISTRYINDEX, "exten");
-- exten = ast_strdupa(lua_tostring(L, -1));
-- lua_pop(L, 1);
--
-- lua_getfield(L, LUA_REGISTRYINDEX, "priority");
-- priority = lua_tointeger(L, -1);
-- lua_pop(L, 1);
--
- lua_concat_args(L, 2, nargs);
- data = lua_tostring(L, -1);
-
-@@ -256,75 +246,51 @@
- return lua_error(L);
- }
-
-- lua_detect_goto(L);
--
-- return 0;
--}
--
--/*!
-- * \brief Detect if a Goto or other dialplan jump has been executed and return
-- * control to the pbx engine.
-- */
--static void lua_detect_goto(lua_State *L)
--{
-- struct ast_channel *chan;
--
-- lua_getfield(L, LUA_REGISTRYINDEX, "channel");
-- chan = lua_touserdata(L, -1);
-- lua_pop(L, 1);
--
-- /* check context */
-- lua_getfield(L, LUA_REGISTRYINDEX, "context");
-- lua_pushstring(L, chan->context);
-- if (!lua_equal(L, -1, -2)) {
-+ if (strcmp(context, chan->context)) {
-+ lua_pushstring(L, context);
-+ lua_pushstring(L, chan->context);
- lua_pushliteral(L, "context");
-- goto e_goto_detected;
-- }
-- lua_pop(L, 2);
--
-- /* check exten */
-- lua_getfield(L, LUA_REGISTRYINDEX, "exten");
-- lua_pushstring(L, chan->exten);
-- if (!lua_equal(L, -1, -2)) {
-+ } else if (strcmp(exten, chan->exten)) {
-+ lua_pushstring(L, exten);
-+ lua_pushstring(L, chan->exten);
- lua_pushliteral(L, "exten");
-- goto e_goto_detected;
-- }
-- lua_pop(L, 2);
--
-- /* check priority */
-- lua_getfield(L, LUA_REGISTRYINDEX, "priority");
-- lua_pushinteger(L, chan->priority);
-- if (!lua_equal(L, -1, -2)) {
-+ } else if (priority != chan->priority) {
-+ lua_pushinteger(L, priority);
-+ lua_pushinteger(L, chan->priority);
- lua_pushliteral(L, "priority");
-- goto e_goto_detected;
-+ } else {
-+ /* no goto - restore the original position back
-+ * to lua state, in case this was a recursive dialplan
-+ * call (a dialplan application re-entering dialplan) */
-+ lua_update_registry(L, context, exten, priority);
-+ return 0;
- }
-- lua_pop(L, 2);
-- return;
--
--e_goto_detected:
-- /* format our debug message */
-- lua_insert(L, -3);
-
-- lua_pushliteral(L, " changed from ");
-+ /* goto detected - construct error message */
- lua_insert(L, -3);
--
-- lua_pushliteral(L, " to ");
-- lua_insert(L, -2);
--
-- lua_concat(L, 5);
--
-- ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1));
-- lua_pop(L, 1);
--
-- /* let the lua engine know it needs to return control to the pbx */
-- lua_pushinteger(L, LUA_GOTO_DETECTED);
-+
-+ lua_pushliteral(L, " changed from ");
-+ lua_insert(L, -3);
-+
-+ lua_pushliteral(L, " to ");
-+ lua_insert(L, -2);
-+
-+ lua_concat(L, 5);
-+
-+ ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1));
-+ lua_pop(L, 1);
-+
-+ /* let the lua engine know it needs to return control to the pbx */
-+ lua_pushinteger(L, LUA_GOTO_DETECTED);
- lua_error(L);
-+
-+ return 0;
- }
-
- /*!
- * \brief [lua_CFunction] Used to get the value of a variable or dialplan
- * function (for access from lua, don't call directly)
-- *
-+ *
- * The value of the variable or function is returned. This function is the
- * 'get()' function in the following example as would be seen in
- * extensions.lua.
diff --git a/main/asterisk/ASTERISK-19106.patch b/main/asterisk/ASTERISK-19106.patch
deleted file mode 100644
index dd23733e3f..0000000000
--- a/main/asterisk/ASTERISK-19106.patch
+++ /dev/null
@@ -1,442 +0,0 @@
-commit f987e47193c1ce64466663134e5e311742d022d2
-Author: twilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>
-Date: Mon Jan 30 23:58:51 2012 +0000
-
- Re-link peers by IP when dnsmgr changes the IP
-
- Asterisk's dnsmgr currently takes a pointer to an ast_sockaddr and updates it
- anytime an address resolves to something different. There are a couple of
- issues with this. First, the ast_sockaddr is usually the address of an
- ast_sockaddr inside a refcounted struct and we never bump the refcount of those
- structs when using dnsmgr. This makes it possible that a refresh could happen
- after the destructor for that object is called (despite ast_dnsmgr_release
- being called in that destructor). Second, the module using dnsmgr cannot be
- aware of an address changing without polling for it in the code. If an action
- needs to be taken on address update (like re-linking a SIP peer in the
- peers_by_ip table), then polling for this change negates many of the benefits
- of having dnsmgr in the first place.
-
- This patch adds a function to the dnsmgr API that calls an update callback
- instead of blindly updating the address itself. It also moves calls to
- ast_dnsmgr_release outside of the destructor functions and into cleanup
- functions that are called when we no longer need the objects and increments the
- refcount of the objects using dnsmgr since those objects are stored on the
- ast_dnsmgr_entry struct. A helper function for returning the proper default SIP
- port (non-tls vs tls) is also added and used.
-
- This patch also incorporates changes from a patch posted by Timo Teräs to
- ASTERISK-19106 for related dnsmgr issues.
-
- (closes issue ASTERISK-19106)
-
- Review: https://reviewboard.asterisk.org/r/1691/
- ........
-
- Merged revisions 353371 from http://svn.asterisk.org/svn/asterisk/branches/1.8
- ........
-
- Merged revisions 353397 from http://svn.asterisk.org/svn/asterisk/branches/10
-
-
- git-svn-id: http://svn.digium.com/svn/asterisk/trunk@353418 f38db490-d61c-443f-a65b-d21fe96a405b
-
-diff --git a/channels/chan_sip.c b/channels/chan_sip.c
-index e1dfaea..698894f 100644
---- a/channels/chan_sip.c
-+++ b/channels/chan_sip.c
-@@ -2897,6 +2897,11 @@ static int match_and_cleanup_peer_sched(void *peerobj, void *arg, int flags)
-
- if (which == SIP_PEERS_ALL || peer->the_mark) {
- peer_sched_cleanup(peer);
-+ if (peer->dnsmgr) {
-+ ast_dnsmgr_release(peer->dnsmgr);
-+ peer->dnsmgr = NULL;
-+ sip_unref_peer(peer, "Release peer from dnsmgr");
-+ }
- return CMP_MATCH;
- }
- return 0;
-@@ -4681,8 +4686,6 @@ static void sip_destroy_peer(struct sip_peer *peer)
- ao2_t_ref(peer->auth, -1, "Removing peer authentication");
- peer->auth = NULL;
- }
-- if (peer->dnsmgr)
-- ast_dnsmgr_release(peer->dnsmgr);
-
- if (peer->socket.tcptls_session) {
- ao2_ref(peer->socket.tcptls_session, -1);
-@@ -5423,6 +5426,12 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
- return 0;
- }
-
-+/*! \brief The default sip port for the given transport */
-+static inline int default_sip_port(enum sip_transport type)
-+{
-+ return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
-+}
-+
- /*! \brief create address structure from device name
- * Or, if peer not found, find it in the global DNS
- * returns TRUE (-1) on failure, FALSE on success */
-@@ -5525,9 +5534,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct ast_soc
- }
-
- if (!ast_sockaddr_port(&dialog->sa)) {
-- ast_sockaddr_set_port(&dialog->sa,
-- (dialog->socket.type == SIP_TRANSPORT_TLS) ?
-- STANDARD_TLS_PORT : STANDARD_SIP_PORT);
-+ ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type));
- }
- ast_sockaddr_copy(&dialog->recv, &dialog->sa);
- return 0;
-@@ -5747,7 +5754,6 @@ static void sip_registry_destroy(struct sip_registry *reg)
-
- ast_string_field_free_memory(reg);
- ast_atomic_fetchadd_int(&regobjs, -1);
-- ast_dnsmgr_release(reg->dnsmgr);
- ast_free(reg);
- }
-
-@@ -5761,7 +5767,6 @@ static void sip_subscribe_mwi_destroy(struct sip_subscription_mwi *mwi)
-
- AST_SCHED_DEL(sched, mwi->resub);
- ast_string_field_free_memory(mwi);
-- ast_dnsmgr_release(mwi->dnsmgr);
- ast_free(mwi);
- }
-
-@@ -12721,6 +12726,72 @@ static int sip_subscribe_mwi_do(const void *data)
- return 0;
- }
-
-+static void on_dns_update_registry(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
-+{
-+ struct sip_registry *reg = data;
-+ const char *old_str;
-+
-+ /* This shouldn't happen, but just in case */
-+ if (ast_sockaddr_isnull(new)) {
-+ ast_debug(1, "Empty sockaddr change...ignoring!\n");
-+ return;
-+ }
-+
-+ if (!ast_sockaddr_port(new)) {
-+ ast_sockaddr_set_port(new, reg->portno);
-+ }
-+
-+ old_str = ast_strdupa(ast_sockaddr_stringify(old));
-+
-+ ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new));
-+ ast_sockaddr_copy(&reg->us, new);
-+}
-+
-+static void on_dns_update_peer(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
-+{
-+ struct sip_peer *peer = data;
-+ const char *old_str;
-+
-+ /* This shouldn't happen, but just in case */
-+ if (ast_sockaddr_isnull(new)) {
-+ ast_debug(1, "Empty sockaddr change...ignoring!\n");
-+ return;
-+ }
-+
-+ if (!ast_sockaddr_isnull(&peer->addr)) {
-+ ao2_unlink(peers_by_ip, peer);
-+ }
-+
-+ if (!ast_sockaddr_port(new)) {
-+ ast_sockaddr_set_port(new, default_sip_port(peer->socket.type));
-+ }
-+
-+ old_str = ast_strdupa(ast_sockaddr_stringify(old));
-+ ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new));
-+
-+ ao2_lock(peer);
-+ ast_sockaddr_copy(&peer->addr, new);
-+ ao2_unlock(peer);
-+
-+ ao2_link(peers_by_ip, peer);
-+}
-+
-+static void on_dns_update_mwi(struct ast_sockaddr *old, struct ast_sockaddr *new, void *data)
-+{
-+ struct sip_subscription_mwi *mwi = data;
-+ const char *old_str;
-+
-+ /* This shouldn't happen, but just in case */
-+ if (ast_sockaddr_isnull(new)) {
-+ ast_debug(1, "Empty sockaddr change...ignoring!\n");
-+ return;
-+ }
-+
-+ old_str = ast_strdupa(ast_sockaddr_stringify(old));
-+ ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new));
-+ ast_sockaddr_copy(&mwi->us, new);
-+}
-+
- /*! \brief Actually setup an MWI subscription or resubscribe */
- static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
- {
-@@ -12730,7 +12801,11 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
- snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport));
-
- mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
-- ast_dnsmgr_lookup(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
-+ ASTOBJ_REF(mwi); /* Add a ref for storing the mwi on the dnsmgr for updates */
-+ ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, mwi);
-+ if (!mwi->dnsmgr) {
-+ ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */
-+ }
- }
-
- /* If we already have a subscription up simply send a resubscription */
-@@ -13411,17 +13486,8 @@ static int sip_reg_timeout(const void *data)
- }
-
- if (r->dnsmgr) {
-- struct sip_peer *peer;
- /* If the registration has timed out, maybe the IP changed. Force a refresh. */
- ast_dnsmgr_refresh(r->dnsmgr);
-- /* If we are resolving a peer, we have to make sure the refreshed address gets copied */
-- if ((peer = sip_find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0))) {
-- ast_sockaddr_copy(&peer->addr, &r->us);
-- if (r->portno) {
-- ast_sockaddr_set_port(&peer->addr, r->portno);
-- }
-- peer = sip_unref_peer(peer, "unref after sip_find_peer");
-- }
- }
-
- /* If the initial tranmission failed, we may not have an existing dialog,
-@@ -13510,7 +13576,12 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
- peer = sip_find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0);
- snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static sip_get_transport function */
- r->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
-- ast_dnsmgr_lookup(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
-+ registry_addref(r, "add reg ref for dnsmgr");
-+ ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r);
-+ if (!r->dnsmgr) {
-+ /*dnsmgr refresh disabled, no reference added! */
-+ registry_unref(r, "remove reg ref, dnsmgr disabled");
-+ }
- if (peer) {
- peer = sip_unref_peer(peer, "removing peer ref for dnsmgr_lookup");
- }
-@@ -13543,18 +13614,21 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
- }
-
- /* Use port number specified if no SRV record was found */
-- if (!ast_sockaddr_port(&r->us) && r->portno) {
-- ast_sockaddr_set_port(&r->us, r->portno);
-- }
--
-- /* It is possible that DNS is unavailable at the time the peer is created. Here, if
-- * we've updated the address in the registry, we copy it to the peer so that
-- * create_addr() can copy it to the dialog via create_addr_from_peer */
-- if ((peer = sip_find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0))) {
-- if (ast_sockaddr_isnull(&peer->addr) && !(ast_sockaddr_isnull(&r->us))) {
-- ast_sockaddr_copy(&peer->addr, &r->us);
-+ if (!ast_sockaddr_isnull(&r->us)) {
-+ if (!ast_sockaddr_port(&r->us) && r->portno) {
-+ ast_sockaddr_set_port(&r->us, r->portno);
-+ }
-+
-+ /* It is possible that DNS was unavailable at the time the peer was created.
-+ * Here, if we've updated the address in the registry via manually calling
-+ * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would
-+ * call if it was updating a peer's address */
-+ if ((peer = sip_find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) {
-+ if (ast_sockaddr_cmp(&peer->addr, &r->us)) {
-+ on_dns_update_peer(&peer->addr, &r->us, peer);
-+ }
-+ peer = sip_unref_peer(peer, "unref after sip_find_peer");
- }
-- peer = sip_unref_peer(peer, "unref after sip_find_peer");
- }
-
- /* Find address to hostname */
-@@ -14392,9 +14466,7 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
- peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
-
- if (!ast_sockaddr_port(&testsa)) {
-- ast_sockaddr_set_port(&testsa,
-- transport_type == SIP_TRANSPORT_TLS ?
-- STANDARD_TLS_PORT : STANDARD_SIP_PORT);
-+ ast_sockaddr_set_port(&testsa, default_sip_port(transport_type));
- }
-
- ast_sockaddr_copy(&peer->addr, &testsa);
-@@ -28679,11 +28751,17 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
- snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
-
- peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
-- if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL)) {
-+ if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL,
-+ on_dns_update_peer, sip_ref_peer(peer, "Store peer on dnsmgr"))) {
- ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
-+ sip_unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref");
- sip_unref_peer(peer, "getting rid of a peer pointer");
- return NULL;
- }
-+ if (!peer->dnsmgr) {
-+ /* dnsmgr refresh disabeld, release reference */
-+ sip_unref_peer(peer, "dnsmgr disabled, unref peer");
-+ }
-
- ast_string_field_set(peer, tohost, srvlookup);
-
-@@ -28817,7 +28895,7 @@ static void cleanup_all_regs(void)
- /* This is needed, since otherwise active registry entries will not be destroyed */
- ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do { /* regl is locked */
-
-- ASTOBJ_RDLOCK(iterator); /* now regl is locked, and the object is also locked */
-+ ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */
- if (iterator->call) {
- ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
- /* This will also remove references to the registry */
-@@ -28830,6 +28908,11 @@ static void cleanup_all_regs(void)
- if (iterator->timeout > -1) {
- AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config"));
- }
-+ if (iterator->dnsmgr) {
-+ ast_dnsmgr_release(iterator->dnsmgr);
-+ iterator->dnsmgr = NULL;
-+ registry_unref(iterator, "reg ptr unref from dnsmgr");
-+ }
- ASTOBJ_UNLOCK(iterator);
- } while(0));
- }
-@@ -31496,6 +31579,16 @@ static int unload_module(void)
- cleanup_all_regs();
- ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
- ASTOBJ_CONTAINER_DESTROY(&regl);
-+
-+ ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
-+ ASTOBJ_WRLOCK(iterator);
-+ if (iterator->dnsmgr) {
-+ ast_dnsmgr_release(iterator->dnsmgr);
-+ iterator->dnsmgr = NULL;
-+ ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy);
-+ }
-+ ASTOBJ_UNLOCK(iterator);
-+ } while(0));
- ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy);
- ASTOBJ_CONTAINER_DESTROY(&submwil);
-
-diff --git a/include/asterisk/dnsmgr.h b/include/asterisk/dnsmgr.h
-index b62c2a1..07d6268 100644
---- a/include/asterisk/dnsmgr.h
-+++ b/include/asterisk/dnsmgr.h
-@@ -37,6 +37,8 @@ extern "C" {
- */
- struct ast_dnsmgr_entry;
-
-+typedef void (*dns_update_func)(struct ast_sockaddr *old_addr, struct ast_sockaddr *new_addr, void *data);
-+
- /*!
- * \brief Allocate a new DNS manager entry
- *
-@@ -105,6 +107,31 @@ void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry);
- int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service);
-
- /*!
-+ * \brief Allocate and initialize a DNS manager entry, with update callback
-+ *
-+ * \param name the hostname
-+ * \param result The addr which is intended to be updated in the update callback when DNS manager calls it on refresh.
-+ * The address family is used as an input parameter to filter the returned addresses.
-+ * If it is 0, both IPv4 and IPv6 addresses can be returned.
-+ * \param dnsmgr Where to store the allocate DNS manager entry
-+ * \param service
-+ * \param func The update callback function
-+ * The update callback will be called when DNS manager detects that an IP address has been changed.
-+ * Instead of updating the addr itself, DNS manager will call this callback function with the old
-+ * and new addresses. It is the responsibility of the callback to perform any updates
-+ * \param data A pointer to data that will be passed through to the callback function
-+ *
-+ * \note
-+ * This function allocates a new DNS manager entry object, and fills it with
-+ * the provided hostname and IP address. This function _does_ force an initial
-+ * lookup, so it may block for some period of time.
-+ *
-+ * \retval 0 success
-+ * \retval non-zero failure
-+ */
-+int ast_dnsmgr_lookup_cb(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data);
-+
-+/*!
- * \brief Force a refresh of a dnsmgr entry
- *
- * \retval non-zero if the result is different than the previous result
-diff --git a/main/dnsmgr.c b/main/dnsmgr.c
-index d11cd99..7cdcd0c 100644
---- a/main/dnsmgr.c
-+++ b/main/dnsmgr.c
-@@ -58,6 +58,10 @@ struct ast_dnsmgr_entry {
- unsigned int family;
- /*! Set to 1 if the entry changes */
- unsigned int changed:1;
-+ /*! Data to pass back to update_func */
-+ void *data;
-+ /*! The callback function to execute on address update */
-+ dns_update_func update_func;
- ast_mutex_t lock;
- AST_RWLIST_ENTRY(ast_dnsmgr_entry) list;
- /*! just 1 here, but we use calloc to allocate the correct size */
-@@ -130,7 +134,7 @@ void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
- ast_free(entry);
- }
-
--int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
-+static int internal_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
- {
- unsigned int family;
-
-@@ -165,9 +169,21 @@ int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_
-
- ast_verb(3, "adding dns manager for '%s'\n", name);
- *dnsmgr = ast_dnsmgr_get_family(name, result, service, family);
-+ (*dnsmgr)->update_func = func;
-+ (*dnsmgr)->data = data;
- return !*dnsmgr;
- }
-
-+int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
-+{
-+ return internal_dnsmgr_lookup(name, result, dnsmgr, service, NULL, NULL);
-+}
-+
-+int ast_dnsmgr_lookup_cb(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data)
-+{
-+ return internal_dnsmgr_lookup(name, result, dnsmgr, service, func, data);
-+}
-+
- /*
- * Refresh a dnsmgr entry
- */
-@@ -187,16 +203,19 @@ static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
- if (!ast_sockaddr_port(&tmp)) {
- ast_sockaddr_set_port(&tmp, ast_sockaddr_port(entry->result));
- }
--
- if (ast_sockaddr_cmp(&tmp, entry->result)) {
- const char *old_addr = ast_strdupa(ast_sockaddr_stringify(entry->result));
- const char *new_addr = ast_strdupa(ast_sockaddr_stringify(&tmp));
-
-- ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s to %s\n",
-- entry->name, old_addr, new_addr);
-+ if (entry->update_func) {
-+ entry->update_func(entry->result, &tmp, entry->data);
-+ } else {
-+ ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s to %s\n",
-+ entry->name, old_addr, new_addr);
-
-- ast_sockaddr_copy(entry->result, &tmp);
-- changed = entry->changed = 1;
-+ ast_sockaddr_copy(entry->result, &tmp);
-+ changed = entry->changed = 1;
-+ }
- }
- }
-