From da683f0cc0ce4fe3b683a703dfe6cfe8eaefd38e Mon Sep 17 00:00:00 2001 From: David Vossel Date: Thu, 19 Aug 2010 20:35:42 +0000 Subject: [PATCH] Merged revisions 282891 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r282891 | dvossel | 2010-08-19 15:34:41 -0500 (Thu, 19 Aug 2010) | 11 lines Merged revisions 282890 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ........ r282890 | dvossel | 2010-08-19 15:31:22 -0500 (Thu, 19 Aug 2010) | 5 lines fixes sip peer memory leaks in the peer_by_ip table (issue #17798) ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@282892 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 47 +++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index cbddd08320..001c40d922 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2621,6 +2621,32 @@ cleanup: return NULL; } +/* this func is used with ao2_callback to unlink/delete all marked + peers */ +static int peer_is_marked(void *peerobj, void *arg, int flags) +{ + struct sip_peer *peer = peerobj; + return peer->the_mark ? CMP_MATCH : 0; +} + + +/* \brief Unlink all marked peers from ao2 containers */ +static void unlink_marked_peers_from_tables(void) +{ + ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, + "initiating callback to remove marked peers"); + ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, + "initiating callback to remove marked peers"); +} + +/* \brief Unlink single peer from all ao2 containers */ +static void unlink_peer_from_tables(struct sip_peer *peer) +{ + ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); + if (!ast_sockaddr_isnull(&peer->addr)) { + ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); + } +} /*! * helper functions to unreference various types of objects. @@ -12684,10 +12710,7 @@ static int expire_register(const void *data) if (peer->selfdestruct || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { - ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); - if (!ast_sockaddr_isnull(&peer->addr)) { - ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); - } + unlink_peer_from_tables(peer); } /* Only clear the addr after we check for destruction. The addr must remain @@ -15836,14 +15859,6 @@ static int dialog_needdestroy(void *dialogobj, void *arg, int flags) return 0; } -/* this func is used with ao2_callback to unlink/delete all marked - peers */ -static int peer_is_marked(void *peerobj, void *arg, int flags) -{ - struct sip_peer *peer = peerobj; - return peer->the_mark ? CMP_MATCH : 0; -} - /*! \brief Remove temporary realtime objects from memory (CLI) */ /*! \todo XXXX Propably needs an overhaul after removal of the devices */ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) @@ -15946,8 +15961,7 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli } ao2_iterator_destroy(&i); if (pruned) { - ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, - "initiating callback to remove marked peers"); + unlink_marked_peers_from_tables(); ast_cli(a->fd, "%d peers pruned.\n", pruned); } else ast_cli(a->fd, "No peers found to prune.\n"); @@ -27754,9 +27768,8 @@ static int sip_do_reload(enum channelreloadreason reason) start_poke = time(0); /* Prune peers who still are supposed to be deleted */ - ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL, - "callback to remove marked peers"); - + unlink_marked_peers_from_tables(); + ast_debug(4, "--------------- Done destroying pruned peers\n"); /* Send qualify (OPTIONS) to all peers */