diff options
author | Timo Teräs <timo.teras@iki.fi> | 2012-01-31 09:07:54 +0200 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2012-01-31 09:08:37 +0200 |
commit | 1ca00eb19499a0b605d9dc766565fc7a4e7067ce (patch) | |
tree | 69135067587d4c7ee67d9f698a9de364323a8d44 /main/asterisk | |
parent | 4d59ce7e0a9d75ecab8839b6c5edb79298e3efd5 (diff) | |
download | aports-1ca00eb19499a0b605d9dc766565fc7a4e7067ce.tar.bz2 aports-1ca00eb19499a0b605d9dc766565fc7a4e7067ce.tar.xz |
main/asterisk: update ASTERISK-19106 patch
It's now the patch that actually got committed.
Diffstat (limited to 'main/asterisk')
-rw-r--r-- | main/asterisk/APKBUILD | 4 | ||||
-rw-r--r-- | main/asterisk/ASTERISK-19106.patch | 287 |
2 files changed, 173 insertions, 118 deletions
diff --git a/main/asterisk/APKBUILD b/main/asterisk/APKBUILD index b7e7486e5c..309c26e5b3 100644 --- a/main/asterisk/APKBUILD +++ b/main/asterisk/APKBUILD @@ -2,7 +2,7 @@ # Maintainer: Timo Teras <timo.teras@iki.fi> pkgname=asterisk pkgver=10.1.0 -pkgrel=0 +pkgrel=1 pkgdesc="Asterisk: A Module Open Source PBX System" url="http://www.asterisk.org/" arch="all" @@ -167,7 +167,7 @@ b794636266cc573f0dda730fba634567 900-tryinclude.patch da5a3c500192dee4275aae5235d25f97 ASTERISK-18976.patch 1ddadef41aa7120e168738b6f3ed8917 ASTERISK-18977.patch bc6713f5434e07b79d3afdd155461d72 ASTERISK-18995.patch -8190437436de46b3a5a607f56f5af539 ASTERISK-19106.patch +2581cf79297ebf4ce4a7145f07512c7e ASTERISK-19106.patch a22bb1d513d026564cb40ec213b1ae7f ASTERISK-19109.patch 74cd25a5638a94ef51e9f4ede2fd28f2 asterisk.initd ed31d7ba37bcf8b0346dcf8593c395f0 asterisk.confd diff --git a/main/asterisk/ASTERISK-19106.patch b/main/asterisk/ASTERISK-19106.patch index 93e9d2d896..d66c4744d5 100644 --- a/main/asterisk/ASTERISK-19106.patch +++ b/main/asterisk/ASTERISK-19106.patch @@ -1,20 +1,62 @@ -Index: channels/chan_sip.c -=================================================================== ---- a/channels/chan_sip.c (revision 352352) -+++ b/channels/chan_sip.c (working copy) -@@ -2883,6 +2883,11 @@ +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); -+ ao2_t_ref(peer, -1, "Release peer from dnsmgr"); + peer->dnsmgr = NULL; ++ sip_unref_peer(peer, "Release peer from dnsmgr"); + } return CMP_MATCH; } return 0; -@@ -4661,8 +4666,6 @@ +@@ -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; } @@ -23,7 +65,7 @@ Index: channels/chan_sip.c if (peer->socket.tcptls_session) { ao2_ref(peer->socket.tcptls_session, -1); -@@ -5401,6 +5404,12 @@ +@@ -5423,6 +5426,12 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer) return 0; } @@ -36,7 +78,7 @@ Index: channels/chan_sip.c /*! \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 */ -@@ -5503,9 +5512,7 @@ +@@ -5525,9 +5534,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct ast_soc } if (!ast_sockaddr_port(&dialog->sa)) { @@ -47,7 +89,7 @@ Index: channels/chan_sip.c } ast_sockaddr_copy(&dialog->recv, &dialog->sa); return 0; -@@ -5725,7 +5732,6 @@ +@@ -5747,7 +5754,6 @@ static void sip_registry_destroy(struct sip_registry *reg) ast_string_field_free_memory(reg); ast_atomic_fetchadd_int(®objs, -1); @@ -55,7 +97,7 @@ Index: channels/chan_sip.c ast_free(reg); } -@@ -5739,7 +5745,6 @@ +@@ -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); @@ -63,13 +105,14 @@ Index: channels/chan_sip.c ast_free(mwi); } -@@ -12565,6 +12570,67 @@ +@@ -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)) { @@ -80,14 +123,17 @@ Index: channels/chan_sip.c + if (!ast_sockaddr_port(new)) { + ast_sockaddr_set_port(new, reg->portno); + } -+ -+ ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), ast_sockaddr_stringify(old), ast_sockaddr_stringify(new)); ++ ++ 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(®->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)) { @@ -95,7 +141,6 @@ Index: channels/chan_sip.c + return; + } + -+ ao2_ref(peer, +1); + if (!ast_sockaddr_isnull(&peer->addr)) { + ao2_unlink(peers_by_ip, peer); + } @@ -104,19 +149,20 @@ Index: channels/chan_sip.c + ast_sockaddr_set_port(new, default_sip_port(peer->socket.type)); + } + -+ ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, ast_sockaddr_stringify(old), ast_sockaddr_stringify(new)); ++ 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); -+ ao2_ref(peer, -1); +} + +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)) { @@ -124,27 +170,28 @@ Index: channels/chan_sip.c + return; + } + -+ ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, ast_sockaddr_stringify(old), ast_sockaddr_stringify(new)); ++ 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) { -@@ -12574,7 +12640,11 @@ +@@ -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 aref for storing the mwi on the dnsmgr for updates */ -+ ast_dnsmgr_lookup(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, mwi); ++ 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 */ -@@ -13255,17 +13325,8 @@ +@@ -13411,17 +13486,8 @@ static int sip_reg_timeout(const void *data) } if (r->dnsmgr) { @@ -162,46 +209,43 @@ Index: channels/chan_sip.c } /* If the initial tranmission failed, we may not have an existing dialog, -@@ -13348,10 +13409,16 @@ - 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(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r); +@@ -13510,7 +13576,12 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * + * or peer NULL. Since we're only concerned with its existence, we're not going to + * bother getting a ref to the proxy*/ + if (!obproxy_get(r->call, peer)) { +- 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"); - } -+ if (!r->dnsmgr) { -+ /* dnsmgr refresh disabled, no reference added! */ -+ registry_unref(r, "remove reg ref, dnsmgr disabled"); -+ } -+ - } - - if (r->call) { /* We have a registration */ -@@ -13380,18 +13447,21 @@ +@@ -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); - } -+ 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 update the address in the registry via manually calling -+ * ast_dnsmgr_lookup() above, then we call the same function that dnsmgr would -+ * call if it was updating a peer's address */ - +- - /* 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); @@ -212,7 +256,7 @@ Index: channels/chan_sip.c } /* Find address to hostname */ -@@ -14243,9 +14313,7 @@ +@@ -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)) { @@ -223,93 +267,68 @@ Index: channels/chan_sip.c } ast_sockaddr_copy(&peer->addr, &testsa); -@@ -28327,11 +28395,16 @@ +@@ -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)) { -+ ao2_t_ref(peer, +1, "Store peer on dnsmgr"); /* Ref for storing peer (and peer->addr) on the dnsmgr for the callback */ -+ if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL, on_dns_update_peer, peer)) { ++ 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 */ -+ ao2_t_ref(peer, -1, "dnsmgr disabled, unref peer"); ++ sip_unref_peer(peer, "dnsmgr disabled, unref peer"); + } ast_string_field_set(peer, tohost, srvlookup); -@@ -28549,6 +28622,11 @@ +@@ -28817,7 +28895,7 @@ static void cleanup_all_regs(void) + /* First, destroy all outstanding registry calls */ + /* This is needed, since otherwise active registry entries will not be destroyed */ + ASTOBJ_CONTAINER_TRAVERSE(®l, 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); -+ registry_unref(iterator, "reg ptr unref from dnsmgr"); + iterator->dnsmgr = NULL; ++ registry_unref(iterator, "reg ptr unref from dnsmgr"); + } ASTOBJ_UNLOCK(iterator); } while(0)); - -@@ -31105,8 +31183,29 @@ - ast_free(default_tls_cfg.capath); - } - -+ ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ -+ ASTOBJ_RDLOCK(iterator); /* now regl is locked, and the object is also locked */ -+ if (iterator->dnsmgr) { -+ ast_dnsmgr_release(iterator->dnsmgr); -+ registry_unref(iterator, "reg ptr unref from dnsmgr"); -+ iterator->dnsmgr = NULL; -+ } -+ ASTOBJ_UNLOCK(iterator); -+ } while(0)); -+ + } +@@ -31496,6 +31579,16 @@ static int unload_module(void) + cleanup_all_regs(); ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); ASTOBJ_CONTAINER_DESTROY(®l); + + ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { -+ ASTOBJ_RDLOCK(iterator); ++ ASTOBJ_WRLOCK(iterator); + if (iterator->dnsmgr) { + ast_dnsmgr_release(iterator->dnsmgr); -+ ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); + 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); -Index: channels/chan_iax2.c -=================================================================== ---- a/channels/chan_iax2.c (revision 352352) -+++ b/channels/chan_iax2.c (working copy) -@@ -8587,7 +8587,7 @@ - return -1; - - reg->addr.ss.ss_family = AF_INET; -- if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { -+ if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL, NULL, NULL) < 0) { - ast_free(reg); - return -1; - } -@@ -12595,7 +12595,7 @@ - /* Non-dynamic. Make sure we become that way if we're not */ - AST_SCHED_DEL(sched, peer->expire); - ast_clear_flag64(peer, IAX_DYNAMIC); -- if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) -+ if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL, NULL, NULL)) - return peer_unref(peer); - if (!ast_sockaddr_port(&peer->addr)) { - ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); -Index: include/asterisk/dnsmgr.h -=================================================================== ---- a/include/asterisk/dnsmgr.h (revision 352352) -+++ b/include/asterisk/dnsmgr.h (working copy) -@@ -37,6 +37,8 @@ +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; @@ -318,20 +337,43 @@ Index: include/asterisk/dnsmgr.h /*! * \brief Allocate a new DNS manager entry * -@@ -102,7 +104,7 @@ - * \retval non-zero failure - * \version 1.6.1 result changed from struct in_addr to struct aockaddr_in to store port number - */ --int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service); -+int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data); +@@ -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 -Index: main/dnsmgr.c -=================================================================== ---- a/main/dnsmgr.c (revision 352352) -+++ b/main/dnsmgr.c (working copy) -@@ -58,6 +58,10 @@ + * + * \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; @@ -342,17 +384,17 @@ Index: main/dnsmgr.c ast_mutex_t lock; AST_RWLIST_ENTRY(ast_dnsmgr_entry) list; /*! just 1 here, but we use calloc to allocate the correct size */ -@@ -129,7 +133,7 @@ +@@ -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) -+int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service, dns_update_func func, void *data) ++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; -@@ -164,6 +168,8 @@ - +@@ -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; @@ -360,7 +402,20 @@ Index: main/dnsmgr.c return !*dnsmgr; } -@@ -186,16 +192,19 @@ ++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)); } |