Module: sip-router Branch: master Commit: f149fe0bf499c2ed9a4238cea5bdf2ecbb28c941 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f149fe0bf499c2ed9a4238cea5bdf2ecbb28c941
Author: Richard Good <[email protected]> Committer: Richard Good <[email protected]> Date: Fri May 2 12:15:05 2014 +0200 modules/ims_registrar_scscf: Fix to not send notifies to UEs that explicitly deregister --- modules/ims_registrar_scscf/registrar_notify.c | 100 +++++++++++++++++++----- modules/ims_registrar_scscf/registrar_notify.h | 3 + 2 files changed, 82 insertions(+), 21 deletions(-) diff --git a/modules/ims_registrar_scscf/registrar_notify.c b/modules/ims_registrar_scscf/registrar_notify.c index 3f04dbe..e5086a5 100644 --- a/modules/ims_registrar_scscf/registrar_notify.c +++ b/modules/ims_registrar_scscf/registrar_notify.c @@ -90,6 +90,8 @@ static str subss_hdr2 = {"\r\n", 2}; static str ctype_hdr1 = {"Content-Type: ", 14}; static str ctype_hdr2 = {"\r\n", 2}; +extern int ue_unsubscribe_on_dereg; + int notify_init() { notification_list = shm_malloc(sizeof (reg_notification_list)); if (!notification_list) return 0; @@ -468,7 +470,7 @@ int event_reg(udomain_t* _d, impurecord_t* r_passed, ucontact_t* c_passed, int e return 0; } - content = get_reginfo_partial(r_passed, c_passed, event_type); + content = get_reginfo_partial(r_passed, c_passed, event_type); create_notifications(_d, r_passed, c_passed, presentity_uri, watcher_contact, content, event_type); if (content.s) pkg_free(content.s); // if (send_now) notification_timer(0, 0); @@ -1202,6 +1204,52 @@ int subscribe_reply(struct sip_msg *msg, int code, char *text, int *expires, str } +/* function to convert contact aor to only have data after @ - ie strip user part */ +int aor_to_contact(str* aor, str* contact) { + char* p; + int ret = 0; //success + + contact->s = aor->s; + contact->len = aor->len; + if (memcmp(aor->s, "sip:", 4) == 0) { + contact->s = aor->s + 4; + contact->len-=4; + } + + if ((p=memchr(contact->s, '@', contact->len))) { + contact->len -= (p - contact->s + 1); + contact->s = p+1; + } + + if ((p=memchr(contact->s, ';', contact->len))) { + contact->len = p - contact->s; + } + + if ((p=memchr(contact->s, '>', contact->len))) { + contact->len = p - contact->s; + } + + return ret; +} + +/*! + * \brief Match a contact record to a contact string but only compare the ip port portion + * \param ptr contact record + * \param _c contact string + * \return ptr on successfull match, 0 when they not match + */ +int contact_port_ip_match(str *c1, str *c2) { + + str ip_port1, ip_port2; + aor_to_contact(c1, &ip_port1);//strip userpart from test contact + aor_to_contact(c2, &ip_port2);//strip userpart from test contact + LM_DBG("Matching contact using only port and ip - comparing [%.*s] and [%.*s]\n", ip_port1.len, ip_port1.s, ip_port2.len, ip_port2.s); + if ((ip_port1.len == ip_port2.len) && !memcmp(ip_port1.s, ip_port2.s, ip_port1.len)) { + return 1; + } + return 0; +} + static str subs_terminated = {"terminated", 10}; static str subs_active = {"active;expires=", 15}; @@ -1268,10 +1316,10 @@ void create_notifications(udomain_t* _t, impurecord_t* r_passed, ucontact_t* c_p LM_DBG("Subscription state: [%.*s]", subscription_state.len, subscription_state.s); } - //This is a fix to ensure that when a user subscribes a full reg info is only sent to that UE + //This is a fix to ensure that when a user subscribes a full reg info is only sent to that UE if (event_type == IMS_REGISTRAR_SUBSCRIBE) { - if ((watcher_contact->len == s->watcher_contact.len) && (strncasecmp(s->watcher_contact.s, watcher_contact->s, watcher_contact->len) == 0) && - (presentity_uri->len == s->presentity_uri.len) && (strncasecmp(s->presentity_uri.s, presentity_uri->s, presentity_uri->len) == 0)) { + if (contact_port_ip_match(watcher_contact, &s->watcher_contact) && + (presentity_uri->len == s->presentity_uri.len) && (memcmp(s->presentity_uri.s, presentity_uri->s, presentity_uri->len) == 0)) { LM_DBG("This is a fix to ensure that we only send full reg info XML to the UE that just subscribed"); LM_DBG("about to make new notification!"); n = new_notification(subscription_state, content_type, content, @@ -1291,23 +1339,33 @@ void create_notifications(udomain_t* _t, impurecord_t* r_passed, ucontact_t* c_p } } } else { - LM_DBG("about to make new notification!"); - n = new_notification(subscription_state, content_type, content, - s->version++, s); - if (n) { - //LM_DBG("Notification exists - about to add it"); - //add_notification(n); - - //Richard just gonna send it - not bother queueing etc. - //TODO look at impact of this - sending straight away vs queueing and getting another process to send - LM_DBG("About to send notification"); - send_notification(n); - LM_DBG("About to free notification"); - free_notification(n); - } else { - LM_DBG("Notification does not exist"); - } - } + + if(event_type == IMS_REGISTRAR_CONTACT_UNREGISTERED && !ue_unsubscribe_on_dereg && + (contact_port_ip_match(&c_passed->c, &s->watcher_contact) && + (r_passed->public_identity.len == s->presentity_uri.len) && (memcmp(s->presentity_uri.s, r_passed->public_identity.s, r_passed->public_identity.len) == 0))){ + //if this is UNREGISTER and the UEs do not unsubscribe to dereg and this is a UE subscribing to its own reg event + //then we do not send notifications + LM_DBG("This is a UNREGISTER event for a UE that subscribed to its own state that does not unsubscribe to dereg - therefore no notification"); + } + else{ + LM_DBG("about to make new notification!"); + n = new_notification(subscription_state, content_type, content, + s->version++, s); + if (n) { + //LM_DBG("Notification exists - about to add it"); + //add_notification(n); + + //Richard just gonna send it - not bother queueing etc. + //TODO look at impact of this - sending straight away vs queueing and getting another process to send + LM_DBG("About to send notification"); + send_notification(n); + LM_DBG("About to free notification"); + free_notification(n); + } else { + LM_DBG("Notification does not exist"); + } + } + } //} s = s->next; diff --git a/modules/ims_registrar_scscf/registrar_notify.h b/modules/ims_registrar_scscf/registrar_notify.h index cbac7d3..8886316 100644 --- a/modules/ims_registrar_scscf/registrar_notify.h +++ b/modules/ims_registrar_scscf/registrar_notify.h @@ -144,4 +144,7 @@ dlg_t* build_dlg_t_from_notification(reg_notification* n); int notify_init(); void notify_destroy(); +int aor_to_contact(str* aor, str* contact); +int contact_port_ip_match(str *c1, str *c2); + #endif //S_CSCF_REGISTRAR_NOTIFY_H_ _______________________________________________ sr-dev mailing list [email protected] http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
