Module: kamailio
Branch: master
Commit: 956be0edcd816134650c5efccb7965fccb4d5916
URL: 
https://github.com/kamailio/kamailio/commit/956be0edcd816134650c5efccb7965fccb4d5916

Author: jaybeepee <[email protected]>
Committer: jaybeepee <[email protected]>
Date: 2015-09-11T11:44:31+02:00

modules/cdp: fixed race condition between CCR update and CCR terminate - lean 
priority towards T

---

Modified: modules/cdp/acctstatemachine.c

---

Diff:  
https://github.com/kamailio/kamailio/commit/956be0edcd816134650c5efccb7965fccb4d5916.diff
Patch: 
https://github.com/kamailio/kamailio/commit/956be0edcd816134650c5efccb7965fccb4d5916.patch

---

diff --git a/modules/cdp/acctstatemachine.c b/modules/cdp/acctstatemachine.c
index d4e524d..31304d2 100644
--- a/modules/cdp/acctstatemachine.c
+++ b/modules/cdp/acctstatemachine.c
@@ -210,29 +210,41 @@ inline int 
cc_acc_client_stateful_sm_process(cdp_session_t* s, int event, AAAMes
                        }
                        break;
                case ACC_CC_ST_PENDING_U:
-                       if (event == ACC_CC_EV_RECV_ANS && msg && !is_req(msg)) 
{
-                               rc = get_result_code(msg);
-                               if (rc >= 2000 && rc < 3000) {
-                                       event = ACC_CC_EV_RECV_ANS_SUCCESS;
-                               } else {
-                                       event = ACC_CC_EV_RECV_ANS_UNSUCCESS;
-                               }
-                       }
-                       switch (event) {
-                               case ACC_CC_EV_RECV_ANS_SUCCESS:
-                                       x->state = ACC_CC_ST_OPEN;
-                                       LM_DBG("success CCA for UPDATE\n");
-                                       update_gsu_response_timers(x, msg);
-                                       break;
-                               case ACC_CC_EV_RECV_ANS_UNSUCCESS:
-                                       //TODO: check whether we grant or 
terminate service to callback clients
-                                       x->state = ACC_CC_ST_DISCON;
-                                       LM_ERR("update failed... going back to 
IDLE/DISCON\n");
-                                       break;
-                               default:
-                                       LM_ERR("Received unknown event [%d] in 
state [%d]\n", event, x->state);
-                               break;
-                       }
+                       
+                        /**Richard added Aug 5 - there is a potential race 
condition where you may send a CCR-U immediately followed by CCR-T
+                         * and then receive a CCA-T while in state 
ACC_CC_ST_PENDING_U (e.g. if update timer and dialog termination at same time)  
+                         * In this event you would incorrectly ignore the CCR-T
+                         * Solution is to change state to change state to 
ACC_CC_ST_PENDING_T if CCR-T is sent while in this state  */
+                        if (event == ACC_CC_EV_SEND_REQ && msg && 
get_accounting_record_type(msg) == 4 /*TERMINATE RECORD*/) {
+                                LM_ERR("Received CCR-T while in state 
ACC_CC_ST_PENDING_U, just going to change to ACC_CC_ST_PENDING_T\n");
+                                s->u.cc_acc.state = ACC_CC_ST_PENDING_T;
+                                //update our reservation and its timers...
+                                update_gsu_request_timers(x, msg);
+                        } else {
+                            if (event == ACC_CC_EV_RECV_ANS && msg && 
!is_req(msg)) {
+                                    rc = get_result_code(msg);
+                                    if (rc >= 2000 && rc < 3000) {
+                                            event = ACC_CC_EV_RECV_ANS_SUCCESS;
+                                    } else {
+                                            event = 
ACC_CC_EV_RECV_ANS_UNSUCCESS;
+                                    }
+                            }
+                            switch (event) {
+                                    case ACC_CC_EV_RECV_ANS_SUCCESS:
+                                            x->state = ACC_CC_ST_OPEN;
+                                            LM_DBG("success CCA for UPDATE\n");
+                                            update_gsu_response_timers(x, msg);
+                                            break;
+                                    case ACC_CC_EV_RECV_ANS_UNSUCCESS:
+                                            //TODO: check whether we grant or 
terminate service to callback clients
+                                            x->state = ACC_CC_ST_DISCON;
+                                            LM_ERR("update failed... going 
back to IDLE/DISCON\n");
+                                            break;
+                                    default:
+                                            LM_ERR("Received unknown event 
[%d] in state [%d]\n", event, x->state);
+                                    break;
+                            }
+                        }
                        break;
                case ACC_CC_ST_DISCON:
                        switch (event) {


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to