2
0
Эх сурвалжийг харах

modules/cdp: fix lifetime and session timeout logic

jaybeepee 10 жил өмнө
parent
commit
00e8c10a5f

+ 77 - 5
modules/cdp/authstatemachine.c

@@ -88,15 +88,36 @@ error:
 void update_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
     AAA_AVP *avp;
     uint32_t session_timeout = 0, grace_period = 0, auth_lifetime = 0;
+    int update_grace = 0, update_timeout = 0, update_lifetime = 0;
 
     avp = AAAFindMatchingAVP(msg, 0, AVP_Auth_Grace_Period, 0, 0);
     if (avp && avp->data.len == 4) {
         grace_period = get_4bytes(avp->data.s);
-        x->grace_period = grace_period;
+        update_grace = 1;
+    } else {
+        if (!avp) {
+            grace_period = x->last_requested_grace;
+        }
     }
+    if (update_grace)
+        x->grace_period = grace_period;
+
+
     avp = AAAFindMatchingAVP(msg, 0, AVP_Authorization_Lifetime, 0, 0);
     if (avp && avp->data.len == 4) {
         auth_lifetime = get_4bytes(avp->data.s);
+        update_lifetime = 1;
+        
+    } else {
+        if (!avp) {
+            LM_DBG("using timers from our request as there is nothing in the response (lifetime) - last requested lifetime was [%d]\n", x->last_requested_lifetime);
+            if (x->last_requested_lifetime > 0) {
+                update_lifetime = 1;
+                auth_lifetime = x->last_requested_lifetime;
+            }
+        }
+    }
+    if (update_lifetime) {
         switch (auth_lifetime) {
             case 0:
                 x->lifetime = time(0);
@@ -107,8 +128,12 @@ void update_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
             default:
                 x->lifetime = time(0) + auth_lifetime;
         }
-        if (x->timeout != -1 && x->timeout <= x->lifetime) x->timeout = x->lifetime + x->grace_period;
+        if (x->timeout != -1 && x->timeout < x->lifetime) {
+            update_timeout = 1;
+            x->timeout = x->lifetime + x->grace_period;
+        }
     }
+    
     avp = AAAFindMatchingAVP(msg, 0, AVP_Session_Timeout, 0, 0);
     if (avp && avp->data.len == 4) {
         session_timeout = get_4bytes(avp->data.s);
@@ -135,6 +160,7 @@ void add_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
     AAA_AVP *avp;
     char data[4];
     uint32_t v;
+    uint32_t lifetime, timeout, grace;
 
     avp = AAAFindMatchingAVP(msg, 0, AVP_Authorization_Lifetime, 0, 0);
     if (!avp) {
@@ -143,9 +169,24 @@ void add_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
             v = x->lifetime - time(0);
             if (v < 0) v = 0;
         }
+        x->last_requested_lifetime = v;
         set_4bytes(data, v);
         avp = AAACreateAVP(AVP_Authorization_Lifetime, AAA_AVP_FLAG_MANDATORY, 0, data, 4, AVP_DUPLICATE_DATA);
         if (avp) AAAAddAVPToMessage(msg, avp, msg->avpList.tail);
+    } else {
+        if (avp->data.len == 4) {
+            lifetime = get_4bytes(avp->data.s);
+            switch (lifetime) {
+                case 0:
+                    x->last_requested_lifetime = 0;
+                    break;
+                case 0xFFFFFFFF:
+                    x->last_requested_lifetime = -1;
+                    break;
+                default:
+                    x->last_requested_lifetime = lifetime;
+            }
+        }
     }
     if (x->lifetime != -1) {
         avp = AAAFindMatchingAVP(msg, 0, AVP_Auth_Grace_Period, 0, 0);
@@ -154,6 +195,21 @@ void add_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
             set_4bytes(data, v);
             avp = AAACreateAVP(AVP_Auth_Grace_Period, AAA_AVP_FLAG_MANDATORY, 0, data, 4, AVP_DUPLICATE_DATA);
             if (avp) AAAAddAVPToMessage(msg, avp, msg->avpList.tail);
+            x->last_requested_grace = v;
+        } else {
+            if (avp->data.len == 4) {
+                grace = get_4bytes(avp->data.s);
+                switch (grace) {
+                    case 0:
+                        x->last_requested_grace = 0;
+                        break;
+                    case 0xFFFFFFFF:
+                        x->last_requested_grace = -1;
+                        break;
+                    default:
+                        x->last_requested_grace = grace;
+                }
+            }
         }
     }
     avp = AAAFindMatchingAVP(msg, 0, AVP_Session_Timeout, 0, 0);
@@ -166,7 +222,23 @@ void add_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
         set_4bytes(data, v);
         avp = AAACreateAVP(AVP_Session_Timeout, AAA_AVP_FLAG_MANDATORY, 0, data, 4, AVP_DUPLICATE_DATA);
         if (avp) AAAAddAVPToMessage(msg, avp, msg->avpList.tail);
+        x->last_requested_timeout = v;
+    } else {
+        if (avp->data.len == 4) {
+            timeout = get_4bytes(avp->data.s);
+            switch (timeout) {
+                case 0:
+                    x->last_requested_timeout = 0;
+                    break;
+                case 0xFFFFFFFF:
+                    x->last_requested_timeout = -1;
+                    break;
+                default:
+                    x->last_requested_timeout = lifetime;
+            }
+        }
     }
+
 }
 
 /**
@@ -243,12 +315,12 @@ inline int auth_client_statefull_sm_process(cdp_session_t* s, int event, AAAMess
                     //LM_INFO("state machine: i was in pending and i am going to open\n");
                     break;
                 case AUTH_EV_RECV_ANS_UNSUCCESS:
-		    LM_DBG("In state AUTH_ST_PENDING and received AUTH_EV_RECV_ANS_UNSUCCESS - nothing to do but clean up session\n");
+                    LM_DBG("In state AUTH_ST_PENDING and received AUTH_EV_RECV_ANS_UNSUCCESS - nothing to do but clean up session\n");
                 case AUTH_EV_SESSION_TIMEOUT:
                 case AUTH_EV_SERVICE_TERMINATED:
                 case AUTH_EV_SESSION_GRACE_TIMEOUT:
                     cdp_session_cleanup(s, NULL);
-		    s=0;
+                    s = 0;
                     break;
 
                 default:
@@ -411,7 +483,7 @@ inline void auth_server_statefull_sm_process(cdp_session_t* s, int event, AAAMes
                     /* Just in case we have some lost sessions */
                 case AUTH_EV_SESSION_TIMEOUT:
                 case AUTH_EV_SESSION_GRACE_TIMEOUT:
-                	cdp_session_cleanup(s, msg);
+                    cdp_session_cleanup(s, msg);
                     s = 0;
                     break;