瀏覽代碼

modules/cdp: housekeeping
- corrected copyright
- fixed timer code (latency thresholds)
- changed to KAMAILIO module interface

Jason Penton 12 年之前
父節點
當前提交
3dd4456169
共有 58 個文件被更改,包括 1832 次插入1507 次删除
  1. 1 1
      modules/cdp/Makefile
  2. 6 1
      modules/cdp/acceptor.c
  3. 6 1
      modules/cdp/acceptor.h
  4. 24 9
      modules/cdp/api_process.c
  5. 6 1
      modules/cdp/api_process.h
  6. 753 748
      modules/cdp/authstatemachine.c
  7. 6 1
      modules/cdp/authstatemachine.h
  8. 6 1
      modules/cdp/cdp_load.c
  9. 6 1
      modules/cdp/cdp_load.h
  10. 57 52
      modules/cdp/config.c
  11. 7 2
      modules/cdp/config.h
  12. 6 1
      modules/cdp/configdtd.h
  13. 6 1
      modules/cdp/configparser.c
  14. 7 2
      modules/cdp/diameter.h
  15. 6 1
      modules/cdp/diameter_api.h
  16. 6 1
      modules/cdp/diameter_avp.c
  17. 6 1
      modules/cdp/diameter_code_avp.h
  18. 6 1
      modules/cdp/diameter_code_result.h
  19. 62 58
      modules/cdp/diameter_comm.c
  20. 6 1
      modules/cdp/diameter_epc.h
  21. 6 1
      modules/cdp/diameter_epc_code_app.h
  22. 6 1
      modules/cdp/diameter_epc_code_avp.h
  23. 6 2
      modules/cdp/diameter_epc_code_cmd.h
  24. 6 1
      modules/cdp/diameter_epc_code_result.h
  25. 6 1
      modules/cdp/diameter_ims.h
  26. 6 1
      modules/cdp/diameter_ims_code_app.h
  27. 6 1
      modules/cdp/diameter_ims_code_avp.h
  28. 6 1
      modules/cdp/diameter_ims_code_cmd.h
  29. 6 1
      modules/cdp/diameter_ims_code_result.h
  30. 6 1
      modules/cdp/diameter_msg.c
  31. 56 52
      modules/cdp/diameter_peer.c
  32. 6 1
      modules/cdp/diameter_peer.h
  33. 34 29
      modules/cdp/globals.c
  34. 6 1
      modules/cdp/globals.h
  35. 52 17
      modules/cdp/mod.c
  36. 7 2
      modules/cdp/mod.h
  37. 6 1
      modules/cdp/peer.c
  38. 6 1
      modules/cdp/peer.h
  39. 30 31
      modules/cdp/peermanager.c
  40. 8 3
      modules/cdp/peermanager.h
  41. 6 1
      modules/cdp/peerstatemachine.c
  42. 6 1
      modules/cdp/peerstatemachine.h
  43. 150 151
      modules/cdp/receiver.c
  44. 6 1
      modules/cdp/receiver.h
  45. 6 1
      modules/cdp/routing.c
  46. 6 1
      modules/cdp/routing.h
  47. 6 1
      modules/cdp/sem.h
  48. 48 48
      modules/cdp/session.c
  49. 28 23
      modules/cdp/session.h
  50. 7 1
      modules/cdp/tcp_accept.c
  51. 6 1
      modules/cdp/tcp_accept.h
  52. 6 1
      modules/cdp/timer.c
  53. 6 1
      modules/cdp/timer.h
  54. 20 12
      modules/cdp/transaction.c
  55. 8 1
      modules/cdp/transaction.h
  56. 6 1
      modules/cdp/utils.h
  57. 245 226
      modules/cdp/worker.c
  58. 6 1
      modules/cdp/worker.h

+ 1 - 1
modules/cdp/Makefile

@@ -2,7 +2,7 @@ include ../../Makefile.defs
 auto_gen=
 auto_gen=
 NAME=cdp.so
 NAME=cdp.so
 
 
-DEFS+=-DSER_MOD_INTERFACE
+DEFS+=-DKAMAILIO_MOD_INTERFACE
 
 
 ifeq ($(CROSS_COMPILE),)
 ifeq ($(CROSS_COMPILE),)
 XML2CFG=$(shell which xml2-config)
 XML2CFG=$(shell which xml2-config)

+ 6 - 1
modules/cdp/acceptor.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/acceptor.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 24 - 9
modules/cdp/api_process.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -43,24 +48,25 @@
 #include "receiver.h"
 #include "receiver.h"
 #include "peerstatemachine.h"
 #include "peerstatemachine.h"
 
 
+extern unsigned int* latency_threshold_p;	/**<max delay for Diameter call */
 
 
 handler_list *handlers = 0; /**< list of handlers */
 handler_list *handlers = 0; /**< list of handlers */
 gen_lock_t *handlers_lock;	/**< lock for list of handlers */
 gen_lock_t *handlers_lock;	/**< lock for list of handlers */
 
 
 /**
 /**
  * This callback is added as an internal message listener and used to process
  * This callback is added as an internal message listener and used to process
- * transaction requests. 
+ * transaction requests.
  * - first it calls all the registered handlers for requests and responses
  * - first it calls all the registered handlers for requests and responses
  * - then it calls the transaction handler
  * - then it calls the transaction handler
  * @param p - peer that this message came from
  * @param p - peer that this message came from
  * @param msg - the diameter message
  * @param msg - the diameter message
  * @param ptr - not used anymore
  * @param ptr - not used anymore
  * @returns 1 always
  * @returns 1 always
- */ 
+ */
 int api_callback(peer *p,AAAMessage *msg,void* ptr)
 int api_callback(peer *p,AAAMessage *msg,void* ptr)
 {
 {
 	cdp_trans_t *t;
 	cdp_trans_t *t;
-	int auto_drop;	
+	int auto_drop;
 	handler *h;
 	handler *h;
 	handler x;
 	handler x;
 	enum handler_types type;
 	enum handler_types type;
@@ -77,7 +83,7 @@ int api_callback(peer *p,AAAMessage *msg,void* ptr)
 					rsp = (x.handler.requestHandler)(msg,h->param);
 					rsp = (x.handler.requestHandler)(msg,h->param);
 					if (rsp) {
 					if (rsp) {
 						//peer_send_msg(p,rsp);
 						//peer_send_msg(p,rsp);
-						sm_process(p,Send_Message,rsp,0,0);	
+						sm_process(p,Send_Message,rsp,0,0);
 					}
 					}
 					lock_get(handlers_lock);
 					lock_get(handlers_lock);
 				}
 				}
@@ -87,17 +93,26 @@ int api_callback(peer *p,AAAMessage *msg,void* ptr)
 					lock_get(handlers_lock);
 					lock_get(handlers_lock);
 				}
 				}
 			}
 			}
-		}		
+		}
 	lock_release(handlers_lock);
 	lock_release(handlers_lock);
-	
-	if (!is_req(msg)){		
+
+	if (!is_req(msg)){
 		/* take care of transactional callback if any */
 		/* take care of transactional callback if any */
 		t = cdp_take_trans(msg);
 		t = cdp_take_trans(msg);
 		if (t){
 		if (t){
 			t->ans = msg;
 			t->ans = msg;
+            struct timeval stop;
+            gettimeofday(&stop, NULL);
+            long elapsed_usecs =  (stop.tv_sec - t->started.tv_sec)*1000000 + (stop.tv_usec - t->started.tv_usec);
+            long elapsed_msecs = elapsed_usecs/1000;
+            if (elapsed_msecs > *latency_threshold_p) {
+            	LM_ERR("Received diameter response outside of threshold (%d) - %ld\n", *latency_threshold_p, elapsed_msecs);
+            }
+            update_stat(replies_received, 1);
+            update_stat(replies_response_time, elapsed_msecs);
 			auto_drop = t->auto_drop;
 			auto_drop = t->auto_drop;
 			if (t->cb){
 			if (t->cb){
-				(t->cb)(0,*(t->ptr),msg);
+				(t->cb)(0,*(t->ptr),msg, elapsed_msecs);
 			}
 			}
 			if (auto_drop) cdp_free_trans(t);
 			if (auto_drop) cdp_free_trans(t);
 		}
 		}

+ 6 - 1
modules/cdp/api_process.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 753 - 748
modules/cdp/authstatemachine.c

@@ -1,20 +1,25 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ *
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
  * branch of the original SER. We are therefore migrating it to
  * branch of the original SER. We are therefore migrating it to
  * Kamailio/SR and look forward to maintaining it from here on out.
  * Kamailio/SR and look forward to maintaining it from here on out.
  * 2011/2012 Smile Communications, Pty. Ltd.
  * 2011/2012 Smile Communications, Pty. Ltd.
- * ported/maintained/improved by 
+ * ported/maintained/improved by
  * Jason Penton (jason(dot)penton(at)smilecoms.com and
  * Jason Penton (jason(dot)penton(at)smilecoms.com and
- * Richard Good (richard(dot)good(at)smilecoms.com) as part of an 
+ * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
  * effort to add full IMS support to Kamailio/SR using a new and
  * effort to add full IMS support to Kamailio/SR using a new and
  * improved architecture
  * improved architecture
- * 
+ *
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus.
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -32,14 +37,14 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  * GNU General Public License for more details.
  *
  *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
  */
 
 
 #include <time.h>
 #include <time.h>
- 
+
 #include "authstatemachine.h"
 #include "authstatemachine.h"
 #include "diameter_ims.h"
 #include "diameter_ims.h"
 
 
@@ -49,69 +54,62 @@
 #include "routing.h"
 #include "routing.h"
 #include "receiver.h"
 #include "receiver.h"
 
 
-char *auth_states[]={"Idle","Pending","Open","Discon"};
-char *auth_events[]={};
-
-extern dp_config *config;	// because i want to use tc for the expire times...
-
-int get_result_code(AAAMessage* msg)
-{
-	AAA_AVP *avp;
-	AAA_AVP_LIST list;
-	list.head=0;
-	list.tail=0;
-	int rc=-1;
-	
-        if (!msg) goto error;
-        
-        for (avp=msg->avpList.tail;avp;avp=avp->prev)
-		{
-		
-			if (avp->code==AVP_Result_Code)
-			{
-				rc = get_4bytes(avp->data.s);	
-				goto finish;
-			} else if (avp->code==AVP_Experimental_Result)
-			{
-				list=AAAUngroupAVPS(avp->data);
-				for(avp=list.head;avp;avp=avp->next)
-				{
-					if (avp->code==AVP_IMS_Experimental_Result_Code)
-						{
-							rc = get_4bytes(avp->data.s);
-							AAAFreeAVPList(&list);
-							goto finish;
-						}
-			 	}
-				AAAFreeAVPList(&list);			 					
-			}
-		}
+char *auth_states[] = {"Idle", "Pending", "Open", "Discon"};
+char *auth_events[] = {};
+
+extern dp_config *config; // because i want to use tc for the expire times...
+
+int get_result_code(AAAMessage* msg) {
+    AAA_AVP *avp;
+    AAA_AVP_LIST list;
+    list.head = 0;
+    list.tail = 0;
+    int rc = -1;
+
+    if (!msg) goto error;
+
+    for (avp = msg->avpList.tail; avp; avp = avp->prev) {
+
+        if (avp->code == AVP_Result_Code) {
+            rc = get_4bytes(avp->data.s);
+            goto finish;
+        } else if (avp->code == AVP_Experimental_Result) {
+            list = AAAUngroupAVPS(avp->data);
+            for (avp = list.head; avp; avp = avp->next) {
+                if (avp->code == AVP_IMS_Experimental_Result_Code) {
+                    rc = get_4bytes(avp->data.s);
+                    AAAFreeAVPList(&list);
+                    goto finish;
+                }
+            }
+            AAAFreeAVPList(&list);
+        }
+    }
 finish:
 finish:
-		return rc;
+    return rc;
 error:
 error:
-        LM_ERR("get_result_code(): no AAAMessage or Result Code not found\n");
-        return -1;
+    LM_ERR("get_result_code(): no AAAMessage or Result Code not found\n");
+    return -1;
 }
 }
 
 
 /*
 /*
  * Alberto Diez changes the default behaviour on error is going to be to return the default state
  * Alberto Diez changes the default behaviour on error is going to be to return the default state
  * that is  STATE_MAINTAINED
  * that is  STATE_MAINTAINED
  * this is because in the Rx specification 3GPP TS 29214 v7.1.0 (2007-06)
  * this is because in the Rx specification 3GPP TS 29214 v7.1.0 (2007-06)
- * the AVP Auth Session State is not included in any message exchange, 
+ * the AVP Auth Session State is not included in any message exchange,
  * therefor we could as well not even check for it, but diameter rfc says to look at this
  * therefor we could as well not even check for it, but diameter rfc says to look at this
- * 
-*/
+ *
+ */
 
 
-int get_auth_session_state(AAAMessage* msg)
-{
-        if (!msg) goto error;
-        AAA_AVP* rc = AAAFindMatchingAVP(msg, 0, AVP_Auth_Session_State, 0, 0);
-        if (!rc) goto error;
-        return get_4bytes(rc->data.s);
+int get_auth_session_state(AAAMessage* msg) {
+    if (!msg) goto error;
+    AAA_AVP* rc = AAAFindMatchingAVP(msg, 0, AVP_Auth_Session_State, 0, 0);
+    if (!rc) goto error;
+    return get_4bytes(rc->data.s);
 
 
 error:
 error:
-        LM_DBG( "get_auth_session_state(): no AAAMessage or Auth Session State not found\n");
-        return STATE_MAINTAINED;
+    LM_DBG("get_auth_session_state(): no AAAMessage or Auth Session State not found\n");
+    return STATE_MAINTAINED;
 }
 }
 
 
 /**
 /**
@@ -119,46 +117,45 @@ error:
  * @param x
  * @param x
  * @param msg
  * @param 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;
-	
-	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;
-	}
-	avp = AAAFindMatchingAVP(msg,0,AVP_Authorization_Lifetime,0,0);
-	if (avp &&avp->data.len==4) {
-		auth_lifetime = get_4bytes(avp->data.s);
-		switch(auth_lifetime){
-			case 0:
-				x->lifetime = time(0);
-				break;
-			case 0xFFFFFFFF:
-				x->lifetime = -1;
-				break;
-			default:
-				x->lifetime = time(0)+auth_lifetime;
-		}
-		if (x->timeout!=-1 && x->timeout<x->lifetime) 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);
-		switch(session_timeout){
-			case 0:
-				x->timeout = time(0)+config->default_auth_session_timeout;
-				break;
-			case 0xFFFFFFFF:
-				x->timeout = -1;
-				break;
-			default:
-				x->timeout = time(0)+session_timeout;
-		}
-		if (!x->lifetime) x->lifetime = x->timeout;
-	}
+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;
+
+    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;
+    }
+    avp = AAAFindMatchingAVP(msg, 0, AVP_Authorization_Lifetime, 0, 0);
+    if (avp && avp->data.len == 4) {
+        auth_lifetime = get_4bytes(avp->data.s);
+        switch (auth_lifetime) {
+            case 0:
+                x->lifetime = time(0);
+                break;
+            case 0xFFFFFFFF:
+                x->lifetime = -1;
+                break;
+            default:
+                x->lifetime = time(0) + auth_lifetime;
+        }
+        if (x->timeout != -1 && x->timeout < x->lifetime) 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);
+        switch (session_timeout) {
+            case 0:
+                x->timeout = time(0) + config->default_auth_session_timeout;
+                break;
+            case 0xFFFFFFFF:
+                x->timeout = -1;
+                break;
+            default:
+                x->timeout = time(0) + session_timeout;
+        }
+        if (!x->lifetime) x->lifetime = x->timeout;
+    }
 }
 }
 
 
 /**
 /**
@@ -166,43 +163,42 @@ void update_auth_session_timers(cdp_auth_session_t *x,AAAMessage *msg)
  * @param x
  * @param x
  * @param msg
  * @param msg
  */
  */
-void add_auth_session_timers(cdp_auth_session_t *x,AAAMessage *msg)
-{
-	AAA_AVP *avp;
-	char data[4];
-	uint32_t v;
-	
-	avp = AAAFindMatchingAVP(msg,0,AVP_Authorization_Lifetime,0,0);
-	if (!avp){ 
-		if (x->lifetime==-1) v=0xFFFFFFFF;
-		else {
-			v = x->lifetime-time(0);
-			if (v<0) v = 0;
-		}
-		set_4bytes(data,v);
-		avp = AAACreateAVP(AVP_Authorization_Lifetime,AAA_AVP_FLAG_MANDATORY,0,data,4,AVP_DUPLICATE_DATA);
-		if (avp) AAAAddAVPToMessage(msg,avp,0);
-	}
-	if (x->lifetime!=-1){
-		avp = AAAFindMatchingAVP(msg,0,AVP_Auth_Grace_Period,0,0);
-		if (!avp){ 
-			v = x->grace_period;
-			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,0);
-		}
-	}
-	avp = AAAFindMatchingAVP(msg,0,AVP_Session_Timeout,0,0);
-	if (!avp){ 
-		if (x->timeout==-1) v=0xFFFFFFFF;
-		else {
-			v = x->timeout-time(0);
-			if (v<0) v = 0;
-		}
-		set_4bytes(data,v);
-		avp = AAACreateAVP(AVP_Session_Timeout,AAA_AVP_FLAG_MANDATORY,0,data,4,AVP_DUPLICATE_DATA);
-		if (avp) AAAAddAVPToMessage(msg,avp,0);
-	}
+void add_auth_session_timers(cdp_auth_session_t *x, AAAMessage *msg) {
+    AAA_AVP *avp;
+    char data[4];
+    uint32_t v;
+
+    avp = AAAFindMatchingAVP(msg, 0, AVP_Authorization_Lifetime, 0, 0);
+    if (!avp) {
+        if (x->lifetime == -1) v = 0xFFFFFFFF;
+        else {
+            v = x->lifetime - time(0);
+            if (v < 0) v = 0;
+        }
+        set_4bytes(data, v);
+        avp = AAACreateAVP(AVP_Authorization_Lifetime, AAA_AVP_FLAG_MANDATORY, 0, data, 4, AVP_DUPLICATE_DATA);
+        if (avp) AAAAddAVPToMessage(msg, avp, 0);
+    }
+    if (x->lifetime != -1) {
+        avp = AAAFindMatchingAVP(msg, 0, AVP_Auth_Grace_Period, 0, 0);
+        if (!avp) {
+            v = x->grace_period;
+            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, 0);
+        }
+    }
+    avp = AAAFindMatchingAVP(msg, 0, AVP_Session_Timeout, 0, 0);
+    if (!avp) {
+        if (x->timeout == -1) v = 0xFFFFFFFF;
+        else {
+            v = x->timeout - time(0);
+            if (v < 0) v = 0;
+        }
+        set_4bytes(data, v);
+        avp = AAACreateAVP(AVP_Session_Timeout, AAA_AVP_FLAG_MANDATORY, 0, data, 4, AVP_DUPLICATE_DATA);
+        if (avp) AAAAddAVPToMessage(msg, avp, 0);
+    }
 }
 }
 
 
 /**
 /**
@@ -213,190 +209,199 @@ void add_auth_session_timers(cdp_auth_session_t *x,AAAMessage *msg)
  * @param msg  - AAAMessage
  * @param msg  - AAAMessage
  * @returns 0 if msg should be given to the upper layer 1 if not
  * @returns 0 if msg should be given to the upper layer 1 if not
  */
  */
-inline int auth_client_statefull_sm_process(cdp_session_t* s, int event, AAAMessage* msg)
-{
-	cdp_auth_session_t *x;
-	int rc;	
-	int rv=0; //return value
-	
-	if (!s) {
-		switch (event) {
-			case AUTH_EV_RECV_ASR:
-				Send_ASA(0,msg);
-				break;				
-			default:
-				LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d with no session!\n",
-				event);				
-		}
-		return rv;
-	}
-	x = &(s->u.auth);
-	
-	if (s->cb) (s->cb)(event,s);
-	LM_INFO("after callback of event %i\n", event);
-
-	//if (x && x->state && msg) LM_ERR("auth_client_statefull_sm_process [event %i] [state %i] endtoend %u hopbyhop %u\n",event,x->state,msg->endtoendId,msg->hopbyhopId);
-
-	switch(x->state){
-		case AUTH_ST_IDLE:
-			switch (event) {
-				case AUTH_EV_SEND_REQ:
-					s->application_id = msg->applicationId;
-					s->u.auth.state = AUTH_ST_PENDING;
-					update_auth_session_timers(x,msg);
-					add_auth_session_timers(x,msg);
-					//LM_INFO("state machine: i was in idle and i am going to pending\n");
-					break;				
-				default:
-					LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!(data %p)\n",
-						event,auth_states[x->state],x->generic_data);				
-			}
-			break;
-		
-		case AUTH_ST_PENDING:
-			if (event == AUTH_EV_RECV_ANS && msg && !is_req(msg)){
-				rc = get_result_code(msg);
-				if (rc>=2000 && rc<3000 && get_auth_session_state(msg)==STATE_MAINTAINED) 
-					event = AUTH_EV_RECV_ANS_SUCCESS;
-				else
-					event = AUTH_EV_RECV_ANS_UNSUCCESS;
-			}
-			
-			switch(event){
-				case AUTH_EV_RECV_ANS_SUCCESS:
-					x->state = AUTH_ST_OPEN;
-					update_auth_session_timers(x,msg);
-					//LM_INFO("state machine: i was in pending and i am going to open\n");
-					break;
-				case AUTH_EV_RECV_ANS_UNSUCCESS:
-					x->state = AUTH_ST_DISCON;
-					//LM_INFO("state machine: i was in pending and i am going to discon\n");
-					Send_STR(s,msg);
-					break;
-				case AUTH_EV_SESSION_TIMEOUT:
-				case AUTH_EV_SERVICE_TERMINATED:
-				case AUTH_EV_SESSION_GRACE_TIMEOUT:
-					Session_Cleanup(s,NULL);					
-					break;					
-					
-				default:
-					LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-		
-		case AUTH_ST_OPEN:
-			if (event == AUTH_EV_RECV_ANS && msg && !is_req(msg)){
-				rc = get_result_code(msg);
-				if (rc>=2000 && rc<3000 && get_auth_session_state(msg)==STATE_MAINTAINED) 
-					event = AUTH_EV_RECV_ANS_SUCCESS;
-				else
-					event = AUTH_EV_RECV_ANS_UNSUCCESS;
-			}
-
-			switch (event) {
-				case AUTH_EV_SEND_REQ:
-					// if the request is STR i should move to Discon .. 
-					// this is not in the state machine but I (Alberto Diez) need it
-					if (msg->commandCode==IMS_STR) 
-						s->u.auth.state = AUTH_ST_DISCON;
-					else {
-						s->u.auth.state = AUTH_ST_OPEN;
-						add_auth_session_timers(x,msg);
-					}
-					break;		
-					
-				case AUTH_EV_RECV_ANS_SUCCESS:
-					x->state = AUTH_ST_OPEN;
-					update_auth_session_timers(x,msg);					
-					//LM_INFO("state machine: i was in open and i am going to open\n");
-					break;
-					
-				case AUTH_EV_RECV_ANS_UNSUCCESS:
-					x->state = AUTH_ST_DISCON;
-					//LM_INFO("state machine: i was in open and i am going to discon\n");
-					break;
-					
-				case AUTH_EV_SESSION_TIMEOUT:
-				case AUTH_EV_SERVICE_TERMINATED:
-				case AUTH_EV_SESSION_GRACE_TIMEOUT:
-					x->state = AUTH_ST_DISCON;
-					//LM_INFO("state machine: i was in open and i am going to discon\n");
-					
-                                        Send_STR(s,msg);					
-					break;
-					
-				case AUTH_EV_SEND_ASA_SUCCESS:
-					x->state = AUTH_ST_DISCON;
-					//LM_INFO("state machine: i was in open and i am going to discon\n");
-					Send_STR(s,msg);					
-					break;
-					
-				case AUTH_EV_SEND_ASA_UNSUCCESS:
-					x->state = AUTH_ST_OPEN;
-					update_auth_session_timers(x,msg);
-					//LM_INFO("state machine: i was in open and i am going to open\n");
-					break;
-					
-				case AUTH_EV_RECV_ASR: 
-					// two cases , client will comply or will not
-					// our client is very nice and always complys.. because
-					// our brain is in the PCRF... if he says to do this , we do it
-					// Alberto Diez , (again this is not Diameter RFC)
-					x->state = AUTH_ST_DISCON;
-					Send_ASA(s,msg);
-					Send_STR(s,msg);
-					break;
-					
-				default:
-					LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-		
-		case AUTH_ST_DISCON:
-			switch (event) {
-				case AUTH_EV_RECV_ASR:
-					x->state = AUTH_ST_DISCON;
-					//LM_INFO("state machine: i was in discon and i am going to discon\n");
-					Send_ASA(s,msg);
-					break;
-					
-				// Just added this because it might happen if the other peer doesnt 
-				// send a valid STA, then the session stays open forever...
-				// We dont accept that... we have lifetime+grace_period for that
-				// This is not in the Diameter RFC ...	
-				case AUTH_EV_SESSION_TIMEOUT:
-				case AUTH_EV_SESSION_GRACE_TIMEOUT:
-				// thats the addition
-				case AUTH_EV_RECV_STA:
-					x->state = AUTH_ST_IDLE;
-					LM_INFO("state machine: AUTH_EV_RECV_STA about to clean up\n");
-					if (msg) AAAFreeMessage(&msg); // if might be needed in frequency
-					// If I register a ResponseHandler then i Free the STA there not here..
-					// but i dont have interest in that now..				
-					Session_Cleanup(s,NULL);
-					s = 0;
-					rv=1;
-					break;
-					
-				default:
-					LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-		default:
-			LM_ERR("auth_client_statefull_sm_process(): Received event %d while in invalid state %d!\n",
-				event,x->state);
-	}
-	if (s) {
-		if (s->cb) (s->cb)(AUTH_EV_SESSION_MODIFIED,s);
-		AAASessionsUnlock(s->hash);
-	}
-	return rv;
+inline int auth_client_statefull_sm_process(cdp_session_t* s, int event, AAAMessage* msg) {
+
+    cdp_auth_session_t *x;
+    int rc;
+    int rv = 0; //return value
+
+    if (!s) {
+        switch (event) {
+            case AUTH_EV_RECV_ASR:
+                Send_ASA(0, msg);
+                break;
+            default:
+                LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d with no session!\n",
+                        event);
+        }
+        return rv;
+    }
+    x = &(s->u.auth);
+
+    if (s->cb) (s->cb)(event, s);
+    LM_INFO("after callback of event %i\n", event);
+
+    //if (x && x->state && msg) LM_ERR("auth_client_statefull_sm_process [event %i] [state %i] endtoend %u hopbyhop %u\n",event,x->state,msg->endtoendId,msg->hopbyhopId);
+
+    switch (x->state) {
+        case AUTH_ST_IDLE:
+            switch (event) {
+                case AUTH_EV_SEND_REQ:
+                    s->application_id = msg->applicationId;
+                    s->u.auth.state = AUTH_ST_PENDING;
+                    update_auth_session_timers(x, msg);
+                    add_auth_session_timers(x, msg);
+
+                    //Richard add this add: add destination realm to cdp session
+                    //use msg origin realm as the destination realm
+                    //we do this here as this is were the state changes to open
+                    //Where must we free this?
+                    s->dest_realm.s = (char*) shm_malloc(msg->dest_realm->data.len);
+                    memcpy(s->dest_realm.s, msg->dest_realm->data.s, msg->dest_realm->data.len);
+                    s->dest_realm.len = msg->dest_realm->data.len;
+
+
+                    //LM_INFO("state machine: i was in idle and i am going to pending\n");
+                    break;
+                default:
+                    LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!(data %p)\n",
+                            event, auth_states[x->state], x->generic_data);
+            }
+            break;
+
+        case AUTH_ST_PENDING:
+            if (event == AUTH_EV_RECV_ANS && msg && !is_req(msg)) {
+                rc = get_result_code(msg);
+                if (rc >= 2000 && rc < 3000 && get_auth_session_state(msg) == STATE_MAINTAINED)
+                    event = AUTH_EV_RECV_ANS_SUCCESS;
+                else
+                    event = AUTH_EV_RECV_ANS_UNSUCCESS;
+            }
+
+            switch (event) {
+                case AUTH_EV_RECV_ANS_SUCCESS:
+                    x->state = AUTH_ST_OPEN;
+                    update_auth_session_timers(x, msg);
+                    //LM_INFO("state machine: i was in pending and i am going to open\n");
+                    break;
+                case AUTH_EV_RECV_ANS_UNSUCCESS:
+                    x->state = AUTH_ST_DISCON;
+                    //LM_INFO("state machine: i was in pending and i am going to discon\n");
+                    Send_STR(s, msg);
+                    break;
+                case AUTH_EV_SESSION_TIMEOUT:
+                case AUTH_EV_SERVICE_TERMINATED:
+                case AUTH_EV_SESSION_GRACE_TIMEOUT:
+                    Session_Cleanup(s, NULL);
+                    break;
+
+                default:
+                    LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        case AUTH_ST_OPEN:
+            if (event == AUTH_EV_RECV_ANS && msg && !is_req(msg)) {
+                rc = get_result_code(msg);
+                if (rc >= 2000 && rc < 3000 && get_auth_session_state(msg) == STATE_MAINTAINED)
+                    event = AUTH_EV_RECV_ANS_SUCCESS;
+                else
+                    event = AUTH_EV_RECV_ANS_UNSUCCESS;
+            }
+
+            switch (event) {
+                case AUTH_EV_SEND_REQ:
+                    // if the request is STR i should move to Discon ..
+                    // this is not in the state machine but I (Alberto Diez) need it
+                    if (msg->commandCode == IMS_STR)
+                        s->u.auth.state = AUTH_ST_DISCON;
+                    else {
+                        s->u.auth.state = AUTH_ST_OPEN;
+                        add_auth_session_timers(x, msg);
+                    }
+                    break;
+
+                case AUTH_EV_RECV_ANS_SUCCESS:
+                    x->state = AUTH_ST_OPEN;
+                    update_auth_session_timers(x, msg);
+                    //LM_INFO("state machine: i was in open and i am going to open\n");
+                    break;
+
+                case AUTH_EV_RECV_ANS_UNSUCCESS:
+                    x->state = AUTH_ST_DISCON;
+                    //LM_INFO("state machine: i was in open and i am going to discon\n");
+                    break;
+
+                case AUTH_EV_SESSION_TIMEOUT:
+                case AUTH_EV_SERVICE_TERMINATED:
+                case AUTH_EV_SESSION_GRACE_TIMEOUT:
+                    x->state = AUTH_ST_DISCON;
+                    //LM_INFO("state machine: i was in open and i am going to discon\n");
+
+                    Send_STR(s, msg);
+                    break;
+
+                case AUTH_EV_SEND_ASA_SUCCESS:
+                    x->state = AUTH_ST_DISCON;
+                    //LM_INFO("state machine: i was in open and i am going to discon\n");
+                    Send_STR(s, msg);
+                    break;
+
+                case AUTH_EV_SEND_ASA_UNSUCCESS:
+                    x->state = AUTH_ST_OPEN;
+                    update_auth_session_timers(x, msg);
+                    //LM_INFO("state machine: i was in open and i am going to open\n");
+                    break;
+
+                case AUTH_EV_RECV_ASR:
+                    // two cases , client will comply or will not
+                    // our client is very nice and always complys.. because
+                    // our brain is in the PCRF... if he says to do this , we do it
+                    // Alberto Diez , (again this is not Diameter RFC)
+                    x->state = AUTH_ST_DISCON;
+                    Send_ASA(s, msg);
+                    Send_STR(s, msg);
+                    break;
+
+                default:
+                    LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        case AUTH_ST_DISCON:
+            switch (event) {
+                case AUTH_EV_RECV_ASR:
+                    x->state = AUTH_ST_DISCON;
+                    //LM_INFO("state machine: i was in discon and i am going to discon\n");
+                    Send_ASA(s, msg);
+                    break;
+
+                    // Just added this because it might happen if the other peer doesnt
+                    // send a valid STA, then the session stays open forever...
+                    // We dont accept that... we have lifetime+grace_period for that
+                    // This is not in the Diameter RFC ...
+                case AUTH_EV_SESSION_TIMEOUT:
+                case AUTH_EV_SESSION_GRACE_TIMEOUT:
+                    // thats the addition
+                case AUTH_EV_RECV_STA:
+                    x->state = AUTH_ST_IDLE;
+                    LM_INFO("state machine: AUTH_EV_RECV_STA about to clean up\n");
+                    if (msg) AAAFreeMessage(&msg); // if might be needed in frequency
+                    // If I register a ResponseHandler then i Free the STA there not here..
+                    // but i dont have interest in that now..
+                    Session_Cleanup(s, NULL);
+                    s = 0;
+                    rv = 1;
+                    break;
+
+                default:
+                    LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+        default:
+            LM_ERR("auth_client_statefull_sm_process(): Received event %d while in invalid state %d!\n",
+                    event, x->state);
+    }
+    if (s) {
+        if (s->cb) (s->cb)(AUTH_EV_SESSION_MODIFIED, s);
+        AAASessionsUnlock(s->hash);
+    }
+    return rv;
 }
 }
 
 
-
 /**
 /**
  * Authorization Server State-Machine - Statefull
  * Authorization Server State-Machine - Statefull
  * \Note - should be called with a lock on the session and will unlock it - do not use it after!
  * \Note - should be called with a lock on the session and will unlock it - do not use it after!
@@ -404,473 +409,473 @@ inline int auth_client_statefull_sm_process(cdp_session_t* s, int event, AAAMess
  * @param event
  * @param event
  * @param msg
  * @param msg
  */
  */
-inline void auth_server_statefull_sm_process(cdp_session_t* s, int event, AAAMessage* msg)
-{
-	cdp_auth_session_t *x;
-	
-	if (!s) return;
-	x = &(s->u.auth);
-	
-	if (s->cb) (s->cb)(event,s);			
-	LM_DBG("after callback for event %i\n", event);
-
-	switch(x->state){
-		case AUTH_ST_IDLE:
-			switch (event) {
-				case AUTH_EV_RECV_STR:
-					break;
-				case AUTH_EV_RECV_REQ:
-					// The RequestHandler will generate a Send event for the answer
-					// and we will only then now if the user is authorised or not
-					// if its not authorised it will move back to idle and cleanup the session 
-					// so no big deal
-					// but this is not the Diameter RFC...
-					x->state = AUTH_ST_OPEN;
-					// execute the cb here because we won't have a chance later
-					if (s->cb) (s->cb)(AUTH_EV_SESSION_MODIFIED,s);			
-					// Don't unlock the session hash table because the session is returned to the user
-					// This can only be called from the AAACreateServerAuthSession()!
-					s=0;
-					break;
-				case AUTH_EV_SEND_STA:
-					x->state = AUTH_ST_IDLE;
-					Session_Cleanup(s,msg);
-					s = 0;
-					break;
-					
-				/* Just in case we have some lost sessions */	
-				case AUTH_EV_SESSION_TIMEOUT:
-				case AUTH_EV_SESSION_GRACE_TIMEOUT:					
-					Session_Cleanup(s,msg);
-					s = 0;
-					break;
-					
-				default:
-					LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-		
-		case AUTH_ST_OPEN:
-		
-		
-			if (event == AUTH_EV_SEND_ANS && msg && !is_req(msg)){
-				int rc = get_result_code(msg);
-				if (rc>=2000 && rc<3000)
-					event = AUTH_EV_SEND_ANS_SUCCESS;
-				else
-					event = AUTH_EV_SEND_ANS_UNSUCCESS;
-			}
-		
-		
-			switch (event) {
-				case AUTH_EV_RECV_STR:
-					break;
-				case AUTH_EV_SEND_ANS_SUCCESS:
-					x->state = AUTH_ST_OPEN;
-					update_auth_session_timers(x,msg);
-					add_auth_session_timers(x,msg);
-					break;
-				case AUTH_EV_SEND_ANS_UNSUCCESS:
-					x->state = AUTH_ST_IDLE;
-					Session_Cleanup(s,msg);	
-					s = 0;
-					break;
-				case AUTH_EV_SEND_ASR:
-					x->state = AUTH_ST_DISCON;
-					break;
-				case AUTH_EV_SESSION_TIMEOUT:
-				case AUTH_EV_SESSION_GRACE_TIMEOUT:
-					x->state=AUTH_ST_IDLE;
-					LM_DBG("before session cleanup\n");
-					Session_Cleanup(s,msg);
-					s = 0;
-					break;
-				case AUTH_EV_SEND_STA:
-					LM_ERR("SENDING STA!!!\n");
-					x->state = AUTH_ST_IDLE;
-					Session_Cleanup(s,msg);
-					s = 0;
-					break;
-				default:
-					LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-		
-		case AUTH_ST_DISCON:
-			switch (event) {
-				case AUTH_EV_RECV_STR:
-					break;
-				case AUTH_EV_RECV_ASA:
-				case AUTH_EV_RECV_ASA_SUCCESS:
-					x->state=AUTH_ST_IDLE;
-					//Session_Cleanup(s,msg);
-					break;
-				case AUTH_EV_RECV_ASA_UNSUCCESS:
-					Send_ASR(s,msg);
-					// how many times will this be done?
-					x->state=AUTH_ST_DISCON;
-					break;
-				case AUTH_EV_SEND_STA:
-					x->state = AUTH_ST_IDLE;
-					Session_Cleanup(s,msg);
-					s = 0;
-					break;
-				default:
-					LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-
-		default:
-			LM_ERR("auth_client_statefull_sm_process(): Received event %d while in invalid state %d!\n",
-				event,x->state);
-	}	
-	if (s) {
-		if (s->cb) (s->cb)(AUTH_EV_SESSION_MODIFIED,s);			
-		AAASessionsUnlock(s->hash);
-	}
+inline void auth_server_statefull_sm_process(cdp_session_t* s, int event, AAAMessage* msg) {
+    cdp_auth_session_t *x;
+
+    if (!s) return;
+    x = &(s->u.auth);
+
+    if (s->cb) (s->cb)(event, s);
+    LM_DBG("after callback for event %i\n", event);
+
+    switch (x->state) {
+        case AUTH_ST_IDLE:
+            switch (event) {
+                case AUTH_EV_RECV_STR:
+                    break;
+                case AUTH_EV_RECV_REQ:
+                    // The RequestHandler will generate a Send event for the answer
+                    // and we will only then now if the user is authorised or not
+                    // if its not authorised it will move back to idle and cleanup the session
+                    // so no big deal
+                    // but this is not the Diameter RFC...
+                    x->state = AUTH_ST_OPEN;
+                    // execute the cb here because we won't have a chance later
+                    if (s->cb) (s->cb)(AUTH_EV_SESSION_MODIFIED, s);
+                    // Don't unlock the session hash table because the session is returned to the user
+                    // This can only be called from the AAACreateServerAuthSession()!
+                    s = 0;
+                    break;
+                case AUTH_EV_SEND_STA:
+                    x->state = AUTH_ST_IDLE;
+                    Session_Cleanup(s, msg);
+                    s = 0;
+                    break;
+
+                    /* Just in case we have some lost sessions */
+                case AUTH_EV_SESSION_TIMEOUT:
+                case AUTH_EV_SESSION_GRACE_TIMEOUT:
+                    Session_Cleanup(s, msg);
+                    s = 0;
+                    break;
+
+                default:
+                    LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        case AUTH_ST_OPEN:
+
+
+            if (event == AUTH_EV_SEND_ANS && msg && !is_req(msg)) {
+                int rc = get_result_code(msg);
+                if (rc >= 2000 && rc < 3000)
+                    event = AUTH_EV_SEND_ANS_SUCCESS;
+                else
+                    event = AUTH_EV_SEND_ANS_UNSUCCESS;
+            }
+
+
+            switch (event) {
+                case AUTH_EV_RECV_STR:
+                    break;
+                case AUTH_EV_SEND_ANS_SUCCESS:
+                    x->state = AUTH_ST_OPEN;
+                    update_auth_session_timers(x, msg);
+                    add_auth_session_timers(x, msg);
+                    break;
+                case AUTH_EV_SEND_ANS_UNSUCCESS:
+                    x->state = AUTH_ST_IDLE;
+                    Session_Cleanup(s, msg);
+                    s = 0;
+                    break;
+                case AUTH_EV_SEND_ASR:
+                    x->state = AUTH_ST_DISCON;
+                    break;
+                case AUTH_EV_SESSION_TIMEOUT:
+                case AUTH_EV_SESSION_GRACE_TIMEOUT:
+                    x->state = AUTH_ST_IDLE;
+                    LM_DBG("before session cleanup\n");
+                    Session_Cleanup(s, msg);
+                    s = 0;
+                    break;
+                case AUTH_EV_SEND_STA:
+                    LM_ERR("SENDING STA!!!\n");
+                    x->state = AUTH_ST_IDLE;
+                    Session_Cleanup(s, msg);
+                    s = 0;
+                    break;
+                default:
+                    LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        case AUTH_ST_DISCON:
+            switch (event) {
+                case AUTH_EV_RECV_STR:
+                    break;
+                case AUTH_EV_RECV_ASA:
+                case AUTH_EV_RECV_ASA_SUCCESS:
+                    x->state = AUTH_ST_IDLE;
+                    //Session_Cleanup(s,msg);
+                    break;
+                case AUTH_EV_RECV_ASA_UNSUCCESS:
+                    Send_ASR(s, msg);
+                    // how many times will this be done?
+                    x->state = AUTH_ST_DISCON;
+                    break;
+                case AUTH_EV_SEND_STA:
+                    x->state = AUTH_ST_IDLE;
+                    Session_Cleanup(s, msg);
+                    s = 0;
+                    break;
+                default:
+                    LM_ERR("auth_client_statefull_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        default:
+            LM_ERR("auth_client_statefull_sm_process(): Received event %d while in invalid state %d!\n",
+                    event, x->state);
+    }
+    if (s) {
+        if (s->cb) (s->cb)(AUTH_EV_SESSION_MODIFIED, s);
+        AAASessionsUnlock(s->hash);
+    }
 }
 }
 
 
-
-
-
-/** 
+/**
  * Authorization Client State-Machine - Stateless
  * Authorization Client State-Machine - Stateless
  * \Note - should be called with a lock on the session and will unlock it - do not use it after!
  * \Note - should be called with a lock on the session and will unlock it - do not use it after!
  * @param s
  * @param s
  * @param event
  * @param event
  * @param msg
  * @param msg
  */
  */
-inline void auth_client_stateless_sm_process(cdp_session_t* s, int event, AAAMessage *msg)
-{
-	cdp_auth_session_t *x;
-	int rc;
-	if (!s) return;
-	x = &(s->u.auth);
-	switch(x->state){
-		case AUTH_ST_IDLE:
-			switch(event){
-				case AUTH_EV_SEND_REQ:
-					x->state = AUTH_ST_PENDING;
-					break;
-				default:
-					LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-			
-		case AUTH_ST_PENDING:
-			if (!is_req(msg)){
-				rc = get_result_code(msg);
-				if (rc>=2000 && rc<3000 && get_auth_session_state(msg)==NO_STATE_MAINTAINED) 
-					event = AUTH_EV_RECV_ANS_SUCCESS;
-				else
-					event = AUTH_EV_RECV_ANS_UNSUCCESS;
-			}
-			switch(event){
-				case AUTH_EV_RECV_ANS_SUCCESS:
-					x->state = AUTH_ST_OPEN;
-					break;
-				case AUTH_EV_RECV_ANS_UNSUCCESS:
-					x->state = AUTH_ST_IDLE;
-					break;					
-				default:
-					LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-			
-		case AUTH_ST_OPEN:
-			switch(event){
-				case AUTH_EV_SESSION_TIMEOUT:
-					x->state = AUTH_ST_IDLE;
-					break;
-				case AUTH_EV_SERVICE_TERMINATED:
-					x->state = AUTH_ST_IDLE;
-					break;					
-				default:
-					LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_states[x->state]);				
-			}
-			break;
-			
-		default:
-			LM_ERR("auth_client_stateless_sm_process(): Received event %d while in invalid state %d!\n",
-				event,x->state);
-	}	
-	if (s) AAASessionsUnlock(s->hash);
+inline void auth_client_stateless_sm_process(cdp_session_t* s, int event, AAAMessage *msg) {
+    cdp_auth_session_t *x;
+    int rc;
+    if (!s) return;
+    x = &(s->u.auth);
+    switch (x->state) {
+        case AUTH_ST_IDLE:
+            switch (event) {
+                case AUTH_EV_SEND_REQ:
+                    x->state = AUTH_ST_PENDING;
+                    break;
+                default:
+                    LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        case AUTH_ST_PENDING:
+            if (!is_req(msg)) {
+                rc = get_result_code(msg);
+                if (rc >= 2000 && rc < 3000 && get_auth_session_state(msg) == NO_STATE_MAINTAINED)
+                    event = AUTH_EV_RECV_ANS_SUCCESS;
+                else
+                    event = AUTH_EV_RECV_ANS_UNSUCCESS;
+            }
+            switch (event) {
+                case AUTH_EV_RECV_ANS_SUCCESS:
+                    x->state = AUTH_ST_OPEN;
+                    break;
+                case AUTH_EV_RECV_ANS_UNSUCCESS:
+                    x->state = AUTH_ST_IDLE;
+                    break;
+                default:
+                    LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        case AUTH_ST_OPEN:
+            switch (event) {
+                case AUTH_EV_SESSION_TIMEOUT:
+                    x->state = AUTH_ST_IDLE;
+                    break;
+                case AUTH_EV_SERVICE_TERMINATED:
+                    x->state = AUTH_ST_IDLE;
+                    break;
+                default:
+                    LM_ERR("auth_client_stateless_sm_process(): Received invalid event %d while in state %s!\n",
+                            event, auth_states[x->state]);
+            }
+            break;
+
+        default:
+            LM_ERR("auth_client_stateless_sm_process(): Received event %d while in invalid state %d!\n",
+                    event, x->state);
+    }
+    if (s) AAASessionsUnlock(s->hash);
 }
 }
 
 
 /**
 /**
  * Authorization Server State-Machine - Stateless
  * Authorization Server State-Machine - Stateless
  * \Note - should be called with a lock on the session and will unlock it - do not use it after!
  * \Note - should be called with a lock on the session and will unlock it - do not use it after!
- * 
+ *
  * @param auth
  * @param auth
  * @param event
  * @param event
  * @param msg
  * @param msg
  */
  */
-inline void auth_server_stateless_sm_process(cdp_session_t* s, int event, AAAMessage* msg)
-{
-	/* empty - no state change, anyway */
-/*
-	cdp_auth_session_t *x;
-	int rc;
-	if (!s) return;
-	x = &(s->u.auth);
-	switch(x->state){
-		case AUTH_ST_IDLE:
-			switch(event){				
-				default:
-					LM_ERR("auth_server_stateless_sm_process(): Received invalid event %d while in state %s!\n",
-						event,auth_state[x->state]);				
-			}
-			break;
-		default:
-			LM_ERR("auth_server_stateless_sm_process(): Received event %d while in invalid state %d!\n",
-				event,x->state);
-	}
-*/
-	if (s) AAASessionsUnlock(s->hash);
+inline void auth_server_stateless_sm_process(cdp_session_t* s, int event, AAAMessage* msg) {
+    /* empty - no state change, anyway */
+    /*
+            cdp_auth_session_t *x;
+            int rc;
+            if (!s) return;
+            x = &(s->u.auth);
+            switch(x->state){
+                    case AUTH_ST_IDLE:
+                            switch(event){
+                                    default:
+                                            LM_ERR("auth_server_stateless_sm_process(): Received invalid event %d while in state %s!\n",
+                                                    event,auth_state[x->state]);
+                            }
+                            break;
+                    default:
+                            LM_ERR("auth_server_stateless_sm_process(): Received event %d while in invalid state %d!\n",
+                                    event,x->state);
+            }
+     */
+    if (s) AAASessionsUnlock(s->hash);
 }
 }
 
 
 /* copies the Origin-Host AVP from the src message in a Destination-Host AVP in the dest message
 /* copies the Origin-Host AVP from the src message in a Destination-Host AVP in the dest message
  * copies the Origin-Realm AVP from the src message in a Destination-Realm AVP in the dest message
  * copies the Origin-Realm AVP from the src message in a Destination-Realm AVP in the dest message
  *
  *
  */
  */
-int dup_routing_avps(AAAMessage* src, AAAMessage *dest){
-
-	AAA_AVP * avp;
-	str dest_realm;
-	/* Unused due to commented out code
-	str dest_host;
-	*/
-
-	if(!src)
-		return 1;
-
-	/* Removed By Jason to facilitate use of Diameter clustering (MUX) in SLEE architecture (Realm-routing only) - TODO - check spec */
-	/*avp = AAAFindMatchingAVP(src,src->avpList.head,AVP_Origin_Host,0,AAA_FORWARD_SEARCH);
-	if(avp && avp->data.s && avp->data.len) {
-		LM_DBG("dup_routing_avps: Origin Host AVP present, duplicating %.*s\n",
-				avp->data.len, avp->data.s);
-		dest_host = avp->data;
-		avp = AAACreateAVP(AVP_Destination_Host,AAA_AVP_FLAG_MANDATORY,0,
-			dest_host.s,dest_host.len,AVP_DUPLICATE_DATA);
-		if (!avp) {
-			LM_ERR("dup_routing_avps: Failed creating Destination Host avp\n");
-			goto error;
-		}
-		if (AAAAddAVPToMessage(dest,avp,dest->avpList.tail)!=AAA_ERR_SUCCESS) {
-			LM_ERR("dup_routing_avps: Failed adding Destination Host avp to message\n");
-			AAAFreeAVP(&avp);
-			goto error;
-		}
-	}*/
-
-	avp = AAAFindMatchingAVP(src,src->avpList.head,AVP_Origin_Realm,0,AAA_FORWARD_SEARCH);
-	if(avp && avp->data.s && avp->data.len) {
-		LM_DBG("dup_routing_avps: Origin Realm AVP present, duplicating %.*s\n",
-				avp->data.len, avp->data.s);
-		dest_realm = avp->data;
-		avp = AAACreateAVP(AVP_Destination_Realm,AAA_AVP_FLAG_MANDATORY,0,
-			dest_realm.s,dest_realm.len,AVP_DUPLICATE_DATA);
-		if (!avp) {
-			LM_ERR("dup_routing_avps: Failed creating Destination Host avp\n");
-			goto error;
-		}
-		if (AAAAddAVPToMessage(dest,avp,dest->avpList.tail)!=AAA_ERR_SUCCESS) {
-			LM_ERR("dup_routing_avps: Failed adding Destination Host avp to message\n");
-			AAAFreeAVP(&avp);
-			goto error;
-		}
-	}
-
-	return 1;
+int dup_routing_avps(AAAMessage* src, AAAMessage *dest) {
+
+    AAA_AVP * avp;
+    str dest_realm;
+
+    if (!src)
+        return 1;
+
+    /* Removed By Jason to facilitate use of Diameter clustering (MUX) in SLEE architecture (Realm-routing only) - TODO - check spec */
+    /*avp = AAAFindMatchingAVP(src,src->avpList.head,AVP_Origin_Host,0,AAA_FORWARD_SEARCH);
+    if(avp && avp->data.s && avp->data.len) {
+            LM_DBG("dup_routing_avps: Origin Host AVP present, duplicating %.*s\n",
+                            avp->data.len, avp->data.s);
+            dest_host = avp->data;
+            avp = AAACreateAVP(AVP_Destination_Host,AAA_AVP_FLAG_MANDATORY,0,
+                    dest_host.s,dest_host.len,AVP_DUPLICATE_DATA);
+            if (!avp) {
+                    LM_ERR("dup_routing_avps: Failed creating Destination Host avp\n");
+                    goto error;
+            }
+            if (AAAAddAVPToMessage(dest,avp,dest->avpList.tail)!=AAA_ERR_SUCCESS) {
+                    LM_ERR("dup_routing_avps: Failed adding Destination Host avp to message\n");
+                    AAAFreeAVP(&avp);
+                    goto error;
+            }
+    }*/
+
+    avp = AAAFindMatchingAVP(src, src->avpList.head, AVP_Origin_Realm, 0, AAA_FORWARD_SEARCH);
+    if (avp && avp->data.s && avp->data.len) {
+        LM_DBG("dup_routing_avps: Origin Realm AVP present, duplicating %.*s\n",
+                avp->data.len, avp->data.s);
+        dest_realm = avp->data;
+        avp = AAACreateAVP(AVP_Destination_Realm, AAA_AVP_FLAG_MANDATORY, 0,
+                dest_realm.s, dest_realm.len, AVP_DUPLICATE_DATA);
+        if (!avp) {
+            LM_ERR("dup_routing_avps: Failed creating Destination Host avp\n");
+            goto error;
+        }
+        if (AAAAddAVPToMessage(dest, avp, dest->avpList.tail) != AAA_ERR_SUCCESS) {
+            LM_ERR("dup_routing_avps: Failed adding Destination Host avp to message\n");
+            AAAFreeAVP(&avp);
+            goto error;
+        }
+    }
+
+    return 1;
 error:
 error:
-	return 0;
+    return 0;
 
 
 }
 }
 
 
-void Send_ASA(cdp_session_t* s, AAAMessage* msg)
-{
-	AAAMessage *asa;
-	char x[4];
-	AAA_AVP *avp;	
-	LM_INFO("Send_ASA():  sending ASA\n");
-	if (!s) {
-	//send an ASA for UNKNOWN_SESSION_ID - use AAASendMessage()
-	// msg is the ASR received
-		asa = AAANewMessage(IMS_ASA,0,0,msg);
-		if (!asa) return;	
-	
-		set_4bytes(x,AAA_SUCCESS);
-		AAACreateAndAddAVPToMessage(asa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);
-	
-		AAASendMessage(asa,0,0);
-	}else{
-		// send... many cases... maybe not needed.
-		// for now we do the same
-		asa = AAANewMessage(IMS_ASA,0,0,msg);
-		if (!asa) return;	
-	
-		set_4bytes(x,AAA_SUCCESS);
-		AAACreateAndAddAVPToMessage(asa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);
-				
-		avp = AAAFindMatchingAVP(msg,0,AVP_Origin_Host,0,0);	
-		if (avp) {
-				// This is because AAASendMessage is not going to find a route to the 
-				// the PCRF because TS 29.214 says no Destination-Host and no Auth-Application-Id
-				// in the ASA
-			LM_INFO("sending ASA to peer %.*s\n",avp->data.len,avp->data.s); 
-			peer *p;
-			p = get_peer_by_fqdn(&avp->data);
-			if (!peer_send_msg(p,asa)) {
-				if (asa) AAAFreeMessage(&asa);	//needed in frequency
-			} else  
-				LM_INFO("success sending ASA\n");
-		}else if (!AAASendMessage(asa,0,0)) {
-			LM_ERR("Send_ASA() : error sending ASA\n");
-		}	
-	}	
+void Send_ASA(cdp_session_t* s, AAAMessage* msg) {
+    AAAMessage *asa;
+    char x[4];
+    AAA_AVP *avp;
+    LM_INFO("Send_ASA():  sending ASA\n");
+    if (!s) {
+        //send an ASA for UNKNOWN_SESSION_ID - use AAASendMessage()
+        // msg is the ASR received
+        asa = AAANewMessage(IMS_ASA, 0, 0, msg);
+        if (!asa) return;
+
+        set_4bytes(x, AAA_SUCCESS);
+        AAACreateAndAddAVPToMessage(asa, AVP_Result_Code, AAA_AVP_FLAG_MANDATORY, 0, x, 4);
+
+        AAASendMessage(asa, 0, 0);
+    } else {
+        // send... many cases... maybe not needed.
+        // for now we do the same
+        asa = AAANewMessage(IMS_ASA, 0, 0, msg);
+        if (!asa) return;
+
+        set_4bytes(x, AAA_SUCCESS);
+        AAACreateAndAddAVPToMessage(asa, AVP_Result_Code, AAA_AVP_FLAG_MANDATORY, 0, x, 4);
+
+        avp = AAAFindMatchingAVP(msg, 0, AVP_Origin_Host, 0, 0);
+        if (avp) {
+            // This is because AAASendMessage is not going to find a route to the
+            // the PCRF because TS 29.214 says no Destination-Host and no Auth-Application-Id
+            // in the ASA
+            LM_INFO("sending ASA to peer %.*s\n", avp->data.len, avp->data.s);
+            peer *p;
+            p = get_peer_by_fqdn(&avp->data);
+            if (!peer_send_msg(p, asa)) {
+                if (asa) AAAFreeMessage(&asa); //needed in frequency
+            } else
+                LM_INFO("success sending ASA\n");
+        } else if (!AAASendMessage(asa, 0, 0)) {
+            LM_ERR("Send_ASA() : error sending ASA\n");
+        }
+    }
 }
 }
 
 
+int add_vendor_specific_application_id_group(AAAMessage * msg, unsigned int vendor_id, unsigned int auth_app_id) {
+    char x[4];
+    AAA_AVP_LIST list_grp = {0, 0};
+    AAA_AVP *avp;
+    str group = {0, 0};
+
+    set_4bytes(x, vendor_id);
+    if (!(avp = AAACreateAVP(AVP_Vendor_Id, AAA_AVP_FLAG_MANDATORY, 0,
+            x, 4, AVP_DUPLICATE_DATA))) goto error;
+    AAAAddAVPToList(&list_grp, avp);
+
+    set_4bytes(x, auth_app_id);
+    if (!(avp = AAACreateAVP(AVP_Auth_Application_Id, AAA_AVP_FLAG_MANDATORY, 0,
+            x, 4, AVP_DUPLICATE_DATA))) goto error;
+    AAAAddAVPToList(&list_grp, avp);
+
+    group = AAAGroupAVPS(list_grp);
+    if (!group.s || !group.len) goto error;
+
+    if (!(avp = AAACreateAVP(AVP_Vendor_Specific_Application_Id, AAA_AVP_FLAG_MANDATORY, 0,
+            group.s, group.len, AVP_DUPLICATE_DATA))) goto error;
+
+    if (AAAAddAVPToMessage(msg, avp, msg->avpList.tail) != AAA_ERR_SUCCESS) goto error;
+
+    AAAFreeAVPList(&list_grp);
+    shm_free(group.s);
+    group.s = NULL;
 
 
-int add_vendor_specific_application_id_group(AAAMessage * msg, unsigned int vendor_id, unsigned int auth_app_id)
-{
-	char x[4];
-	AAA_AVP_LIST list_grp={0,0};
-	AAA_AVP *avp;
-	str group = {0,0};
-
-	set_4bytes(x,vendor_id);
-	if(!(avp = AAACreateAVP(AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,
-					x,4, AVP_DUPLICATE_DATA))) goto error;
-	AAAAddAVPToList(&list_grp,avp);
-											
-	set_4bytes(x, auth_app_id);
-	if(!(avp = AAACreateAVP(AVP_Auth_Application_Id, AAA_AVP_FLAG_MANDATORY,0,
-					x,4,AVP_DUPLICATE_DATA))) goto error;
-	AAAAddAVPToList(&list_grp,avp);
-											
-	group = AAAGroupAVPS(list_grp);	
-	if(!group.s || !group.len) goto error;
-								
-	if(!(avp = AAACreateAVP(AVP_Vendor_Specific_Application_Id, AAA_AVP_FLAG_MANDATORY,0,
-					group.s, group.len,AVP_DUPLICATE_DATA))) goto error;
-
-	if(AAAAddAVPToMessage(msg, avp, msg->avpList.tail)!= AAA_ERR_SUCCESS) goto error;
-																	
-	AAAFreeAVPList(&list_grp);
-	shm_free(group.s); group.s = NULL;
-	
-	return 1;
+    return 1;
 
 
 error:
 error:
 
 
-	AAAFreeAVPList(&list_grp);
-	if(group.s) shm_free(group.s);
-	return 0;
+    AAAFreeAVPList(&list_grp);
+    if (group.s) shm_free(group.s);
+    return 0;
 }
 }
 
 
-void Send_STR(cdp_session_t* s, AAAMessage* msg)
-{
-	AAAMessage *str=0;
-	AAA_AVP *avp=0;
-	peer *p=0;
-	char x[4];
-	LM_DBG( "sending STR\n");
-	//if (msg) LM_DBG("Send_STR() : sending STR for %d, flags %#1x endtoend %u hopbyhop %u\n",msg->commandCode,msg->flags,msg->endtoendId,msg->hopbyhopId);
-	//else LM_DBG("Send_STR() called from AAATerminateAuthSession or some other event\n");
-	str = AAACreateRequest(s->application_id,IMS_STR,Flag_Proxyable,s);
-	
-	if (!str) {
-		LM_ERR("Send_STR(): error creating STR!\n");
-		return;
-	}
-	if(!dup_routing_avps(msg, str)){
-		LM_ERR("Send_STR(): error duplicating routing AVPs!\n");
-		AAAFreeMessage(&str);
-		return;
-	}
-	if(s->vendor_id!=0 && !add_vendor_specific_application_id_group(str,s->vendor_id,s->application_id)){ 
-		LM_ERR("Send_STR(): error adding Vendor-Id-Specific-Application-Id Group!\n");
-		AAAFreeMessage(&str);
-		return;
-	}
-	
-	set_4bytes(x,s->application_id);
-	avp = AAACreateAVP(AVP_Auth_Application_Id,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA);
-	AAAAddAVPToMessage(str,avp,str->avpList.tail);
-	
-	set_4bytes(x,4); // Diameter_administrative
-	avp = AAACreateAVP(AVP_Termination_Cause,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA);
-	AAAAddAVPToMessage(str,avp,str->avpList.tail);
-	//todo - add all the other avps
-
-	p = get_routing_peer(str);
-	if (!p) {
-		LM_ERR("unable to get routing peer in Send_STR \n");
-		if (str) AAAFreeMessage(&str); //needed in frequency
-		return;
-	}
-	//if (str) LM_CRIT("Send_STR() : sending STR  %d, flags %#1x endtoend %u hopbyhop %u\n",str->commandCode,str->flags,str->endtoendId,str->hopbyhopId);
-	if (!peer_send_msg(p,str))
-	{
-		LM_DBG("Send_STR peer_send_msg return error!\n");
-		if (str) AAAFreeMessage(&str); //needed in frequency	
-	} else { 
-		LM_DBG("success sending STR\n");
-	}
+void Send_STR(cdp_session_t* s, AAAMessage* msg) {
+    AAAMessage *str = 0;
+    AAA_AVP *avp = 0;
+    peer *p = 0;
+    char x[4];
+    LM_DBG("sending STR\n");
+    //if (msg) LM_DBG("Send_STR() : sending STR for %d, flags %#1x endtoend %u hopbyhop %u\n",msg->commandCode,msg->flags,msg->endtoendId,msg->hopbyhopId);
+    //else LM_DBG("Send_STR() called from AAATerminateAuthSession or some other event\n");
+    str = AAACreateRequest(s->application_id, IMS_STR, Flag_Proxyable, s);
+
+    if (!str) {
+        LM_ERR("Send_STR(): error creating STR!\n");
+        return;
+    }
+    if (!dup_routing_avps(msg, str)) {
+        LM_ERR("Send_STR(): error duplicating routing AVPs!\n");
+        AAAFreeMessage(&str);
+        return;
+    }
+    if (s->vendor_id != 0 && !add_vendor_specific_application_id_group(str, s->vendor_id, s->application_id)) {
+        LM_ERR("Send_STR(): error adding Vendor-Id-Specific-Application-Id Group!\n");
+        AAAFreeMessage(&str);
+        return;
+    }
+
+    //Richard added this - if timers expire dest realm is not here!
+    LM_DBG("Adding dest realm if not there already...\n");
+    LM_DBG("Destination realm: [%.*s] \n", s->dest_realm.len, s->dest_realm.s);
+    /* Add Destination-Realm AVP, if not already there */
+    avp = AAAFindMatchingAVP(str, str->avpList.head, AVP_Destination_Realm, 0, AAA_FORWARD_SEARCH);
+    if (!avp) {
+        avp = AAACreateAVP(AVP_Destination_Realm, AAA_AVP_FLAG_MANDATORY, 0,
+                s->dest_realm.s, s->dest_realm.len, AVP_DUPLICATE_DATA);
+        AAAAddAVPToMessage(str, avp, str->avpList.tail);
+    }
+
+
+
+
+    set_4bytes(x, s->application_id);
+    avp = AAACreateAVP(AVP_Auth_Application_Id, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA);
+    AAAAddAVPToMessage(str, avp, str->avpList.tail);
+
+    set_4bytes(x, 4); // Diameter_administrative
+    avp = AAACreateAVP(AVP_Termination_Cause, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA);
+    AAAAddAVPToMessage(str, avp, str->avpList.tail);
+    //todo - add all the other avps
+
+    p = get_routing_peer(str);
+
+    if (!p) {
+        LM_ERR("unable to get routing peer in Send_STR \n");
+        if (str) AAAFreeMessage(&str); //needed in frequency
+        return;
+    }
+    //if (str) LM_CRIT("Send_STR() : sending STR  %d, flags %#1x endtoend %u hopbyhop %u\n",str->commandCode,str->flags,str->endtoendId,str->hopbyhopId);
+    if (!peer_send_msg(p, str)) {
+        LM_DBG("Send_STR peer_send_msg return error!\n");
+        if (str) AAAFreeMessage(&str); //needed in frequency
+    } else {
+        LM_DBG("success sending STR\n");
+    }
 }
 }
 
 
-void Send_ASR(cdp_session_t* s, AAAMessage* msg)
-{
-	AAAMessage *asr=0;
-	AAA_AVP *avp=0;
-	peer *p=0;
-	char x[4];
-	LM_DBG("Send_ASR() : sending ASR\n");
-	asr = AAACreateRequest(s->application_id,IMS_ASR,Flag_Proxyable,s);
-	
-	if (!asr) {
-		LM_ERR("Send_ASR(): error creating ASR!\n");
-		return;
-	}
-	
-	set_4bytes(x,s->application_id);
-	avp = AAACreateAVP(AVP_Auth_Application_Id,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA);
-	AAAAddAVPToMessage(asr,avp,asr->avpList.tail);
-	
-	set_4bytes(x,3); // Not specified
-	avp = AAACreateAVP(AVP_IMS_Abort_Cause,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA);
-	AAAAddAVPToMessage(asr,avp,asr->avpList.tail);
-	//todo - add all the other avps
-	
-	p = get_routing_peer(asr);
-	if (!p) {
-		LM_ERR("unable to get routing peer in Send_ASR \n");
-		if (asr) AAAFreeMessage(&asr); //needed in frequency
-	}
-	
-	if (!peer_send_msg(p,asr)) {
-		if (asr) AAAFreeMessage(&asr); //needed in frequency	
-	} else  
-		LM_DBG("success sending ASR\n");
+void Send_ASR(cdp_session_t* s, AAAMessage* msg) {
+    AAAMessage *asr = 0;
+    AAA_AVP *avp = 0;
+    peer *p = 0;
+    char x[4];
+    LM_DBG("Send_ASR() : sending ASR\n");
+    asr = AAACreateRequest(s->application_id, IMS_ASR, Flag_Proxyable, s);
+
+    if (!asr) {
+        LM_ERR("Send_ASR(): error creating ASR!\n");
+        return;
+    }
+
+    set_4bytes(x, s->application_id);
+    avp = AAACreateAVP(AVP_Auth_Application_Id, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA);
+    AAAAddAVPToMessage(asr, avp, asr->avpList.tail);
+
+    set_4bytes(x, 3); // Not specified
+    avp = AAACreateAVP(AVP_IMS_Abort_Cause, AAA_AVP_FLAG_MANDATORY, 0, x, 4, AVP_DUPLICATE_DATA);
+    AAAAddAVPToMessage(asr, avp, asr->avpList.tail);
+    //todo - add all the other avps
+
+    p = get_routing_peer(asr);
+    if (!p) {
+        LM_ERR("unable to get routing peer in Send_ASR \n");
+        if (asr) AAAFreeMessage(&asr); //needed in frequency
+    }
+
+    if (!peer_send_msg(p, asr)) {
+        if (asr) AAAFreeMessage(&asr); //needed in frequency
+    } else
+        LM_DBG("success sending ASR\n");
 }
 }
 
 
-void Session_Cleanup(cdp_session_t* s, AAAMessage* msg)
-{
-	// Here we should drop the session ! and free everything related to it
-	// but the generic_data thing should be freed by the callback function registered
-	// when the auth session was created
-	AAASessionCallback_f *cb;
-	LM_INFO("cleaning up session %.*s\n",s->id.len,s->id.s);
-	if (s->cb) {
-		cb = s->cb;
-		(cb) (AUTH_EV_SERVICE_TERMINATED,s);
-	}
-	
-	AAADropAuthSession(s);
+void Session_Cleanup(cdp_session_t* s, AAAMessage* msg) {
+    // Here we should drop the session ! and free everything related to it
+    // but the generic_data thing should be freed by the callback function registered
+    // when the auth session was created
+    AAASessionCallback_f *cb;
+    LM_INFO("cleaning up session %.*s\n", s->id.len, s->id.s);
+    if (s->cb) {
+        cb = s->cb;
+        (cb) (AUTH_EV_SERVICE_TERMINATED, s);
+    }
+
+    AAADropAuthSession(s);
 }
 }

+ 6 - 1
modules/cdp/authstatemachine.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/cdp_load.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/cdp_load.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 57 - 52
modules/cdp/config.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -45,16 +50,16 @@
  */
  */
 inline dp_config *new_dp_config()
 inline dp_config *new_dp_config()
 {
 {
-	dp_config *x;	
+	dp_config *x;
 	x = shm_malloc(sizeof(dp_config));
 	x = shm_malloc(sizeof(dp_config));
 	if (!x) {
 	if (!x) {
 		LOG_NO_MEM("shm",sizeof(dp_config));
 		LOG_NO_MEM("shm",sizeof(dp_config));
 		goto error;
 		goto error;
-	}	
+	}
 	memset(x,0,sizeof(dp_config));
 	memset(x,0,sizeof(dp_config));
 	return x;
 	return x;
 error:
 error:
-	LM_ERR("%s(): failed to create new dp_config.\n",__FUNCTION__);	
+	LM_ERR("%s(): failed to create new dp_config.\n",__FUNCTION__);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -63,16 +68,16 @@ error:
  */
  */
 inline routing_realm *new_routing_realm()
 inline routing_realm *new_routing_realm()
 {
 {
-	routing_realm *x;	
+	routing_realm *x;
 	x = shm_malloc(sizeof(routing_realm));
 	x = shm_malloc(sizeof(routing_realm));
 	if (!x) {
 	if (!x) {
 		LOG_NO_MEM("shm",sizeof(routing_realm));
 		LOG_NO_MEM("shm",sizeof(routing_realm));
 		goto error;
 		goto error;
-	}	
+	}
 	memset(x,0,sizeof(routing_realm));
 	memset(x,0,sizeof(routing_realm));
 	return x;
 	return x;
 error:
 error:
-	LM_ERR("%s(): failed to create new routing_realm.\n",__FUNCTION__);	
+	LM_ERR("%s(): failed to create new routing_realm.\n",__FUNCTION__);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -81,21 +86,21 @@ error:
  */
  */
 inline routing_entry *new_routing_entry()
 inline routing_entry *new_routing_entry()
 {
 {
-	routing_entry *x;	
+	routing_entry *x;
 	x = shm_malloc(sizeof(routing_entry));
 	x = shm_malloc(sizeof(routing_entry));
 	if (!x) {
 	if (!x) {
 		LOG_NO_MEM("shm",sizeof(routing_entry));
 		LOG_NO_MEM("shm",sizeof(routing_entry));
 		goto error;
 		goto error;
-	}	
+	}
 	memset(x,0,sizeof(routing_entry));
 	memset(x,0,sizeof(routing_entry));
 	return x;
 	return x;
 error:
 error:
-	LM_ERR("%s(): failed to create new routing_entry.\n",__FUNCTION__);	
+	LM_ERR("%s(): failed to create new routing_entry.\n",__FUNCTION__);
 	return 0;
 	return 0;
 }
 }
 
 
 
 
-/** 
+/**
  * Free the space claimed by a routing entry
  * Free the space claimed by a routing entry
  */
  */
 inline void free_routing_entry(routing_entry *re)
 inline void free_routing_entry(routing_entry *re)
@@ -105,7 +110,7 @@ inline void free_routing_entry(routing_entry *re)
 	shm_free(re);
 	shm_free(re);
 }
 }
 
 
-/** 
+/**
  * Free the space claimed by a routing realm
  * Free the space claimed by a routing realm
  */
  */
 inline void free_routing_realm(routing_realm *rr)
 inline void free_routing_realm(routing_realm *rr)
@@ -144,13 +149,13 @@ inline void free_dp_config(dp_config *x)
 	if (x->acceptors) {
 	if (x->acceptors) {
 		for(i=0;i<x->acceptors_cnt;i++){
 		for(i=0;i<x->acceptors_cnt;i++){
 			if (x->acceptors[i].bind.s) shm_free(x->acceptors[i].bind.s);
 			if (x->acceptors[i].bind.s) shm_free(x->acceptors[i].bind.s);
-		}		
+		}
 		shm_free(x->acceptors);
 		shm_free(x->acceptors);
 	}
 	}
 	if (x->applications) shm_free(x->applications);
 	if (x->applications) shm_free(x->applications);
-	
+
 	if (x->supported_vendors) shm_free(x->supported_vendors);
 	if (x->supported_vendors) shm_free(x->supported_vendors);
-	
+
 	if (x->r_table) {
 	if (x->r_table) {
 		routing_realm *rr,*rrn;
 		routing_realm *rr,*rrn;
 		routing_entry *re,*ren;
 		routing_entry *re,*ren;
@@ -163,66 +168,66 @@ inline void free_dp_config(dp_config *x)
 			free_routing_entry(re);
 			free_routing_entry(re);
 		}
 		}
 		shm_free(x->r_table);
 		shm_free(x->r_table);
-	}	
+	}
 	shm_free(x);
 	shm_free(x);
 }
 }
 
 
 /**
 /**
  * Log the dp_config to output, for debug purposes.
  * Log the dp_config to output, for debug purposes.
- */	
-inline void log_dp_config(int level,dp_config *x)
+ */
+inline void log_dp_config(dp_config *x)
 {
 {
 	int i;
 	int i;
-	LOG(level,"Diameter Peer Config:\n");
-	LOG(level,"\tFQDN    : %.*s\n",x->fqdn.len,x->fqdn.s);
-	LOG(level,"\tRealm   : %.*s\n",x->realm.len,x->realm.s);
-	LOG(level,"\tVendorID: %d\n",x->vendor_id);
-	LOG(level,"\tProdName: %.*s\n",x->product_name.len,x->product_name.s);
-	LOG(level,"\tAcceptUn: [%c]\n",x->accept_unknown_peers?'X':' ');
-	LOG(level,"\tDropUnkn: [%c]\n",x->drop_unknown_peers?'X':' ');
-	LOG(level,"\tTc      : %d\n",x->tc);
-	LOG(level,"\tWorkers : %d\n",x->workers);
-	LOG(level,"\tQueueLen: %d\n",x->queue_length);
-	LOG(level,"\tConnTime: %d\n",x->connect_timeout);
-	LOG(level,"\tTranTime: %d\n",x->transaction_timeout);
-	LOG(level,"\tSessHash: %d\n",x->sessions_hash_size);
-	LOG(level,"\tDefAuthT: %d\n",x->default_auth_session_timeout);
-	LOG(level,"\tMaxAuthT: %d\n",x->max_auth_session_timeout);
-	LOG(level,"\tPeers   : %d\n",x->peers_cnt);
+	LM_DBG("Diameter Peer Config:\n");
+	LM_DBG("\tFQDN    : %.*s\n",x->fqdn.len,x->fqdn.s);
+	LM_DBG("\tRealm   : %.*s\n",x->realm.len,x->realm.s);
+	LM_DBG("\tVendorID: %d\n",x->vendor_id);
+	LM_DBG("\tProdName: %.*s\n",x->product_name.len,x->product_name.s);
+	LM_DBG("\tAcceptUn: [%c]\n",x->accept_unknown_peers?'X':' ');
+	LM_DBG("\tDropUnkn: [%c]\n",x->drop_unknown_peers?'X':' ');
+	LM_DBG("\tTc      : %d\n",x->tc);
+	LM_DBG("\tWorkers : %d\n",x->workers);
+	LM_DBG("\tQueueLen: %d\n",x->queue_length);
+	LM_DBG("\tConnTime: %d\n",x->connect_timeout);
+	LM_DBG("\tTranTime: %d\n",x->transaction_timeout);
+	LM_DBG("\tSessHash: %d\n",x->sessions_hash_size);
+	LM_DBG("\tDefAuthT: %d\n",x->default_auth_session_timeout);
+	LM_DBG("\tMaxAuthT: %d\n",x->max_auth_session_timeout);
+	LM_DBG("\tPeers   : %d\n",x->peers_cnt);
 	for(i=0;i<x->peers_cnt;i++)
 	for(i=0;i<x->peers_cnt;i++)
-		LOG(level,"\t\tFQDN:  %.*s \t Realm: %.*s \t Port: %d\n",
+		LM_DBG("\t\tFQDN:  %.*s \t Realm: %.*s \t Port: %d\n",
 			x->peers[i].fqdn.len,x->peers[i].fqdn.s,
 			x->peers[i].fqdn.len,x->peers[i].fqdn.s,
 			x->peers[i].realm.len,x->peers[i].realm.s,
 			x->peers[i].realm.len,x->peers[i].realm.s,
 			x->peers[i].port);
 			x->peers[i].port);
-	LOG(level,"\tAcceptors : %d\n",x->acceptors_cnt);
+	LM_DBG("\tAcceptors : %d\n",x->acceptors_cnt);
 	for(i=0;i<x->acceptors_cnt;i++)
 	for(i=0;i<x->acceptors_cnt;i++)
-		LOG(level,"\t\tPort:  %d \t Bind: %.*s \n",
+		LM_DBG("\t\tPort:  %d \t Bind: %.*s \n",
 			x->acceptors[i].port,
 			x->acceptors[i].port,
 			x->acceptors[i].bind.len,x->acceptors[i].bind.s);
 			x->acceptors[i].bind.len,x->acceptors[i].bind.s);
-	LOG(level,"\tApplications : %d\n",x->applications_cnt);
+	LM_DBG("\tApplications : %d\n",x->applications_cnt);
 	for(i=0;i<x->applications_cnt;i++)
 	for(i=0;i<x->applications_cnt;i++)
-		LOG(level,"\t\t%s ID:  %d \t Vendor: %d \n",
+		LM_DBG("\t\t%s ID:  %d \t Vendor: %d \n",
 			(x->applications[i].type==DP_AUTHORIZATION)?"Auth":"Acct",
 			(x->applications[i].type==DP_AUTHORIZATION)?"Auth":"Acct",
 			x->applications[i].id,
 			x->applications[i].id,
-			x->applications[i].vendor);	
-	LOG(level,"\tSupported Vendors : %d\n",x->supported_vendors_cnt);
+			x->applications[i].vendor);
+	LM_DBG("\tSupported Vendors : %d\n",x->supported_vendors_cnt);
 	for(i=0;i<x->supported_vendors_cnt;i++)
 	for(i=0;i<x->supported_vendors_cnt;i++)
-		LOG(level,"\t\t Vendor: %d \n",			
-			x->supported_vendors[i]);	
+		LM_DBG("\t\t Vendor: %d \n",
+			x->supported_vendors[i]);
 	if (x->r_table){
 	if (x->r_table){
 		routing_realm *rr;
 		routing_realm *rr;
 		routing_entry *re;
 		routing_entry *re;
-		LOG(level,"\tRouting Table : \n");
+		LM_DBG("\tRouting Table : \n");
 		for(rr=x->r_table->realms;rr;rr=rr->next){
 		for(rr=x->r_table->realms;rr;rr=rr->next){
-			LOG(level,"\t\tRealm: %.*s\n",
+			LM_DBG("\t\tRealm: %.*s\n",
 				rr->realm.len,rr->realm.s);
 				rr->realm.len,rr->realm.s);
-			for(re=rr->routes;re;re=re->next)		
-				LOG(level,"\t\t\tRoute: [%4d] %.*s\n",
-					re->metric,re->fqdn.len,re->fqdn.s);			
+			for(re=rr->routes;re;re=re->next)
+				LM_DBG("\t\t\tRoute: [%4d] %.*s\n",
+					re->metric,re->fqdn.len,re->fqdn.s);
 		}
 		}
-		for(re=x->r_table->routes;re;re=re->next)		
-			LOG(level,"\t\tDefaultRoute: [%4d] %.*s\n",
-				re->metric,re->fqdn.len,re->fqdn.s);			
+		for(re=x->r_table->routes;re;re=re->next)
+			LM_DBG("\t\tDefaultRoute: [%4d] %.*s\n",
+				re->metric,re->fqdn.len,re->fqdn.s);
 	}
 	}
-	
+
 }
 }

+ 7 - 2
modules/cdp/config.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -135,7 +140,7 @@ routing_entry *new_routing_entry();
 void free_dp_config(dp_config *x);
 void free_dp_config(dp_config *x);
 void free_routing_realm(routing_realm *rr);
 void free_routing_realm(routing_realm *rr);
 void free_routing_entry(routing_entry *re);
 void free_routing_entry(routing_entry *re);
-inline void log_dp_config(int level,dp_config *x);
+inline void log_dp_config(dp_config *x);
 
 
 xmlDocPtr parse_dp_config_file(char* filename);
 xmlDocPtr parse_dp_config_file(char* filename);
 xmlDocPtr parse_dp_config_str(str config_str);
 xmlDocPtr parse_dp_config_str(str config_str);

+ 6 - 1
modules/cdp/configdtd.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/configparser.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 7 - 2
modules/cdp/diameter.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -278,7 +283,7 @@ typedef struct _AAATransaction{
 
 
 
 
 /** Function for callback on transaction events: response or time-out for request. */
 /** Function for callback on transaction events: response or time-out for request. */
-typedef void (AAATransactionCallback_f)(int is_timeout,void *param,AAAMessage *ans);
+typedef void (AAATransactionCallback_f)(int is_timeout,void *param,AAAMessage *ans, long elapsed_msecs);
 /** Function for callback on request received */
 /** Function for callback on request received */
 typedef AAAMessage* (AAARequestHandler_f)(AAAMessage *req, void *param);
 typedef AAAMessage* (AAARequestHandler_f)(AAAMessage *req, void *param);
 /** Function for callback on response received */
 /** Function for callback on response received */

+ 6 - 1
modules/cdp/diameter_api.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_avp.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_code_avp.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_code_result.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 62 - 58
modules/cdp/diameter_comm.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -49,7 +54,7 @@
 #include "globals.h"
 #include "globals.h"
 
 
 extern dp_config *config;				/**< Configuration for this diameter peer 	*/
 extern dp_config *config;				/**< Configuration for this diameter peer 	*/
-extern unsigned int latency_threshold;	/**<max delay for Diameter call */
+extern unsigned int* latency_threshold_p;	/**<max delay for Diameter call */
 
 
 				/* CALLBACKS */
 				/* CALLBACKS */
 extern handler_list *handlers; 		/**< list of handlers */
 extern handler_list *handlers; 		/**< list of handlers */
@@ -119,10 +124,10 @@ int AAAAddResponseHandler(AAAResponseHandler_f *f,void *param)
  * @param peer_id - FQDN of the peer to send
  * @param peer_id - FQDN of the peer to send
  * @param callback_f - callback to be called on transactional response or transaction timeout
  * @param callback_f - callback to be called on transactional response or transaction timeout
  * @param callback_param - generic parameter to call the transactional callback function with
  * @param callback_param - generic parameter to call the transactional callback function with
- * @returns 1 on success, 0 on failure 
+ * @returns 1 on success, 0 on failure
  * \todo remove peer_id and add Realm routing
  * \todo remove peer_id and add Realm routing
  */
  */
-AAAReturnCode AAASendMessage(	
+AAAReturnCode AAASendMessage(
 		AAAMessage *message,
 		AAAMessage *message,
 		AAATransactionCallback_f *callback_f,
 		AAATransactionCallback_f *callback_f,
 		void *callback_param)
 		void *callback_param)
@@ -144,13 +149,13 @@ AAAReturnCode AAASendMessage(
 		else
 		else
 			LM_ERR("AAASendMessage(): can't add transaction callback for answer.\n");
 			LM_ERR("AAASendMessage(): can't add transaction callback for answer.\n");
 	}
 	}
-	
+
 //	if (!peer_send_msg(p,message))
 //	if (!peer_send_msg(p,message))
-	if (!sm_process(p,Send_Message,message,0,0))	
+	if (!sm_process(p,Send_Message,message,0,0))
 		goto error;
 		goto error;
-		
+
 	return 1;
 	return 1;
-error:	
+error:
 	AAAFreeMessage(&message);
 	AAAFreeMessage(&message);
 	return 0;
 	return 0;
 }
 }
@@ -162,12 +167,12 @@ error:
  * @param peer_id - FQDN of the peer to send
  * @param peer_id - FQDN of the peer to send
  * @param callback_f - callback to be called on transactional response or transaction timeout
  * @param callback_f - callback to be called on transactional response or transaction timeout
  * @param callback_param - generic parameter to call the transactional callback function with
  * @param callback_param - generic parameter to call the transactional callback function with
- * @returns 1 on success, 0 on failure 
+ * @returns 1 on success, 0 on failure
  * \todo remove peer_id and add Realm routing
  * \todo remove peer_id and add Realm routing
  */
  */
-AAAReturnCode AAASendMessageToPeer(	
+AAAReturnCode AAASendMessageToPeer(
 		AAAMessage *message,
 		AAAMessage *message,
-		str *peer_id, 
+		str *peer_id,
 		AAATransactionCallback_f *callback_f,
 		AAATransactionCallback_f *callback_f,
 		void *callback_param)
 		void *callback_param)
 {
 {
@@ -188,13 +193,13 @@ AAAReturnCode AAASendMessageToPeer(
 		else
 		else
 			LM_ERR("AAASendMessageToPeer(): can't add transaction callback for answer.\n");
 			LM_ERR("AAASendMessageToPeer(): can't add transaction callback for answer.\n");
 	}
 	}
-		
+
 //	if (!peer_send_msg(p,message))
 //	if (!peer_send_msg(p,message))
-	if (!sm_process(p,Send_Message,message,0,0))	
+	if (!sm_process(p,Send_Message,message,0,0))
 		goto error;
 		goto error;
-		
+
 	return 1;
 	return 1;
-error:	
+error:
 	AAAFreeMessage(&message);
 	AAAFreeMessage(&message);
 	return 0;
 	return 0;
 }
 }
@@ -203,15 +208,15 @@ error:
 /**
 /**
  * Generic callback used by AAASendRecvMessage() to block until a transactional response
  * Generic callback used by AAASendRecvMessage() to block until a transactional response
  * is received.
  * is received.
- * The AAASendRecvMessage() is basically a AAASendMessage() that has a callback 
- * (this function) that blocks until a transactional response or timeout is received and 
+ * The AAASendRecvMessage() is basically a AAASendMessage() that has a callback
+ * (this function) that blocks until a transactional response or timeout is received and
  * then it returns that.
  * then it returns that.
- *  
+ *
  * @param is_timeout - if this is a time-out or response event
  * @param is_timeout - if this is a time-out or response event
  * @param param - generic parameter to call the transactional callback function with
  * @param param - generic parameter to call the transactional callback function with
  * @param ans - the answer for the callback
  * @param ans - the answer for the callback
  */
  */
-void sendrecv_cb(int is_timeout,void *param,AAAMessage *ans)
+void sendrecv_cb(int is_timeout,void *param,AAAMessage *ans, long elapsed_msecs)
 {
 {
 	if (sem_release((gen_sem_t*)param)<0)
 	if (sem_release((gen_sem_t*)param)<0)
 		LM_ERR("sendrecv_cb(): Failed to unlock a transactional sendrecv! > %s\n",strerror(errno));
 		LM_ERR("sendrecv_cb(): Failed to unlock a transactional sendrecv! > %s\n",strerror(errno));
@@ -219,10 +224,10 @@ void sendrecv_cb(int is_timeout,void *param,AAAMessage *ans)
 
 
 /**
 /**
  * Send a AAAMessage synchronously.
  * Send a AAAMessage synchronously.
- * This blocks until a response is received or a transactional time-out happens. 
+ * This blocks until a response is received or a transactional time-out happens.
  * @param message - the request to be sent
  * @param message - the request to be sent
  * @param peer_id - FQDN of the peer to send
  * @param peer_id - FQDN of the peer to send
- * @returns 1 on success, 0 on failure 
+ * @returns 1 on success, 0 on failure
  * \todo remove peer_id and add Realm routing
  * \todo remove peer_id and add Realm routing
  * \todo replace the busy-waiting lock in here with one that does not consume CPU
  * \todo replace the busy-waiting lock in here with one that does not consume CPU
  */
  */
@@ -232,8 +237,11 @@ AAAMessage* AAASendRecvMessage(AAAMessage *message)
 	gen_sem_t *sem=0;
 	gen_sem_t *sem=0;
 	cdp_trans_t *t;
 	cdp_trans_t *t;
 	AAAMessage *ans;
 	AAAMessage *ans;
-	unsigned int ms = 0;
-	
+    struct timeval start, stop;
+    long elapsed_usecs=0, elapsed_millis=0;
+
+    gettimeofday(&start, NULL);
+
 	p = get_routing_peer(message);
 	p = get_routing_peer(message);
 	if (!p) {
 	if (!p) {
 		LM_ERR("AAASendRecvMessage(): Can't find a suitable connected peer in the routing table.\n");
 		LM_ERR("AAASendRecvMessage(): Can't find a suitable connected peer in the routing table.\n");
@@ -243,23 +251,16 @@ AAAMessage* AAASendRecvMessage(AAAMessage *message)
 		LM_ERR("AAASendRecvMessage(): Peer not connected to %.*s\n",p->fqdn.len,p->fqdn.s);
 		LM_ERR("AAASendRecvMessage(): Peer not connected to %.*s\n",p->fqdn.len,p->fqdn.s);
 		goto error;
 		goto error;
 	}
 	}
-	
-	
+
+
 	if (is_req(message)){
 	if (is_req(message)){
 		sem_new(sem,0);
 		sem_new(sem,0);
 		t = cdp_add_trans(message,sendrecv_cb,(void*)sem,config->transaction_timeout,0);
 		t = cdp_add_trans(message,sendrecv_cb,(void*)sem,config->transaction_timeout,0);
 
 
-		ms = TICKS_TO_MS(get_ticks_raw());
-//		if (!peer_send_msg(p,message)) {
-		if (!sm_process(p,Send_Message,message,0,0)){	
-			sem_free(sem);	
+		if (!sm_process(p,Send_Message,message,0,0)){
+			sem_free(sem);
 			goto error;
 			goto error;
 		}
 		}
-		ms = TICKS_TO_MS(get_ticks_raw()) - ms;
-		if (ms > latency_threshold)
-			LM_ERR("took too long to transition state machine for Send_Message [%dms]\n", ms);
-
-		ms = TICKS_TO_MS(get_ticks_raw());
 
 
 		/* block until callback is executed */
 		/* block until callback is executed */
 		while(sem_get(sem)<0){
 		while(sem_get(sem)<0){
@@ -267,9 +268,11 @@ AAAMessage* AAASendRecvMessage(AAAMessage *message)
 			LM_WARN("AAASendRecvMessage(): interrupted by signal or something > %s\n",strerror(errno));
 			LM_WARN("AAASendRecvMessage(): interrupted by signal or something > %s\n",strerror(errno));
 		}
 		}
 		sem_free(sem);
 		sem_free(sem);
-		ms = TICKS_TO_MS(get_ticks_raw()) - ms;
-		if (ms > latency_threshold) {
-			LM_ERR("CDP response to Send_Message took too long (>%dms) - [%dms]\n", latency_threshold, ms);
+		gettimeofday(&stop, NULL);
+        elapsed_usecs = (stop.tv_sec - start.tv_sec)*1000000 + (stop.tv_usec - start.tv_usec);
+        elapsed_millis = elapsed_usecs/1000;
+		if (elapsed_millis > *latency_threshold_p) {
+			LM_ERR("CDP response to Send_Message took too long (>%dms) - [%ldms]\n", *latency_threshold_p, elapsed_millis);
 		}
 		}
 		ans = t->ans;
 		ans = t->ans;
 		cdp_free_trans(t);
 		cdp_free_trans(t);
@@ -279,8 +282,8 @@ AAAMessage* AAASendRecvMessage(AAAMessage *message)
 		goto error;
 		goto error;
 	}
 	}
 
 
-		
-error:	
+
+error:
 out_of_memory:
 out_of_memory:
 	AAAFreeMessage(&message);
 	AAAFreeMessage(&message);
 	return 0;
 	return 0;
@@ -288,10 +291,10 @@ out_of_memory:
 
 
 /**
 /**
  * Send a AAAMessage synchronously.
  * Send a AAAMessage synchronously.
- * This blocks until a response is received or a transactional time-out happens. 
+ * This blocks until a response is received or a transactional time-out happens.
  * @param message - the request to be sent
  * @param message - the request to be sent
  * @param peer_id - FQDN of the peer to send
  * @param peer_id - FQDN of the peer to send
- * @returns 1 on success, 0 on failure 
+ * @returns 1 on success, 0 on failure
  * \todo remove peer_id and add Realm routing
  * \todo remove peer_id and add Realm routing
  * \todo replace the busy-waiting lock in here with one that does not consume CPU
  * \todo replace the busy-waiting lock in here with one that does not consume CPU
  */
  */
@@ -301,8 +304,11 @@ AAAMessage* AAASendRecvMessageToPeer(AAAMessage *message, str *peer_id)
 	gen_sem_t *sem;
 	gen_sem_t *sem;
 	cdp_trans_t *t;
 	cdp_trans_t *t;
 	AAAMessage *ans;
 	AAAMessage *ans;
-	int ms = 0;
-	
+	struct timeval start, stop;
+    long elapsed_usecs=0, elapsed_millis=0;
+
+    gettimeofday(&start, NULL);
+
 	p = get_peer_by_fqdn(peer_id);
 	p = get_peer_by_fqdn(peer_id);
 	if (!p) {
 	if (!p) {
 		LM_ERR("AAASendRecvMessageToPeer(): Peer unknown %.*s\n",peer_id->len,peer_id->s);
 		LM_ERR("AAASendRecvMessageToPeer(): Peer unknown %.*s\n",peer_id->len,peer_id->s);
@@ -312,33 +318,31 @@ AAAMessage* AAASendRecvMessageToPeer(AAAMessage *message, str *peer_id)
 		LM_ERR("AAASendRecvMessageToPeer(): Peer not connected to %.*s\n",peer_id->len,peer_id->s);
 		LM_ERR("AAASendRecvMessageToPeer(): Peer not connected to %.*s\n",peer_id->len,peer_id->s);
 		goto error;
 		goto error;
 	}
 	}
-	
+
 	if (is_req(message)){
 	if (is_req(message)){
 		sem_new(sem,0);
 		sem_new(sem,0);
 		t = cdp_add_trans(message,sendrecv_cb,(void*)sem,config->transaction_timeout,0);
 		t = cdp_add_trans(message,sendrecv_cb,(void*)sem,config->transaction_timeout,0);
 
 
-		ms = TICKS_TO_MS(get_ticks_raw());
 //		if (!peer_send_msg(p,message)) {
 //		if (!peer_send_msg(p,message)) {
-		if (!sm_process(p,Send_Message,message,0,0)){	
-			sem_free(sem);				
+		if (!sm_process(p,Send_Message,message,0,0)){
+			sem_free(sem);
 			goto error;
 			goto error;
 		}
 		}
-		ms = TICKS_TO_MS(get_ticks_raw()) - ms;
-		if (ms > latency_threshold)
-					LM_ERR("took too long to transition state machine for Send_Message [%dms]\n", ms);
-
-		ms = TICKS_TO_MS(get_ticks_raw());
 		/* block until callback is executed */
 		/* block until callback is executed */
 		while(sem_get(sem)<0){
 		while(sem_get(sem)<0){
 			if (shutdownx&&(*shutdownx)) goto error;
 			if (shutdownx&&(*shutdownx)) goto error;
 			LM_WARN("AAASendRecvMessageToPeer(): interrupted by signal or something > %s\n",strerror(errno));
 			LM_WARN("AAASendRecvMessageToPeer(): interrupted by signal or something > %s\n",strerror(errno));
 		}
 		}
-		sem_free(sem);
 
 
-		ms = TICKS_TO_MS(get_ticks_raw()) - ms;
-		if (ms > latency_threshold) {
-			LM_ERR("CDP response to Send_Message took too long (>%dms) - [%dms]\n", latency_threshold, ms);
+		gettimeofday(&stop, NULL);
+		elapsed_usecs = (stop.tv_sec - start.tv_sec) * 1000000
+				+ (stop.tv_usec - start.tv_usec);
+		elapsed_millis = elapsed_usecs / 1000;
+		if (elapsed_millis > *latency_threshold_p) {
+			LM_ERR("CDP response to Send_Message took too long (>%dms) - [%ldms]\n", *latency_threshold_p, elapsed_millis);
 		}
 		}
+		sem_free(sem);
+
 		ans = t->ans;
 		ans = t->ans;
 		cdp_free_trans(t);
 		cdp_free_trans(t);
 		return ans;
 		return ans;
@@ -347,8 +351,8 @@ AAAMessage* AAASendRecvMessageToPeer(AAAMessage *message, str *peer_id)
 		goto error;
 		goto error;
 	}
 	}
 
 
-		
-error:	
+
+error:
 out_of_memory:
 out_of_memory:
 	AAAFreeMessage(&message);
 	AAAFreeMessage(&message);
 	return 0;
 	return 0;

+ 6 - 1
modules/cdp/diameter_epc.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_epc_code_app.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_epc_code_avp.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 2
modules/cdp/diameter_epc_code_cmd.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -37,7 +42,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
  */
  */
-
 #ifndef DIAMETER_EPC_CODE_CMD_H_
 #ifndef DIAMETER_EPC_CODE_CMD_H_
 #define DIAMETER_EPC_CODE_CMD_H_
 #define DIAMETER_EPC_CODE_CMD_H_
 /*	Command Codes used in the EPC 	*/
 /*	Command Codes used in the EPC 	*/

+ 6 - 1
modules/cdp/diameter_epc_code_result.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_ims.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_ims_code_app.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_ims_code_avp.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_ims_code_cmd.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_ims_code_result.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/diameter_msg.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 56 - 52
modules/cdp/diameter_peer.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -39,7 +44,7 @@
  */
  */
 
 
 #include <stdlib.h>
 #include <stdlib.h>
-#include <sys/wait.h> 
+#include <sys/wait.h>
 #include <signal.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdio.h>
 
 
@@ -115,10 +120,10 @@ inline int dp_last_pid()
 
 
 /**
 /**
  * Delete a pid from the process list
  * Delete a pid from the process list
- * @param pid - the pid to remove 
+ * @param pid - the pid to remove
  */
  */
 inline void dp_del_pid(pid_t pid)
 inline void dp_del_pid(pid_t pid)
-{	
+{
 	pid_list_t *i;
 	pid_list_t *i;
 	lock_get(pid_list_lock);
 	lock_get(pid_list_lock);
 	i = pid_list->head;
 	i = pid_list->head;
@@ -142,29 +147,29 @@ inline void dp_del_pid(pid_t pid)
  * Real initialization, called after the config is parsed
  * Real initialization, called after the config is parsed
  */
  */
 int diameter_peer_init_real()
 int diameter_peer_init_real()
-{	
+{
 	pid_list_t *i,*j;
 	pid_list_t *i,*j;
 
 
 	if (!config) {
 	if (!config) {
 		LM_ERR("diameter_peer_init_real(): Configuration was not parsed yet. Aborting...\n");
 		LM_ERR("diameter_peer_init_real(): Configuration was not parsed yet. Aborting...\n");
 		goto error;
 		goto error;
 	}
 	}
-	log_dp_config(L_INFO,config);
-	
+	log_dp_config(config);
+
 	dp_first_pid = shm_malloc(sizeof(pid_t));
 	dp_first_pid = shm_malloc(sizeof(pid_t));
 	if (!dp_first_pid){
 	if (!dp_first_pid){
 		LOG_NO_MEM("shm",sizeof(pid_t));
 		LOG_NO_MEM("shm",sizeof(pid_t));
 		goto error;
 		goto error;
 	}
 	}
 	*dp_first_pid = getpid();
 	*dp_first_pid = getpid();
-	
+
 	shutdownx = shm_malloc(sizeof(int));
 	shutdownx = shm_malloc(sizeof(int));
 	if (!shutdownx){
 	if (!shutdownx){
 		LOG_NO_MEM("shm",sizeof(int));
 		LOG_NO_MEM("shm",sizeof(int));
 		goto error;
 		goto error;
 	}
 	}
 	*shutdownx = 0;
 	*shutdownx = 0;
-	
+
 	shutdownx_lock = lock_alloc();
 	shutdownx_lock = lock_alloc();
 	if (!shutdownx_lock){
 	if (!shutdownx_lock){
 		LOG_NO_MEM("shm",sizeof(gen_lock_t));
 		LOG_NO_MEM("shm",sizeof(gen_lock_t));
@@ -203,19 +208,19 @@ int diameter_peer_init_real()
 
 
 	/* init the peer manager */
 	/* init the peer manager */
 	peer_manager_init(config);
 	peer_manager_init(config);
-	
+
 	/* init diameter transactions */
 	/* init diameter transactions */
 	cdp_trans_init();
 	cdp_trans_init();
-	
+
 	/* init the session */
 	/* init the session */
 	if (!cdp_sessions_init(config->sessions_hash_size)) goto error;
 	if (!cdp_sessions_init(config->sessions_hash_size)) goto error;
-	
-	
+
+
 	/* add callback for messages - used to implement the API */
 	/* add callback for messages - used to implement the API */
 	cb_add(api_callback,0);
 	cb_add(api_callback,0);
-	
+
 	return 1;
 	return 1;
-	
+
 error:
 error:
 	if (shutdownx) shm_free(shutdownx);
 	if (shutdownx) shm_free(shutdownx);
 	if (config) free_dp_config(config);
 	if (config) free_dp_config(config);
@@ -229,7 +234,7 @@ error:
 	lock_get(pid_list_lock);
 	lock_get(pid_list_lock);
 	lock_destroy(pid_list_lock);
 	lock_destroy(pid_list_lock);
 	lock_dealloc((void*)pid_list_lock);
 	lock_dealloc((void*)pid_list_lock);
-	return 0;	
+	return 0;
 
 
 }
 }
 
 
@@ -241,14 +246,14 @@ error:
  * @returns 1 on success, 0 on error
  * @returns 1 on success, 0 on error
  */
  */
 int diameter_peer_init(char *cfg_filename)
 int diameter_peer_init(char *cfg_filename)
-{	
+{
 	xmlDocPtr doc = parse_dp_config_file(cfg_filename);
 	xmlDocPtr doc = parse_dp_config_file(cfg_filename);
 	config = parse_dp_config(doc);
 	config = parse_dp_config(doc);
 	if (!config) {
 	if (!config) {
 		LM_ERR("init_diameter_peer(): Error loading configuration file. Aborting...\n");
 		LM_ERR("init_diameter_peer(): Error loading configuration file. Aborting...\n");
 		goto error;
 		goto error;
 	}
 	}
-	
+
 	return diameter_peer_init_real();
 	return diameter_peer_init_real();
 error:
 error:
 	return 0;
 	return 0;
@@ -261,14 +266,14 @@ error:
  * @returns 1 on success, 0 on error
  * @returns 1 on success, 0 on error
  */
  */
 int diameter_peer_init_str(str config_str)
 int diameter_peer_init_str(str config_str)
-{	
+{
 	xmlDocPtr doc = parse_dp_config_str(config_str);
 	xmlDocPtr doc = parse_dp_config_str(config_str);
 	config = parse_dp_config(doc);
 	config = parse_dp_config(doc);
 	if (!config) {
 	if (!config) {
 		LM_ERR("init_diameter_peer(): Error loading configuration file. Aborting...\n");
 		LM_ERR("init_diameter_peer(): Error loading configuration file. Aborting...\n");
 		goto error;
 		goto error;
 	}
 	}
-	
+
 	return diameter_peer_init_real();
 	return diameter_peer_init_real();
 error:
 error:
 	return 0;
 	return 0;
@@ -279,10 +284,10 @@ error:
 /**
 /**
  * Start the CDiameterPeer operations.
  * Start the CDiameterPeer operations.
  * It forks all the processes required.
  * It forks all the processes required.
- * @param blocking - if this is set, use the calling processes for the timer and never 
+ * @param blocking - if this is set, use the calling processes for the timer and never
  * return; else fork a new one for the timer and return
  * return; else fork a new one for the timer and return
  * @returns 1 on success, 0 on error, never if blocking
  * @returns 1 on success, 0 on error, never if blocking
- */ 
+ */
 int diameter_peer_start(int blocking)
 int diameter_peer_start(int blocking)
 {
 {
 	int pid;
 	int pid;
@@ -301,20 +306,20 @@ int diameter_peer_start(int blocking)
 			snprintf(pt[process_no].desc, MAX_PT_DESC,"cdp worker child=%d", k );
 			snprintf(pt[process_no].desc, MAX_PT_DESC,"cdp worker child=%d", k );
 			worker_process(k);
 			worker_process(k);
 			LM_CRIT("init_diameter_peer(): worker_process finished without exit!\n");
 			LM_CRIT("init_diameter_peer(): worker_process finished without exit!\n");
-			exit(-1);		
+			exit(-1);
 		}else{
 		}else{
 			dp_add_pid(pid);
 			dp_add_pid(pid);
 		}
 		}
 	}
 	}
 
 
 	/* init the fd_exchange pipes */
 	/* init the fd_exchange pipes */
-	receiver_init(NULL);	
+	receiver_init(NULL);
 	for(p = peer_list->head,k=0;p;p=p->next,k++)
 	for(p = peer_list->head,k=0;p;p=p->next,k++)
 		receiver_init(p);
 		receiver_init(p);
-	
-	
+
+
 	/* fork receiver for unknown peers */
 	/* fork receiver for unknown peers */
-	
+
 	pid = fork_process(1001+k,"cdp_receiver_peer_unkown",1);
 	pid = fork_process(1001+k,"cdp_receiver_peer_unkown",1);
 
 
 	if (pid==-1){
 	if (pid==-1){
@@ -327,11 +332,11 @@ int diameter_peer_start(int blocking)
 				"cdp receiver peer unknown");
 				"cdp receiver peer unknown");
 		receiver_process(NULL);
 		receiver_process(NULL);
 		LM_CRIT("init_diameter_peer(): receiver_process finished without exit!\n");
 		LM_CRIT("init_diameter_peer(): receiver_process finished without exit!\n");
-		exit(-1);		
+		exit(-1);
 	}else{
 	}else{
 		dp_add_pid(pid);
 		dp_add_pid(pid);
 	}
 	}
-	
+
 	/* fork receivers for each pre-configured peers */
 	/* fork receivers for each pre-configured peers */
 	lock_get(peer_list_lock);
 	lock_get(peer_list_lock);
 	for(p = peer_list->head,k=-1;p;p = p->next,k--){
 	for(p = peer_list->head,k=-1;p;p = p->next,k--){
@@ -346,13 +351,13 @@ int diameter_peer_start(int blocking)
 					"cdp_receiver_peer=%.*s", p->fqdn.len,p->fqdn.s );
 					"cdp_receiver_peer=%.*s", p->fqdn.len,p->fqdn.s );
 			receiver_process(p);
 			receiver_process(p);
 			LM_CRIT("init_diameter_peer(): receiver_process finished without exit!\n");
 			LM_CRIT("init_diameter_peer(): receiver_process finished without exit!\n");
-			exit(-1);		
+			exit(-1);
 		}else{
 		}else{
 			dp_add_pid(pid);
 			dp_add_pid(pid);
 		}
 		}
 	}
 	}
 	lock_release(peer_list_lock);
 	lock_release(peer_list_lock);
-	
+
 
 
 	/* Fork the acceptor process (after receivers, so it inherits all the right sockets) */
 	/* Fork the acceptor process (after receivers, so it inherits all the right sockets) */
 	pid = fork_process(1000,"cdp_acceptor",1);
 	pid = fork_process(1000,"cdp_acceptor",1);
@@ -364,17 +369,17 @@ int diameter_peer_start(int blocking)
 	if (pid==0) {
 	if (pid==0) {
 		acceptor_process(config);
 		acceptor_process(config);
 		LM_CRIT("init_diameter_peer(): acceptor_process finished without exit!\n");
 		LM_CRIT("init_diameter_peer(): acceptor_process finished without exit!\n");
-		exit(-1);		
+		exit(-1);
 	}else{
 	}else{
 		dp_add_pid(pid);
 		dp_add_pid(pid);
 	}
 	}
-		
+
 	/* fork/become timer */
 	/* fork/become timer */
 	if (blocking) {
 	if (blocking) {
 		dp_add_pid(getpid());
 		dp_add_pid(getpid());
 		timer_process(1);
 		timer_process(1);
-	}		
-	else{		
+	}
+	else{
 		pid = fork_process(1001,"cdp_timer",1);
 		pid = fork_process(1001,"cdp_timer",1);
 		if (pid==-1){
 		if (pid==-1){
 			LM_CRIT("init_diameter_peer(): Error on fork() for timer!\n");
 			LM_CRIT("init_diameter_peer(): Error on fork() for timer!\n");
@@ -383,13 +388,12 @@ int diameter_peer_start(int blocking)
 		if (pid==0) {
 		if (pid==0) {
 			timer_process(0);
 			timer_process(0);
 			LM_CRIT("init_diameter_peer(): timer_process finished without exit!\n");
 			LM_CRIT("init_diameter_peer(): timer_process finished without exit!\n");
-			exit(-1);		
-		}else{			
+			exit(-1);
+		}else{
 			dp_add_pid(pid);
 			dp_add_pid(pid);
 		}
 		}
 	}
 	}
-	
-	
+
 	return 1;
 	return 1;
 }
 }
 
 
@@ -401,11 +405,11 @@ void diameter_peer_destroy()
 {
 {
 	int pid,status;
 	int pid,status;
 	handler *h;
 	handler *h;
-	
+
 	lock_get(shutdownx_lock);
 	lock_get(shutdownx_lock);
 	if (*shutdownx) {
 	if (*shutdownx) {
 		/* already other process is cleaning stuff */
 		/* already other process is cleaning stuff */
-		lock_release(shutdownx_lock);			
+		lock_release(shutdownx_lock);
 		return;
 		return;
 	}else {
 	}else {
 		/* indicating that we are shuting down */
 		/* indicating that we are shuting down */
@@ -427,41 +431,41 @@ void diameter_peer_destroy()
 			continue;
 			continue;
 		}
 		}
 		if (!WIFEXITED(status) /*|| WIFSIGNALED(status)*/){
 		if (!WIFEXITED(status) /*|| WIFSIGNALED(status)*/){
-			sleep(1);			
+			sleep(1);
 		} else {
 		} else {
 			dp_del_pid(pid);
 			dp_del_pid(pid);
 		}
 		}
 
 
 	}
 	}
 	LM_INFO("destroy_diameter_peer(): All processes terminated. Cleaning up.\n");
 	LM_INFO("destroy_diameter_peer(): All processes terminated. Cleaning up.\n");
-	
+
 	/* clean upt the timer */
 	/* clean upt the timer */
 	timer_cdp_destroy();
 	timer_cdp_destroy();
-	
+
 	/* cleaning up workers */
 	/* cleaning up workers */
 	worker_destroy();
 	worker_destroy();
-	
+
 	/* cleaning peer_manager */
 	/* cleaning peer_manager */
 	peer_manager_destroy();
 	peer_manager_destroy();
-	
+
 	/* cleaning up sessions */
 	/* cleaning up sessions */
 	cdp_sessions_destroy();
 	cdp_sessions_destroy();
 
 
 	/* cleaning up transactions */
 	/* cleaning up transactions */
 	cdp_trans_destroy();
 	cdp_trans_destroy();
-	
+
 	/* cleaning up global vars */
 	/* cleaning up global vars */
 /*	lock_get(pid_list_lock);*/
 /*	lock_get(pid_list_lock);*/
 	shm_free(dp_first_pid);
 	shm_free(dp_first_pid);
 	shm_free(pid_list);
 	shm_free(pid_list);
 	lock_destroy(pid_list_lock);
 	lock_destroy(pid_list_lock);
 	lock_dealloc((void*)pid_list_lock);
 	lock_dealloc((void*)pid_list_lock);
-	
+
 	shm_free(shutdownx);
 	shm_free(shutdownx);
-	
+
 	lock_destroy(shutdownx_lock);
 	lock_destroy(shutdownx_lock);
 	lock_dealloc((void*)shutdownx_lock);
 	lock_dealloc((void*)shutdownx_lock);
-	
+
 	lock_get(handlers_lock);
 	lock_get(handlers_lock);
 	while(handlers->head){
 	while(handlers->head){
 		h = handlers->head->next;
 		h = handlers->head->next;
@@ -471,8 +475,8 @@ void diameter_peer_destroy()
 	lock_destroy(handlers_lock);
 	lock_destroy(handlers_lock);
 	lock_dealloc((void*)handlers_lock);
 	lock_dealloc((void*)handlers_lock);
 	shm_free(handlers);
 	shm_free(handlers);
-		
-	free_dp_config(config);	
+
+	free_dp_config(config);
 	LM_CRIT("destroy_diameter_peer(): Bye Bye from C Diameter Peer test\n");
 	LM_CRIT("destroy_diameter_peer(): Bye Bye from C Diameter Peer test\n");
 
 
 }
 }

+ 6 - 1
modules/cdp/diameter_peer.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 34 - 29
modules/cdp/globals.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -46,34 +51,34 @@
 //str aaa_identity={"unset_identity",14};
 //str aaa_identity={"unset_identity",14};
 
 
 /** initialized the pkg and shm memory */
 /** initialized the pkg and shm memory */
-int init_memory(int show_status)
-{
-#ifdef PKG_MALLOC
-	if (init_pkg_mallocs()==-1)
-		goto error;
-	if (show_status){
-		LM_DBG( "Memory status (pkg):\n");
-		pkg_status();
-	}
-#endif
-
-#ifdef SHM_MEM
-	
-	if (init_shm_mallocs(
-#ifdef SER_MOD_INTERFACE
-				1
-#endif
-		)==-1)
-		goto error;
-	if (show_status){
-		LM_DBG( "Memory status (shm):\n");
-		shm_status();
-	}
-#endif
-	return 1;
-error:
-	return 0;
-}	
+//int init_memory(int show_status)
+//{
+//#ifdef PKG_MALLOC
+//	if (init_pkg_mallocs()==-1)
+//		goto error;
+//	if (show_status){
+//		LM_DBG( "Memory status (pkg):\n");
+//		pkg_status();
+//	}
+//#endif
+//
+//#ifdef SHM_MEM
+//
+//	if (init_shm_mallocs(
+//#ifdef SER_MOD_INTERFACE
+//				1
+//#endif
+//		)==-1)
+//		goto error;
+//	if (show_status){
+//		LM_DBG( "Memory status (shm):\n");
+//		shm_status();
+//	}
+//#endif
+//	return 1;
+//error:
+//	return 0;
+//}
 
 
 /** call it before exiting; if show_status==1, mem status is displayed */
 /** call it before exiting; if show_status==1, mem status is displayed */
 void destroy_memory(int show_status)
 void destroy_memory(int show_status)

+ 6 - 1
modules/cdp/globals.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 52 - 17
modules/cdp/mod.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -40,6 +45,9 @@
 
 
 #include "mod.h"
 #include "mod.h"
 
 
+#include "../../sr_module.h"
+#include "../../globals.h"
+
 #include "diameter_peer.h"
 #include "diameter_peer.h"
 #include "config.h"
 #include "config.h"
 #include "cdp_load.h"
 #include "cdp_load.h"
@@ -48,6 +56,8 @@ MODULE_VERSION
 
 
 char* config_file="DiameterPeer.xml"; 	/**< default DiameterPeer configuration filename */
 char* config_file="DiameterPeer.xml"; 	/**< default DiameterPeer configuration filename */
 unsigned int latency_threshold = 500;			/**< default threshold for Diameter calls (ms) */
 unsigned int latency_threshold = 500;			/**< default threshold for Diameter calls (ms) */
+unsigned int *latency_threshold_p = &latency_threshold;
+unsigned int workerq_latency_threshold = 100;	/**< default threshold for putting a task into worker queue (ms) */
 
 
 extern dp_config *config; 				/**< DiameterPeer configuration structure */
 extern dp_config *config; 				/**< DiameterPeer configuration structure */
 
 
@@ -66,7 +76,7 @@ extern dp_config *config; 				/**< DiameterPeer configuration structure */
  * - AAASendMessage() - asynchronously send a message
  * - AAASendMessage() - asynchronously send a message
  * - AAASendMessageToPeer() - asynchronously send a message to a forced peer
  * - AAASendMessageToPeer() - asynchronously send a message to a forced peer
  * - AAASendRecvMessage() - synchronously send a message and get the response
  * - AAASendRecvMessage() - synchronously send a message and get the response
- * - AAASendRecvMessageToPeer() - synchronously send a message and get the response to a forced peer 
+ * - AAASendRecvMessageToPeer() - synchronously send a message and get the response to a forced peer
  * <p>
  * <p>
  * - AAACreateSession() - create a diameter #AAASessionId
  * - AAACreateSession() - create a diameter #AAASessionId
  * - AAADropSession() - drop a diameter #AAASessionId
  * - AAADropSession() - drop a diameter #AAASessionId
@@ -79,7 +89,7 @@ extern dp_config *config; 				/**< DiameterPeer configuration structure */
  * - AAAFindMatchingAVP() - find an #AAA_AVP inside a #AAAMessage
  * - AAAFindMatchingAVP() - find an #AAA_AVP inside a #AAAMessage
  * - AAAGetNextAVP() - get the next #AAA_AVP from the #AAAMessage
  * - AAAGetNextAVP() - get the next #AAA_AVP from the #AAAMessage
  * - AAAFreeAVP() - free the memory taken by the #AAA_AVP
  * - AAAFreeAVP() - free the memory taken by the #AAA_AVP
- * - AAAGroupAVPS() - group a #AAA_AVP_LIST of #AAA_AVP into a grouped #AAA_AVP 
+ * - AAAGroupAVPS() - group a #AAA_AVP_LIST of #AAA_AVP into a grouped #AAA_AVP
  * - AAAUngroupAVPS() - ungroup a grouped #AAA_AVP into a #AAA_AVP_LIST of #AAA_AVP
  * - AAAUngroupAVPS() - ungroup a grouped #AAA_AVP into a #AAA_AVP_LIST of #AAA_AVP
  * - AAAFindMatchingAVPList() - find an #AAA_AVP inside a #AAA_AVP_LIST
  * - AAAFindMatchingAVPList() - find an #AAA_AVP inside a #AAA_AVP_LIST
  * - AAAFreeAVPList() - free the memory taken by the all members of #AAA_AVP_LIST
  * - AAAFreeAVPList() - free the memory taken by the all members of #AAA_AVP_LIST
@@ -89,7 +99,7 @@ extern dp_config *config; 				/**< DiameterPeer configuration structure */
  */
  */
 static cmd_export_t cdp_cmds[] = {
 static cmd_export_t cdp_cmds[] = {
 	{"load_cdp",					(cmd_function)load_cdp, 				NO_SCRIPT, 0, 0},
 	{"load_cdp",					(cmd_function)load_cdp, 				NO_SCRIPT, 0, 0},
-	
+
 	EXP_FUNC(AAACreateRequest)
 	EXP_FUNC(AAACreateRequest)
 	EXP_FUNC(AAACreateResponse)
 	EXP_FUNC(AAACreateResponse)
 	EXP_FUNC(AAAFreeMessage)
 	EXP_FUNC(AAAFreeMessage)
@@ -132,7 +142,7 @@ static cmd_export_t cdp_cmds[] = {
 	EXP_FUNC(AAAGetAuthSession)
 	EXP_FUNC(AAAGetAuthSession)
 	EXP_FUNC(AAADropAuthSession)
 	EXP_FUNC(AAADropAuthSession)
 	EXP_FUNC(AAATerminateAuthSession)
 	EXP_FUNC(AAATerminateAuthSession)
-	
+
 	{ 0, 0, 0, 0, 0 }
 	{ 0, 0, 0, 0, 0 }
 };
 };
 
 
@@ -141,37 +151,63 @@ static cmd_export_t cdp_cmds[] = {
  * Exported parameters.
  * Exported parameters.
  * - config_file - Configuration filename. See configdtd.h for the structure and ConfigExample.xml.
  * - config_file - Configuration filename. See configdtd.h for the structure and ConfigExample.xml.
  */
  */
-static param_export_t cdp_params[] = {	
-	{ "config_file",		PARAM_STRING,	&config_file}, 			/**< configuration filename */
-	{ "latency_threshold", 	PARAM_INT, 		&latency_threshold},	/**<threshold above which we will log*/
+static param_export_t cdp_params[] = {
+	{ "config_file",				PARAM_STRING,	&config_file}, 				/**< configuration filename */
+	{ "latency_threshold", 			PARAM_INT, 		&latency_threshold},		/**<threshold above which we will log*/
+	{ "workerq_latency_threshold", 	PARAM_INT, 		&workerq_latency_threshold},/**<time threshold putting job into queue*/
 	{ 0, 0, 0 }
 	{ 0, 0, 0 }
 };
 };
 
 
+stat_export_t mod_stats[] = {
+	{"avg_response_time" ,  STAT_IS_FUNC, 	(stat_var**)get_avg_cdp_response_time	},
+	{"timeouts" ,  			0, 				(stat_var**)&stat_cdp_timeouts  		},
+	{0,0,0}
+};
 
 
 /**
 /**
  * Exported module interface
  * Exported module interface
  */
  */
 struct module_exports exports = {
 struct module_exports exports = {
 	"cdp",
 	"cdp",
+	DEFAULT_DLFLAGS,
 	cdp_cmds,                       		/**< Exported functions */
 	cdp_cmds,                       		/**< Exported functions */
-	0,
 	cdp_params,                     		/**< Exported parameters */
 	cdp_params,                     		/**< Exported parameters */
+	mod_stats,
+	0,										/**< MI cmds */
+	0,										/**< pseudovariables */
+	0,										/**< extra processes */
 	cdp_init,                   			/**< Module initialization function */
 	cdp_init,                   			/**< Module initialization function */
 	(response_function) 0,
 	(response_function) 0,
 	(destroy_function) cdp_exit,
 	(destroy_function) cdp_exit,
-	0,
 	(child_init_function) cdp_child_init 	/**< per-child init function */
 	(child_init_function) cdp_child_init 	/**< per-child init function */
 };
 };
 
 
-/** 
+/**
  * Module init function.
  * Module init function.
- * 
+ *
  * - Initializes the diameter peer using the provided configuration file.
  * - Initializes the diameter peer using the provided configuration file.
  * - Registers with pt the required number of processes.
  * - Registers with pt the required number of processes.
  */
  */
 static int cdp_init( void )
 static int cdp_init( void )
 {
 {
-	LM_INFO("CDiameterPeer initializing\n");
+#ifdef STATISTICS
+	/* register statistics */
+	if ( register_stat("cdp", "replies_response_time", &replies_response_time,0 )!=0 ) {
+		LM_ERR("failed to register stat\n");
+		return -1;
+	}
+
+	if ( register_stat("cdp", "replies_received", &replies_received, 0)!=0 ) {
+		LM_ERR("failed to register stat\n");
+		return -1;
+	}
+
+	if (register_module_stats( exports.name, mod_stats)!=0 ) {
+		LM_ERR("failed to register core statistics\n");
+		return -1;
+	}
+#endif
+
 	if (!diameter_peer_init(config_file)){
 	if (!diameter_peer_init(config_file)){
 		LM_ERR("error initializing the diameter peer\n");
 		LM_ERR("error initializing the diameter peer\n");
 		return 1;
 		return 1;
@@ -183,16 +219,16 @@ static int cdp_init( void )
 /**
 /**
  *	Child init function.
  *	Child init function.
  * - starts the DiameterPeer by forking the processes
  * - starts the DiameterPeer by forking the processes
- * @param rank - id of the child 
+ * @param rank - id of the child
  */
  */
 static int cdp_child_init( int rank )
 static int cdp_child_init( int rank )
 {
 {
-	if (rank == PROC_MAIN) { 
+	if (rank == PROC_MAIN) {
 		LM_INFO("CDiameterPeer child starting ...\n");
 		LM_INFO("CDiameterPeer child starting ...\n");
 		diameter_peer_start(0);
 		diameter_peer_start(0);
 		LM_INFO("... CDiameterPeer child started\n");
 		LM_INFO("... CDiameterPeer child started\n");
 	}
 	}
-	
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -208,4 +244,3 @@ static int cdp_exit( void )
 	LM_INFO("... CDiameterPeer child stoped\n");
 	LM_INFO("... CDiameterPeer child stoped\n");
 	return 0;
 	return 0;
 }
 }
-

+ 7 - 2
modules/cdp/mod.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -42,6 +47,7 @@
 #define _CDP__H
 #define _CDP__H
 
 
 #include "../../sr_module.h"
 #include "../../sr_module.h"
+#include "statistics.h"
 
 
 #define M_NAME "cdp"
 #define M_NAME "cdp"
 
 
@@ -50,5 +56,4 @@ static int cdp_init( void );
 static int cdp_child_init( int rank );
 static int cdp_child_init( int rank );
 static int cdp_exit( void );
 static int cdp_exit( void );
 
 
-
 #endif
 #endif

+ 6 - 1
modules/cdp/peer.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/peer.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 30 - 31
modules/cdp/peermanager.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -60,7 +65,7 @@ AAAMsgIdentifier *endtoend_id=0;/**< Current id for End-to-end */
 gen_lock_t *msg_id_lock;		/**< lock for the message identifier changes */
 gen_lock_t *msg_id_lock;		/**< lock for the message identifier changes */
 
 
 /**
 /**
- * Initializes the Peer Manager. 
+ * Initializes the Peer Manager.
  * The initial list of peers is taken from the configuration provided
  * The initial list of peers is taken from the configuration provided
  * @param config - configuration for initial peers
  * @param config - configuration for initial peers
  * @returns 1
  * @returns 1
@@ -71,20 +76,20 @@ int peer_manager_init(dp_config *config)
 	peer *p;
 	peer *p;
 	LM_DBG("peer_manager_init(): Peer Manager initialization...\n");
 	LM_DBG("peer_manager_init(): Peer Manager initialization...\n");
 	peer_list = shm_malloc(sizeof(peer_list_t));
 	peer_list = shm_malloc(sizeof(peer_list_t));
-	peer_list->head = 0; 
+	peer_list->head = 0;
 	peer_list->tail = 0;
 	peer_list->tail = 0;
 	peer_list_lock = lock_alloc();
 	peer_list_lock = lock_alloc();
 	peer_list_lock = lock_init(peer_list_lock);
 	peer_list_lock = lock_init(peer_list_lock);
-	
+
 	hopbyhop_id = shm_malloc(sizeof(AAAMsgIdentifier));
 	hopbyhop_id = shm_malloc(sizeof(AAAMsgIdentifier));
 	endtoend_id = shm_malloc(sizeof(AAAMsgIdentifier));
 	endtoend_id = shm_malloc(sizeof(AAAMsgIdentifier));
 	msg_id_lock = lock_alloc();
 	msg_id_lock = lock_alloc();
 	msg_id_lock = lock_init(msg_id_lock);
 	msg_id_lock = lock_init(msg_id_lock);
-	
+
 	srand((unsigned int)time(0));
 	srand((unsigned int)time(0));
 	*hopbyhop_id = rand();
 	*hopbyhop_id = rand();
 	*endtoend_id = (time(0)&0xFFF)<<20;
 	*endtoend_id = (time(0)&0xFFF)<<20;
-	*endtoend_id |= rand() & 0xFFFFF;	
+	*endtoend_id |= rand() & 0xFFFFF;
 
 
 	for(i=0;i<config->peers_cnt;i++){
 	for(i=0;i<config->peers_cnt;i++){
 		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
 		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
@@ -92,9 +97,9 @@ int peer_manager_init(dp_config *config)
 		p->is_dynamic = 0;
 		p->is_dynamic = 0;
 		add_peer(p);
 		add_peer(p);
 	}
 	}
-	
+
 	add_timer(1,0,&peer_timer,0);
 	add_timer(1,0,&peer_timer,0);
-	
+
 	return 1;
 	return 1;
 }
 }
 
 
@@ -116,11 +121,11 @@ void peer_manager_destroy()
 
 
 /*	lock_get(msg_id_lock);	*/
 /*	lock_get(msg_id_lock);	*/
 	shm_free(hopbyhop_id);
 	shm_free(hopbyhop_id);
-	shm_free(endtoend_id);	
+	shm_free(endtoend_id);
 	lock_destroy(msg_id_lock);
 	lock_destroy(msg_id_lock);
 	lock_dealloc((void*)msg_id_lock);
 	lock_dealloc((void*)msg_id_lock);
 
 
-	shm_free(peer_list);	
+	shm_free(peer_list);
 	lock_destroy(peer_list_lock);
 	lock_destroy(peer_list_lock);
 	lock_dealloc((void*)peer_list_lock);
 	lock_dealloc((void*)peer_list_lock);
 	LM_DBG("peer_manager_init(): ...Peer Manager destroyed\n");
 	LM_DBG("peer_manager_init(): ...Peer Manager destroyed\n");
@@ -130,25 +135,19 @@ void peer_manager_destroy()
  * Logs the list of peers
  * Logs the list of peers
  * @param level - log level to print to
  * @param level - log level to print to
  */
  */
-void log_peer_list(int level)
+void log_peer_list()
 {
 {
 	/* must have lock on peer_list_lock when calling this!!! */
 	/* must have lock on peer_list_lock when calling this!!! */
 	peer *p;
 	peer *p;
 	int i;
 	int i;
-#ifdef SER_MOD_INTERFACE
-	if (!is_printable(level))
-#else		
-	if (debug<level)
-#endif
-		return;
-	
-	LOG(level,"--- Peer List: ---\n");
+
+    LM_DBG("--- Peer List: ---\n");
 	for(p = peer_list->head;p;p = p->next){
 	for(p = peer_list->head;p;p = p->next){
-		LOG(level,ANSI_GREEN" S["ANSI_YELLOW"%s"ANSI_GREEN"] "ANSI_BLUE"%.*s:%d"ANSI_GREEN" D["ANSI_RED"%c"ANSI_GREEN"]\n",dp_states[p->state],p->fqdn.len,p->fqdn.s,p->port,p->is_dynamic?'X':' ');
+		LM_DBG(ANSI_GREEN" S["ANSI_YELLOW"%s"ANSI_GREEN"] "ANSI_BLUE"%.*s:%d"ANSI_GREEN" D["ANSI_RED"%c"ANSI_GREEN"]\n",dp_states[p->state],p->fqdn.len,p->fqdn.s,p->port,p->is_dynamic?'X':' ');
 		for(i=0;i<p->applications_cnt;i++)
 		for(i=0;i<p->applications_cnt;i++)
-			LOG(level,ANSI_YELLOW"\t [%d,%d]"ANSI_GREEN"\n",p->applications[i].id,p->applications[i].vendor);
+			LM_DBG(ANSI_YELLOW"\t [%d,%d]"ANSI_GREEN"\n",p->applications[i].id,p->applications[i].vendor);
 	}
 	}
-	LOG(level,"------------------\n");		 
+	LM_DBG("------------------\n");
 }
 }
 
 
 /**
 /**
@@ -170,7 +169,7 @@ void add_peer(peer *p)
 /**
 /**
  * Removes a peer from the peer list
  * Removes a peer from the peer list
  * @param p - the peer to remove
  * @param p - the peer to remove
- */ 
+ */
 void remove_peer(peer *p)
 void remove_peer(peer *p)
 {
 {
 	peer *i;
 	peer *i;
@@ -194,7 +193,7 @@ peer *get_peer_from_sock(int sock)
 {
 {
 	peer *i;
 	peer *i;
 	lock_get(peer_list_lock);
 	lock_get(peer_list_lock);
-	
+
 	i = peer_list->head;
 	i = peer_list->head;
 	while(i&&i->I_sock!=sock&&i->R_sock!=sock) i = i->next;
 	while(i&&i->I_sock!=sock&&i->R_sock!=sock) i = i->next;
 	lock_release(peer_list_lock);
 	lock_release(peer_list_lock);
@@ -213,7 +212,7 @@ peer *get_peer_from_fqdn(str fqdn,str realm)
 	lock_get(peer_list_lock);
 	lock_get(peer_list_lock);
 	i = peer_list->head;
 	i = peer_list->head;
 	while(i){
 	while(i){
-		if (fqdn.len == i->fqdn.len && strncasecmp(fqdn.s,i->fqdn.s,fqdn.len)==0) 
+		if (fqdn.len == i->fqdn.len && strncasecmp(fqdn.s,i->fqdn.s,fqdn.len)==0)
 			break;
 			break;
 		i = i->next;
 		i = i->next;
 	}
 	}
@@ -240,7 +239,7 @@ peer *get_peer_by_fqdn(str *fqdn)
 	lock_get(peer_list_lock);
 	lock_get(peer_list_lock);
 	i = peer_list->head;
 	i = peer_list->head;
 	while(i){
 	while(i){
-		if (fqdn->len == i->fqdn.len && strncasecmp(fqdn->s,i->fqdn.s,fqdn->len)==0) 
+		if (fqdn->len == i->fqdn.len && strncasecmp(fqdn->s,i->fqdn.s,fqdn->len)==0)
 			break;
 			break;
 		i = i->next;
 		i = i->next;
 	}
 	}
@@ -278,7 +277,7 @@ int peer_timer(time_t now,void *ptr)
 					touch_peer(p);
 					touch_peer(p);
 					sm_process(p,Start,0,1,0);
 					sm_process(p,Start,0,1,0);
 					break;
 					break;
-				/* timeouts */	
+				/* timeouts */
 				case Wait_Conn_Ack:
 				case Wait_Conn_Ack:
 				case Wait_I_CEA:
 				case Wait_I_CEA:
 				case Closing:
 				case Closing:
@@ -286,7 +285,7 @@ int peer_timer(time_t now,void *ptr)
 				case Wait_Conn_Ack_Elect:
 				case Wait_Conn_Ack_Elect:
 					touch_peer(p);
 					touch_peer(p);
 					sm_process(p,Timeout,0,1,0);
 					sm_process(p,Timeout,0,1,0);
-					break;	
+					break;
 				/* inactivity detected */
 				/* inactivity detected */
 				case I_Open:
 				case I_Open:
 				case R_Open:
 				case R_Open:
@@ -300,18 +299,18 @@ int peer_timer(time_t now,void *ptr)
 						touch_peer(p);
 						touch_peer(p);
 					}
 					}
 					break;
 					break;
-				/* ignored states */	
+				/* ignored states */
 				/* unknown states */
 				/* unknown states */
 				default:
 				default:
 					LM_ERR("peer_timer(): Peer %.*s inactive  in state %d\n",
 					LM_ERR("peer_timer(): Peer %.*s inactive  in state %d\n",
 						p->fqdn.len,p->fqdn.s,p->state);
 						p->fqdn.len,p->fqdn.s,p->state);
-			}				
+			}
 		}
 		}
 		lock_release(p->lock);
 		lock_release(p->lock);
 		p = n;
 		p = n;
 	}
 	}
 	lock_release(peer_list_lock);
 	lock_release(peer_list_lock);
-	log_peer_list(L_INFO);
+	log_peer_list();
 	i = config->tc/5;
 	i = config->tc/5;
 	if (i<=0) i=1;
 	if (i<=0) i=1;
 	return i;
 	return i;

+ 8 - 3
modules/cdp/peermanager.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -49,7 +54,7 @@
 
 
 /** list of peers */
 /** list of peers */
 typedef struct {
 typedef struct {
-	peer *head;	/**< first peer in the list */	
+	peer *head;	/**< first peer in the list */
 	peer *tail; /**< last peer in the list */
 	peer *tail; /**< last peer in the list */
 } peer_list_t;
 } peer_list_t;
 
 
@@ -57,7 +62,7 @@ int peer_manager_init(dp_config *config);
 
 
 void peer_manager_destroy();
 void peer_manager_destroy();
 
 
-void log_peer_list(int level);
+void log_peer_list();
 
 
 void add_peer(peer *p);
 void add_peer(peer *p);
 
 

+ 6 - 1
modules/cdp/peerstatemachine.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/peerstatemachine.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 150 - 151
modules/cdp/receiver.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -90,27 +95,21 @@ serviced_peer_t *serviced_peers=0; 	/**< pointer to the list of peers serviced b
  * Print debug information about this receiver process
  * Print debug information about this receiver process
  * @param level
  * @param level
  */
  */
-static void log_serviced_peers(int level)
+static void log_serviced_peers()
 {
 {
 	serviced_peer_t *sp;
 	serviced_peer_t *sp;
-#ifdef SER_MOD_INTERFACE
-	if (!is_printable(level))
-#else		
-	if (debug<level)
-#endif
-		return;
-	
-	LOG(level,"--- Receiver ["ANSI_BLUE"%s"ANSI_GREEN"] Serviced Peers: ---\n", 
+
+	LM_DBG("--- Receiver ["ANSI_BLUE"%s"ANSI_GREEN"] Serviced Peers: ---\n",
 			pt[process_no].desc
 			pt[process_no].desc
 			);
 			);
 	for(sp=serviced_peers;sp;sp=sp->next){
 	for(sp=serviced_peers;sp;sp=sp->next){
-		LOG(level,ANSI_GREEN" Peer: ["ANSI_YELLOW"%.*s"ANSI_GREEN"]  TCP Socket: ["ANSI_YELLOW"%d"ANSI_GREEN"] Recv.State: ["ANSI_YELLOW"%d"ANSI_GREEN"]\n",
+		LM_DBG(ANSI_GREEN" Peer: ["ANSI_YELLOW"%.*s"ANSI_GREEN"]  TCP Socket: ["ANSI_YELLOW"%d"ANSI_GREEN"] Recv.State: ["ANSI_YELLOW"%d"ANSI_GREEN"]\n",
 				sp->p?sp->p->fqdn.len:0,
 				sp->p?sp->p->fqdn.len:0,
 				sp->p?sp->p->fqdn.s:0,
 				sp->p?sp->p->fqdn.s:0,
 				sp->tcp_socket,
 				sp->tcp_socket,
 				sp->state);
 				sp->state);
 	}
 	}
-	LOG(level,"--------------------------------------------------------\n");	
+	LM_DBG("--------------------------------------------------------\n");
 }
 }
 
 
 
 
@@ -121,12 +120,12 @@ static void log_serviced_peers(int level)
  * @return 1 on success or 0 on failure
  * @return 1 on success or 0 on failure
  */
  */
 static int make_send_pipe(serviced_peer_t *sp)
 static int make_send_pipe(serviced_peer_t *sp)
-{		
+{
 	local_id++;
 	local_id++;
 	sp->send_pipe_name.s = shm_malloc(sizeof(PIPE_PREFIX)+64);
 	sp->send_pipe_name.s = shm_malloc(sizeof(PIPE_PREFIX)+64);
 	sprintf(sp->send_pipe_name.s,"%s%d_%d_%d",PIPE_PREFIX,getpid(),local_id,(unsigned int) time(0));
 	sprintf(sp->send_pipe_name.s,"%s%d_%d_%d",PIPE_PREFIX,getpid(),local_id,(unsigned int) time(0));
 	sp->send_pipe_name.len = strlen(sp->send_pipe_name.s);
 	sp->send_pipe_name.len = strlen(sp->send_pipe_name.s);
-		
+
 	if (mkfifo(sp->send_pipe_name.s, 0666)<0){
 	if (mkfifo(sp->send_pipe_name.s, 0666)<0){
 		LM_ERR("make_send_pipe(): FIFO make failed > %s\n",strerror(errno));
 		LM_ERR("make_send_pipe(): FIFO make failed > %s\n",strerror(errno));
 		return 0;
 		return 0;
@@ -142,11 +141,11 @@ static int make_send_pipe(serviced_peer_t *sp)
 		LM_ERR("receiver_init(): FIFO open for write (keep-alive) failed > %s\n",strerror(errno));
 		LM_ERR("receiver_init(): FIFO open for write (keep-alive) failed > %s\n",strerror(errno));
 		return 0;
 		return 0;
 	}
 	}
-	
-	if (sp->p) 
+
+	if (sp->p)
 		sp->p->send_pipe_name=sp->send_pipe_name;
 		sp->p->send_pipe_name=sp->send_pipe_name;
-	
-	return 1;	
+
+	return 1;
 }
 }
 
 
 /**
 /**
@@ -164,7 +163,7 @@ static void close_send_pipe(serviced_peer_t *sp)
 		sp->send_pipe_name.len=0;
 		sp->send_pipe_name.len=0;
 		sp->send_pipe_fd = -1;
 		sp->send_pipe_fd = -1;
 		sp->send_pipe_fd_out = -1;
 		sp->send_pipe_fd_out = -1;
-	}	
+	}
 }
 }
 
 
 
 
@@ -187,7 +186,7 @@ static serviced_peer_t* add_serviced_peer(peer *p)
 	}
 	}
 	memset(sp,0,sizeof(serviced_peer_t));
 	memset(sp,0,sizeof(serviced_peer_t));
 
 
-	sp->p = p;	
+	sp->p = p;
 	sp->tcp_socket = -1;
 	sp->tcp_socket = -1;
 	sp->prev = 0;
 	sp->prev = 0;
 	if (serviced_peers) {
 	if (serviced_peers) {
@@ -195,12 +194,12 @@ static serviced_peer_t* add_serviced_peer(peer *p)
 		sp->next = serviced_peers;
 		sp->next = serviced_peers;
 	}
 	}
 	serviced_peers = sp;
 	serviced_peers = sp;
-	
+
 	if (!make_send_pipe(sp)){
 	if (!make_send_pipe(sp)){
 		pkg_free(sp);
 		pkg_free(sp);
 		return 0;
 		return 0;
 	}
 	}
-	
+
 	return sp;
 	return sp;
 }
 }
 
 
@@ -222,7 +221,7 @@ static void disconnect_serviced_peer(serviced_peer_t *sp,int locked)
 			if (sp->p->R_sock == sp->tcp_socket) sm_process(sp->p,R_Peer_Disc,0,1,sp->tcp_socket);
 			if (sp->p->R_sock == sp->tcp_socket) sm_process(sp->p,R_Peer_Disc,0,1,sp->tcp_socket);
 			sp->p->send_pipe_name.s = 0;
 			sp->p->send_pipe_name.s = 0;
 			sp->p->send_pipe_name.len = 0;
 			sp->p->send_pipe_name.len = 0;
-		if (!locked) lock_release(sp->p->lock);		
+		if (!locked) lock_release(sp->p->lock);
 	}
 	}
 	sp->tcp_socket = -1;
 	sp->tcp_socket = -1;
 	close_send_pipe(sp);
 	close_send_pipe(sp);
@@ -266,7 +265,7 @@ static int send_fd(int pipe_fd,int fd, peer *p)
 	struct msghdr msg;
 	struct msghdr msg;
 	struct iovec iov[1];
 	struct iovec iov[1];
 	int ret;
 	int ret;
-	
+
 #ifdef HAVE_MSGHDR_MSG_CONTROL
 #ifdef HAVE_MSGHDR_MSG_CONTROL
 	struct cmsghdr* cmsg;
 	struct cmsghdr* cmsg;
 	/* make sure msg_control will point to properly aligned data */
 	/* make sure msg_control will point to properly aligned data */
@@ -274,12 +273,12 @@ static int send_fd(int pipe_fd,int fd, peer *p)
 		struct cmsghdr cm;
 		struct cmsghdr cm;
 		char control[CMSG_SPACE(sizeof(fd))];
 		char control[CMSG_SPACE(sizeof(fd))];
 	}control_un;
 	}control_un;
-	
+
 	msg.msg_control=control_un.control;
 	msg.msg_control=control_un.control;
 	/* openbsd doesn't like "more space", msg_controllen must not
 	/* openbsd doesn't like "more space", msg_controllen must not
 	 * include the end padding */
 	 * include the end padding */
 	msg.msg_controllen=CMSG_LEN(sizeof(fd));
 	msg.msg_controllen=CMSG_LEN(sizeof(fd));
-	
+
 	cmsg=CMSG_FIRSTHDR(&msg);
 	cmsg=CMSG_FIRSTHDR(&msg);
 	cmsg->cmsg_level = SOL_SOCKET;
 	cmsg->cmsg_level = SOL_SOCKET;
 	cmsg->cmsg_type = SCM_RIGHTS;
 	cmsg->cmsg_type = SCM_RIGHTS;
@@ -290,15 +289,15 @@ static int send_fd(int pipe_fd,int fd, peer *p)
 	msg.msg_accrights=(caddr_t) &fd;
 	msg.msg_accrights=(caddr_t) &fd;
 	msg.msg_accrightslen=sizeof(fd);
 	msg.msg_accrightslen=sizeof(fd);
 #endif
 #endif
-	
+
 	msg.msg_name=0;
 	msg.msg_name=0;
 	msg.msg_namelen=0;
 	msg.msg_namelen=0;
-	
+
 	iov[0].iov_base=&p;
 	iov[0].iov_base=&p;
 	iov[0].iov_len=sizeof(peer*);
 	iov[0].iov_len=sizeof(peer*);
 	msg.msg_iov=iov;
 	msg.msg_iov=iov;
 	msg.msg_iovlen=1;
 	msg.msg_iovlen=1;
-	
+
 again:
 again:
 	ret=sendmsg(pipe_fd, &msg, 0);
 	ret=sendmsg(pipe_fd, &msg, 0);
 	if (ret<0){
 	if (ret<0){
@@ -309,7 +308,7 @@ again:
 			return 0;
 			return 0;
 		}
 		}
 	}
 	}
-	
+
 	return 1;
 	return 1;
 }
 }
 
 
@@ -328,29 +327,29 @@ static int receive_fd(int pipe_fd, int* fd,peer **p)
 	struct iovec iov[1];
 	struct iovec iov[1];
 	int new_fd;
 	int new_fd;
 	int ret;
 	int ret;
-	
+
 #ifdef HAVE_MSGHDR_MSG_CONTROL
 #ifdef HAVE_MSGHDR_MSG_CONTROL
 	struct cmsghdr* cmsg;
 	struct cmsghdr* cmsg;
 	union{
 	union{
 		struct cmsghdr cm;
 		struct cmsghdr cm;
 		char control[CMSG_SPACE(sizeof(new_fd))];
 		char control[CMSG_SPACE(sizeof(new_fd))];
 	}control_un;
 	}control_un;
-	
+
 	msg.msg_control=control_un.control;
 	msg.msg_control=control_un.control;
 	msg.msg_controllen=sizeof(control_un.control);
 	msg.msg_controllen=sizeof(control_un.control);
 #else
 #else
 	msg.msg_accrights=(caddr_t) &new_fd;
 	msg.msg_accrights=(caddr_t) &new_fd;
 	msg.msg_accrightslen=sizeof(int);
 	msg.msg_accrightslen=sizeof(int);
 #endif
 #endif
-	
+
 	msg.msg_name=0;
 	msg.msg_name=0;
 	msg.msg_namelen=0;
 	msg.msg_namelen=0;
-	
+
 	iov[0].iov_base=p;
 	iov[0].iov_base=p;
 	iov[0].iov_len=sizeof(peer*);
 	iov[0].iov_len=sizeof(peer*);
 	msg.msg_iov=iov;
 	msg.msg_iov=iov;
 	msg.msg_iovlen=1;
 	msg.msg_iovlen=1;
-	
+
 again:
 again:
 	ret=recvmsg(pipe_fd, &msg, MSG_DONTWAIT|MSG_WAITALL);
 	ret=recvmsg(pipe_fd, &msg, MSG_DONTWAIT|MSG_WAITALL);
 	if (ret<0){
 	if (ret<0){
@@ -370,7 +369,7 @@ again:
 				    "trying to fix...\n", ret, (long int)sizeof(peer*));
 				    "trying to fix...\n", ret, (long int)sizeof(peer*));
 		goto error;
 		goto error;
 	}
 	}
-	
+
 #ifdef HAVE_MSGHDR_MSG_CONTROL
 #ifdef HAVE_MSGHDR_MSG_CONTROL
 	cmsg=CMSG_FIRSTHDR(&msg);
 	cmsg=CMSG_FIRSTHDR(&msg);
 	if ((cmsg!=0) && (cmsg->cmsg_len==CMSG_LEN(sizeof(new_fd)))){
 	if ((cmsg!=0) && (cmsg->cmsg_len==CMSG_LEN(sizeof(new_fd)))){
@@ -388,7 +387,7 @@ again:
 			LM_ERR("receive_fd: no descriptor passed, empty control message");
 			LM_ERR("receive_fd: no descriptor passed, empty control message");
 		else
 		else
 			LM_ERR("receive_fd: no descriptor passed, cmsg=%p,"
 			LM_ERR("receive_fd: no descriptor passed, cmsg=%p,"
-				"len=%d\n", cmsg, (unsigned)cmsg->cmsg_len); 
+				"len=%d\n", cmsg, (unsigned)cmsg->cmsg_len);
 		*fd=-1;
 		*fd=-1;
 		*p=0;
 		*p=0;
 		/* it's not really an error */
 		/* it's not really an error */
@@ -398,11 +397,11 @@ again:
 		*fd=new_fd;
 		*fd=new_fd;
 	}else{
 	}else{
 		LM_ERR("receive_fd: no descriptor passed,"
 		LM_ERR("receive_fd: no descriptor passed,"
-				" accrightslen=%d\n", msg.msg_accrightslen); 
+				" accrightslen=%d\n", msg.msg_accrightslen);
 		*fd=-1;
 		*fd=-1;
 	}
 	}
 #endif
 #endif
-	
+
 	return 1;
 	return 1;
 error:
 error:
 	return 0;
 	return 0;
@@ -429,7 +428,7 @@ int receiver_init(peer *p)
 		fd_exchange_pipe_unknown_local = fd_exchange_pipe[0];
 		fd_exchange_pipe_unknown_local = fd_exchange_pipe[0];
 		fd_exchange_pipe_unknown = fd_exchange_pipe[1];
 		fd_exchange_pipe_unknown = fd_exchange_pipe[1];
 	}
 	}
-	
+
 	return 1;
 	return 1;
 }
 }
 
 
@@ -442,25 +441,25 @@ void receiver_process(peer *p)
 {
 {
 	LM_INFO("receiver_process(): [%.*s] Receiver process doing init on new process...\n",
 	LM_INFO("receiver_process(): [%.*s] Receiver process doing init on new process...\n",
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
-	if (p)	
+	if (p)
 		if (!add_serviced_peer(p)) goto done;
 		if (!add_serviced_peer(p)) goto done;
-	
+
 	LM_INFO("receiver_process(): [%.*s] Receiver process starting up...\n",
 	LM_INFO("receiver_process(): [%.*s] Receiver process starting up...\n",
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
 
 
-	log_serviced_peers(L_INFO);		
+	log_serviced_peers();
 
 
 	if (receive_loop(p)<0){
 	if (receive_loop(p)<0){
 		LM_INFO("receiver_process(): [%.*s] receive_loop() return -1 (error)!\n",
 		LM_INFO("receiver_process(): [%.*s] receive_loop() return -1 (error)!\n",
 						p?p->fqdn.len:0,p?p->fqdn.s:0);
 						p?p->fqdn.len:0,p?p->fqdn.s:0);
-				
+
 	}
 	}
 
 
-done:	
+done:
 	if (!*shutdownx){
 	if (!*shutdownx){
 		LM_INFO("receiver_process(): [%.*s]... Receiver process cleaning-up - should not happen unless shuting down!\n",
 		LM_INFO("receiver_process(): [%.*s]... Receiver process cleaning-up - should not happen unless shuting down!\n",
 				p?p->fqdn.len:0,p?p->fqdn.s:0);
 				p?p->fqdn.len:0,p?p->fqdn.s:0);
-		
+
 	}
 	}
 	LM_INFO("receiver_process(): [%.*s]... Receiver process cleaning-up.\n",
 	LM_INFO("receiver_process(): [%.*s]... Receiver process cleaning-up.\n",
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
@@ -471,9 +470,9 @@ done:
 	}
 	}
 	/* remove pid from list of running processes */
 	/* remove pid from list of running processes */
 	dp_del_pid(getpid());
 	dp_del_pid(getpid());
-	
+
 #ifdef CDP_FOR_SER
 #ifdef CDP_FOR_SER
-			
+
 #else
 #else
 #ifdef PKG_MALLOC
 #ifdef PKG_MALLOC
 	#ifdef PKG_MALLOC
 	#ifdef PKG_MALLOC
@@ -482,11 +481,11 @@ done:
 		//pkg_status();
 		//pkg_status();
 		#ifdef pkg_sums
 		#ifdef pkg_sums
 			pkg_sums();
 			pkg_sums();
-		#endif 
+		#endif
 	#endif
 	#endif
 #endif
 #endif
-#endif		
-		
+#endif
+
 	LM_INFO("receiver_process(): [%.*s]... Receiver process finished.\n",
 	LM_INFO("receiver_process(): [%.*s]... Receiver process finished.\n",
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
 			p?p->fqdn.len:0,p?p->fqdn.s:0);
 	exit(0);
 	exit(0);
@@ -505,38 +504,38 @@ static inline int do_receive(serviced_peer_t *sp)
 	int cnt,n,version;
 	int cnt,n,version;
 	char *dst;
 	char *dst;
 	AAAMessage *dmsg;
 	AAAMessage *dmsg;
-	
+
 	switch (sp->state){
 	switch (sp->state){
 		case Receiver_Waiting:
 		case Receiver_Waiting:
 			n = 1; /* wait for version */
 			n = 1; /* wait for version */
 			dst = sp->buf;
 			dst = sp->buf;
 			break;
 			break;
-			
-		case Receiver_Header: 
+
+		case Receiver_Header:
 			n = DIAMETER_HEADER_LEN - sp->buf_len; /* waiting for rest of header */
 			n = DIAMETER_HEADER_LEN - sp->buf_len; /* waiting for rest of header */
 			dst = sp->buf+sp->buf_len;
 			dst = sp->buf+sp->buf_len;
 			break;
 			break;
-			
+
 		case Receiver_Rest_of_Message:
 		case Receiver_Rest_of_Message:
 			n = sp->length - sp->msg_len;	/* waiting for the rest of the message */
 			n = sp->length - sp->msg_len;	/* waiting for the rest of the message */
 			dst = sp->msg+sp->msg_len;
 			dst = sp->msg+sp->msg_len;
 			break;
 			break;
-			
+
 		default:
 		default:
 			LM_ERR("do_receive(): [%.*s] Unknown state %d\n",
 			LM_ERR("do_receive(): [%.*s] Unknown state %d\n",
 					sp->p?sp->p->fqdn.len:0,
 					sp->p?sp->p->fqdn.len:0,
 					sp->p?sp->p->fqdn.s:0,
 					sp->p?sp->p->fqdn.s:0,
-					sp->state);			
+					sp->state);
 			goto error_and_reset;
 			goto error_and_reset;
 	}
 	}
-	
+
 	cnt = recv(sp->tcp_socket,dst,n,0);
 	cnt = recv(sp->tcp_socket,dst,n,0);
-	
-	if (cnt<=0)	
+
+	if (cnt<=0)
 		goto error_and_reset;
 		goto error_and_reset;
-	
+
 	switch (sp->state){
 	switch (sp->state){
-		case Receiver_Waiting:			
+		case Receiver_Waiting:
 			version = (unsigned char)(sp->buf[0]);
 			version = (unsigned char)(sp->buf[0]);
 			if (version!=1) {
 			if (version!=1) {
 		  		LM_ERR("do_receive(): [%.*s] Received Unknown version [%d]\n",
 		  		LM_ERR("do_receive(): [%.*s] Received Unknown version [%d]\n",
@@ -549,9 +548,9 @@ static inline int do_receive(serviced_peer_t *sp)
 				sp->buf_len = 1;
 				sp->buf_len = 1;
 			}
 			}
 			break;
 			break;
-			
+
 		case Receiver_Header:
 		case Receiver_Header:
-			sp->buf_len+=cnt;			
+			sp->buf_len+=cnt;
 			if (sp->buf_len==DIAMETER_HEADER_LEN){
 			if (sp->buf_len==DIAMETER_HEADER_LEN){
 				sp->length = get_3bytes(sp->buf+1);
 				sp->length = get_3bytes(sp->buf+1);
 				if (sp->length>DP_MAX_MSG_LENGTH){
 				if (sp->length>DP_MAX_MSG_LENGTH){
@@ -571,17 +570,17 @@ static inline int do_receive(serviced_peer_t *sp)
 					LOG_NO_MEM("shm",sp->length);
 					LOG_NO_MEM("shm",sp->length);
 					goto error_and_reset;
 					goto error_and_reset;
 				}
 				}
-				
+
 				memcpy(sp->msg,sp->buf,sp->buf_len);
 				memcpy(sp->msg,sp->buf,sp->buf_len);
 				sp->msg_len=sp->buf_len;
 				sp->msg_len=sp->buf_len;
 				sp->state = Receiver_Rest_of_Message;
 				sp->state = Receiver_Rest_of_Message;
 			}
 			}
 			break;
 			break;
-			
+
 		case Receiver_Rest_of_Message:
 		case Receiver_Rest_of_Message:
 			sp->msg_len+=cnt;
 			sp->msg_len+=cnt;
 			if (sp->msg_len==sp->length){
 			if (sp->msg_len==sp->length){
-		    	dmsg = AAATranslateMessage((unsigned char*)sp->msg,(unsigned int)sp->msg_len,1);		    	
+		    	dmsg = AAATranslateMessage((unsigned char*)sp->msg,(unsigned int)sp->msg_len,1);
 				if (dmsg) {
 				if (dmsg) {
 					sp->msg = 0;
 					sp->msg = 0;
 					receive_message(dmsg,sp);
 					receive_message(dmsg,sp);
@@ -595,12 +594,12 @@ static inline int do_receive(serviced_peer_t *sp)
 				sp->state = Receiver_Waiting;
 				sp->state = Receiver_Waiting;
 			}
 			}
 			break;
 			break;
-			
+
 		default:
 		default:
 			LM_ERR("do_receive(): [%.*s] Unknown state %d\n",
 			LM_ERR("do_receive(): [%.*s] Unknown state %d\n",
 					sp->p?sp->p->fqdn.len:0,
 					sp->p?sp->p->fqdn.len:0,
 					sp->p?sp->p->fqdn.s:0,
 					sp->p?sp->p->fqdn.s:0,
-					sp->state);			
+					sp->state);
 			goto error_and_reset;
 			goto error_and_reset;
 	}
 	}
 	return 1;
 	return 1;
@@ -622,7 +621,7 @@ error_and_reset:
  *  - the tcp sockets of all serviced peers, triggering the incoming messages do_receive()
  *  - the tcp sockets of all serviced peers, triggering the incoming messages do_receive()
  *  - the send pipes of all serviced peers, triggering the sending of outgoing messages
  *  - the send pipes of all serviced peers, triggering the sending of outgoing messages
  * @returns 0 on normal exit or -1 on error
  * @returns 0 on normal exit or -1 on error
- */ 
+ */
 int receive_loop(peer *original_peer)
 int receive_loop(peer *original_peer)
 {
 {
 	fd_set rfds,efds;
 	fd_set rfds,efds;
@@ -637,24 +636,24 @@ int receive_loop(peer *original_peer)
 	if (original_peer) fd_exchange_pipe_local = original_peer->fd_exchange_pipe_local;
 	if (original_peer) fd_exchange_pipe_local = original_peer->fd_exchange_pipe_local;
 	else fd_exchange_pipe_local = fd_exchange_pipe_unknown_local;
 	else fd_exchange_pipe_local = fd_exchange_pipe_unknown_local;
 
 
-//	if (shutdownx) return -1;	
-	
+//	if (shutdownx) return -1;
+
 	while(shutdownx&&!*shutdownx){
 	while(shutdownx&&!*shutdownx){
 		n = 0;
 		n = 0;
-	
+
 		while(!n){
 		while(!n){
-			if (shutdownx&&*shutdownx) break;	
-	
-			log_serviced_peers(L_DBG);
-	
+			if (shutdownx&&*shutdownx) break;
+
+			log_serviced_peers();
+
 			max =-1;
 			max =-1;
-	
+
 			FD_ZERO(&rfds);
 			FD_ZERO(&rfds);
 			FD_ZERO(&efds);
 			FD_ZERO(&efds);
-			
+
 			FD_SET(fd_exchange_pipe_local,&rfds);
 			FD_SET(fd_exchange_pipe_local,&rfds);
 			if (fd_exchange_pipe_local>max) max = fd_exchange_pipe_local;
 			if (fd_exchange_pipe_local>max) max = fd_exchange_pipe_local;
-			
+
 			for(sp=serviced_peers;sp;sp=sp->next){
 			for(sp=serviced_peers;sp;sp=sp->next){
 				if (sp->tcp_socket>=0){
 				if (sp->tcp_socket>=0){
 					FD_SET(sp->tcp_socket,&rfds);
 					FD_SET(sp->tcp_socket,&rfds);
@@ -664,12 +663,12 @@ int receive_loop(peer *original_peer)
 				if (sp->send_pipe_fd>=0) {
 				if (sp->send_pipe_fd>=0) {
 					FD_SET(sp->send_pipe_fd,&rfds);
 					FD_SET(sp->send_pipe_fd,&rfds);
 					if (sp->send_pipe_fd>max) max = sp->send_pipe_fd;
 					if (sp->send_pipe_fd>max) max = sp->send_pipe_fd;
-				}			
+				}
 			}
 			}
-			
+
 			tv.tv_sec=1;
 			tv.tv_sec=1;
 			tv.tv_usec=0;
 			tv.tv_usec=0;
-	
+
 			n = select(max+1,&rfds,0,&efds,&tv);
 			n = select(max+1,&rfds,0,&efds,&tv);
 			if (n==-1){
 			if (n==-1){
 				if (shutdownx&&*shutdownx) return 0;
 				if (shutdownx&&*shutdownx) return 0;
@@ -684,7 +683,7 @@ int receive_loop(peer *original_peer)
 				break;
 				break;
 			}else
 			}else
 				if (n){
 				if (n){
-					
+
 					if (FD_ISSET(fd_exchange_pipe_local,&rfds)){
 					if (FD_ISSET(fd_exchange_pipe_local,&rfds)){
 						/* fd exchange */
 						/* fd exchange */
 						LM_DBG("select_recv(): There is something on the fd exchange pipe\n");
 						LM_DBG("select_recv(): There is something on the fd exchange pipe\n");
@@ -692,7 +691,7 @@ int receive_loop(peer *original_peer)
 						fd = -1;
 						fd = -1;
 						if (!receive_fd(fd_exchange_pipe_local,&fd,&p)){
 						if (!receive_fd(fd_exchange_pipe_local,&fd,&p)){
 							LM_ERR("select_recv(): Error reading from fd exchange pipe\n");
 							LM_ERR("select_recv(): Error reading from fd exchange pipe\n");
-						}else{	
+						}else{
 							LM_DBG("select_recv(): fd exchange pipe says fd [%d] for peer %p:[%.*s]\n",fd,
 							LM_DBG("select_recv(): fd exchange pipe says fd [%d] for peer %p:[%.*s]\n",fd,
 									p,
 									p,
 									p?p->fqdn.len:0,
 									p?p->fqdn.len:0,
@@ -712,13 +711,13 @@ int receive_loop(peer *original_peer)
 									LM_ERR("Error on add_serviced_peer()\n");
 									LM_ERR("Error on add_serviced_peer()\n");
 									continue;
 									continue;
 								}
 								}
-								
+
 								sp2->tcp_socket = fd;
 								sp2->tcp_socket = fd;
 								if (p->state == Wait_Conn_Ack){
 								if (p->state == Wait_Conn_Ack){
 									p->I_sock = fd;
 									p->I_sock = fd;
 									sm_process(p,I_Rcv_Conn_Ack,0,0,fd);
 									sm_process(p,I_Rcv_Conn_Ack,0,0,fd);
 								}else{
 								}else{
-									p->R_sock = fd;								
+									p->R_sock = fd;
 								}
 								}
 							}else{
 							}else{
 								sp2 = add_serviced_peer(NULL);
 								sp2 = add_serviced_peer(NULL);
@@ -730,7 +729,7 @@ int receive_loop(peer *original_peer)
 							}
 							}
 						}
 						}
 					}
 					}
-										
+
 					for(sp=serviced_peers;sp;){
 					for(sp=serviced_peers;sp;){
 						if (sp->tcp_socket>=0 && FD_ISSET(sp->tcp_socket,&efds)) {
 						if (sp->tcp_socket>=0 && FD_ISSET(sp->tcp_socket,&efds)) {
 							LM_INFO("select_recv(): [%.*s] Peer socket [%d] found on the exception list... dropping\n",
 							LM_INFO("select_recv(): [%.*s] Peer socket [%d] found on the exception list... dropping\n",
@@ -739,7 +738,7 @@ int receive_loop(peer *original_peer)
 									sp->tcp_socket);
 									sp->tcp_socket);
 							goto drop_peer;
 							goto drop_peer;
 						}
 						}
-						if (sp->send_pipe_fd>=0 && FD_ISSET(sp->send_pipe_fd,&rfds)) {					
+						if (sp->send_pipe_fd>=0 && FD_ISSET(sp->send_pipe_fd,&rfds)) {
 							/* send */
 							/* send */
 							LM_DBG("select_recv(): There is something on the send pipe\n");
 							LM_DBG("select_recv(): There is something on the send pipe\n");
 							cnt = read(sp->send_pipe_fd,&msg,sizeof(AAAMessage *));
 							cnt = read(sp->send_pipe_fd,&msg,sizeof(AAAMessage *));
@@ -753,7 +752,7 @@ int receive_loop(peer *original_peer)
 							if (cnt<sizeof(AAAMessage *)){
 							if (cnt<sizeof(AAAMessage *)){
 								if (cnt<0) LM_ERR("select_recv(): Error reading from send pipe\n");
 								if (cnt<0) LM_ERR("select_recv(): Error reading from send pipe\n");
 								goto receive;
 								goto receive;
-							}	
+							}
 							LM_DBG("select_recv(): Send pipe says [%p] %d\n",msg,cnt);
 							LM_DBG("select_recv(): Send pipe says [%p] %d\n",msg,cnt);
 							if (sp->tcp_socket<0){
 							if (sp->tcp_socket<0){
 								LM_ERR("select_recv(): got a signal to send something, but the connection was not opened");
 								LM_ERR("select_recv(): got a signal to send something, but the connection was not opened");
@@ -768,19 +767,19 @@ int receive_loop(peer *original_peer)
 											strerror(errno));
 											strerror(errno));
 									AAAFreeMessage(&msg);
 									AAAFreeMessage(&msg);
 									close(sp->tcp_socket);
 									close(sp->tcp_socket);
-									goto drop_peer;								
+									goto drop_peer;
 								}
 								}
-														
+
 								if (cnt!=msg->buf.len){
 								if (cnt!=msg->buf.len){
 									LM_ERR("select_recv(): [%.*s] write on socket [%d] only wrote %d/%d bytes... dropping\n",
 									LM_ERR("select_recv(): [%.*s] write on socket [%d] only wrote %d/%d bytes... dropping\n",
 											sp->p?sp->p->fqdn.len:0,
 											sp->p?sp->p->fqdn.len:0,
 											sp->p?sp->p->fqdn.s:0,
 											sp->p?sp->p->fqdn.s:0,
 											sp->tcp_socket,
 											sp->tcp_socket,
 											cnt,
 											cnt,
-											msg->buf.len);							
+											msg->buf.len);
 									AAAFreeMessage(&msg);
 									AAAFreeMessage(&msg);
-									close(sp->tcp_socket);								
-									goto drop_peer;			
+									close(sp->tcp_socket);
+									goto drop_peer;
 								}
 								}
 							}
 							}
 							AAAFreeMessage(&msg);
 							AAAFreeMessage(&msg);
@@ -797,12 +796,12 @@ int receive_loop(peer *original_peer)
 										sp->p?sp->p->fqdn.s:0,
 										sp->p?sp->p->fqdn.s:0,
 										sp->tcp_socket,
 										sp->tcp_socket,
 										cnt,
 										cnt,
-										errno?strerror(errno):"");							
+										errno?strerror(errno):"");
 								goto drop_peer;
 								goto drop_peer;
-							}						
+							}
 						}
 						}
-						
-	//next_sp:			
+
+	//next_sp:
 						/* go to next serviced peer */
 						/* go to next serviced peer */
 						sp=sp->next;
 						sp=sp->next;
 						continue;
 						continue;
@@ -812,7 +811,7 @@ int receive_loop(peer *original_peer)
 						disconnect_serviced_peer(sp,0);
 						disconnect_serviced_peer(sp,0);
 						if (sp->p && sp->p->is_dynamic)
 						if (sp->p && sp->p->is_dynamic)
 							drop_serviced_peer(sp,0);
 							drop_serviced_peer(sp,0);
-						sp = sp2;					 				
+						sp = sp2;
 					}
 					}
 				}
 				}
 		}
 		}
@@ -833,8 +832,8 @@ int peer_connect(peer *p)
 {
 {
 	int sock;
 	int sock;
 	unsigned int option = 1;
 	unsigned int option = 1;
-	
-	struct addrinfo *ainfo=0,*res=0,hints;		
+
+	struct addrinfo *ainfo=0,*res=0,hints;
 	char buf[256],host[256],serv[256];
 	char buf[256],host[256],serv[256];
 	int error;
 	int error;
 
 
@@ -843,7 +842,7 @@ int peer_connect(peer *p)
  	//hints.ai_protocol = IPPROTO_TCP;
  	//hints.ai_protocol = IPPROTO_TCP;
  	hints.ai_flags = AI_ADDRCONFIG;
  	hints.ai_flags = AI_ADDRCONFIG;
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_socktype = SOCK_STREAM;
-	
+
 	sprintf(buf,"%d",p->port);
 	sprintf(buf,"%d",p->port);
 
 
 	error = getaddrinfo(p->fqdn.s, buf, &hints, &res);
 	error = getaddrinfo(p->fqdn.s, buf, &hints, &res);
@@ -853,14 +852,14 @@ int peer_connect(peer *p)
 			p->fqdn.len,p->fqdn.s,p->port,gai_strerror(error));
 			p->fqdn.len,p->fqdn.s,p->port,gai_strerror(error));
 		goto error;
 		goto error;
 	}
 	}
-		
+
 	for(ainfo = res;ainfo;ainfo = ainfo->ai_next)
 	for(ainfo = res;ainfo;ainfo = ainfo->ai_next)
 	{
 	{
 		if (getnameinfo(ainfo->ai_addr,ainfo->ai_addrlen,
 		if (getnameinfo(ainfo->ai_addr,ainfo->ai_addrlen,
 			host,256,serv,256,NI_NUMERICHOST|NI_NUMERICSERV)==0){
 			host,256,serv,256,NI_NUMERICHOST|NI_NUMERICSERV)==0){
 				LM_WARN("peer_connect(): Trying to connect to %s port %s\n",
 				LM_WARN("peer_connect(): Trying to connect to %s port %s\n",
 					host,serv);
 					host,serv);
-		}				
+		}
 
 
 		if ((sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) == -1) {
 		if ((sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) == -1) {
 			LM_ERR("peer_connect(): error creating client socket to %s port %s >"
 			LM_ERR("peer_connect(): error creating client socket to %s port %s >"
@@ -879,35 +878,35 @@ int peer_connect(peer *p)
 						  .tv_sec = config->connect_timeout,
 						  .tv_sec = config->connect_timeout,
 						  .tv_usec = 0,
 						  .tv_usec = 0,
 					  };
 					  };
-					  fd_set myset; 
-					  FD_ZERO(&myset); 
+					  fd_set myset;
+					  FD_ZERO(&myset);
 					  FD_SET(sock, &myset);
 					  FD_SET(sock, &myset);
-					  if (select(sock+1, NULL, &myset, NULL, &tv) > 0) { 
+					  if (select(sock+1, NULL, &myset, NULL, &tv) > 0) {
 						  socklen_t lon = sizeof(int);
 						  socklen_t lon = sizeof(int);
 						  int  valopt;
 						  int  valopt;
-						  getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon); 
-						  if (valopt) { 
+						  getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon);
+						  if (valopt) {
 					    	  LM_WARN("peer_connect(): Error opening connection to to %s port %s >%s\n",host,serv,strerror(valopt));
 					    	  LM_WARN("peer_connect(): Error opening connection to to %s port %s >%s\n",host,serv,strerror(valopt));
-					    	  close(sock);		
+					    	  close(sock);
 					    	  continue;
 					    	  continue;
-					      } 
-					  }else{ 
+					      }
+					  }else{
 				    	  LM_WARN("peer_connect(): Timeout or error opening connection to to %s port %s >%s\n",host,serv,strerror(errno));
 				    	  LM_WARN("peer_connect(): Timeout or error opening connection to to %s port %s >%s\n",host,serv,strerror(errno));
-				    	  close(sock);		
+				    	  close(sock);
 				    	  continue;
 				    	  continue;
-					  } 					  
+					  }
 				}
 				}
 			}else{
 			}else{
 				LM_WARN("peer_connect(): Error opening connection to to %s port %s >%s\n",host,serv,strerror(errno));
 				LM_WARN("peer_connect(): Error opening connection to to %s port %s >%s\n",host,serv,strerror(errno));
-				close(sock);		
+				close(sock);
 				continue;
 				continue;
 			}
 			}
-			
+
 			x=fcntl(sock,F_GETFL,0);
 			x=fcntl(sock,F_GETFL,0);
 			fcntl(sock,F_SETFL,x & (~O_NONBLOCK));
 			fcntl(sock,F_SETFL,x & (~O_NONBLOCK));
 		}
 		}
 		setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
 		setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
-	
+
 		LM_INFO("peer_connect(): Peer %.*s:%d connected\n",p->fqdn.len,p->fqdn.s,p->port);
 		LM_INFO("peer_connect(): Peer %.*s:%d connected\n",p->fqdn.len,p->fqdn.s,p->port);
 
 
 		if (!send_fd(p->fd_exchange_pipe,sock,p)){
 		if (!send_fd(p->fd_exchange_pipe,sock,p)){
@@ -915,13 +914,13 @@ int peer_connect(peer *p)
 			close(sock);
 			close(sock);
 			goto error;
 			goto error;
 		}
 		}
-		
-		if (res) freeaddrinfo(res);			
+
+		if (res) freeaddrinfo(res);
 		return sock;
 		return sock;
 	}
 	}
 error:
 error:
-	if (res) freeaddrinfo(res);	
-	return -1;	
+	if (res) freeaddrinfo(res);
+	return -1;
 }
 }
 
 
 
 
@@ -937,7 +936,7 @@ int receiver_send_socket(int sock, peer *p)
 		pipe_fd = p->fd_exchange_pipe;
 		pipe_fd = p->fd_exchange_pipe;
 	else
 	else
 		pipe_fd = fd_exchange_pipe_unknown;
 		pipe_fd = fd_exchange_pipe_unknown;
-	
+
 	return send_fd(pipe_fd,sock,p);
 	return send_fd(pipe_fd,sock,p);
 }
 }
 
 
@@ -962,18 +961,18 @@ int peer_send_msg(peer *p,AAAMessage *msg)
 	}
 	}
 	fd = open(p->send_pipe_name.s,O_WRONLY);
 	fd = open(p->send_pipe_name.s,O_WRONLY);
 	if (fd<0){
 	if (fd<0){
-		LM_ERR("peer_send_msg(): Peer %.*s error on pipe open > %s\n",p->fqdn.len,p->fqdn.s,strerror(errno));		
+		LM_ERR("peer_send_msg(): Peer %.*s error on pipe open > %s\n",p->fqdn.len,p->fqdn.s,strerror(errno));
 		return 0;
 		return 0;
 	}
 	}
 	LM_DBG("peer_send_msg(): Pipe push [%p]\n",msg);
 	LM_DBG("peer_send_msg(): Pipe push [%p]\n",msg);
 	n = write(fd,&msg,sizeof(AAAMessage *));
 	n = write(fd,&msg,sizeof(AAAMessage *));
 	if (n<0) {
 	if (n<0) {
-		LM_ERR("peer_send_msg(): Peer %.*s error on pipe write > %s\n",p->fqdn.len,p->fqdn.s,strerror(errno));		
+		LM_ERR("peer_send_msg(): Peer %.*s error on pipe write > %s\n",p->fqdn.len,p->fqdn.s,strerror(errno));
 		close(fd);
 		close(fd);
 		return 0;
 		return 0;
 	}
 	}
 	if (n!=sizeof(AAAMessage *)) {
 	if (n!=sizeof(AAAMessage *)) {
-		LM_ERR("peer_send_msg(): Peer %.*s error on pipe write > only %d bytes written\n",p->fqdn.len,p->fqdn.s,n);		
+		LM_ERR("peer_send_msg(): Peer %.*s error on pipe write > only %d bytes written\n",p->fqdn.len,p->fqdn.s,n);
 		close(fd);
 		close(fd);
 		return 0;
 		return 0;
 	}
 	}
@@ -985,7 +984,7 @@ int peer_send_msg(peer *p,AAAMessage *msg)
  * Send a message to a peer (only to be called from the receiver process).
  * Send a message to a peer (only to be called from the receiver process).
  * This directly writes the message on the socket. It is used for transmission during
  * This directly writes the message on the socket. It is used for transmission during
  * the Capability Exchange procedure, when the send pipes are not opened yet.
  * the Capability Exchange procedure, when the send pipes are not opened yet.
- * It also sends the file descriptor to the peer's dedicated receiver if one found. 
+ * It also sends the file descriptor to the peer's dedicated receiver if one found.
  * @param p - the peer to send to
  * @param p - the peer to send to
  * @param sock - the socket to send through
  * @param sock - the socket to send through
  * @param msg - the message to send
  * @param msg - the message to send
@@ -997,14 +996,14 @@ int peer_send(peer *p,int sock,AAAMessage *msg,int locked)
 	int n;
 	int n;
 	serviced_peer_t *sp;
 	serviced_peer_t *sp;
 
 
-	
+
 	if (!p||!msg||sock<0) return 0;
 	if (!p||!msg||sock<0) return 0;
 	LM_DBG("peer_send(): [%.*s] sending direct message to peer\n",
 	LM_DBG("peer_send(): [%.*s] sending direct message to peer\n",
 			p->fqdn.len,
 			p->fqdn.len,
 			p->fqdn.s);
 			p->fqdn.s);
-	
+
 	if (!AAABuildMsgBuffer(msg)) return 0;
 	if (!AAABuildMsgBuffer(msg)) return 0;
-	
+
 	if (!locked) lock_get(p->lock);
 	if (!locked) lock_get(p->lock);
 
 
 	while( (n=write(sock,msg->buf.s,msg->buf.len))==-1 ) {
 	while( (n=write(sock,msg->buf.s,msg->buf.len))==-1 ) {
@@ -1015,18 +1014,18 @@ int peer_send(peer *p,int sock,AAAMessage *msg,int locked)
 		if (p->I_sock==sock) sm_process(p,I_Peer_Disc,0,1,p->I_sock);
 		if (p->I_sock==sock) sm_process(p,I_Peer_Disc,0,1,p->I_sock);
 		if (p->R_sock==sock) sm_process(p,R_Peer_Disc,0,1,p->R_sock);
 		if (p->R_sock==sock) sm_process(p,R_Peer_Disc,0,1,p->R_sock);
 		if (!locked) lock_release(p->lock);
 		if (!locked) lock_release(p->lock);
-		AAAFreeMessage(&msg);		
+		AAAFreeMessage(&msg);
 		return 0;
 		return 0;
 	}
 	}
 
 
 	if (n!=msg->buf.len){
 	if (n!=msg->buf.len){
 		LM_ERR("peer_send(): only wrote %d/%d bytes\n",n,msg->buf.len);
 		LM_ERR("peer_send(): only wrote %d/%d bytes\n",n,msg->buf.len);
 		if (!locked) lock_release(p->lock);
 		if (!locked) lock_release(p->lock);
-		AAAFreeMessage(&msg);		
+		AAAFreeMessage(&msg);
 		return 0;
 		return 0;
 	}
 	}
 	if (!locked) lock_release(p->lock);
 	if (!locked) lock_release(p->lock);
-	
+
 	AAAFreeMessage(&msg);
 	AAAFreeMessage(&msg);
 
 
 	/* now switch the peer processing to its dedicated process if this is not a dynamic peer */
 	/* now switch the peer processing to its dedicated process if this is not a dynamic peer */
@@ -1041,8 +1040,8 @@ int peer_send(peer *p,int sock,AAAMessage *msg,int locked)
 				break;
 				break;
 			}
 			}
 	}
 	}
-	
-	return 1;	
+
+	return 1;
 }
 }
 
 
 
 
@@ -1060,7 +1059,7 @@ void receive_message(AAAMessage *msg,serviced_peer_t *sp)
 			sp->p?sp->p->fqdn.len:0,
 			sp->p?sp->p->fqdn.len:0,
 			sp->p?sp->p->fqdn.s:0,
 			sp->p?sp->p->fqdn.s:0,
 			msg->commandCode);
 			msg->commandCode);
-	
+
 	if (!sp->p){
 	if (!sp->p){
 		switch (msg->commandCode){
 		switch (msg->commandCode){
 			case Code_CE:
 			case Code_CE:
@@ -1077,7 +1076,7 @@ void receive_message(AAAMessage *msg,serviced_peer_t *sp)
 					}else{
 					}else{
 						LM_DBG("receive_message(): [%.*s] This receiver has no peer associated\n",
 						LM_DBG("receive_message(): [%.*s] This receiver has no peer associated\n",
 								sp->p?sp->p->fqdn.len:0,
 								sp->p?sp->p->fqdn.len:0,
-								sp->p?sp->p->fqdn.s:0	);						
+								sp->p?sp->p->fqdn.s:0	);
 						//set_peer_pipe();
 						//set_peer_pipe();
 						make_send_pipe(sp);
 						make_send_pipe(sp);
 						sm_process(sp->p,R_Conn_CER,msg,0,sp->tcp_socket);
 						sm_process(sp->p,R_Conn_CER,msg,0,sp->tcp_socket);
@@ -1090,7 +1089,7 @@ void receive_message(AAAMessage *msg,serviced_peer_t *sp)
 				break;
 				break;
 			default:
 			default:
 				LM_ERR("receive_msg(): Received non-CE from an unknown peer -ignored\n");
 				LM_ERR("receive_msg(): Received non-CE from an unknown peer -ignored\n");
-				AAAFreeMessage(&msg);				
+				AAAFreeMessage(&msg);
 		}
 		}
 	}else{
 	}else{
 		touch_peer(sp->p);
 		touch_peer(sp->p);
@@ -1101,48 +1100,48 @@ void receive_message(AAAMessage *msg,serviced_peer_t *sp)
 				}else
 				}else
 					sm_process(sp->p,I_Rcv_CEA,msg,0,sp->tcp_socket);
 					sm_process(sp->p,I_Rcv_CEA,msg,0,sp->tcp_socket);
 				break;
 				break;
-			case I_Open:			
+			case I_Open:
 				switch (msg->commandCode){
 				switch (msg->commandCode){
 					case Code_CE:
 					case Code_CE:
-						if (is_req(msg)) sm_process(sp->p,I_Rcv_CER,msg,0,sp->tcp_socket);	
+						if (is_req(msg)) sm_process(sp->p,I_Rcv_CER,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,I_Rcv_CEA,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,I_Rcv_CEA,msg,0,sp->tcp_socket);
 						break;
 						break;
 					case Code_DW:
 					case Code_DW:
-						if (is_req(msg)) sm_process(sp->p,I_Rcv_DWR,msg,0,sp->tcp_socket);	
+						if (is_req(msg)) sm_process(sp->p,I_Rcv_DWR,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,I_Rcv_DWA,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,I_Rcv_DWA,msg,0,sp->tcp_socket);
 						break;
 						break;
 					case Code_DP:
 					case Code_DP:
-						if (is_req(msg)) sm_process(sp->p,I_Rcv_DPR,msg,0,sp->tcp_socket);	
+						if (is_req(msg)) sm_process(sp->p,I_Rcv_DPR,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,I_Rcv_DPA,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,I_Rcv_DPA,msg,0,sp->tcp_socket);
 						break;
 						break;
 					default:
 					default:
 						sm_process(sp->p,I_Rcv_Message,msg,0,sp->tcp_socket);
 						sm_process(sp->p,I_Rcv_Message,msg,0,sp->tcp_socket);
-				}				
-				break;				
-			case R_Open:			
+				}
+				break;
+			case R_Open:
 				switch (msg->commandCode){
 				switch (msg->commandCode){
 					case Code_CE:
 					case Code_CE:
-						if (is_req(msg)) sm_process(sp->p,R_Rcv_CER,msg,0,sp->tcp_socket);	
+						if (is_req(msg)) sm_process(sp->p,R_Rcv_CER,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,R_Rcv_CEA,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,R_Rcv_CEA,msg,0,sp->tcp_socket);
 						break;
 						break;
 					case Code_DW:
 					case Code_DW:
-						if (is_req(msg)) sm_process(sp->p,R_Rcv_DWR,msg,0,sp->tcp_socket);	
+						if (is_req(msg)) sm_process(sp->p,R_Rcv_DWR,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,R_Rcv_DWA,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,R_Rcv_DWA,msg,0,sp->tcp_socket);
 						break;
 						break;
 					case Code_DP:
 					case Code_DP:
-						if (is_req(msg)) sm_process(sp->p,R_Rcv_DPR,msg,0,sp->tcp_socket);	
+						if (is_req(msg)) sm_process(sp->p,R_Rcv_DPR,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,R_Rcv_DPA,msg,0,sp->tcp_socket);
 									else sm_process(sp->p,R_Rcv_DPA,msg,0,sp->tcp_socket);
 						break;
 						break;
 					default:
 					default:
 						sm_process(sp->p,R_Rcv_Message,msg,0,sp->tcp_socket);
 						sm_process(sp->p,R_Rcv_Message,msg,0,sp->tcp_socket);
-				}				
-				break;				
+				}
+				break;
 			default:
 			default:
 				LM_ERR("receive_msg(): [%.*s] Received msg while peer in state %d -ignored\n",
 				LM_ERR("receive_msg(): [%.*s] Received msg while peer in state %d -ignored\n",
 						sp->p->fqdn.len,
 						sp->p->fqdn.len,
 						sp->p->fqdn.s,
 						sp->p->fqdn.s,
 						sp->p->state);
 						sp->p->state);
-				AAAFreeMessage(&msg);								
+				AAAFreeMessage(&msg);
 		}
 		}
 	}
 	}
 }
 }

+ 6 - 1
modules/cdp/receiver.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/routing.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/routing.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/sem.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 48 - 48
modules/cdp/session.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -77,7 +82,7 @@ inline void AAASessionsLock(unsigned int hash)
  */
  */
 inline void AAASessionsUnlock(unsigned int hash)
 inline void AAASessionsUnlock(unsigned int hash)
 {
 {
-	
+
 	if ( hash >=0 && hash < sessions_hash_size ){
 	if ( hash >=0 && hash < sessions_hash_size ){
 		lock_release(sessions[hash].lock);
 		lock_release(sessions[hash].lock);
 	}
 	}
@@ -109,7 +114,7 @@ void free_session(cdp_session_t *x)
 			default:
 			default:
 				LM_ERR("free_session(): Unknown session type %d!\n",x->type);
 				LM_ERR("free_session(): Unknown session type %d!\n",x->type);
 		}
 		}
-		
+
 		if(x->dest_host.s) shm_free(x->dest_host.s);
 		if(x->dest_host.s) shm_free(x->dest_host.s);
 		if(x->dest_realm.s) shm_free(x->dest_realm.s);
 		if(x->dest_realm.s) shm_free(x->dest_realm.s);
 
 
@@ -131,14 +136,14 @@ int cdp_sessions_init(int hash_size)
 	}
 	}
 	session_lock = lock_init(session_lock);
 	session_lock = lock_init(session_lock);
 	sessions_hash_size=hash_size;
 	sessions_hash_size=hash_size;
-	
+
 	sessions = shm_malloc(sizeof(cdp_session_list_t)*hash_size);
 	sessions = shm_malloc(sizeof(cdp_session_list_t)*hash_size);
 	if (!sessions){
 	if (!sessions){
 		LOG_NO_MEM("shm",sizeof(cdp_session_list_t)*hash_size);
 		LOG_NO_MEM("shm",sizeof(cdp_session_list_t)*hash_size);
 		goto error;
 		goto error;
 	}
 	}
 	memset(sessions,0,sizeof(cdp_session_list_t)*hash_size);
 	memset(sessions,0,sizeof(cdp_session_list_t)*hash_size);
-	
+
 	for(i=0;i<hash_size;i++){
 	for(i=0;i<hash_size;i++){
 		sessions[i].lock = lock_alloc();
 		sessions[i].lock = lock_alloc();
 		if (!sessions[i].lock){
 		if (!sessions[i].lock){
@@ -147,7 +152,7 @@ int cdp_sessions_init(int hash_size)
 		}
 		}
 		sessions[i].lock = lock_init(sessions[i].lock);
 		sessions[i].lock = lock_init(sessions[i].lock);
 	}
 	}
-	
+
 	session_id1 = shm_malloc(sizeof(unsigned int));
 	session_id1 = shm_malloc(sizeof(unsigned int));
 	if (!session_id1){
 	if (!session_id1){
 		LOG_NO_MEM("shm",sizeof(unsigned int));
 		LOG_NO_MEM("shm",sizeof(unsigned int));
@@ -158,12 +163,12 @@ int cdp_sessions_init(int hash_size)
 		LOG_NO_MEM("shm",sizeof(unsigned int));
 		LOG_NO_MEM("shm",sizeof(unsigned int));
 		goto error;
 		goto error;
 	}
 	}
-	srand((unsigned int)time(0));	
+	srand((unsigned int)time(0));
 	*session_id1 = rand();
 	*session_id1 = rand();
 	*session_id1 <<= 16;
 	*session_id1 <<= 16;
 	*session_id1 += time(0)&0xFFFF;
 	*session_id1 += time(0)&0xFFFF;
 	*session_id2 = 0;
 	*session_id2 = 0;
-	
+
 	add_timer(1,0,cdp_sessions_timer,0);
 	add_timer(1,0,cdp_sessions_timer,0);
 	return 1;
 	return 1;
 error:
 error:
@@ -177,24 +182,24 @@ int cdp_sessions_destroy()
 {
 {
 	int i;
 	int i;
 	cdp_session_t *n,*x;
 	cdp_session_t *n,*x;
-	
+
 	if (session_lock){
 	if (session_lock){
 		lock_get(session_lock);
 		lock_get(session_lock);
 		lock_destroy(session_lock);
 		lock_destroy(session_lock);
-		lock_dealloc((void*)session_lock);		
+		lock_dealloc((void*)session_lock);
 		session_lock=0;
 		session_lock=0;
-	}	
+	}
 	for(i=0;i<sessions_hash_size;i++){
 	for(i=0;i<sessions_hash_size;i++){
 		AAASessionsLock(i);
 		AAASessionsLock(i);
 		for(x = sessions[i].head; x; x = n){
 		for(x = sessions[i].head; x; x = n){
 			n = x->next;
 			n = x->next;
-			free_session(x);	
+			free_session(x);
 		}
 		}
 		lock_destroy(sessions[i].lock);
 		lock_destroy(sessions[i].lock);
 		lock_dealloc((void*)sessions[i].lock);
 		lock_dealloc((void*)sessions[i].lock);
 	}
 	}
 	shm_free(sessions);
 	shm_free(sessions);
-			
+
 	shm_free(session_id1);
 	shm_free(session_id1);
 	shm_free(session_id2);
 	shm_free(session_id2);
 	return 1;
 	return 1;
@@ -230,7 +235,7 @@ inline unsigned int get_str_hash(str x,int hash_size)
 
 
    h=((h)+(h>>11))+((h>>13)+(h>>23));
    h=((h)+(h>>11))+((h>>13)+(h>>23));
    return (h)%hash_size;
    return (h)%hash_size;
-#undef h_inc 
+#undef h_inc
 }
 }
 
 
 /**
 /**
@@ -274,7 +279,7 @@ void cdp_add_session(cdp_session_t *x)
 	x->prev = sessions[x->hash].tail;
 	x->prev = sessions[x->hash].tail;
 	if (sessions[x->hash].tail) sessions[x->hash].tail->next = x;
 	if (sessions[x->hash].tail) sessions[x->hash].tail->next = x;
 	sessions[x->hash].tail = x;
 	sessions[x->hash].tail = x;
-	if (!sessions[x->hash].head) sessions[x->hash].head = x;	
+	if (!sessions[x->hash].head) sessions[x->hash].head = x;
 }
 }
 
 
 /**
 /**
@@ -296,8 +301,8 @@ cdp_session_t* cdp_get_session(str id)
 			if (x->id.len == id.len &&
 			if (x->id.len == id.len &&
 				strncasecmp(x->id.s,id.s,id.len)==0)
 				strncasecmp(x->id.s,id.s,id.len)==0)
 					return x;
 					return x;
-		}			
-	AAASessionsUnlock(hash);	
+		}
+	AAASessionsUnlock(hash);
 	LM_DBG("no session found\n");
 	LM_DBG("no session found\n");
 	return 0;
 	return 0;
 }
 }
@@ -306,7 +311,7 @@ cdp_session_t* cdp_get_session(str id)
 /**
 /**
  * Removes and frees a session.
  * Removes and frees a session.
  * \note must be called with a lock on the x->hash and it will unlock on exit. Do not use x after calling this
  * \note must be called with a lock on the x->hash and it will unlock on exit. Do not use x after calling this
- * 
+ *
  * @param x - the session to remove
  * @param x - the session to remove
  */
  */
 void del_session(cdp_session_t *x)
 void del_session(cdp_session_t *x)
@@ -325,9 +330,9 @@ void del_session(cdp_session_t *x)
 	else if (x->prev) x->prev->next = x->next;
 	else if (x->prev) x->prev->next = x->next;
 	if (sessions[x->hash].tail == x) sessions[x->hash].tail = x->prev;
 	if (sessions[x->hash].tail == x) sessions[x->hash].tail = x->prev;
 	else if (x->next) x->next->prev = x->prev;
 	else if (x->next) x->next->prev = x->prev;
-	
+
 	AAASessionsUnlock(hash);
 	AAASessionsUnlock(hash);
-	
+
 	free_session(x);
 	free_session(x);
 }
 }
 
 
@@ -364,7 +369,7 @@ static int generate_session_id(str *id, unsigned int end_pad_len)
 	s2 = *session_id2 +1;
 	s2 = *session_id2 +1;
 	*session_id2 = s2;
 	*session_id2 = s2;
 	lock_release(session_lock);
 	lock_release(session_lock);
-	
+
 	/* build the sessionID */
 	/* build the sessionID */
 	sprintf(id->s,"%.*s;%u;%u",config->identity.len,config->identity.s,*session_id1,s2);
 	sprintf(id->s,"%.*s;%u;%u",config->identity.len,config->identity.s,*session_id1,s2);
 	id->len = strlen(id->s);
 	id->len = strlen(id->s);
@@ -373,21 +378,16 @@ error:
 	return -1;
 	return -1;
 }
 }
 
 
-void cdp_sessions_log(int level)
+void cdp_sessions_log()
 {
 {
 	int hash;
 	int hash;
 	cdp_session_t *x;
 	cdp_session_t *x;
-#ifdef SER_MOD_INTERFACE
-	if (!is_printable(level))
-#else		
-	if (debug<level)
-#endif
-		return;
-	LOG(level,"------- CDP Sessions ----------------\n");
-	for(hash=0;hash<sessions_hash_size;hash++){		
+
+	LM_DBG("------- CDP Sessions ----------------\n");
+	for(hash=0;hash<sessions_hash_size;hash++){
 		AAASessionsLock(hash);
 		AAASessionsLock(hash);
-		for(x = sessions[hash].head;x;x=x->next) {						
-			LOG(level," %3u. [%.*s] AppId [%d] Type [%d]\n",
+		for(x = sessions[hash].head;x;x=x->next) {
+			LM_DBG(" %3u. [%.*s] AppId [%d] Type [%d]\n",
 					hash,
 					hash,
 					x->id.len,x->id.s,
 					x->id.len,x->id.s,
 					x->application_id,
 					x->application_id,
@@ -395,7 +395,7 @@ void cdp_sessions_log(int level)
 			switch (x->type){
 			switch (x->type){
 				case AUTH_CLIENT_STATEFULL:
 				case AUTH_CLIENT_STATEFULL:
 				case AUTH_SERVER_STATEFULL:
 				case AUTH_SERVER_STATEFULL:
-					LOG(level,"\tAuth State [%d] Timeout [%d] Lifetime [%d] Grace [%d] Generic [%p]\n",
+					LM_DBG("\tAuth State [%d] Timeout [%d] Lifetime [%d] Grace [%d] Generic [%p]\n",
 							x->u.auth.state,
 							x->u.auth.state,
 							(int)(x->u.auth.timeout-time(0)),
 							(int)(x->u.auth.timeout-time(0)),
 							x->u.auth.lifetime?(int)(x->u.auth.lifetime-time(0)):-1,
 							x->u.auth.lifetime?(int)(x->u.auth.lifetime-time(0)):-1,
@@ -408,14 +408,14 @@ void cdp_sessions_log(int level)
 		}
 		}
 		AAASessionsUnlock(hash);
 		AAASessionsUnlock(hash);
 	}
 	}
-	LOG(level,"-------------------------------------\n");
+	LM_DBG("-------------------------------------\n");
 }
 }
 
 
 int cdp_sessions_timer(time_t now, void* ptr)
 int cdp_sessions_timer(time_t now, void* ptr)
 {
 {
 	int hash;
 	int hash;
 	cdp_session_t *x,*n;
 	cdp_session_t *x,*n;
-	for(hash=0;hash<sessions_hash_size;hash++){		
+	for(hash=0;hash<sessions_hash_size;hash++){
 		AAASessionsLock(hash);
 		AAASessionsLock(hash);
 		for(x = sessions[hash].head;x;x=n) {
 		for(x = sessions[hash].head;x;x=n) {
 			n = x->next;
 			n = x->next;
@@ -452,12 +452,12 @@ int cdp_sessions_timer(time_t now, void* ptr)
 					break;
 					break;
 				default:
 				default:
 					break;
 					break;
-					
+
 			}
 			}
 		}
 		}
 		AAASessionsUnlock(hash);
 		AAASessionsUnlock(hash);
 	}
 	}
-	if (now%5==0)cdp_sessions_log(L_DBG);
+	if (now%5==0)cdp_sessions_log();
 	return 1;
 	return 1;
 }
 }
 
 
@@ -472,7 +472,7 @@ AAASession* AAACreateSession(void *generic_data)
 {
 {
 	AAASession *s;
 	AAASession *s;
 	str id;
 	str id;
-	
+
 	generate_session_id(&id,0);
 	generate_session_id(&id,0);
 	s = cdp_new_session(id,UNKNOWN_SESSION);
 	s = cdp_new_session(id,UNKNOWN_SESSION);
 	if (s) {
 	if (s) {
@@ -494,7 +494,7 @@ AAASession* AAAMakeSession(int app_id,int type,str session_id)
 {
 {
 	AAASession *s;
 	AAASession *s;
 	str id;
 	str id;
-	
+
 	id.s = shm_malloc(session_id.len);
 	id.s = shm_malloc(session_id.len);
 	if (!id.s){
 	if (!id.s){
 		LM_ERR("Error allocating %d bytes!\n",session_id.len);
 		LM_ERR("Error allocating %d bytes!\n",session_id.len);
@@ -504,7 +504,7 @@ AAASession* AAAMakeSession(int app_id,int type,str session_id)
 	id.len = session_id.len;
 	id.len = session_id.len;
 	s = cdp_new_session(id,type);
 	s = cdp_new_session(id,type);
 	s->application_id = app_id;
 	s->application_id = app_id;
-	if (s) {		
+	if (s) {
 		cdp_add_session(s);
 		cdp_add_session(s);
 	}
 	}
 	return s;
 	return s;
@@ -515,7 +515,7 @@ AAASession* AAAMakeSession(int app_id,int type,str session_id)
 void AAADropSession(AAASession *s)
 void AAADropSession(AAASession *s)
 {
 {
 	// first give a chance to the cb to free the generic param
 	// first give a chance to the cb to free the generic param
-	if (s&&s->cb) 
+	if (s&&s->cb)
 		(s->cb)(AUTH_EV_SESSION_DROP,s);
 		(s->cb)(AUTH_EV_SESSION_DROP,s);
 	del_session(s);
 	del_session(s);
 }
 }
@@ -525,17 +525,17 @@ AAASession* cdp_new_auth_session(str id,int is_client,int is_statefull)
 {
 {
 	AAASession *s;
 	AAASession *s;
 	cdp_session_type_t type;
 	cdp_session_type_t type;
-	
+
 	if (is_client){
 	if (is_client){
 		if (is_statefull) type = AUTH_CLIENT_STATEFULL;
 		if (is_statefull) type = AUTH_CLIENT_STATEFULL;
 		else type = AUTH_CLIENT_STATELESS;
 		else type = AUTH_CLIENT_STATELESS;
 	}else{
 	}else{
 		if (is_statefull) type = AUTH_SERVER_STATEFULL;
 		if (is_statefull) type = AUTH_SERVER_STATEFULL;
-		else type = AUTH_SERVER_STATELESS;		
+		else type = AUTH_SERVER_STATELESS;
 	}
 	}
 	s = cdp_new_session(id,type);
 	s = cdp_new_session(id,type);
 	if (s) {
 	if (s) {
-		s->u.auth.timeout=time(0)+config->default_auth_session_timeout; 
+		s->u.auth.timeout=time(0)+config->default_auth_session_timeout;
 		s->u.auth.lifetime=0;
 		s->u.auth.lifetime=0;
 		s->u.auth.grace_period=0;
 		s->u.auth.grace_period=0;
 		cdp_add_session(s);
 		cdp_add_session(s);
@@ -553,7 +553,7 @@ AAASession* AAACreateClientAuthSession(int is_statefull,AAASessionCallback_f *cb
 {
 {
 	AAASession *s;
 	AAASession *s;
 	str id;
 	str id;
-	
+
 	generate_session_id(&id,0);
 	generate_session_id(&id,0);
 
 
 	s = cdp_new_auth_session(id,1,is_statefull);
 	s = cdp_new_auth_session(id,1,is_statefull);
@@ -575,7 +575,7 @@ AAASession* AAACreateServerAuthSession(AAAMessage *msg,int is_statefull,AAASessi
 {
 {
 	AAASession *s;
 	AAASession *s;
 	str id;
 	str id;
-	
+
 	if (!msg||!msg->sessionId||!msg->sessionId->data.len){
 	if (!msg||!msg->sessionId||!msg->sessionId->data.len){
 		LM_ERR("Error retrieving the Session-Id from the message.\n");
 		LM_ERR("Error retrieving the Session-Id from the message.\n");
 		return 0;
 		return 0;
@@ -594,8 +594,8 @@ AAASession* AAACreateServerAuthSession(AAAMessage *msg,int is_statefull,AAASessi
 			if (s->cb)
 			if (s->cb)
 				(s->cb)(AUTH_EV_SESSION_CREATED,s);
 				(s->cb)(AUTH_EV_SESSION_CREATED,s);
 			update_auth_session_timers(&(s->u.auth),msg);
 			update_auth_session_timers(&(s->u.auth),msg);
-			auth_server_statefull_sm_process(s,AUTH_EV_RECV_REQ,msg);	
-			// this is a special exception where the session lock is not released 
+			auth_server_statefull_sm_process(s,AUTH_EV_RECV_REQ,msg);
+			// this is a special exception where the session lock is not released
 			//s=0;
 			//s=0;
 		}
 		}
 	}
 	}

+ 28 - 23
modules/cdp/session.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -52,16 +57,16 @@ typedef void (AAASessionCallback_f)(int event,void *session);
 /** Types of sessions */
 /** Types of sessions */
 typedef enum {
 typedef enum {
 	UNKNOWN_SESSION			= 0,
 	UNKNOWN_SESSION			= 0,
-	
+
 	AUTH_CLIENT_STATELESS	= 1,
 	AUTH_CLIENT_STATELESS	= 1,
 	AUTH_SERVER_STATELESS	= 2,
 	AUTH_SERVER_STATELESS	= 2,
 	AUTH_CLIENT_STATEFULL	= 3,
 	AUTH_CLIENT_STATEFULL	= 3,
 	AUTH_SERVER_STATEFULL	= 4,
 	AUTH_SERVER_STATEFULL	= 4,
-	
+
 	ACCT_CLIENT				= 5,
 	ACCT_CLIENT				= 5,
 	ACCT_SERVER_STATELESS	= 6,
 	ACCT_SERVER_STATELESS	= 6,
 	ACCT_SERVER_STATEFULL	= 7,
 	ACCT_SERVER_STATEFULL	= 7,
-		
+
 } cdp_session_type_t;
 } cdp_session_type_t;
 
 
 /** auth session states */
 /** auth session states */
@@ -76,7 +81,7 @@ typedef enum {
 typedef enum {
 typedef enum {
 	AUTH_EV_START						=0,
 	AUTH_EV_START						=0,
 	AUTH_EV_SEND_REQ 					=1,
 	AUTH_EV_SEND_REQ 					=1,
-	AUTH_EV_SEND_ANS					=2,	
+	AUTH_EV_SEND_ANS					=2,
 	AUTH_EV_SEND_ANS_SUCCESS			=3,
 	AUTH_EV_SEND_ANS_SUCCESS			=3,
 	AUTH_EV_SEND_ANS_UNSUCCESS			=4,
 	AUTH_EV_SEND_ANS_UNSUCCESS			=4,
 	AUTH_EV_RECV_ASR					=5,
 	AUTH_EV_RECV_ASR					=5,
@@ -101,15 +106,15 @@ typedef enum {
 	AUTH_EV_SESSION_MODIFIED			=24,
 	AUTH_EV_SESSION_MODIFIED			=24,
 	AUTH_EV_SESSION_DROP				=25,
 	AUTH_EV_SESSION_DROP				=25,
 } cdp_auth_event;
 } cdp_auth_event;
-	
+
 /** structure for auth session */
 /** structure for auth session */
 typedef struct _cdp_auth_session_t {
 typedef struct _cdp_auth_session_t {
 	cdp_auth_state state;	/**< current state */
 	cdp_auth_state state;	/**< current state */
-	
+
 	time_t timeout;			/**< absolute time for session timeout  -1 means forever */
 	time_t timeout;			/**< absolute time for session timeout  -1 means forever */
 	time_t lifetime;		/**< absolute time for auth lifetime -1 means forever */
 	time_t lifetime;		/**< absolute time for auth lifetime -1 means forever */
-	time_t grace_period;	/**< grace_period in seconds 	*/ 
-	void* generic_data;			
+	time_t grace_period;	/**< grace_period in seconds 	*/
+	void* generic_data;
 } cdp_auth_session_t;
 } cdp_auth_session_t;
 
 
 /** Accounting states definition */
 /** Accounting states definition */
@@ -147,16 +152,16 @@ typedef enum {
 typedef struct _acc_session {
 typedef struct _acc_session {
 
 
 	cdp_acc_state_t state;						/**< current state */
 	cdp_acc_state_t state;						/**< current state */
-	
+
 	str dlgid;       						/**< application-level identifier, combines application session (e.g. SIP dialog) or event with diameter accounting session */
 	str dlgid;       						/**< application-level identifier, combines application session (e.g. SIP dialog) or event with diameter accounting session */
-	
+
 	unsigned int acct_record_number; 		/**< number of last accounting record within this session */
 	unsigned int acct_record_number; 		/**< number of last accounting record within this session */
 	time_t aii;	 							/**< expiration of Acct-Interim-Interval (seconds) */
 	time_t aii;	 							/**< expiration of Acct-Interim-Interval (seconds) */
 	time_t timeout;							/**< session timeout (seconds) */
 	time_t timeout;							/**< session timeout (seconds) */
-	
-	
-	void* generic_data;			
-	
+
+
+	void* generic_data;
+
 } cdp_acc_session_t;
 } cdp_acc_session_t;
 
 
 
 
@@ -166,32 +171,32 @@ typedef struct _acc_session {
 typedef struct _cdp_session_t {
 typedef struct _cdp_session_t {
 	unsigned int hash;
 	unsigned int hash;
 	str id;                             /**< session-ID as string */
 	str id;                             /**< session-ID as string */
-	unsigned int application_id;		/**< specific application id associated with this session */	
+	unsigned int application_id;		/**< specific application id associated with this session */
 	unsigned int vendor_id;				/**< specific vendor id for this session */
 	unsigned int vendor_id;				/**< specific vendor id for this session */
 	cdp_session_type_t type;
 	cdp_session_type_t type;
-	str dest_host, dest_realm; /*the destination host and realm, used only for auth, for the moment*/	
+	str dest_host, dest_realm; /*the destination host and realm, used only for auth, for the moment*/
 	union {
 	union {
 		cdp_auth_session_t auth;
 		cdp_auth_session_t auth;
 		cdp_acc_session_t acc;
 		cdp_acc_session_t acc;
 		void *generic_data;
 		void *generic_data;
 	} u;
 	} u;
-	 
+
 	AAASessionCallback_f *cb;			/**< session callback function */
 	AAASessionCallback_f *cb;			/**< session callback function */
-	
-	struct _cdp_session_t *next,*prev; 	
+
+	struct _cdp_session_t *next,*prev;
 } cdp_session_t;
 } cdp_session_t;
 
 
 /** Session list structure */
 /** Session list structure */
-typedef struct _cdp_session_list_t {		
+typedef struct _cdp_session_list_t {
 	gen_lock_t *lock;				/**< lock for list operations */
 	gen_lock_t *lock;				/**< lock for list operations */
-	cdp_session_t *head,*tail;		/**< first, last sessions in the list */ 
+	cdp_session_t *head,*tail;		/**< first, last sessions in the list */
 } cdp_session_list_t;
 } cdp_session_list_t;
 
 
 
 
 
 
 int cdp_sessions_init(int hash_size);
 int cdp_sessions_init(int hash_size);
 int cdp_sessions_destroy();
 int cdp_sessions_destroy();
-void cdp_sessions_log(int level);
+void cdp_sessions_log();
 int cdp_sessions_timer(time_t now, void* ptr);
 int cdp_sessions_timer(time_t now, void* ptr);
 
 
 cdp_session_t* cdp_get_session(str id);
 cdp_session_t* cdp_get_session(str id);

+ 7 - 1
modules/cdp/tcp_accept.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -38,6 +43,7 @@
  * 
  * 
  */
  */
 
 
+
 #include <unistd.h>
 #include <unistd.h>
 #include <errno.h>
 #include <errno.h>
 #include <string.h>
 #include <string.h>

+ 6 - 1
modules/cdp/tcp_accept.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/timer.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 6 - 1
modules/cdp/timer.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 20 - 12
modules/cdp/transaction.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -76,13 +81,13 @@ int cdp_trans_destroy()
 			t = trans_list->head;
 			t = trans_list->head;
 			trans_list->head = t->next;
 			trans_list->head = t->next;
 			cdp_free_trans(t);
 			cdp_free_trans(t);
-		}		
+		}
 		lock_destroy(trans_list->lock);
 		lock_destroy(trans_list->lock);
 		lock_dealloc((void*)trans_list->lock);
 		lock_dealloc((void*)trans_list->lock);
 		shm_free(trans_list);
 		shm_free(trans_list);
 		trans_list = 0;
 		trans_list = 0;
 	}
 	}
-	
+
 	return 1;
 	return 1;
 }
 }
 /**
 /**
@@ -92,7 +97,7 @@ int cdp_trans_destroy()
  * @param ptr - generic pointer to pass to the callback on call
  * @param ptr - generic pointer to pass to the callback on call
  * @param timeout - timeout time in seconds
  * @param timeout - timeout time in seconds
  * @param auto_drop - whether to auto drop the transaction on event, or let the application do it later
  * @param auto_drop - whether to auto drop the transaction on event, or let the application do it later
- * @returns the created cdp_trans_t* or NULL on error 
+ * @returns the created cdp_trans_t* or NULL on error
  */
  */
 inline cdp_trans_t* cdp_add_trans(AAAMessage *msg,AAATransactionCallback_f *cb, void *ptr,int timeout,int auto_drop)
 inline cdp_trans_t* cdp_add_trans(AAAMessage *msg,AAATransactionCallback_f *cb, void *ptr,int timeout,int auto_drop)
 {
 {
@@ -108,6 +113,8 @@ inline cdp_trans_t* cdp_add_trans(AAAMessage *msg,AAATransactionCallback_f *cb,
 		shm_free(x);
 		shm_free(x);
 		return 0;
 		return 0;
 	}
 	}
+
+	gettimeofday(&x->started, NULL);
 	x->endtoendid = msg->endtoendId;
 	x->endtoendid = msg->endtoendId;
 	x->hopbyhopid = msg->hopbyhopId;
 	x->hopbyhopid = msg->hopbyhopId;
 	x->cb = cb;
 	x->cb = cb;
@@ -183,27 +190,28 @@ inline void cdp_free_trans(cdp_trans_t *x)
  */
  */
 int cdp_trans_timer(time_t now, void* ptr)
 int cdp_trans_timer(time_t now, void* ptr)
 {
 {
-	cdp_trans_t *x,*n;	
+	cdp_trans_t *x,*n;
 	LM_DBG("trans_timer(): taking care of diameter transactions...\n");
 	LM_DBG("trans_timer(): taking care of diameter transactions...\n");
 	lock_get(trans_list->lock);
 	lock_get(trans_list->lock);
 	x = trans_list->head;
 	x = trans_list->head;
 	while(x)
 	while(x)
 	{
 	{
 		if (now>x->expires){
 		if (now>x->expires){
+            update_stat(stat_cdp_timeouts, 1);		//Transaction has timed out waiting for response
 			x->ans = 0;
 			x->ans = 0;
 			if (x->cb){
 			if (x->cb){
-				(x->cb)(1,*(x->ptr),0);
+				(x->cb)(1,*(x->ptr),0, (now - x->expires));
 			}
 			}
 			n = x->next;
 			n = x->next;
-			
+
 			if (x->prev) x->prev->next = x->next;
 			if (x->prev) x->prev->next = x->next;
 			else trans_list->head = x->next;
 			else trans_list->head = x->next;
 			if (x->next) x->next->prev = x->prev;
 			if (x->next) x->next->prev = x->prev;
 			else trans_list->tail = x->prev;
 			else trans_list->tail = x->prev;
 			if (x->auto_drop) cdp_free_trans(x);
 			if (x->auto_drop) cdp_free_trans(x);
-			
+
 			x = n;
 			x = n;
-		} else 
+		} else
 			x = x->next;
 			x = x->next;
 	}
 	}
 	lock_release(trans_list->lock);
 	lock_release(trans_list->lock);
@@ -219,15 +227,15 @@ int cdp_trans_timer(time_t now, void* ptr)
 * @param app_id - id of the request's application
 * @param app_id - id of the request's application
 * @param cmd_code - request's code
 * @param cmd_code - request's code
 * @returns the AAATransaction*
 * @returns the AAATransaction*
-*/				
+*/
 AAATransaction *AAACreateTransaction(AAAApplicationId app_id,AAACommandCode cmd_code)
 AAATransaction *AAACreateTransaction(AAAApplicationId app_id,AAACommandCode cmd_code)
 {
 {
 	AAATransaction *t;
 	AAATransaction *t;
 	t = shm_malloc(sizeof(AAATransaction));
 	t = shm_malloc(sizeof(AAATransaction));
 	if (!t) return 0;
 	if (!t) return 0;
-	memset(t,0,sizeof(AAATransaction));	
+	memset(t,0,sizeof(AAATransaction));
 	t->application_id=app_id;
 	t->application_id=app_id;
-	t->command_code=cmd_code;			
+	t->command_code=cmd_code;
 	return t;
 	return t;
 }
 }
 
 

+ 8 - 1
modules/cdp/transaction.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -42,12 +47,14 @@
 #define __TRANSACTION_H_
 #define __TRANSACTION_H_
 
 
 #include <time.h>
 #include <time.h>
+#include "statistics.h"
 #include "utils.h"
 #include "utils.h"
 #include "diameter.h"
 #include "diameter.h"
 #include "diameter_api.h"
 #include "diameter_api.h"
 
 
 /** Diameter Transaction representation */
 /** Diameter Transaction representation */
 typedef struct _cdp_trans_t{
 typedef struct _cdp_trans_t{
+	struct timeval started;			/**< Time the transaction was created - used to measure response times */
 	AAAMsgIdentifier endtoendid;	/**< End-to-end id of the messages */
 	AAAMsgIdentifier endtoendid;	/**< End-to-end id of the messages */
 	AAAMsgIdentifier hopbyhopid;	/**< Hop-by-hop id of the messages */
 	AAAMsgIdentifier hopbyhopid;	/**< Hop-by-hop id of the messages */
 	AAATransactionCallback_f *cb;	/**< transactional callback function */
 	AAATransactionCallback_f *cb;	/**< transactional callback function */

+ 6 - 1
modules/cdp/utils.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier

+ 245 - 226
modules/cdp/worker.c

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier
@@ -38,10 +43,10 @@
  * 
  * 
  */
  */
 
 
-#include <time.h> 
+#include <time.h>
 #include <stdlib.h>
 #include <stdlib.h>
-#include <sys/types.h> 
-#include <unistd.h> 
+#include <sys/types.h>
+#include <unistd.h>
 #include <sys/ipc.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
 #include <sys/sem.h>
 
 
@@ -56,144 +61,138 @@
 int dp_add_pid(pid_t pid);
 int dp_add_pid(pid_t pid);
 void dp_del_pid(pid_t pid);
 void dp_del_pid(pid_t pid);
 
 
-extern dp_config *config;		/**< Configuration for this diameter peer 	*/
-
-task_queue_t *tasks;			/**< queue of tasks */
-
-cdp_cb_list_t *callbacks;		/**< list of callbacks for message processing */
+extern dp_config *config; /**< Configuration for this diameter peer 	*/
 
 
+task_queue_t *tasks; /**< queue of tasks */
 
 
+cdp_cb_list_t *callbacks; /**< list of callbacks for message processing */
 
 
+extern unsigned int workerq_latency_threshold; /**<max delay for putting task into worker queue */
 /**
 /**
  * Initializes the worker structures, like the task queue.
  * Initializes the worker structures, like the task queue.
  */
  */
-void worker_init()
-{
-	tasks = shm_malloc(sizeof(task_queue_t));
-	
-	tasks->lock = lock_alloc();
-	tasks->lock = lock_init(tasks->lock);
-	
-	sem_new(tasks->empty,0);
-		
-	sem_new(tasks->full,1);
-		
-	tasks->start = 0;
-	tasks->end = 0;
-	tasks->max = config->queue_length;
-	tasks->queue = shm_malloc(tasks->max*sizeof(task_t));
-	if (!tasks->queue) {
-		LOG_NO_MEM("shm",tasks->max*sizeof(task_t));
-		goto out_of_memory;
-	}
-	memset(tasks->queue,0,tasks->max*sizeof(task_t));
-		
-	callbacks = shm_malloc(sizeof(cdp_cb_list_t));
-	if (!callbacks) goto out_of_memory;
-	callbacks->head = 0; 
-	callbacks->tail = 0;
-	return;
+void worker_init() {
+    tasks = shm_malloc(sizeof (task_queue_t));
+
+    tasks->lock = lock_alloc();
+    tasks->lock = lock_init(tasks->lock);
+
+    sem_new(tasks->empty, 0);
+
+    sem_new(tasks->full, 1);
+
+    tasks->start = 0;
+    tasks->end = 0;
+    tasks->max = config->queue_length;
+    tasks->queue = shm_malloc(tasks->max * sizeof (task_t));
+    if (!tasks->queue) {
+        LOG_NO_MEM("shm", tasks->max * sizeof (task_t));
+        goto out_of_memory;
+    }
+    memset(tasks->queue, 0, tasks->max * sizeof (task_t));
+
+    callbacks = shm_malloc(sizeof (cdp_cb_list_t));
+    if (!callbacks) goto out_of_memory;
+    callbacks->head = 0;
+    callbacks->tail = 0;
+    return;
 out_of_memory:
 out_of_memory:
-	if (tasks){
-		if (tasks->lock) {
-			lock_destroy(tasks->lock);
-			lock_dealloc(&(tasks->lock)); 
-		}
-		sem_free(tasks->full);
-		sem_free(tasks->empty);
-		if (tasks->queue) shm_free(tasks->queue);
-		shm_free(tasks);
-	}
-	if (callbacks) shm_free(callbacks);
+    if (tasks) {
+        if (tasks->lock) {
+            lock_destroy(tasks->lock);
+            lock_dealloc(&(tasks->lock));
+        }
+        sem_free(tasks->full);
+        sem_free(tasks->empty);
+        if (tasks->queue) shm_free(tasks->queue);
+        shm_free(tasks);
+    }
+    if (callbacks) shm_free(callbacks);
 }
 }
 
 
 /**
 /**
- * Destroys the worker structures. 
+ * Destroys the worker structures.
  */
  */
-void worker_destroy()
-{
-	int i,sval=0;
-	if (callbacks){
-		while(callbacks->head)
-			cb_remove(callbacks->head);
-		shm_free(callbacks);
-	}
-
-	// to deny runing the poison queue again
-	config->workers = 0;
-	if (tasks) {
-		lock_get(tasks->lock);
-		for(i=0;i<tasks->max;i++){
-			if (tasks->queue[i].msg) AAAFreeMessage(&(tasks->queue[i].msg));
-			tasks->queue[i].msg = 0;
-			tasks->queue[i].p = 0;
-		}
-		lock_release(tasks->lock);
-
-		LM_INFO("Unlocking workers waiting on empty queue...\n");
-		for(i=0;i<config->workers;i++)
-			sem_release(tasks->empty);
-		LM_INFO("Unlocking workers waiting on full queue...\n");
-		i=0;
-		while(sem_getvalue(tasks->full,&sval)==0)			
-			if (sval<=0) {
-				sem_release(tasks->full);
-				i=1;
-			}
-			else break;
-		sleep(i);
-		
-		lock_get(tasks->lock);
-		shm_free(tasks->queue);
-		lock_destroy(tasks->lock);
-		lock_dealloc((void*)tasks->lock);
-		
-		//lock_release(tasks->empty);
-		sem_free(tasks->full);
-		sem_free(tasks->empty);
-		
-		shm_free(tasks);
-	}
+void worker_destroy() {
+    int i, sval = 0;
+    if (callbacks) {
+        while (callbacks->head)
+            cb_remove(callbacks->head);
+        shm_free(callbacks);
+    }
+
+    // to deny runing the poison queue again
+    config->workers = 0;
+    if (tasks) {
+        lock_get(tasks->lock);
+        for (i = 0; i < tasks->max; i++) {
+            if (tasks->queue[i].msg) AAAFreeMessage(&(tasks->queue[i].msg));
+            tasks->queue[i].msg = 0;
+            tasks->queue[i].p = 0;
+        }
+        lock_release(tasks->lock);
+
+        LM_INFO("Unlocking workers waiting on empty queue...\n");
+        for (i = 0; i < config->workers; i++)
+            sem_release(tasks->empty);
+        LM_INFO("Unlocking workers waiting on full queue...\n");
+        i = 0;
+        while (sem_getvalue(tasks->full, &sval) == 0)
+            if (sval <= 0) {
+                sem_release(tasks->full);
+                i = 1;
+            } else break;
+        sleep(i);
+
+        lock_get(tasks->lock);
+        shm_free(tasks->queue);
+        lock_destroy(tasks->lock);
+        lock_dealloc((void*) tasks->lock);
+
+        //lock_release(tasks->empty);
+        sem_free(tasks->full);
+        sem_free(tasks->empty);
+
+        shm_free(tasks);
+    }
 }
 }
 
 
 /*unsafe*/
 /*unsafe*/
-int cb_add(cdp_cb_f cb,void *ptr)
-{
-	cdp_cb_t *x;
-	x = shm_malloc(sizeof(cdp_cb_t));
-	if (!x){
-		LOG_NO_MEM("shm",sizeof(cdp_cb_t));
-		return 0;
-	}
-	x->cb = cb;
-	x->ptr = shm_malloc(sizeof(void*));
-	if (!x->ptr){
-		LOG_NO_MEM("shm",sizeof(void*));
-		return 0;
-	}
-	*(x->ptr) = ptr;
-	x->next = 0;
-	x->prev = callbacks->tail;
-	if (callbacks->tail) callbacks->tail->next = x;
-	callbacks->tail = x;
-	if (!callbacks->head) callbacks->head = x;
-	return 1;	
+int cb_add(cdp_cb_f cb, void *ptr) {
+    cdp_cb_t *x;
+    x = shm_malloc(sizeof (cdp_cb_t));
+    if (!x) {
+        LOG_NO_MEM("shm", sizeof (cdp_cb_t));
+        return 0;
+    }
+    x->cb = cb;
+    x->ptr = shm_malloc(sizeof (void*));
+    if (!x->ptr) {
+        LOG_NO_MEM("shm", sizeof (void*));
+        return 0;
+    }
+    *(x->ptr) = ptr;
+    x->next = 0;
+    x->prev = callbacks->tail;
+    if (callbacks->tail) callbacks->tail->next = x;
+    callbacks->tail = x;
+    if (!callbacks->head) callbacks->head = x;
+    return 1;
 }
 }
 
 
 /*unsafe*/
 /*unsafe*/
-void cb_remove(cdp_cb_t *cb)
-{
-	cdp_cb_t *x;
-	x = callbacks->head;
-	while(x && x!=cb) x = x->next;
-	if (!x) return;
-	if (x->prev) x->prev->next = x->next;
-	else callbacks->head = x->next;
-	if (x->next) x->next->prev = x->prev;
-	else callbacks->tail = x->prev;
-	
-	if (x->ptr) shm_free(x->ptr);
-	shm_free(x);
+void cb_remove(cdp_cb_t *cb) {
+    cdp_cb_t *x;
+    x = callbacks->head;
+    while (x && x != cb) x = x->next;
+    if (!x) return;
+    if (x->prev) x->prev->next = x->next;
+    else callbacks->head = x->next;
+    if (x->next) x->next->prev = x->prev;
+    else callbacks->tail = x->prev;
+
+    if (x->ptr) shm_free(x->ptr);
+    shm_free(x);
 }
 }
 
 
 /**
 /**
@@ -203,66 +202,90 @@ void cb_remove(cdp_cb_t *cb)
  * @param msg - the message
  * @param msg - the message
  * @returns 1 on success, 0 on failure (eg. shutdown in progress)
  * @returns 1 on success, 0 on failure (eg. shutdown in progress)
  */
  */
-int put_task(peer *p,AAAMessage *msg)
-{
-	lock_get(tasks->lock);
-	while ((tasks->end+1)%tasks->max == tasks->start){
-		lock_release(tasks->lock);
-
-		if (*shutdownx) {
-			sem_release(tasks->full);
-			return 0;
-		}
-
-		sem_get(tasks->full);
-
-		if (*shutdownx) {
-			sem_release(tasks->full);
-			return 0;
-		}
-
-		lock_get(tasks->lock);
-	}
-	tasks->queue[tasks->end].p = p;
-	tasks->queue[tasks->end].msg = msg;
-	tasks->end = (tasks->end+1) % tasks->max;
-	if (sem_release(tasks->empty)<0)
-		LM_WARN("Error releasing tasks->empty semaphore > %s!\n",strerror(errno));
-	lock_release(tasks->lock);
-	return 1;
+int put_task(peer *p, AAAMessage *msg) {
+
+    struct timeval start, stop;
+    long elapsed_useconds=0, elapsed_seconds=0, elapsed_millis=0;
+    lock_get(tasks->lock);
+
+    gettimeofday(&start, NULL);
+    while ((tasks->end + 1) % tasks->max == tasks->start) {
+        lock_release(tasks->lock);
+
+        if (*shutdownx) {
+            sem_release(tasks->full);
+            return 0;
+        }
+
+        sem_get(tasks->full);
+
+        if (*shutdownx) {
+            sem_release(tasks->full);
+            return 0;
+        }
+
+        lock_get(tasks->lock);
+    }
+
+    gettimeofday(&stop, NULL);
+    elapsed_useconds = stop.tv_usec - start.tv_usec;
+    elapsed_seconds = stop.tv_sec - start.tv_sec;
+
+    elapsed_useconds = elapsed_seconds*1000000 + elapsed_useconds;
+    elapsed_millis = elapsed_useconds/1000;
+    if (elapsed_millis > workerq_latency_threshold) {
+        LM_ERR("took too long to put task into task queue > %d - [%ld]\n", workerq_latency_threshold, elapsed_millis);
+    }
+
+    tasks->queue[tasks->end].p = p;
+    tasks->queue[tasks->end].msg = msg;
+    tasks->end = (tasks->end + 1) % tasks->max;
+    if (sem_release(tasks->empty) < 0)
+        LM_WARN("Error releasing tasks->empty semaphore > %s!\n", strerror(errno));
+    lock_release(tasks->lock);
+
+    //int num_tasks = tasks->end - tasks->start;
+    //LM_ERR("Added task to task queue.  Queue length [%i]", num_tasks);
+
+
+    return 1;
 }
 }
-	
+
 /**
 /**
  * Remove and return the first task from the queue (FIFO).
  * Remove and return the first task from the queue (FIFO).
  * This blocks until there is something in the queue.
  * This blocks until there is something in the queue.
  * @returns the first task from the queue or an empty task on error (eg. shutdown in progress)
  * @returns the first task from the queue or an empty task on error (eg. shutdown in progress)
  */
  */
-task_t take_task()
-{
-	task_t t={0,0};
-	lock_get(tasks->lock);
-	while(tasks->start == tasks->end){
-		lock_release(tasks->lock);
-		if (*shutdownx) {
-			sem_release(tasks->empty);
-			return t;
-		}
-		sem_get(tasks->empty);
-		if (*shutdownx) {
-			sem_release(tasks->empty);
-			return t;
-		}
-		
-		lock_get(tasks->lock);
-	}
-	
-	t = tasks->queue[tasks->start];
-	tasks->queue[tasks->start].msg = 0;
-	tasks->start = (tasks->start+1) % tasks->max;
-	if (sem_release(tasks->full)<0)
-		LM_WARN("Error releasing tasks->full semaphore > %s!\n",strerror(errno));
-	lock_release(tasks->lock);
-	return t;
+task_t take_task() {
+    task_t t = {0, 0};
+    lock_get(tasks->lock);
+    while (tasks->start == tasks->end) {
+        lock_release(tasks->lock);
+        if (*shutdownx) {
+            sem_release(tasks->empty);
+            return t;
+        }
+        sem_get(tasks->empty);
+        if (*shutdownx) {
+            sem_release(tasks->empty);
+            return t;
+        }
+
+        lock_get(tasks->lock);
+    }
+
+    t = tasks->queue[tasks->start];
+    tasks->queue[tasks->start].msg = 0;
+    tasks->start = (tasks->start + 1) % tasks->max;
+    if (sem_release(tasks->full) < 0)
+        LM_WARN("Error releasing tasks->full semaphore > %s!\n", strerror(errno));
+    lock_release(tasks->lock);
+
+    //int num_tasks = tasks->end - tasks->start;
+    //LM_ERR("Taken task from task queue.  Queue length [%i]", num_tasks);
+
+
+    return t;
 }
 }
 
 
 /**
 /**
@@ -270,63 +293,59 @@ task_t take_task()
  * Actually it just releases the task queue locks so that the workers get to evaluate
  * Actually it just releases the task queue locks so that the workers get to evaluate
  * if a shutdown is in process and exit.
  * if a shutdown is in process and exit.
  */
  */
-void worker_poison_queue()
-{
-	int i;
-	if (config->workers&&tasks)
-	for(i=0;i<config->workers;i++)
-		if (sem_release(tasks->empty)<0)
-			LM_WARN("Error releasing tasks->empty semaphore > %s!\n",strerror(errno));
+void worker_poison_queue() {
+    int i;
+    if (config->workers && tasks)
+        for (i = 0; i < config->workers; i++)
+            if (sem_release(tasks->empty) < 0)
+                LM_WARN("Error releasing tasks->empty semaphore > %s!\n", strerror(errno));
 }
 }
 
 
-
-
 /**
 /**
  * This is the main worker process.
  * This is the main worker process.
  * Takes tasks from the queue in a loop and processes them by calling the registered callbacks.
  * Takes tasks from the queue in a loop and processes them by calling the registered callbacks.
  * @param id - id of the worker
  * @param id - id of the worker
  * @returns never, exits on shutdown.
  * @returns never, exits on shutdown.
  */
  */
-void worker_process(int id)
-{
-	task_t t;
-	cdp_cb_t *cb;
-	int r;
-	LM_INFO("[%d] Worker process started...\n",id);	
-	/* init the application level for this child */
-	while(1){
-		if (shutdownx&&(*shutdownx)) break;
-		t = take_task();
-		if (!t.msg) {
-			if (shutdownx&&(*shutdownx)) break;
-			LM_INFO("[%d] got empty task Q(%d/%d)\n",id,tasks->start,tasks->end);
-			continue;
-		}		
-		LM_DBG("worker_process(): [%d] got task Q(%d/%d)\n",id,tasks->start,tasks->end);
-		r = is_req(t.msg);
-		for(cb = callbacks->head;cb;cb = cb->next)
-			(*(cb->cb))(t.p,t.msg,*(cb->ptr));
-		
-		if (r){
-			AAAFreeMessage(&(t.msg));
-		}else{
-			/* will be freed by the user in upper api */
-			/*AAAFreeMessage(&(t.msg));*/
-		}
-	}
-	worker_poison_queue();
-	LM_INFO("[%d]... Worker process finished\n",id);	
+void worker_process(int id) {
+    task_t t;
+    cdp_cb_t *cb;
+    int r;
+    LM_INFO("[%d] Worker process started...\n", id);
+    /* init the application level for this child */
+    while (1) {
+        if (shutdownx && (*shutdownx)) break;
+        t = take_task();
+        if (!t.msg) {
+            if (shutdownx && (*shutdownx)) break;
+            LM_INFO("[%d] got empty task Q(%d/%d)\n", id, tasks->start, tasks->end);
+            continue;
+        }
+        LM_DBG("worker_process(): [%d] got task Q(%d/%d)\n", id, tasks->start, tasks->end);
+        r = is_req(t.msg);
+        for (cb = callbacks->head; cb; cb = cb->next)
+            (*(cb->cb))(t.p, t.msg, *(cb->ptr));
+
+        if (r) {
+            AAAFreeMessage(&(t.msg));
+        } else {
+            /* will be freed by the user in upper api */
+            /*AAAFreeMessage(&(t.msg));*/
+        }
+    }
+    worker_poison_queue();
+    LM_INFO("[%d]... Worker process finished\n", id);
 #ifdef CDP_FOR_SER
 #ifdef CDP_FOR_SER
 #else
 #else
-	#ifdef PKG_MALLOC
-		LM_DBG("Worker[%d] Memory status (pkg):\n",id);
-		//pkg_status();
-		#ifdef pkg_sums
-			pkg_sums();
-		#endif 
-	#endif
-	dp_del_pid(getpid());	
+#ifdef PKG_MALLOC
+    LM_DBG("Worker[%d] Memory status (pkg):\n", id);
+    //pkg_status();
+#ifdef pkg_sums
+    pkg_sums();
+#endif
+#endif
+    dp_del_pid(getpid());
 #endif
 #endif
-	exit(0);
+    exit(0);
 }
 }
 
 

+ 6 - 1
modules/cdp/worker.h

@@ -1,6 +1,9 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
  * The initial version of this code was written by Dragos Vingarzan
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  * Fruanhofer Institute. It was and still is maintained in a separate
  * Fruanhofer Institute. It was and still is maintained in a separate
@@ -14,7 +17,9 @@
  * improved architecture
  * improved architecture
  * 
  * 
  * NB: Alot of this code was originally part of OpenIMSCore,
  * NB: Alot of this code was originally part of OpenIMSCore,
- * FhG Focus. Thanks for great work! This is an effort to 
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
  * break apart the various CSCF functions into logically separate
  * break apart the various CSCF functions into logically separate
  * components. We hope this will drive wider use. We also feel
  * components. We hope this will drive wider use. We also feel
  * that in this way the architecture is more complete and thereby easier
  * that in this way the architecture is more complete and thereby easier