[sr-dev] git:master: modules/ims_charging: possible crash fixed on CCR timeout and some cleanup

Jason Penton jason.penton at gmail.com
Thu May 29 12:59:02 CEST 2014


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

Author: Jason Penton <jason.penton at gmail.com>
Committer: Jason Penton <jason.penton at gmail.com>
Date:   Thu May 29 12:57:16 2014 +0200

modules/ims_charging: possible crash fixed on CCR timeout and some cleanup
	- diameter destination realm correctly setup for routing/load balancing of request to multiple peers

---

 modules/ims_charging/ccr.c    |    5 ++-
 modules/ims_charging/config.h |    1 -
 modules/ims_charging/ims_ro.c |   73 +++++++++++++---------------------------
 modules/ims_charging/mod.c    |    3 --
 modules/ims_charging/ro_avp.c |   53 +++++++++++++++++++++++++++++
 modules/ims_charging/ro_avp.h |   17 +++++++++
 6 files changed, 97 insertions(+), 55 deletions(-)

diff --git a/modules/ims_charging/ccr.c b/modules/ims_charging/ccr.c
index 51a8bf7..3621a75 100644
--- a/modules/ims_charging/ccr.c
+++ b/modules/ims_charging/ccr.c
@@ -2,8 +2,10 @@
 
 #include "ccr.h"
 #include "Ro_data.h"
+#include "ro_avp.h"
 
 extern cdp_avp_bind_t *cdp_avp;
+extern struct cdp_binds cdpb;
 
 int Ro_write_event_type_avps(AAA_AVP_LIST * avp_list, event_type_t * x) {
     AAA_AVP_LIST aList = {0, 0};
@@ -187,9 +189,8 @@ AAAMessage * Ro_write_CCR_avps(AAAMessage * ccr, Ro_CCR_t* x) {
     if (!ccr) return 0;
 
     if (!cdp_avp->base.add_Origin_Host(&(ccr->avpList), x->origin_host, 0)) goto error;
-
     if (!cdp_avp->base.add_Origin_Realm(&(ccr->avpList), x->origin_realm, 0)) goto error;
-    if (!cdp_avp->base.add_Destination_Realm(&(ccr->avpList), x->destination_realm, 0)) goto error;
+    if (!ro_add_destination_realm_avp(ccr, x->destination_realm)) goto error;
 
     if (!cdp_avp->base.add_Accounting_Record_Type(&(ccr->avpList), x->acct_record_type)) goto error;
     if (!cdp_avp->base.add_Accounting_Record_Number(&(ccr->avpList), x->acct_record_number)) goto error;
diff --git a/modules/ims_charging/config.h b/modules/ims_charging/config.h
index d3868b5..8ceabd4 100644
--- a/modules/ims_charging/config.h
+++ b/modules/ims_charging/config.h
@@ -5,7 +5,6 @@ typedef struct {
     str origin_host;
     str origin_realm;
     str destination_realm;
-    str destination_host;
     str * service_context_id;
 } client_ro_cfg;
 
diff --git a/modules/ims_charging/ims_ro.c b/modules/ims_charging/ims_ro.c
index f71dc98..59c3ab3 100644
--- a/modules/ims_charging/ims_ro.c
+++ b/modules/ims_charging/ims_ro.c
@@ -29,12 +29,14 @@
 #include "config.h"
 #include "ro_session_hash.h"
 #include "stats.h"
+#include "ro_avp.h"
 
 extern struct tm_binds tmb;
 extern struct cdp_binds cdpb;
 extern client_ro_cfg cfg;
 extern struct dlg_binds dlgb;
 extern cdp_avp_bind_t *cdp_avp;
+extern str ro_forced_peer;
 
 struct session_setup_data {
 	struct ro_session *ro_session;
@@ -85,34 +87,6 @@ struct sip_msg * trans_get_request_from_current_reply() {
 }
 
 /**
- * Create and add an AVP to a Diameter message.
- * @param m - Diameter message to add to
- * @param d - the payload data
- * @param len - length of the payload data
- * @param avp_code - the code of the AVP
- * @param flags - flags for the AVP
- * @param vendorid - the value of the vendor id or 0 if none
- * @param data_do - what to do with the data when done
- * @param func - the name of the calling function, for debugging purposes
- * @returns 1 on success or 0 on failure
- */
-static inline int Ro_add_avp(AAAMessage *m, char *d, int len, int avp_code, int flags, int vendorid, int data_do, const char *func) {
-    AAA_AVP *avp;
-    if (vendorid != 0) flags |= AAA_AVP_FLAG_VENDOR_SPECIFIC;
-    avp = cdpb.AAACreateAVP(avp_code, flags, vendorid, d, len, data_do);
-    if (!avp) {
-        LM_ERR("%s: Failed creating avp\n", func);
-        return 0;
-    }
-    if (cdpb.AAAAddAVPToMessage(m, avp, m->avpList.tail) != AAA_ERR_SUCCESS) {
-        LM_ERR("%s: Failed adding avp to message\n", func);
-       cdpb.AAAFreeAVP(&avp);
-        return 0;
-    }
-    return 1;
-}
-
-/**
  * Create and add an AVP to a list of AVPs.
  * @param list - the AVP list to add to
  * @param d - the payload data
@@ -148,22 +122,6 @@ static inline int Ro_add_avp_list(AAA_AVP_LIST *list, char *d, int len, int avp_
     return 1;
 }
 
-/**
- * Creates and adds a Destination-Realm AVP.
- * @param msg - the Diameter message to add to.
- * @param data - the value for the AVP payload
- * @returns 1 on success or 0 on error
- */
-inline int ro_add_destination_realm_avp(AAAMessage *msg, str data) {
-    return
-    Ro_add_avp(msg, data.s, data.len,
-            AVP_Destination_Realm,
-            AAA_AVP_FLAG_MANDATORY,
-            0,
-            AVP_DUPLICATE_DATA,
-            __FUNCTION__);
-}
-
 inline int Ro_add_cc_request(AAAMessage *msg, unsigned int cc_request_type, unsigned int cc_request_number) {
     char x[4];
     set_4bytes(x, cc_request_type);
@@ -631,8 +589,11 @@ void send_ccr_interim(struct ro_session* ro_session, unsigned int used, unsigned
 
     cdpb.AAASessionsUnlock(auth->hash);
 
-    //AAAMessage *cca = cdpb.AAASendRecvMessageToPeer(ccr, &cfg.destination_host);
-    cdpb.AAASendMessageToPeer(ccr, &cfg.destination_host, resume_on_interim_ccr, (void *) i_req);
+    if (ro_forced_peer.len > 0) {
+    	cdpb.AAASendMessageToPeer(ccr, &ro_forced_peer, resume_on_interim_ccr, (void *) i_req);
+    } else {
+    	cdpb.AAASendMessage(ccr, resume_on_interim_ccr, (void *) i_req);
+    }
 
 //    cdpb.AAASessionsUnlock(auth->hash);
 
@@ -850,7 +811,12 @@ void send_ccr_stop(struct ro_session *ro_session) {
     }
 
     cdpb.AAASessionsUnlock(auth->hash);
-    cdpb.AAASendMessageToPeer(ccr, &cfg.destination_host, resume_on_termination_ccr, NULL);
+
+    if (ro_forced_peer.len > 0) {
+    	cdpb.AAASendMessageToPeer(ccr, &ro_forced_peer, resume_on_termination_ccr, NULL);
+    } else {
+    	cdpb.AAASendMessage(ccr, resume_on_termination_ccr, NULL);
+    }
 
     Ro_free_CCR(ro_ccr_data);
 
@@ -1050,7 +1016,14 @@ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, str* charge_
 
     LM_DBG("Sending CCR Diameter message.\n");
     cdpb.AAASessionsUnlock(cc_acc_session->hash);
-    cdpb.AAASendMessageToPeer(ccr, &cfg.destination_host, resume_on_initial_ccr, (void *) ssd);
+
+    if (ro_forced_peer.len > 0) {
+    	LM_DBG("Sending message with Peer\n");
+    	cdpb.AAASendMessageToPeer(ccr, &ro_forced_peer, resume_on_initial_ccr, (void *) ssd);
+    } else {
+    	LM_DBG("Sending message without Peer and realm is [%.*s]\n", ccr->dest_realm->data.len, ccr->dest_realm->data.s);
+    	cdpb.AAASendMessage(ccr, resume_on_initial_ccr, (void *) ssd);
+    }
 
     Ro_free_CCR(ro_ccr_data);
 
@@ -1177,7 +1150,9 @@ error0:
     LM_DBG("Trying to reserve credit on initial INVITE failed on cdp callback\n");
     create_cca_return_code(error_code);
 
-    cdpb.AAAFreeMessage(&cca);
+    if (!is_timeout && cca) {
+    	cdpb.AAAFreeMessage(&cca);
+    }
 
     if (t)
     	tmb.unref_cell(t);
diff --git a/modules/ims_charging/mod.c b/modules/ims_charging/mod.c
index e305bb5..30442ba 100644
--- a/modules/ims_charging/mod.c
+++ b/modules/ims_charging/mod.c
@@ -150,9 +150,6 @@ int fix_parameters() {
 	cfg.destination_realm.s = ro_destination_realm_s;
 	cfg.destination_realm.len = strlen(ro_destination_realm_s);
 
-	cfg.destination_host.s = ro_destination_host_s;
-	cfg.destination_host.len = strlen(ro_destination_host_s);
-
 	cfg.service_context_id = shm_malloc(sizeof(str));
 	if (!cfg.service_context_id) {
 		LM_ERR("fix_parameters:not enough shm memory\n");
diff --git a/modules/ims_charging/ro_avp.c b/modules/ims_charging/ro_avp.c
new file mode 100644
index 0000000..25c37d2
--- /dev/null
+++ b/modules/ims_charging/ro_avp.c
@@ -0,0 +1,53 @@
+/*
+ * ro_avp.c
+ *
+ *  Created on: 29 May 2014
+ *      Author: jaybeepee
+ */
+#include "ro_avp.h"
+
+extern struct cdp_binds cdpb;
+/**
+ * Creates and adds a Destination-Realm AVP.
+ * @param msg - the Diameter message to add to.
+ * @param data - the value for the AVP payload
+ * @returns 1 on success or 0 on error
+ */
+int ro_add_destination_realm_avp(AAAMessage *msg, str data) {
+    return
+    Ro_add_avp(msg, data.s, data.len,
+            AVP_Destination_Realm,
+            AAA_AVP_FLAG_MANDATORY,
+            0,
+            AVP_DUPLICATE_DATA,
+            __FUNCTION__);
+}
+
+/**
+ * Create and add an AVP to a Diameter message.
+ * @param m - Diameter message to add to
+ * @param d - the payload data
+ * @param len - length of the payload data
+ * @param avp_code - the code of the AVP
+ * @param flags - flags for the AVP
+ * @param vendorid - the value of the vendor id or 0 if none
+ * @param data_do - what to do with the data when done
+ * @param func - the name of the calling function, for debugging purposes
+ * @returns 1 on success or 0 on failure
+ */
+int Ro_add_avp(AAAMessage *m, char *d, int len, int avp_code, int flags, int vendorid, int data_do, const char *func) {
+    AAA_AVP *avp;
+    if (vendorid != 0) flags |= AAA_AVP_FLAG_VENDOR_SPECIFIC;
+    avp = cdpb.AAACreateAVP(avp_code, flags, vendorid, d, len, data_do);
+    if (!avp) {
+        LM_ERR("%s: Failed creating avp\n", func);
+        return 0;
+    }
+    if (cdpb.AAAAddAVPToMessage(m, avp, m->avpList.tail) != AAA_ERR_SUCCESS) {
+        LM_ERR("%s: Failed adding avp to message\n", func);
+       cdpb.AAAFreeAVP(&avp);
+        return 0;
+    }
+    return 1;
+}
+
diff --git a/modules/ims_charging/ro_avp.h b/modules/ims_charging/ro_avp.h
new file mode 100644
index 0000000..d5cfede
--- /dev/null
+++ b/modules/ims_charging/ro_avp.h
@@ -0,0 +1,17 @@
+/*
+ * ro_avp.h
+ *
+ *  Created on: 29 May 2014
+ *      Author: jaybeepee
+ */
+
+#ifndef RO_AVP_H_
+#define RO_AVP_H_
+
+#include "../cdp/cdp_load.h"
+
+int ro_add_destination_realm_avp(AAAMessage *msg, str data);
+int Ro_add_avp(AAAMessage *m, char *d, int len, int avp_code, int flags, int vendorid, int data_do, const char *func);
+
+
+#endif /* RO_AVP_H_ */




More information about the sr-dev mailing list