Index: extensions/app_radgw/rgwx_auth.c
===================================================================
--- extensions/app_radgw/rgwx_auth.c	(revision 740)
+++ extensions/app_radgw/rgwx_auth.c	(revision 924)
@@ -458,5 +458,5 @@
 		if (si_len) {
 			/* We already have the Session-Id, just use it */
-			CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) );
+			CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, session, NULL) );
 		} else {
 			/* Create a new Session-Id string */
@@ -496,4 +496,5 @@
 		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 		CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+		CHECK_FCT( fd_msg_sess_set( *diam_fw, *session) );
 	}
 	
Index: extensions/app_radgw/rgwx_sip.c
===================================================================
--- extensions/app_radgw/rgwx_sip.c	(revision 816)
+++ extensions/app_radgw/rgwx_sip.c	(revision 924)
@@ -480,4 +480,5 @@
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+	CHECK_FCT( fd_msg_sess_set( *diam_fw, *session) );
 	
 	/*
Index: extensions/app_sip/registrationtermination.c
===================================================================
--- extensions/app_sip/registrationtermination.c	(revision 706)
+++ extensions/app_sip/registrationtermination.c	(revision 924)
@@ -148,13 +148,5 @@
 	{
 		#define APP_SIP_SID_OPT  "app_sip"
-		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ));
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
-		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
-		value.os.data = sid;
-		value.os.len  = sidlen;
-		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
-		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+		CHECK_FCT( fd_msg_new_session( message, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ) );
 	}
 	
Index: extensions/test_app/ta_bench.c
===================================================================
--- extensions/test_app/ta_bench.c	(revision 879)
+++ extensions/test_app/ta_bench.c	(revision 924)
@@ -122,5 +122,4 @@
 	union avp_value val;
 	struct ta_mess_info * mi = NULL;
-	struct session *sess = NULL;
 	
 	TRACE_DEBUG(FULL, "Creating a new message for sending.");
@@ -131,5 +130,5 @@
 	/* Create a new session */
 	#define TEST_APP_SID_OPT  "app_testb"
-	CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
+	CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
 	
 	/* Create the random value to store with the session */
@@ -143,17 +142,4 @@
 	
 	/* Now set all AVPs values */
-	
-	/* Session-Id */
-	{
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out );
-		CHECK_FCT_DO( fd_msg_avp_new ( ta_sess_id, 0, &avp ), goto out );
-		val.os.data = sid;
-		val.os.len  = sidlen;
-		CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
-		CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out );
-		
-	}
 	
 	/* Set the Destination-Realm AVP */
Index: extensions/test_app/ta_cli.c
===================================================================
--- extensions/test_app/ta_cli.c	(revision 740)
+++ extensions/test_app/ta_cli.c	(revision 924)
@@ -151,5 +151,6 @@
 	/* Create a new session */
 	#define TEST_APP_SID_OPT  "app_test"
-	CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
+	CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
+	CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL), goto out );
 	
 	/* Create the random value to store with the session */
@@ -164,17 +165,4 @@
 	/* Now set all AVPs values */
 	
-	/* Session-Id */
-	{
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out );
-		CHECK_FCT_DO( fd_msg_avp_new ( ta_sess_id, 0, &avp ), goto out );
-		val.os.data = sid;
-		val.os.len  = sidlen;
-		CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
-		CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out );
-		
-	}
-	
 	/* Set the Destination-Realm AVP */
 	{
Index: extensions/test_sip/locationinfo.c
===================================================================
--- extensions/test_sip/locationinfo.c	(revision 706)
+++ extensions/test_sip/locationinfo.c	(revision 924)
@@ -42,5 +42,4 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
-	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -62,13 +61,5 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
-		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
-		value.os.data = sid;
-		value.os.len  = sidlen;
-		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
-		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
 	}
 	
Index: extensions/test_sip/locationinfosl.c
===================================================================
--- extensions/test_sip/locationinfosl.c	(revision 706)
+++ extensions/test_sip/locationinfosl.c	(revision 924)
@@ -42,5 +42,4 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
-	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -62,13 +61,5 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
-		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
-		value.os.data = sid;
-		value.os.len  = sidlen;
-		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
-		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
 	}
 	
Index: extensions/test_sip/serverassignment.c
===================================================================
--- extensions/test_sip/serverassignment.c	(revision 706)
+++ extensions/test_sip/serverassignment.c	(revision 924)
@@ -42,5 +42,4 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
-	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -71,13 +70,5 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
-		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
-		value.os.data = sid;
-		value.os.len  = sidlen;
-		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
-		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
 	}
 	
Index: extensions/test_sip/userauthorization.c
===================================================================
--- extensions/test_sip/userauthorization.c	(revision 706)
+++ extensions/test_sip/userauthorization.c	(revision 924)
@@ -42,5 +42,4 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
-	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -67,13 +66,5 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"appsip", 6 ));
-		os0_t sid;
-		size_t sidlen;
-		CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ));
-		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
-		value.os.data = sid;
-		value.os.len  = sidlen;
-		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
-		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
 	}
 	
Index: include/freeDiameter/libfdproto.h
===================================================================
--- include/freeDiameter/libfdproto.h	(revision 922)
+++ include/freeDiameter/libfdproto.h	(revision 924)
@@ -1816,7 +1816,7 @@
  *
  * RETURN VALUE:
- *  0      	: The session is created.
- *  EINVAL 	: A parameter is invalid.
- *  EALREADY	: A session with the same name already exists (returned in *session)
+ *  0      	: The session is created, the initial msg refcount is 1.
+ *  EINVAL 	: A parameter is invalid.
+ *  EALREADY	: A session with the same name already exists (returned in *session), the msg refcount is increased.
  *  ENOMEM	: Not enough memory to complete the operation
  */
@@ -2505,4 +2505,8 @@
 int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * isnew);
 
+/* This one is used by the libfdcore, you should use fd_msg_new_session rather than fd_sess_new, when possible */
+int fd_msg_sess_set(struct msg * msg, struct session * session);
+
+
 /***************************************/
 /*   Manage AVP values                 */
Index: libfdcore/messages.c
===================================================================
--- libfdcore/messages.c	(revision 912)
+++ libfdcore/messages.c	(revision 924)
@@ -158,4 +158,7 @@
 	/* Add it to the message */
 	CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_FIRST_CHILD, avp ) );
+	
+	/* Save the session associated with the message */
+	CHECK_FCT( fd_msg_sess_set( msg, sess) );
 	
 	/* Done! */
Index: libfdproto/fdproto-internal.h
===================================================================
--- libfdproto/fdproto-internal.h	(revision 909)
+++ libfdproto/fdproto-internal.h	(revision 924)
@@ -70,4 +70,5 @@
 int fd_sess_reclaim_msg ( struct session ** session );
 
+
 /* For dump routines into string buffers */
 #include <stdarg.h>
Index: libfdproto/messages.c
===================================================================
--- libfdproto/messages.c	(revision 920)
+++ libfdproto/messages.c	(revision 924)
@@ -1216,4 +1216,18 @@
 }
 
+/* Associate a session with a message, use only when the session was just created */
+int fd_msg_sess_set(struct msg * msg, struct session * session)
+{
+	TRACE_ENTRY("%p %p", msg, session);
+	
+	/* Check we received valid parameters */
+	CHECK_PARAMS( CHECK_MSG(msg) );
+	CHECK_PARAMS( session );
+	CHECK_PARAMS( msg->msg_sess == NULL );
+	
+	msg->msg_sess = session;
+	return 0;
+}
+
 
 /* Retrieve the session of the message */
Index: libfdproto/sessions.c
===================================================================
--- libfdproto/sessions.c	(revision 788)
+++ libfdproto/sessions.c	(revision 924)
@@ -360,5 +360,5 @@
 
 
-/* Create a new session object with the default timeout value, and link it */
+/* Create a new session object with the default timeout value, and link it. The refcount is increased by 1, whether the session existed or not */
 int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen )
 {
@@ -461,6 +461,12 @@
 	
 		fd_list_insert_before(li, &sess->chain_h); /* hash table */
+		sess->msg_cnt++;
 	} else {
 		free(sid);
+		
+		CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); 
+		(*session)->msg_cnt++;
+		CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); 
+		
 		/* it was found: was it previously destroyed? */
 		if ((*session)->is_destroyed == 0) {
@@ -469,6 +475,6 @@
 		} else {
 			/* the session was marked destroyed, let's re-activate it. */
-			TODO("Re-creating a deleted session. Should investigate if this can lead to an issue... (need more feedback)");
 			sess = *session;
+			sess->is_destroyed = 0;
 			
 			/* update the expiry time */
@@ -501,5 +507,5 @@
 
 out:
-	;	
+	;
 	pthread_cleanup_pop(0);
 	CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
@@ -512,6 +518,6 @@
 }
 
-/* Find or create a session */
-int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
+/* Find or create a session -- the msg refcount is increased */
+int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
 {
 	int ret;
@@ -802,5 +808,5 @@
 
 /* For the messages module */
-int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
+int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
 {
 	TRACE_ENTRY("%p %zd %p %p", sid, len, session, new);
@@ -808,9 +814,11 @@
 	
 	/* Get the session object */
-	CHECK_FCT( fd_sess_fromsid ( sid, len, session, new) );
-	
-	/* Increase count */
-	CHECK_FCT( fd_sess_ref_msg ( *session ) );
-	
+	CHECK_FCT( fd_sess_fromsid_msg ( sid, len, session, new) );
+	
+	/* Decrease the refcount */
+	CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
+	(*session)->msg_cnt--; /* was increased in fd_sess_new */
+	CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
+		
 	/* Done */
 	return 0;
@@ -833,8 +841,14 @@
 {
 	int reclaim;
+	uint32_t hash;
 	
 	TRACE_ENTRY("%p", session);
 	CHECK_PARAMS( session && VALIDATE_SI(*session) );
 	
+	/* Lock the hash line to avoid possibility that session is freed while we are reclaiming */
+	hash = (*session)->hash;
+	CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash)) );
+	pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); 
+
 	/* Update the msg refcount */
 	CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
@@ -843,4 +857,9 @@
 	CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
 	
+	/* Ok, now unlock the hash line */
+	pthread_cleanup_pop( 0 );
+	CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
+	
+	/* and reclaim if no message references the session anymore */
 	if (reclaim == 1) {
 		CHECK_FCT(fd_sess_reclaim ( session ));
