From: Tilghman Lesher Date: Mon, 7 Jun 2010 22:47:13 +0000 (+0000) Subject: Mailbox list would previously grow at each reload, containing duplicates. X-Git-Tag: 11.0.0-beta1~2890 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8b790e4f06fd21412b8818c2d34fdaf0bc4eb70f;p=thirdparty%2Fasterisk.git Mailbox list would previously grow at each reload, containing duplicates. Also, optimize the allocation of mailboxes to avoid additional memory structures. (closes issue #16320) Reported by: Marquis Patches: 20100525__issue16320.diff.txt uploaded by tilghman (license 14) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@268817 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index d7b6c180b6..d65471da1a 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -4145,10 +4145,6 @@ static void register_peer_exten(struct sip_peer *peer, int onoff) /*! Destroy mailbox subscriptions */ static void destroy_mailbox(struct sip_mailbox *mailbox) { - if (mailbox->mailbox) - ast_free(mailbox->mailbox); - if (mailbox->context) - ast_free(mailbox->context); if (mailbox->event_sub) ast_event_unsubscribe(mailbox->event_sub); ast_free(mailbox); @@ -24933,17 +24929,35 @@ static void add_peer_mailboxes(struct sip_peer *peer, const char *value) while ((mbox = context = strsep(&next, ","))) { struct sip_mailbox *mailbox; - - if (!(mailbox = ast_calloc(1, sizeof(*mailbox)))) - continue; + int duplicate = 0; strsep(&context, "@"); + if (ast_strlen_zero(mbox)) { - ast_free(mailbox); continue; } - mailbox->mailbox = ast_strdup(mbox); - mailbox->context = ast_strdup(context); + + /* Check whether the mailbox is already in the list */ + AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { + if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) { + duplicate = 1; + mailbox->delme = 0; + break; + } + } + if (duplicate) { + continue; + } + + if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) { + continue; + } + + if (!ast_strlen_zero(context)) { + mailbox->context = mailbox->mailbox + strlen(mbox) + 1; + strcpy(mailbox->context, context); /* SAFE */ + } + strcpy(mailbox->mailbox, mbox); /* SAFE */ AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); } @@ -25035,6 +25049,13 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str peer->default_outbound_transport = 0; peer->transports = 0; + if (!devstate_only) { + struct sip_mailbox *mailbox; + AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { + mailbox->delme = 1; + } + } + for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { if (!devstate_only) { if (handle_common_options(&peerflags[0], &mask[0], v)) { @@ -25413,6 +25434,17 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str } } + if (!devstate_only) { + struct sip_mailbox *mailbox; + AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) { + if (mailbox->delme) { + AST_LIST_REMOVE_CURRENT(entry); + ast_free(mailbox); + } + } + AST_LIST_TRAVERSE_SAFE_END; + } + if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) { ast_log(LOG_WARNING, "Peer %s has a cc_agent_policy of 'native' but required libxml2 dependency is not installed. Changing policy to 'never'\n", peer->name); ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER); diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h index 0ee377c325..9017d7e6be 100644 --- a/channels/sip/include/sip.h +++ b/channels/sip/include/sip.h @@ -1112,11 +1112,12 @@ struct sip_pkt { * too much effort ... */ struct sip_mailbox { - char *mailbox; - char *context; /*! Associated MWI subscription */ struct ast_event_sub *event_sub; AST_LIST_ENTRY(sip_mailbox) entry; + unsigned int delme:1; + char *context; + char mailbox[2]; }; /*! \brief Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host)