From 00e8c10a5f96b7e8fbf8193885d1dc8450df3e45 Mon Sep 17 00:00:00 2001 From: jaybeepee Date: Fri, 11 Sep 2015 12:11:58 +0200 Subject: [PATCH] modules/cdp: fix lifetime and session timeout logic --- modules/cdp/authstatemachine.c | 82 +++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/modules/cdp/authstatemachine.c b/modules/cdp/authstatemachine.c index 462065d9866..33b56904f0f 100644 --- a/modules/cdp/authstatemachine.c +++ b/modules/cdp/authstatemachine.c @@ -88,15 +88,36 @@ int get_auth_session_state(AAAMessage* msg) { 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;