diff options
author | Kevin Harwell <kharwell@digium.com> | 2014-01-31 22:08:46 +0000 |
---|---|---|
committer | Kevin Harwell <kharwell@digium.com> | 2014-01-31 22:08:46 +0000 |
commit | 6b114b654eb498bce14f91ce9240ae48d5c33ff6 (patch) | |
tree | 9d13945137811bfd41ec07605d390adbc77524cd /res/res_pjsip_mwi.c | |
parent | d5431ed358d8e661bdb0ca7608636059f8679af8 (diff) |
res_pjsip_mwi: Subscribe fails when missing aor name
When subscribing to MWI (res_pjsip_mwi) and the sip uri did not contain a name
(ex: sip:<ip address>) then the subscription would fail since it would be unable
to locate an associated aor. This patch makes it so that when a subscribe comes
with no aor name then it will subscribe to all aors on the located endpoint.
(closes issue ASTERISK-23072)
Reported by: Bob M
Review: https://reviewboard.asterisk.org/r/3164/
........
Merged revisions 407014 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@407015 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_mwi.c')
-rw-r--r-- | res/res_pjsip_mwi.c | 114 |
1 files changed, 85 insertions, 29 deletions
diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c index 42aa34f1e..bb12aa5e9 100644 --- a/res/res_pjsip_mwi.c +++ b/res/res_pjsip_mwi.c @@ -453,57 +453,113 @@ static int add_mwi_datastore(struct mwi_subscription *sub) return 0; } -static struct ast_sip_subscription *mwi_new_subscribe(struct ast_sip_endpoint *endpoint, - pjsip_rx_data *rdata) +static int mwi_on_aor(void *obj, void *arg, int flags) { - RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup); - /* It's not obvious here, but the reference(s) to this subscription, - * once this function exits, is held by the stasis subscription(s) - * created in mwi_stasis_subscription_alloc() - */ - RAII_VAR(struct mwi_subscription *, sub, NULL, ao2_cleanup); - pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri; - pjsip_sip_uri *sip_ruri; - pjsip_evsub *evsub; - char aor_name[80]; + struct ast_sip_aor *aor = obj; + struct mwi_subscription *sub = arg; char *mailboxes; char *mailbox; - if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) { - ast_log(LOG_WARNING, "Attempt to SUBSCRIBE to a non-SIP URI\n"); + if (ast_strlen_zero(aor->mailboxes)) { + return 0; + } + + mailboxes = ast_strdupa(aor->mailboxes); + while ((mailbox = strsep(&mailboxes, ","))) { + RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub, + mwi_stasis_subscription_alloc(mailbox, sub), ao2_cleanup); + if (mwi_stasis_sub) { + ao2_link(sub->stasis_subs, mwi_stasis_sub); + } + } + + return 0; +} + +static struct mwi_subscription *mwi_create_subscription( + struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata) +{ + struct mwi_subscription *sub = mwi_subscription_alloc( + endpoint, AST_SIP_NOTIFIER, 1, rdata); + + if (!sub) { return NULL; } - sip_ruri = pjsip_uri_get_uri(ruri); - ast_copy_pj_str(aor_name, &sip_ruri->user, sizeof(aor_name)); - aor = ast_sip_location_retrieve_aor(aor_name); + if (add_mwi_datastore(sub)) { + ast_log(LOG_WARNING, "Unable to allocate datastore on MWI " + "subscription from %s\n", sub->id); + ao2_ref(sub, -1); + return NULL; + } + + return sub; +} + +static struct mwi_subscription *mwi_subscribe_single( + struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *name) +{ + RAII_VAR(struct ast_sip_aor *, aor, + ast_sip_location_retrieve_aor(name), ao2_cleanup); + struct mwi_subscription *sub; + if (!aor) { - ast_log(LOG_WARNING, "Unable to locate aor %s. MWI subscription failed.\n", aor_name); + ast_log(LOG_WARNING, "Unable to locate aor %s. MWI " + "subscription failed.\n", name); return NULL; } if (ast_strlen_zero(aor->mailboxes)) { - ast_log(LOG_WARNING, "AOR %s has no configured mailboxes. MWI subscription failed\n", aor_name); + ast_log(LOG_WARNING, "AOR %s has no configured mailboxes. " + "MWI subscription failed\n", name); + return NULL; + } + + if (!(sub = mwi_create_subscription(endpoint, rdata))) { return NULL; } - sub = mwi_subscription_alloc(endpoint, AST_SIP_NOTIFIER, 1, rdata); + mwi_on_aor(aor, sub, 0); + return sub; +} + +static struct mwi_subscription *mwi_subscribe_all( + struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata) +{ + struct mwi_subscription *sub = mwi_create_subscription(endpoint, rdata); + if (!sub) { return NULL; } - if (add_mwi_datastore(sub)) { - ast_log(LOG_WARNING, "Unable to allocate datastore on MWI subscription from %s\n", sub->id); + ast_sip_for_each_aor(endpoint->aors, mwi_on_aor, sub); + return sub; +} + +static struct ast_sip_subscription *mwi_new_subscribe(struct ast_sip_endpoint *endpoint, + pjsip_rx_data *rdata) +{ + /* It's not obvious here, but the reference(s) to this subscription, + * once this function exits, is held by the stasis subscription(s) + * created in mwi_stasis_subscription_alloc() + */ + RAII_VAR(struct mwi_subscription *, sub, NULL, ao2_cleanup); + pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri; + pjsip_sip_uri *sip_ruri; + pjsip_evsub *evsub; + char aor_name[80]; + + if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) { + ast_log(LOG_WARNING, "Attempt to SUBSCRIBE to a non-SIP URI\n"); return NULL; } + sip_ruri = pjsip_uri_get_uri(ruri); + ast_copy_pj_str(aor_name, &sip_ruri->user, sizeof(aor_name)); - mailboxes = ast_strdupa(aor->mailboxes); - while ((mailbox = strsep(&mailboxes, ","))) { - RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub, - mwi_stasis_subscription_alloc(mailbox, sub), ao2_cleanup); - if (mwi_stasis_sub) { - ao2_link(sub->stasis_subs, mwi_stasis_sub); - } + /* no aor in uri? subscribe to all on endpoint */ + if (!(sub = ast_strlen_zero(aor_name) ? mwi_subscribe_all(endpoint, rdata) : + mwi_subscribe_single(endpoint, rdata, aor_name))) { + return NULL; } evsub = ast_sip_subscription_get_evsub(sub->sip_sub); |