aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c52
-rw-r--r--channels/sip/include/sip.h5
2 files changed, 45 insertions, 12 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index d7b6c180b..d65471da1 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 0ee377c32..9017d7e6b 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)