From 526678f013bbbefab459da9bfb77f0783a0983d7 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Fri, 22 Jul 2011 17:39:18 +0200 Subject: [PATCH] b/f: fix registration refresh if calculated in the past for restarts with expired registrations and with minimum_register_interval set, this could lead to lost registrations --- apps/db_reg_agent/DBRegAgent.cpp | 49 ++++++++++++++++++++----- apps/db_reg_agent/DBRegAgent.h | 4 +- apps/db_reg_agent/RegistrationTimer.cpp | 34 ++++++++--------- 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/apps/db_reg_agent/DBRegAgent.cpp b/apps/db_reg_agent/DBRegAgent.cpp index b38258cc..359ea3a0 100644 --- a/apps/db_reg_agent/DBRegAgent.cpp +++ b/apps/db_reg_agent/DBRegAgent.cpp @@ -322,7 +322,7 @@ bool DBRegAgent::loadRegistrations() { DBG("scheduling imminent re-registration for subscriber %ld\n", subscriber_id); scheduleRegistration(subscriber_id); } else { - setRegistrationTimer(subscriber_id, dt_expiry, dt_registration_ts); + setRegistrationTimer(subscriber_id, dt_expiry, dt_registration_ts, now_time); } }; break; @@ -779,7 +779,9 @@ void DBRegAgent::onSipReplyEvent(AmSipReplyEvent* ev) { } else if (ev->reply.code >= 200) { // positive reply if (!registration->getUnregistering()) { - setRegistrationTimer(subscriber_id, registration->getExpiresTS(), time(0)); + time_t now_time = time(0); + setRegistrationTimer(subscriber_id, registration->getExpiresTS(), + now_time, now_time); update_status = true; status = REG_STATUS_ACTIVE; @@ -892,7 +894,8 @@ void DBRegAgent::setRegistrationTimer(long subscriber_id, unsigned int timeout, } void DBRegAgent::setRegistrationTimer(long subscriber_id, - time_t expiry, time_t reg_start_ts) { + time_t expiry, time_t reg_start_ts, + time_t now_time) { DBG("setting re-Register timer for subscription %ld, expiry %ld, reg_start_t %ld\n", subscriber_id, expiry, reg_start_ts); @@ -920,19 +923,45 @@ void DBRegAgent::setRegistrationTimer(long subscriber_id, t_expiry_max+=(expiry - reg_start_ts) * reregister_interval; if (expiry > reg_start_ts) t_expiry_min+=(expiry - reg_start_ts) * minimum_reregister_interval; + + if (t_expiry_max < now_time) { + // calculated interval completely in the past - immediate re-registration + // by setting the timer to now + t_expiry_max = now_time; + } + + if (t_expiry_min > t_expiry_max) + t_expiry_min = t_expiry_max; + timer->expires = t_expiry_max; - DBG("calculated re-registration at TS %ld .. %ld" - "(reg_start_ts=%ld, reg_expiry=%ld, reregister_interval=%f, " - "minimum_reregister_interval=%f)\n", - t_expiry_min, t_expiry_max, reg_start_ts, expiry, - reregister_interval, minimum_reregister_interval); + + if (t_expiry_max == now_time) { + // immediate re-registration + DBG("calculated re-registration at TS (%ld)" + "(reg_start_ts=%ld, reg_expiry=%ld, reregister_interval=%f, " + "minimum_reregister_interval=%f)\n", + t_expiry_max, reg_start_ts, expiry, + reregister_interval, minimum_reregister_interval); + registration_scheduler.insert_timer(timer); + } else { + DBG("calculated re-registration at TS %ld .. %ld" + "(reg_start_ts=%ld, reg_expiry=%ld, reregister_interval=%f, " + "minimum_reregister_interval=%f)\n", + t_expiry_min, t_expiry_max, reg_start_ts, expiry, + reregister_interval, minimum_reregister_interval); - registration_scheduler.insert_timer_leastloaded(timer, t_expiry_min, t_expiry_max); - + registration_scheduler.insert_timer_leastloaded(timer, t_expiry_min, t_expiry_max); + } } else { time_t t_expiry = reg_start_ts; if (expiry > reg_start_ts) t_expiry+=(expiry - reg_start_ts) * reregister_interval; + + if (t_expiry < now_time) { + t_expiry = now_time; + DBG("re-registering at TS (%ld)\n", now_time); + } + DBG("calculated re-registration at TS %ld " "(reg_start_ts=%ld, reg_expiry=%ld, reregister_interval=%f)\n", t_expiry, reg_start_ts, expiry, reregister_interval); diff --git a/apps/db_reg_agent/DBRegAgent.h b/apps/db_reg_agent/DBRegAgent.h index 7fa42da5..ef02623c 100644 --- a/apps/db_reg_agent/DBRegAgent.h +++ b/apps/db_reg_agent/DBRegAgent.h @@ -198,8 +198,10 @@ class DBRegAgent @param subscriber_id - ID of subscription @param expiry - SIP registration expiry time @param reg_start_ts - start TS of the SIP registration + @param now_time - current time */ - void setRegistrationTimer(long subscriber_id, time_t expiry, time_t reg_start_ts); + void setRegistrationTimer(long subscriber_id, + time_t expiry, time_t reg_start_ts, time_t now_time); /** clear re-registration timer and remove timer object */ void clearRegistrationTimer(long subscriber_id); diff --git a/apps/db_reg_agent/RegistrationTimer.cpp b/apps/db_reg_agent/RegistrationTimer.cpp index ced6a31c..9371e272 100644 --- a/apps/db_reg_agent/RegistrationTimer.cpp +++ b/apps/db_reg_agent/RegistrationTimer.cpp @@ -239,25 +239,25 @@ bool RegistrationTimer::insert_timer_leastloaded(RegTimer* timer, int res_index = from_index; if (from_index < 0) { - // use to_index (should not occur) - res_index = to_index; - } else { - // find least loaded bucket - size_t least_load = buckets[from_index].timers.size(); - - int i = from_index; - while (i != to_index) { - if (buckets[i].timers.size() <= least_load) { - least_load = buckets[i].timers.size(); - res_index = i; - } - - i++; - i %= TIMER_BUCKETS; + // use now .. to_index + DBG("from_time (%ld) in the past - searching load loaded from now()\n", from_time); + from_index = current_bucket; + } + // find least loaded bucket + size_t least_load = buckets[from_index].timers.size(); + + int i = from_index; + while (i != to_index) { + if (buckets[i].timers.size() <= least_load) { + least_load = buckets[i].timers.size(); + res_index = i; } - DBG("found bucket %i with least load %zd (between %i and %i)\n", - res_index, least_load, from_index, to_index); + + i++; + i %= TIMER_BUCKETS; } + DBG("found bucket %i with least load %zd (between %i and %i)\n", + res_index, least_load, from_index, to_index); // update expires to some random value inside the selected bucket int diff = (unsigned)res_index - current_bucket;