<p>Christian Savinovich has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/11627">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mwi_subscribe_replaces_unsolicited:<br><br>Fixes an bug whereby multiple NOTIFYs were replied back to endpoint when a<br>REGISTER was received. This occurred when parameter<br>mwi_subscribe_replaces_unsolicited is set to yes in pjsip.conf.<br>The underlying problem here is that the<br>endpoint_receives_unsolicited_mwi_for_mailbox() function in res/res_pjsip_mwi.c<br>is sort of an overloaded function. When invoked from mwi_validate_for_aor() you<br>DO want to have the subscribe_replaces_unsolicited() logic occur whereby it<br>unsubscribes from stasis. When invoked from<br>create_mwi_subscriptions_for_endpoint you DO NOT want to have the<br>subscribe_replaces_unsolicited logic occur.The function should have a parameter<br>added to it which determines whether the logic is invoked or not.<br>The bug itself occurs because there are multiple mwi_subscription structures<br>for the mailbox, the logic which sends the NOTIFY when a REGISTER occurs goes<br>through all looking for mwi_subscription structures with the AOR. It finds<br>these multiple structures, calculates message count on them (despite having<br>no stasis subscriptions), and sends a NOTIFY.<br>Note: This fix does not restore back unsolicted NOTIFYs in the event<br>all subscriptions on a given AOR go away. It was decided to create<br>a new issue for that.<br><br>Change-Id: I8f77c33b9b4d374d510aa5ecd4f700a77107d8d4<br>---<br>M res/res_pjsip_mwi.c<br>1 file changed, 31 insertions(+), 12 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/27/11627/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c</span><br><span>index abd7ac0..c5e7963 100644</span><br><span>--- a/res/res_pjsip_mwi.c</span><br><span>+++ b/res/res_pjsip_mwi.c</span><br><span>@@ -119,6 +119,10 @@</span><br><span> char *aors;</span><br><span> /*! Is the MWI solicited (i.e. Initiated with an external SUBSCRIBE) ? */</span><br><span> unsigned int is_solicited;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! identifies if user wants to mute unsolicited NOTIFYs if subscription</span><br><span style="color: hsl(120, 100%, 40%);">+ * exists.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int is_subscribe_replaces_unsolicited;</span><br><span> /*! Identifier for the subscription.</span><br><span> * The identifier is the same as the corresponding endpoint's stasis ID.</span><br><span> * Used as a hash key</span><br><span>@@ -498,7 +502,6 @@</span><br><span> .body_type = AST_SIP_MESSAGE_ACCUMULATOR,</span><br><span> .body_data = mwi_data->counter,</span><br><span> };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> if (ast_sip_create_request("NOTIFY", NULL, endpoint, NULL, contact, &tdata)) {</span><br><span> ast_log(LOG_WARNING, "Unable to create unsolicited NOTIFY request to endpoint %s URI %s\n", sub->id, contact->uri);</span><br><span> return 0;</span><br><span>@@ -677,7 +680,15 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (sub->is_subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_endpoint *endpoint = ast_sip_subscription_get_endpoint(sub->sip_sub);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> send_unsolicited_mwi_notify(sub, &counter);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static int unsubscribe_stasis(void *obj, void *arg, int flags)</span><br><span>@@ -710,7 +721,6 @@</span><br><span> static void mwi_ds_destroy(void *data)</span><br><span> {</span><br><span> struct mwi_subscription *sub = data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> ao2_ref(sub, -1);</span><br><span> }</span><br><span> </span><br><span>@@ -744,11 +754,12 @@</span><br><span> *</span><br><span> * \param endpoint The endpoint to check</span><br><span> * \param mailbox The candidate mailbox</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param invokedByValidate 1 or 0 if called from mwi_validate_for_aor</span><br><span> * \retval 0 The endpoint does not receive unsolicited MWI for this mailbox</span><br><span> * \retval 1 The endpoint receives unsolicited MWI for this mailbox</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">-static int endpoint_receives_unsolicited_mwi_for_mailbox(struct ast_sip_endpoint *endpoint,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *mailbox)</span><br><span style="color: hsl(120, 100%, 40%);">+static int endpoint_receives_unsolicited_mwi_for_mailbox(struct ast_sip_endpoint *endpoint, </span><br><span style="color: hsl(120, 100%, 40%);">+ const char *mailbox, int invokedByValidate)</span><br><span> {</span><br><span> struct ao2_iterator *mwi_subs;</span><br><span> struct mwi_subscription *mwi_sub;</span><br><span>@@ -765,13 +776,19 @@</span><br><span> </span><br><span> mwi_stasis = ao2_find(mwi_sub->stasis_subs, mailbox, OBJ_SEARCH_KEY);</span><br><span> if (mwi_stasis) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(0, 100%, 40%);">- unsubscribe_stasis(mwi_stasis, NULL, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_unlink(mwi_sub->stasis_subs, mwi_stasis);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (invokedByValidate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(120, 100%, 40%);">+ mwi_sub->is_subscribe_replaces_unsolicited = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsubscribe_stasis(mwi_stasis, NULL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_unlink(mwi_sub->stasis_subs, mwi_stasis);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_cleanup(mwi_stasis);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span> ret = 1;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(mwi_stasis);</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>@@ -808,7 +825,8 @@</span><br><span> continue;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* parameter 3 = 1 means "invoked-from-function-mwi-validate-for-aor" */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox, 1)) {</span><br><span> ast_debug(1, "Endpoint '%s' already configured for unsolicited MWI for mailbox '%s'. "</span><br><span> "Denying MWI subscription to %s\n", ast_sorcery_object_get_id(endpoint), mailbox,</span><br><span> ast_sorcery_object_get_id(aor));</span><br><span>@@ -1021,7 +1039,7 @@</span><br><span> }</span><br><span> </span><br><span> static void mwi_to_ami(struct ast_sip_subscription *sub,</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_str **buf)</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str **buf)</span><br><span> {</span><br><span> struct mwi_subscription *mwi_sub;</span><br><span> struct ast_datastore *mwi_datastore;</span><br><span>@@ -1127,8 +1145,9 @@</span><br><span> struct mwi_stasis_subscription *mwi_stasis_sub;</span><br><span> </span><br><span> /* check if subscription exists */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* parameter 3 = 0 means "not-invoked-from-function-mwi-validate-for-aor" */</span><br><span> if (ast_strlen_zero(mailbox) ||</span><br><span style="color: hsl(0, 100%, 40%);">- (!aggregate_sub && endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ (!aggregate_sub && endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox, 0))) {</span><br><span> continue;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/11627">change 11627</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/11627"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I8f77c33b9b4d374d510aa5ecd4f700a77107d8d4 </div>
<div style="display:none"> Gerrit-Change-Number: 11627 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Christian Savinovich <csavinovich@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>