Module: sip-router Branch: admorten/sca Commit: 55dd3bb2f1f4c5675686d49012fcbe08f086d489 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=55dd3bb2...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Thu Jun 13 15:34:00 2013 -0400
modules/sca: clear appearance on receipt of out-of-dialog SUBSCRIBE
- If a call-info SUBSCRIBE with no To-tag arrives from a subscriber with an active subscription, release any appearances owned by the subscriber, on the assumption that the subscriber has lost track of SCA (reboot, power/network loss).
---
modules/sca/sca_appearance.c | 54 ++++++++++++++++++++++++++++++++++++++++++ modules/sca/sca_appearance.h | 1 + modules/sca/sca_subscribe.c | 22 ++++++++++++++++- 3 files changed, 76 insertions(+), 1 deletions(-)
diff --git a/modules/sca/sca_appearance.c b/modules/sca/sca_appearance.c index 7904abb..22d8413 100644 --- a/modules/sca/sca_appearance.c +++ b/modules/sca/sca_appearance.c @@ -1087,6 +1087,60 @@ done: return( rc ); }
+ int +sca_appearance_owner_release_all( str *aor, str *owner ) +{ + sca_appearance_list *app_list = NULL; + sca_appearance *app, **cur_app, **tmp_app; + sca_hash_slot *slot; + sca_hash_entry *ent; + int slot_idx = -1; + int released = -1; + + slot_idx = sca_uri_lock_shared_appearance( sca, aor ); + slot = sca_hash_table_slot_for_index( sca->appearances, slot_idx ); + + for ( ent = slot->entries; ent != NULL; ent = ent->next ) { + if ( ent->compare( aor, ent->value ) == 0 ) { + app_list = (sca_appearance_list *)ent->value; + break; + } + } + + released = 0; + + if ( app_list == NULL ) { + LM_DBG( "sca_appearance_owner_release_all: No appearances for %.*s", + STR_FMT( aor )); + goto done; + } + + for ( cur_app = &app_list->appearances; *cur_app != NULL; + cur_app = tmp_app ) { + tmp_app = &(*cur_app)->next; + + if ( !SCA_STR_EQ( owner, &(*cur_app)->owner )) { + continue; + } + + app = *cur_app; + *cur_app = (*cur_app)->next; + tmp_app = cur_app; + + if ( app ) { + sca_appearance_free( app ); + released++; + } + } + +done: + if ( slot_idx >= 0 ) { + sca_hash_table_unlock_index( sca->appearances, slot_idx ); + } + + return( released ); +} + sca_appearance * sca_appearance_for_index_unsafe( sca_mod *scam, str *aor, int app_idx, int slot_idx ) diff --git a/modules/sca/sca_appearance.h b/modules/sca/sca_appearance.h index a1feab7..74d6b39 100644 --- a/modules/sca/sca_appearance.h +++ b/modules/sca/sca_appearance.h @@ -140,6 +140,7 @@ int sca_appearance_update_unsafe( sca_appearance *, int, str *, str *, int sca_appearance_update_index( sca_mod *, str *, int, int, str *, str *, sca_dialog * ); int sca_appearance_release_index( sca_mod *, str *, int ); +int sca_appearance_owner_release_all( str *, str * ); int sca_appearance_state_for_index( sca_mod *, str *, int ); sca_appearance *sca_appearance_for_index_unsafe( sca_mod *, str *, int, int ); sca_appearance *sca_appearance_for_dialog_unsafe( sca_mod *, str *, diff --git a/modules/sca/sca_subscribe.c b/modules/sca/sca_subscribe.c index cf8feb7..1b8107e 100644 --- a/modules/sca/sca_subscribe.c +++ b/modules/sca/sca_subscribe.c @@ -1120,6 +1120,7 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 ) int app_idx = SCA_CALL_INFO_APPEARANCE_INDEX_ANY; int idx = -1; int rc = -1; + int released = 0;
if ( parse_headers( msg, HDR_EOH_F, 0 ) < 0 ) { LM_ERR( "header parsing failed: bad request" ); @@ -1227,6 +1228,22 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 ) } req_sub.index = app_idx; } + } else { + if ( SCA_STR_EMPTY( to_tag )) { + /* + * if the subscriber owns any active appearances, clear them. + * we assume that an out-of-dialog SUBSCRIBE for a subscriber + * with active appearances is indicative of a reboot. + */ + released = sca_appearance_owner_release_all( + &req_sub.target_aor, + &req_sub.subscriber ); + if ( released ) { + LM_INFO( "sca_handle_subscribe: released %d appearances " + "for subscriber %.*s", released, + STR_FMT( &req_sub.subscriber )); + } + } } } else { /* in-dialog request, but we didn't find it. */ @@ -1268,6 +1285,9 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 ) } }
+ sca_hash_table_unlock_index( sca->subscriptions, idx ); + idx = -1; + status = sca_ok_status_for_event( event_type ); status_text = sca_ok_text_for_event( event_type ); if ( sca_subscription_reply( sca, status, status_text, event_type, @@ -1287,7 +1307,7 @@ sca_handle_subscribe( sip_msg_t *msg, char *p1, char *p2 ) goto done; }
- if ( req_sub.event == SCA_EVENT_TYPE_LINE_SEIZE ) { + if ( req_sub.event == SCA_EVENT_TYPE_LINE_SEIZE || released ) { if ( sca_notify_call_info_subscribers( sca, &req_sub.target_aor) < 0 ) { LM_ERR( "SCA %s NOTIFY to all %.*s subscribers failed", sca_event_name_from_type( req_sub.event ),