Module: sems
Branch: master
Commit: 018cb90a975735566f92cb49b5b5a8ef2cde3115
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=018cb90a975735566f92cb49b5b5a8ef2cde3115

Author: Stefan Sayer <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Fri Jul 22 17:39:18 2011 +0200

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 b38258c..359ea3a 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 <now> (%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 <now> (%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 7fa42da..ef02623 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 ced6a31..9371e27 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;

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to