From: Terry Wilson Date: Wed, 25 Jan 2012 16:46:56 +0000 (+0000) Subject: Clean up some SIP registry-related memory leaks X-Git-Tag: 1.8.10.0-rc1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1dc1012ae458c662decced4aef1d152e1c7f469;p=thirdparty%2Fasterisk.git Clean up some SIP registry-related memory leaks 1) Be sure and free at unload the epa_backend we allocate at startup 2) Do the same sip_registry cleanup at unload we do at reload Review: https://reviewboard.asterisk.org/r/1689/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@352514 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 6a19c423de..b444e6da78 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -875,6 +875,17 @@ static int sip_epa_register(const struct epa_static_data *static_data) return 0; } +static void sip_epa_unregister_all(void) +{ + struct epa_backend *backend; + + AST_LIST_LOCK(&epa_static_data_list); + while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { + ast_free(backend); + } + AST_LIST_UNLOCK(&epa_static_data_list); +} + static void cc_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry); static void cc_epa_destructor(void *data) @@ -27737,6 +27748,31 @@ static void display_nat_warning(const char *cat, int reason, struct ast_flags *f } } +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 */ + char buf[1024]; + + ASTOBJ_RDLOCK(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 */ + 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, registry_unref(iterator, "reg ptr unref from reload config")); + } + if (iterator->timeout > -1) { + AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); + } + ASTOBJ_DUMP(buf, sizeof(buf), iterator); + ASTOBJ_UNLOCK(iterator); + } while(0)); +} + /*! \brief Re-read SIP.conf config file \note This function reloads all config data, except for active peers (with registrations). They will only @@ -27811,26 +27847,8 @@ static int reload_config(enum channelreloadreason reason) } ast_mutex_unlock(&authl_lock); - /* 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 */ - 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, registry_unref(iterator, "reg ptr unref from reload config")); - } - if (iterator->timeout > -1) { - AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); - } - ASTOBJ_UNLOCK(iterator); - } while(0)); + cleanup_all_regs(); /* Then, actually destroy users and registry */ ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); ast_debug(4, "--------------- Done destroying registry list\n"); @@ -30332,6 +30350,7 @@ static int unload_module(void) } ast_mutex_unlock(&authl_lock); + sip_epa_unregister_all(); destroy_escs(); if (default_tls_cfg.certfile) { @@ -30350,6 +30369,7 @@ static int unload_module(void) ast_free(default_tls_cfg.capath); } + cleanup_all_regs(); ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); ASTOBJ_CONTAINER_DESTROY(®l); ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy);