Module: sems Branch: master Commit: d386f9dc649e91b4cdc36b51257e3b4509b09b1e URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=d386f9dc649e91b4cdc36b51257e3b4509b09b1e
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Wed Mar 6 14:14:58 2013 +0100 sbc: reg-cache: added UA-side expiry detection (w/ timers) --- apps/sbc/RegisterCache.cpp | 56 +++++++++++++++++++++++++++++++++++++++--- apps/sbc/RegisterCache.h | 10 +++++++ apps/sbc/RegisterDialog.cpp | 2 + 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/apps/sbc/RegisterCache.cpp b/apps/sbc/RegisterCache.cpp index ab4f8f8..c09e2ef 100644 --- a/apps/sbc/RegisterCache.cpp +++ b/apps/sbc/RegisterCache.cpp @@ -112,6 +112,10 @@ void AliasBucket::dump_elmt(const string& alias, const AliasEntry* p_ae) const p_ae ? p_ae->contact_uri.c_str() : "NULL"); } +void AliasEntry::fire() +{ + DBG("Alias expired (UA): '%s' -> '%s'\n",alias.c_str(),aor.c_str()); +} struct RegCacheLogHandler : RegCacheStorageHandler @@ -168,6 +172,10 @@ void _RegisterCache::gbc(unsigned int bucket_id) it != alias_list.end(); it++){ AliasBucket* alias_bucket = getAliasBucket(*it); alias_bucket->lock(); + AliasEntry* alias_e = alias_bucket->getContact(*it); + if(alias_e && alias_e->ua_expire) { + removeAliasUATimer(alias_e); + } alias_bucket->remove(*it); alias_bucket->unlock(); } @@ -269,6 +277,20 @@ AliasBucket* _RegisterCache::getAliasBucket(const string& alias) return id_idx.get_bucket(hash_1str(alias)); } +void _RegisterCache::setAliasUATimer(AliasEntry* alias_e) +{ + AmAppTimer* app_timer = AmAppTimer::instance(); + double timeout = alias_e->ua_expire - app_timer->unix_clock.get(); + if(timeout > 0.0) { + app_timer->setTimer(alias_e,timeout); + } +} + +void _RegisterCache::removeAliasUATimer(AliasEntry* alias_e) +{ + AmAppTimer::instance()->removeTimer(alias_e); +} + void _RegisterCache::update(const string& canon_aor, const string& alias, long int reg_expires, const AliasEntry& alias_update) { @@ -319,14 +341,19 @@ void _RegisterCache::update(const string& canon_aor, const string& alias, if(!alias_e) { DBG("inserting alias map entry: '%s' -> '%s'", alias.c_str(), uri.c_str()); - alias_bucket->insert(alias,new AliasEntry(alias_update)); + alias_e = new AliasEntry(alias_update); + alias_bucket->insert(alias,alias_e); } else { *alias_e = alias_update; } + + if(alias_e->ua_expire) { + setAliasUATimer(alias_e); + } if(storage_handler.get()) - storage_handler->onUpdate(canon_aor,alias,reg_expires,alias_update); + storage_handler->onUpdate(canon_aor,alias,reg_expires,*alias_e); alias_bucket->unlock(); bucket->unlock(); @@ -378,15 +405,22 @@ void _RegisterCache::update(const string& canon_aor, long int reg_expires, if(!alias_e) { DBG("inserting alias map entry: '%s' -> '%s'", binding->alias.c_str(), uri.c_str()); - alias_bucket->insert(binding->alias,new AliasEntry(alias_update)); + alias_e = new AliasEntry(alias_update); + alias_e->alias = binding->alias; + alias_bucket->insert(binding->alias,alias_e); } else { *alias_e = alias_update; + alias_e->alias = binding->alias; + } + + if(alias_e->ua_expire) { + setAliasUATimer(alias_e); } if(storage_handler.get()) storage_handler->onUpdate(canon_aor,binding->alias, - reg_expires,alias_update); + reg_expires,*alias_e); alias_bucket->unlock(); bucket->unlock(); @@ -401,6 +435,9 @@ bool _RegisterCache::updateAliasExpires(const string& alias, long int ua_expires AliasEntry* alias_e = alias_bucket->getContact(alias); if(alias_e) { alias_e->ua_expire = ua_expires; + if(alias_e->ua_expire) { + setAliasUATimer(alias_e); + } if(storage_handler.get()) { storage_handler->onUpdate(alias,ua_expires); } @@ -442,6 +479,10 @@ void _RegisterCache::remove(const string& canon_aor, const string& uri, } } + AliasEntry* alias_e = alias_bucket->getContact(alias); + if(alias_e && alias_e->ua_expire) { + removeAliasUATimer(alias_e); + } alias_bucket->remove(alias); alias_bucket->unlock(); @@ -470,6 +511,12 @@ void _RegisterCache::remove(const string& aor) AliasBucket* alias_bucket = getAliasBucket(binding->alias); alias_bucket->lock(); + + AliasEntry* alias_e = alias_bucket->getContact(binding->alias); + if(alias_e && alias_e->ua_expire) { + removeAliasUATimer(alias_e); + } + alias_bucket->remove(binding->alias); alias_bucket->unlock(); @@ -821,6 +868,7 @@ bool _RegisterCache::saveSingleContact(RegisterCacheCtx& ctx, // - send 200 reply AliasEntry alias_update; + alias_update.aor = ctx.from_aor; alias_update.contact_uri = contact->uri_str(); alias_update.source_ip = req.remote_ip; alias_update.source_port = req.remote_port; diff --git a/apps/sbc/RegisterCache.h b/apps/sbc/RegisterCache.h index 1417bad..9e0ed69 100644 --- a/apps/sbc/RegisterCache.h +++ b/apps/sbc/RegisterCache.h @@ -6,6 +6,7 @@ #include "AmSipMsg.h" #include "AmUriParser.h" +#include "AmAppTimer.h" #include <string> #include <map> @@ -46,8 +47,11 @@ struct RegBinding typedef map<string,RegBinding*> AorEntry; struct AliasEntry + : public DirectAppTimer { + string aor; string contact_uri; + string alias; // saved state for NAT handling string source_ip; @@ -64,6 +68,9 @@ struct AliasEntry AliasEntry() : source_port(0), local_if(0), ua_expire(0) {} + + // from DirectAppTimer + void fire(); }; struct RegCacheStorageHandler @@ -187,6 +194,9 @@ protected: int parseContacts(RegisterCacheCtx& ctx, const AmSipRequest& req); int parseExpires(RegisterCacheCtx& ctx, const AmSipRequest& req); + void setAliasUATimer(AliasEntry* alias_e); + void removeAliasUATimer(AliasEntry* alias_e); + public: static string canonicalize_aor(const string& aor); diff --git a/apps/sbc/RegisterDialog.cpp b/apps/sbc/RegisterDialog.cpp index d328a19..5328064 100644 --- a/apps/sbc/RegisterDialog.cpp +++ b/apps/sbc/RegisterDialog.cpp @@ -468,7 +468,9 @@ void RegisterDialog::onSipReply(const AmSipRequest& req, // with new 'expire' value and new entries AliasEntry alias_entry; + alias_entry.aor = aor; alias_entry.contact_uri = orig_contact.uri_str(); + alias_entry.alias = alias_it->first; alias_entry.source_ip = source_ip; alias_entry.source_port = source_port; alias_entry.local_if = local_if; _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
