summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2015-01-21 13:36:52 +0000
committerMatthew Jordan <mjordan@digium.com>2015-01-21 13:36:52 +0000
commit5835bf7a7f2ba2b374aee6807307a6c3c73676f2 (patch)
tree21ca0ddb583c41ffefbdd7e550b707b776630c44 /channels
parent958a41a884e350b7e01b8805e230d4d20e3a4873 (diff)
channels/chan_sip: Fix registration leak during reload
When the SIP registrations were migrated to using ao2 in what was then trunk, the explicit destruction of the registrations on module reload was removed and not replaced with an ao2 equivalent. Debugging done by Stefan Engström, the issue reporter, on ASTERISK-24673 confirmed that the reference in the registry_list container was being leaked. Since the purpose of cleanup_all_regs is to prep a registration for destruction, this function now calls an ao2_callback function callback with the OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK flags used to remove the registrations. This cleans up each registration, and also removes it from the registration container registry_list. Review: https://reviewboard.asterisk.org/r/4355/ ASTERISK-24640 #close Reported by: Max Man ASTERISK-24673 #close Reported by: Stefan Engström Tested by: Stefan Engström ........ Merged revisions 430864 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430866 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 1a0ff94b7..d5213da7a 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -31093,38 +31093,37 @@ static void display_nat_warning(const char *cat, int reason, struct ast_flags *f
}
}
-static void cleanup_all_regs(void)
+static int cleanup_registration(void *obj, void *arg, int flags)
{
- struct ao2_iterator iter;
- struct sip_registry *iterator;
- /* First, destroy all outstanding registry calls */
- /* This is needed, since otherwise active registry entries will not be destroyed */
- iter = ao2_iterator_init(registry_list, 0);
- while ((iterator = ao2_t_iterator_next(&iter, "cleanup_all_regs iter"))) {
- ao2_lock(iterator);
-
- 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 */
- dialog_unlink_all(iterator->call);
- iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
- }
- if (iterator->expire > -1) {
- AST_SCHED_DEL_UNREF(sched, iterator->expire, ao2_t_ref(iterator, -1, "reg ptr unref from reload config"));
- }
- if (iterator->timeout > -1) {
- AST_SCHED_DEL_UNREF(sched, iterator->timeout, ao2_t_ref(iterator, -1, "reg ptr unref from reload config"));
- }
- if (iterator->dnsmgr) {
- ast_dnsmgr_release(iterator->dnsmgr);
- iterator->dnsmgr = NULL;
- ao2_t_ref(iterator, -1, "reg ptr unref from dnsmgr");
- }
+ struct sip_registry *reg = obj;
+ ao2_lock(reg);
- ao2_unlock(iterator);
- ao2_t_ref(iterator, -1, "cleanup_all_regs iter");
+ if (reg->call) {
+ ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
+ /* This will also remove references to the registry */
+ dialog_unlink_all(reg->call);
+ reg->call = dialog_unref(reg->call, "remove iterator->call from registry traversal");
}
- ao2_iterator_destroy(&iter);
+ if (reg->expire > -1) {
+ AST_SCHED_DEL_UNREF(sched, reg->expire, ao2_t_ref(reg, -1, "reg ptr unref from reload config"));
+ }
+ if (reg->timeout > -1) {
+ AST_SCHED_DEL_UNREF(sched, reg->timeout, ao2_t_ref(reg, -1, "reg ptr unref from reload config"));
+ }
+ if (reg->dnsmgr) {
+ ast_dnsmgr_release(reg->dnsmgr);
+ reg->dnsmgr = NULL;
+ ao2_t_ref(reg, -1, "reg ptr unref from dnsmgr");
+ }
+
+ ao2_unlock(reg);
+ return CMP_MATCH;
+}
+
+static void cleanup_all_regs(void)
+{
+ ao2_t_callback(registry_list, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
+ cleanup_registration, NULL, "remove all SIP registry items");
}
/*! \brief Re-read SIP.conf config file