Index: .hgtags
===================================================================
--- .hgtags	(revision 932)
+++ .hgtags	(revision 883)
@@ -30,3 +30,2 @@
 226f5957186ae4369467b070aeb61b1c631c9a5c 1.1.5-rc2
 ae96ae28f3ddc48b9e2676e9538008eab2b9d60a 1.1.5
-155d45d0653025f45b58ab96b6ba0d5e6fb7fcf8 1.1.6
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 929)
+++ CMakeLists.txt	(revision 880)
@@ -12,8 +12,8 @@
 SET(FD_PROJECT_VERSION_MAJOR 1)
 SET(FD_PROJECT_VERSION_MINOR 1)
-SET(FD_PROJECT_VERSION_REV 6)
+SET(FD_PROJECT_VERSION_REV 5)
 
 # Version of the API with the library
-SET(FD_PROJECT_VERSION_API 5)
+SET(FD_PROJECT_VERSION_API 4)
 
 # The test framework, using CTest and CDash.
Index: INSTALL.FreeBSD
===================================================================
--- INSTALL.FreeBSD	(revision 921)
+++ INSTALL.FreeBSD	(revision 707)
@@ -9,5 +9,5 @@
 
 Then the cmake command had to look like:
- cmake -DFLEX_EXECUTABLE:FILEPATH=/usr/local/bin/flex -DSCTP_USE_MAPPED_ADDRESSES:BOOL=ON ...
+ cmake -DFLEX_EXECUTABLE:FILEPATH=/usr/local/bin/flex ...
 
 
@@ -46,5 +46,5 @@
    
 7) Run cmake for freeDiameter (add other flags as you see fit, see INSTALL for more details)
-   # /usr/local/bin/cmake -DFLEX_EXECUTABLE:FILEPATH=/usr/local/bin/flex -DSCTP_USE_MAPPED_ADDRESSES:BOOL=ON ../freeDiameter
+   # /usr/local/bin/cmake -DFLEX_EXECUTABLE:FILEPATH=/usr/local/bin/flex ../freeDiameter
 
 8) Compile, optionnaly test
Index: contrib/debian/changelog
===================================================================
--- contrib/debian/changelog	(revision 929)
+++ contrib/debian/changelog	(revision 880)
@@ -1,17 +1,2 @@
-freediameter (1.1.6) UNRELEASED; urgency=low
-
-  * Fix major issue in 1.1.5 preventing to send answers to a received message.
-  * New command-line option: --enable_msg_log=( DROPPED | RECEIVED | SENT | NODELIVER | TIMING )
-  * Improved parsing error handling and Failed-AVP generation.
-  * Added support for some timings measurements in freeDiameter (in the logs)
-  * Fix port handling when using non-default port.
-  * Some cleanups in several dictionary files.
-  * New option to fd_dict_search: AVP_BY_STRUCT
-  * Improved compatibility with C++ compilers.
-  * Cleanups in sessions creation/destruction to avoid memory corruption under stress.
-  * Add support for "include" directive in freeDiameter.conf file.
-
- -- Sebastien Decugis <sdecugis@freediameter.net>  Sun, 03 Mar 2013 07:40:43 +0100
-
 freediameter (1.1.5) UNRELEASED; urgency=low
 
Index: contrib/debian/update_changelog.txt
===================================================================
--- contrib/debian/update_changelog.txt	(revision 929)
+++ contrib/debian/update_changelog.txt	(revision 654)
@@ -1,3 +1,3 @@
-new release: dch -v 1.0.3 -D UNRELEASED --release-heuristic log
+new release: dch -v 1.0.3 -D UNRELEASED
 Simple addition: dch "changelog entry text"
 
Index: doc/freediameter.conf.sample
===================================================================
--- doc/freediameter.conf.sample	(revision 925)
+++ doc/freediameter.conf.sample	(revision 873)
@@ -2,8 +2,4 @@
 
 # Only the "TLS_Cred" directive is really mandatory in this file.
-
-# It is possible to use "include" keyword to import additional files
-# e.g.: include "/etc/freeDiameter.d/*.conf"
-
 
 ##############################################################
Index: extensions/_sample/hello.cpp
===================================================================
--- extensions/_sample/hello.cpp	(revision 931)
+++ extensions/_sample/hello.cpp	(revision 904)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: extensions/acl_wl/aw_conf.l
===================================================================
--- extensions/acl_wl/aw_conf.l	(revision 928)
+++ extensions/acl_wl/aw_conf.l	(revision 741)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -93,10 +93,3 @@
 			}
 
-	/* No match */
-<*>[[:alnum:]]+		|	/* This rule is only useful to print a complete token in error messages */
-<*>.			{
-				TRACE_DEBUG_ERROR("Unrecognized text on line %d col %d: '%s'.\n", yylloc->first_line, yylloc->first_column, yytext);
-			 	return LEX_ERROR; 
-			}
-
 %%
Index: extensions/acl_wl/aw_conf.y
===================================================================
--- extensions/acl_wl/aw_conf.y	(revision 928)
+++ extensions/acl_wl/aw_conf.y	(revision 741)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -127,9 +127,4 @@
 				fqdn_added++;
 			}
-			| conffile LEX_ERROR
-			{
-				yyerror(&yylloc, conffile, "An error occurred while parsing the configuration file");
-				return EINVAL;
-			}
 			;
 
Index: extensions/app_radgw/rgwx_auth.c
===================================================================
--- extensions/app_radgw/rgwx_auth.c	(revision 928)
+++ extensions/app_radgw/rgwx_auth.c	(revision 740)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -458,5 +458,5 @@
 		if (si_len) {
 			/* We already have the Session-Id, just use it */
-			CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, session, NULL) );
+			CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) );
 		} else {
 			/* Create a new Session-Id string */
@@ -496,5 +496,4 @@
 		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 924)
+++ extensions/app_radgw/rgwx_sip.c	(revision 816)
@@ -480,5 +480,4 @@
 	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 924)
+++ extensions/app_sip/registrationtermination.c	(revision 706)
@@ -148,5 +148,13 @@
 	{
 		#define APP_SIP_SID_OPT  "app_sip"
-		CHECK_FCT( fd_msg_new_session( message, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ) );
+		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 ));
 	}
 	
Index: extensions/test_app/ta_bench.c
===================================================================
--- extensions/test_app/ta_bench.c	(revision 928)
+++ extensions/test_app/ta_bench.c	(revision 879)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -122,4 +122,5 @@
 	union avp_value val;
 	struct ta_mess_info * mi = NULL;
+	struct session *sess = NULL;
 	
 	TRACE_DEBUG(FULL, "Creating a new message for sending.");
@@ -130,5 +131,5 @@
 	/* Create a new session */
 	#define TEST_APP_SID_OPT  "app_testb"
-	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_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 );
 	
 	/* Create the random value to store with the session */
@@ -142,4 +143,17 @@
 	
 	/* 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 930)
+++ extensions/test_app/ta_cli.c	(revision 740)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -59,6 +59,4 @@
 	struct avp * avp;
 	struct avp_hdr * hdr;
-	unsigned long dur;
-	int error = 0;
 	
 	CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
@@ -82,13 +80,7 @@
 	if (avp) {
 		CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
-		if (hdr->avp_value->i32 == mi->randval) {
-			fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "Ok");
-		} else {
-			fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "PROBLEM");
-			error++;
-		}
+		fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, (hdr->avp_value->i32 == mi->randval) ? "Ok" : "PROBLEM");
 	} else {
 		fprintf(stderr, "no_Test-AVP ");
-		error++;
 	}
 	
@@ -98,9 +90,6 @@
 		CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
 		fprintf(stderr, "Status: %d ", hdr->avp_value->i32);
-		if (hdr->avp_value->i32 != 2001)
-			error++;
 	} else {
 		fprintf(stderr, "no_Result-Code ");
-		error++;
 	}
 	
@@ -112,5 +101,4 @@
 	} else {
 		fprintf(stderr, "no_Origin-Host ");
-		error++;
 	}
 	
@@ -122,32 +110,7 @@
 	} else {
 		fprintf(stderr, "no_Origin-Realm ");
-		error++;
-	}
-	
-	CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
-	dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000);
-	if (ta_conf->stats.nb_recv) {
-		/* Ponderate in the avg */
-		ta_conf->stats.avg = (ta_conf->stats.avg * ta_conf->stats.nb_recv + dur) / (ta_conf->stats.nb_recv + 1);
-		/* Min, max */
-		if (dur < ta_conf->stats.shortest)
-			ta_conf->stats.shortest = dur;
-		if (dur > ta_conf->stats.longest)
-			ta_conf->stats.longest = dur;
-	} else {
-		ta_conf->stats.shortest = dur;
-		ta_conf->stats.longest = dur;
-		ta_conf->stats.avg = dur;
-	}
-	
-	if (error)
-		ta_conf->stats.nb_errs++;
-	else 
-		ta_conf->stats.nb_recv++;
-	
-	
-	CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
-	
-	/* Display how long it took */
+	}
+	
+	/* Now compute how long it took */
 	if (ts.tv_nsec > mi->ts.tv_nsec) {
 		fprintf(stderr, "in %d.%06ld sec", 
@@ -159,4 +122,5 @@
 				(long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000);
 	}
+	
 	fprintf(stderr, "\n");
 	fflush(stderr);
@@ -187,6 +151,5 @@
 	/* Create a new session */
 	#define TEST_APP_SID_OPT  "app_test"
-	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 );
+	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 );
 	
 	/* Create the random value to store with the session */
@@ -201,4 +164,17 @@
 	/* 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 */
 	{
@@ -254,9 +230,4 @@
 	CHECK_FCT_DO( fd_msg_send( &req, ta_cb_ans, svg ), goto out );
 
-	/* Increment the counter */
-	CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
-	ta_conf->stats.nb_sent++;
-	CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
-
 out:
 	return;
Index: extensions/test_sip/locationinfo.c
===================================================================
--- extensions/test_sip/locationinfo.c	(revision 924)
+++ extensions/test_sip/locationinfo.c	(revision 706)
@@ -42,4 +42,5 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
+	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -61,5 +62,13 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+		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 ));
 	}
 	
Index: extensions/test_sip/locationinfosl.c
===================================================================
--- extensions/test_sip/locationinfosl.c	(revision 924)
+++ extensions/test_sip/locationinfosl.c	(revision 706)
@@ -42,4 +42,5 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
+	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -61,5 +62,13 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+		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 ));
 	}
 	
Index: extensions/test_sip/serverassignment.c
===================================================================
--- extensions/test_sip/serverassignment.c	(revision 924)
+++ extensions/test_sip/serverassignment.c	(revision 706)
@@ -42,4 +42,5 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
+	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -70,5 +71,13 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+		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 ));
 	}
 	
Index: extensions/test_sip/userauthorization.c
===================================================================
--- extensions/test_sip/userauthorization.c	(revision 924)
+++ extensions/test_sip/userauthorization.c	(revision 706)
@@ -42,4 +42,5 @@
 	struct msg * message=NULL;
 	struct avp *avp=NULL;
+	struct session *sess=NULL;
 	union avp_value value;
 	
@@ -66,5 +67,13 @@
 	// Create a new session 
 	{
-		CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+		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 ));
 	}
 	
Index: freeDiameterd/main.c
===================================================================
--- freeDiameterd/main.c	(revision 931)
+++ freeDiameterd/main.c	(revision 900)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: include/freeDiameter/CMakeLists.txt
===================================================================
--- include/freeDiameter/CMakeLists.txt	(revision 935)
+++ include/freeDiameter/CMakeLists.txt	(revision 871)
@@ -25,14 +25,5 @@
 ENDIF (NOT DIAMID_IDNA_IGNORE)
 
-# Disable expiration of connections with dynamically connected peers as per RFC 3539 ? (default is enabled)
-# Note: if someone needs, we could also make the delay configurable here...
-OPTION(DISABLE_PEER_EXPIRY "Disable RFC3539 Peers Connections Expiration after inactivity?" OFF)
-
-# The following workaround increases compatibility with some implementations without breaking anything in freeDiameter, 
-# so it can be enabled without risk. We keep it disabled by default anyway for those people who use freeDiameter to check the 
-# compliancy of their implementation with the Diameter RFC...
-OPTION(WORKAROUND_ACCEPT_INVALID_VSAI "Do not reject a CER/CEA with a Vendor-Specific-Application-Id AVP containing both Auth- and Acct- application AVPs?" OFF)
-
-MARK_AS_ADVANCED(DISABLE_SCTP DEBUG_SCTP SCTP_USE_MAPPED_ADDRESSES ERRORS_ON_TODO DIAMID_IDNA_IGNORE DIAMID_IDNA_REJECT DISABLE_PEER_EXPIRY WORKAROUND_ACCEPT_INVALID_VSAI)
+MARK_AS_ADVANCED(DISABLE_SCTP DEBUG_SCTP SCTP_USE_MAPPED_ADDRESSES ERRORS_ON_TODO DIAMID_IDNA_IGNORE DIAMID_IDNA_REJECT)
 
 ########################
Index: include/freeDiameter/extension.h
===================================================================
--- include/freeDiameter/extension.h	(revision 931)
+++ include/freeDiameter/extension.h	(revision 904)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: include/freeDiameter/freeDiameter-host.h.in
===================================================================
--- include/freeDiameter/freeDiameter-host.h.in	(revision 935)
+++ include/freeDiameter/freeDiameter-host.h.in	(revision 904)
@@ -59,6 +59,4 @@
 #cmakedefine DIAMID_IDNA_IGNORE
 #cmakedefine DIAMID_IDNA_REJECT
-#cmakedefine DISABLE_PEER_EXPIRY
-#cmakedefine WORKAROUND_ACCEPT_INVALID_VSAI
 #cmakedefine GNUTLS_VERSION_210
 #cmakedefine GNUTLS_VERSION_300
Index: include/freeDiameter/libfdcore.h
===================================================================
--- include/freeDiameter/libfdcore.h	(revision 939)
+++ include/freeDiameter/libfdcore.h	(revision 904)
@@ -385,21 +385,4 @@
 int fd_peer_get_state(struct peer_hdr *peer);
 
-/* 
- * FUNCTION:	fd_peer_get_load_pending
- *
- * PARAMETERS:
- *  peer	: The peer which load to read
- *
- * DESCRIPTION: 
- *   Returns the current number of requests sent to this peer
- *  that have not been answered yet. This is an empirical indication
- *  of the workload of this peer.
- *
- * RETURN VALUE:
- *  0  : The load parameter has been updated. (it should have a positive value always)
- * !0  : An error occurred
- */
-int fd_peer_get_load_pending(struct peer_hdr *peer, int * load);
-
 /*
  * FUNCTION:	fd_peer_validate_register
Index: include/freeDiameter/libfdproto.h
===================================================================
--- include/freeDiameter/libfdproto.h	(revision 928)
+++ include/freeDiameter/libfdproto.h	(revision 941)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -110,22 +110,23 @@
 
 /*
- * FUNCTION:	fd_log_debug_fstr
+ * FUNCTION:	fd_log
  * MACRO:	fd_log_debug
  *
  * PARAMETERS:
- *  fstr	: Stream where the text will be sent (default: stdout) 
+ *  loglevel	: Integer, how important the message is
  *  format 	: Same format string as in the printf function
  *  ...		: Same list as printf
  *
  * DESCRIPTION: 
- *  Log internal information for use of developpers only.
+ * Write information to log.
  * The format and arguments may contain UTF-8 encoded data. The
- * output medium (file or console) is expected to support this encoding.
+ * output medium is expected to support this encoding.
  *
  * RETURN VALUE:
  *  None.
  */
-void fd_log_debug_fstr ( FILE * fstr, const char * format, ... );
-#define fd_log_debug(format,args...) fd_log_debug_fstr(NULL, format, ## args)
+void fd_log ( int, const char *, ... );
+#define fd_log_debug(format,args...) fd_log(FD_LOG_DEBUG, format, ## args)
+void fd_log_debug_fstr( FILE *, const char *, ... );
 
 /* these are internal objects of the debug facility, 
@@ -174,5 +175,5 @@
  *
  * PARAMETERS:
- *  fstr        : Stream where the text will be sent to (default: stdout)
+ *  loglevel    : priority of the message
  *  format      : Same format string as in the printf function
  *  va_list     : Argument list
@@ -184,5 +185,5 @@
  * int          : Success or failure
  */
-int fd_log_handler_register ( void (*logger)(const char * format, va_list *args) );
+int fd_log_handler_register ( void (*logger)(int loglevel, const char * format, va_list args) );
 
 /*
@@ -209,5 +210,9 @@
 #endif /* ASSERT */
 
-/* levels definitions */
+/* log levels definitions */
+#define FD_LOG_DEBUG 0
+#define FD_LOG_ERROR 5
+
+/* print level definitions */
 #define NONE 0	/* Display no debug message */
 #define INFO 1	/* Display errors only */
@@ -264,6 +269,6 @@
 		char __buf[25];													\
 		const char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");					\
-		fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n"								\
-			  "\t%s|%*s" format "\n",  										\
+		fd_log(level, "\t | tid:%-20s\t%s\tin %s@%s:%d\n"  \
+			  "\t%s|%*s" format,  										\
 					__thn, fd_log_time(NULL, __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__,\
 					(level < FULL)?"@":" ",level, "", ## args); 						\
@@ -277,10 +282,10 @@
 			char __buf[25];													\
 			const char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");					\
-			fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n"								\
-				  "\t%s|%*s" format "\n",  										\
+			fd_log(level, "\t | tid:%-20s\t%s\tin %s@%s:%d\n" \
+				  "\t%s|%*s" format,  										\
 						__thn, fd_log_time(NULL, __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__,\
 						(level < FULL)?"@":" ",level, "", ## args); 						\
 		} else {														\
-			fd_log_debug(format "\n", ## args); 										\
+			fd_log(level, format, ## args);           \
 		}															\
 	}																\
@@ -321,12 +326,12 @@
 		uint8_t * __buf = (uint8_t *)(buf);										\
 		char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");					\
-		fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n"								\
+		fd_log(level, "\t | tid:%-20s\t%s\tin %s@%s:%d\n"  \
 			  "\t%s|%*s" prefix ,  											\
 					__thn, fd_log_time(NULL, __ts, sizeof(__ts)), __PRETTY_FUNCTION__, __FILE__, __LINE__,	\
 					(level < FULL)?"@":" ",level, ""); 							\
 		for (__i = 0; __i < __sz; __i++) {										\
-			fd_log_debug("%02.2hhx", __buf[__i]);									\
+			fd_log(level, "%02.2hhx", __buf[__i]);         \
 		}														\
-		fd_log_debug(suffix "\n");											\
+		fd_log(level, suffix);                        \
 	}															\
 }
@@ -357,9 +362,9 @@
 			flag);					\
 	  if (__rc)						\
-	  	fd_log_debug("%s", (char *)gai_strerror(__rc));	\
+		fd_log_debug("%s", (char *)gai_strerror(__rc));	\
 	  else							\
-	  	fd_log_debug("%s", &__addrbuf[0]);		\
+		fd_log_debug("%s", &__addrbuf[0]);		\
 	} else {						\
-		fd_log_debug("(NULL / ANY)");			\
+		fd_log_debug("(NULL / ANY)");                   \
 	}							\
 }
@@ -378,7 +383,7 @@
 			flag);						\
 	  if (__rc)							\
-	  	fd_log_debug("%s", (char *)gai_strerror(__rc));		\
+		fd_log_debug("%s", (char *)gai_strerror(__rc));		\
 	  else								\
-	  	fd_log_debug("[%s]:%s", &__addrbuf[0],&__servbuf[0]);	\
+		fd_log_debug("[%s]:%s", &__addrbuf[0],&__servbuf[0]);	\
 	} else {							\
 		fd_log_debug("(NULL / ANY)");				\
@@ -391,10 +396,10 @@
 		char __buf[25];													\
 		char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");					\
-		fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n"								\
+		fd_log(level, "\t | tid:%-20s\t%s\tin %s@%s:%d\n"  \
 			  "\t%s|%*s" prefix ,  											\
 					__thn, fd_log_time(NULL, __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__,\
 					(level < FULL)?"@":" ",level, ""); 							\
 		sSA_DUMP_NODE_SERV( sa, flags );										\
-		fd_log_debug(suffix "\n");											\
+		fd_log(level, suffix);                        \
 	}															\
 }
@@ -418,5 +423,5 @@
 #define TRACE_DEBUG_sSA(level, prefix, sa, flags, suffix )
 #define TRACE_DEBUG_ERROR(format,args... ) {	\
-	fd_log_debug(format "\n", ## args); 	\
+	fd_log(FD_LOG_ERROR, format, ## args); 	\
 }
 #endif /* STRIP_DEBUG_CODE */
@@ -1164,24 +1169,4 @@
 };
 
-/****
- Callbacks defined in libfdproto/dictionary_functions.c file -- see that file for usage. 
- */
-
-/* Convert an Address type AVP into a struct sockaddr_storage */
-int fd_dictfct_Address_encode(void * data, union avp_value * avp_value);
-int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted);
-char * fd_dictfct_Address_dump(union avp_value * avp_value);
-
-/* Display the content of an AVP of type UTF8String in the log file */
-char * fd_dictfct_UTF8String_dump(union avp_value * avp_value);
-
-/* For Time AVPs, map with time_t value directly */
-int fd_dictfct_Time_encode(void * data, union avp_value * avp_value);
-int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted);
-char * fd_dictfct_Time_dump(union avp_value * avp_value);
-
-
-
-/****/
 
 /***
@@ -1214,5 +1199,5 @@
  
 */
-
+	 
 /*
  ***************************************************************************
@@ -1816,7 +1801,7 @@
  *
  * RETURN VALUE:
- *  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.
+ *  0      	: The session is created.
+ *  EINVAL 	: A parameter is invalid.
+ *  EALREADY	: A session with the same name already exists (returned in *session)
  *  ENOMEM	: Not enough memory to complete the operation
  */
@@ -2505,8 +2490,4 @@
 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/cnxctx.c
===================================================================
--- libfdcore/cnxctx.c	(revision 928)
+++ libfdcore/cnxctx.c	(revision 896)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -561,7 +561,4 @@
 			continue;
 		
-		if (cur->ifa_addr == NULL) /* may happen with ppp interfaces */
-			continue;
-		
 		if (fd_g_config->cnf_flags.no_ip4 && (cur->ifa_addr->sa_family == AF_INET))
 			continue;
Index: libfdcore/core.c
===================================================================
--- libfdcore/core.c	(revision 928)
+++ libfdcore/core.c	(revision 908)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: libfdcore/dict_base_proto.c
===================================================================
--- libfdcore/dict_base_proto.c	(revision 928)
+++ libfdcore/dict_base_proto.c	(revision 838)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -45,4 +45,167 @@
 struct dictionary * fd_g_dict = NULL;
 
+/* The functions to encode and interpret the derived types defined in the base protocol */
+
+/* Address AVP <-> struct sockaddr_storage */
+static int Address_encode(void * data, union avp_value * avp_value)
+{
+	sSS * ss = (sSS *) data;
+	uint16_t AddressType = 0;
+	size_t	size = 0;
+	unsigned char * buf = NULL;
+	
+	TRACE_ENTRY("%p %p", data, avp_value);
+	CHECK_PARAMS( data && avp_value  );
+	
+	switch (ss->ss_family) {
+		case AF_INET:
+			{
+				/* We are encoding an IP address */
+				sSA4 * sin = (sSA4 *)ss;
+				
+				AddressType = 1;/* see http://www.iana.org/assignments/address-family-numbers/ */
+				size = 6;	/* 2 for AddressType + 4 for data */
+				
+				CHECK_MALLOC(  buf = malloc(size)  );
+				
+				/* may not work because of alignment: *(uint32_t *)(buf+2) = htonl(sin->sin_addr.s_addr); */
+				memcpy(buf + 2, &sin->sin_addr.s_addr, 4);
+			}
+			break;
+				
+		case AF_INET6:
+			{
+				/* We are encoding an IPv6 address */
+				sSA6 * sin6 = (sSA6 *)ss;
+				
+				AddressType = 2;/* see http://www.iana.org/assignments/address-family-numbers/ */
+				size = 18;	/* 2 for AddressType + 16 for data */
+				
+				CHECK_MALLOC(  buf = malloc(size)  );
+				
+				/* The order is already good here */
+				memcpy(buf + 2, &sin6->sin6_addr.s6_addr, 16);
+			}
+			break;
+				
+		default:
+			CHECK_PARAMS( AddressType = 0 );
+	}
+	
+	*(uint16_t *)buf = htons(AddressType);
+
+	avp_value->os.len = size;
+	avp_value->os.data = buf;
+	
+	return 0;
+}
+
+static int Address_interpret(union avp_value * avp_value, void * interpreted)
+{
+	uint16_t AddressType = 0;
+	unsigned char * buf;
+	
+	TRACE_ENTRY("%p %p", avp_value, interpreted);
+	
+	CHECK_PARAMS( avp_value && interpreted && (avp_value->os.len >= 2)  );
+	
+	AddressType = ntohs(*(uint16_t *)avp_value->os.data);
+	buf = &avp_value->os.data[2];
+	
+	switch (AddressType) {
+		case 1 /* IP */:
+			{
+				sSA4 * sin = (sSA4 *)interpreted;
+				
+				CHECK_PARAMS(  avp_value->os.len == 6  );
+				
+				sin->sin_family = AF_INET;
+				/* sin->sin_addr.s_addr = ntohl( * (uint32_t *) buf); -- may not work because of bad alignment */
+				memcpy(&sin->sin_addr.s_addr, buf, 4);
+			}
+			break;
+				
+		case 2 /* IP6 */:
+			{
+				sSA6 * sin6 = (sSA6 *)interpreted;
+				
+				CHECK_PARAMS(  avp_value->os.len == 18  );
+				
+				sin6->sin6_family = AF_INET6;
+				memcpy(&sin6->sin6_addr.s6_addr, buf, 16);
+			}
+			break;
+				
+		default:
+			CHECK_PARAMS( AddressType = 0 );
+	}
+	
+	return 0;
+}
+
+/* Dump the content of an Address AVP */
+static char * Address_dump(union avp_value * avp_value)
+{
+	char * ret;
+	#define STR_LEN	1024
+	union {
+		sSA	sa;
+		sSS	ss;
+		sSA4	sin;
+		sSA6	sin6;
+	} s;
+	uint16_t fam;
+	
+	memset(&s, 0, sizeof(s));
+	
+	CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );
+	
+	/* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */
+	if (avp_value->os.len < 2) {
+		snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len);
+		return ret;
+	}
+	
+	/* Following octets are the address in network byte order already */
+	fam = avp_value->os.data[0] << 8 | avp_value->os.data[1];
+	switch (fam) {
+		case 1:
+			/* IP */
+			s.sa.sa_family = AF_INET;
+			if (avp_value->os.len != 6) {
+				snprintf(ret, STR_LEN, "[invalid IP length: %zd]", avp_value->os.len);
+				return ret;
+			}
+			memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4);
+			break;
+		case 2:
+			/* IP6 */
+			s.sa.sa_family = AF_INET6;
+			if (avp_value->os.len != 18) {
+				snprintf(ret, STR_LEN, "[invalid IP6 length: %zd]", avp_value->os.len);
+				return ret;
+			}
+			memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16);
+			break;
+		default:
+			snprintf(ret, STR_LEN, "[unsupported family: 0x%hx]", fam);
+			return ret;
+	}
+	
+	{
+		int rc = getnameinfo(&s.sa, sSAlen(&s.sa), ret, STR_LEN, NULL, 0, NI_NUMERICHOST);
+		if (rc)
+			snprintf(ret, STR_LEN, "%s", (char *)gai_strerror(rc));
+	}
+	
+	return ret;
+}
+
+static char * UTF8String_dump(union avp_value * avp_value)
+{
+	return strndup((char *)avp_value->os.data, 42); /* avoid very long strings */
+}
+
+
 
 
@@ -132,5 +295,5 @@
 				the content and format of the remaining octets.
 			*/
-			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"Address"		, fd_dictfct_Address_interpret	, fd_dictfct_Address_encode,	fd_dictfct_Address_dump	};
+			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"Address"		, Address_interpret	, Address_encode,	Address_dump	};
 			CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
 		}
@@ -151,5 +314,5 @@
 				This procedure MUST be supported by all DIAMETER nodes.
 			*/
-			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"Time"			, fd_dictfct_Time_interpret	, fd_dictfct_Time_encode, 	fd_dictfct_Time_dump		};
+			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"Time"			, NULL			, NULL		, NULL		};
 			CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
 		}
@@ -189,5 +352,5 @@
 				octets, not characters.
 			*/
-			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"UTF8String"		, NULL			, NULL	, fd_dictfct_UTF8String_dump	};
+			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"UTF8String"		, NULL			, NULL	, UTF8String_dump	};
 			CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
 		}
@@ -218,5 +381,5 @@
 				Domain Name (IDNs).
 			*/
-			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"DiameterIdentity"	, NULL			, NULL		, fd_dictfct_UTF8String_dump	};
+			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"DiameterIdentity"	, NULL			, NULL		, UTF8String_dump	};
 			CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
 		}
@@ -273,5 +436,5 @@
 				aaa://host.example.com:1813;transport=udp;protocol=radius
 			*/
-			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"DiameterURI"		, NULL			, NULL		, fd_dictfct_UTF8String_dump	};
+			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"DiameterURI"		, NULL			, NULL		, UTF8String_dump	};
 			CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
 		}
@@ -335,5 +498,5 @@
 				infrastructure.
 			*/
-			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"IPFilterRule"		, NULL			, NULL		, fd_dictfct_UTF8String_dump	};
+			struct dict_type_data data = { AVP_TYPE_OCTETSTRING,	"IPFilterRule"		, NULL			, NULL		, UTF8String_dump	};
 			CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
 		}
Index: libfdcore/fdcore-internal.h
===================================================================
--- libfdcore/fdcore-internal.h	(revision 938)
+++ libfdcore/fdcore-internal.h	(revision 909)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -126,5 +126,4 @@
 	struct fd_list 	srs; /* requests ordered by hop-by-hop id */
 	struct fd_list  exp; /* requests that have a timeout set, ordered by timeout */
-	int             cnt; /* number of requests in the srs list */
 	pthread_mutex_t	mtx; /* mutex to protect these lists */
 	pthread_cond_t  cnd; /* cond var used by the thread that handles timeouts */
Index: libfdcore/fdd.l
===================================================================
--- libfdcore/fdd.l	(revision 940)
+++ libfdcore/fdd.l	(revision 740)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -52,5 +52,5 @@
 	yylloc->first_column = yylloc->last_column + 1; 		\
 	yylloc->last_column = yylloc->first_column + yyleng - 1;	\
-	fd_log_debug(	 						\
+	TRACE_DEBUG(FULL, 						\
 		"(%d:%d-%d:%d) matched rule %d, length=%d, txt='%s'\n",	\
 		yylloc->first_line, yylloc->first_column, 		\
@@ -67,25 +67,4 @@
 /* %option noinput ? */
 #define YY_NO_INPUT
-
-/* Additional for files inclusion */
-#include <glob.h>
-#include <string.h>
-
-#define MAX_NESTED_CONF_FILES	5
-
-struct nested_conffiles_t {
-	YY_BUFFER_STATE parent_level_state;
-	glob_t filelist;
-	int current_file;
-} nested_conffiles[MAX_NESTED_CONF_FILES];
-
-int current_nested_level = 0;
-
-int globerrfct(const char *epath, int eerrno)
-{
-	TRACE_DEBUG_ERROR("Failed to scan %s: %s\n", epath, strerror(eerrno));
-	return 1;
-}
-
 %}
 
@@ -94,10 +73,9 @@
 %option nounput
 
-%x in_include
-
 /* Quoted string. Multilines do not match. */
 qstring		\"[^\"\n]*\"
 
 %%
+
 <*>\n			{ 
 				/* Update the line count */
@@ -109,112 +87,4 @@
 <*>([[:space:]]{-}[\n])+	; /* Eat all spaces, not new lines */
 <*>#.*$			; /* Eat all comments */
-
-
-include		BEGIN(in_include);
-	/* Following an "include" keyword */
-<in_include>{
-{qstring}	{ /* Name of the file to include. This is directly sent to glob. */
-			int globerror=0;
-			char * buf = strdup(yytext+1);
-			if (buf[yyleng-2] != '"')
-			{
-				TRACE_DEBUG_ERROR("Unterminated string: %s\n", yytext);
-				return LEX_ERROR;
-			}
-			buf[yyleng-2] = '\0';
-
-			if (current_nested_level >= MAX_NESTED_CONF_FILES)
-			{
-				TRACE_DEBUG_ERROR("Too many recursion levels in configuration files includes\n");
-				return LEX_ERROR;
-			}
-
-			/* glob the include */
-			globerror = glob(buf, GLOB_ERR, globerrfct, &nested_conffiles[current_nested_level].filelist);
-
-			if (globerror == GLOB_NOSPACE)
-			{
-				TRACE_DEBUG_ERROR("Not enough memory to parse include directive.\n");
-				return LEX_ERROR;
-			}
-			if (globerror == GLOB_ABORTED)
-			{
-				TRACE_DEBUG_ERROR("An error was encountered in include directive.\n");
-				return LEX_ERROR;
-			}
-			if (globerror == GLOB_NOMATCH)
-			{
-				globfree(&nested_conffiles[current_nested_level].filelist);
-				goto nomatch;
-			}
-			if (globerror)
-			{
-				TRACE_DEBUG_ERROR("Unexpected error in glob (%d).\n", globerror);
-				return LEX_ERROR;
-			}
-
-			/* We have a list of files to include. */
-
-			/* save the current buffer for returning when this include has been parsed */
-			nested_conffiles[current_nested_level].parent_level_state = YY_CURRENT_BUFFER;
-
-			/* Start with the first match */
-			nested_conffiles[current_nested_level].current_file = 0;
-
-			yyin = fopen( nested_conffiles[current_nested_level].filelist.gl_pathv[0], "r" );
-
-			if ( ! yyin )
-			{
-				TRACE_DEBUG_ERROR("Error in %s: %s", nested_conffiles[current_nested_level].filelist.gl_pathv[0], strerror(errno));
-				return LEX_ERROR;
-			}
-
-			yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ));
-
-			/* In case of recursive includes */
-			current_nested_level++;
-
-nomatch:
-			BEGIN(INITIAL);
-		}
-}
-
-<<EOF>>	{
-			if (current_nested_level == 0)
-			{
-			      /* We are at the end of parsing */
-			      yyterminate();
-			}
-
-			/* Otherwise we are doing an include statement */
-			--current_nested_level;
-			yy_delete_buffer(YY_CURRENT_BUFFER);
-
-			/* Go to next file, if any */
-			nested_conffiles[current_nested_level].current_file++;
-			if ( nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file] == NULL )
-			{
-				/* We have finished with this list of includes */
-				globfree(&nested_conffiles[current_nested_level].filelist);
-				yy_switch_to_buffer(nested_conffiles[current_nested_level].parent_level_state);
-			}
-			else
-			{
-				/* Proceed to next included file */
-				yyin = fopen( nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file], "r" );
-
-				if ( ! yyin )
-				{
-					TRACE_DEBUG_ERROR("Error in %s: %s", nested_conffiles[current_nested_level].filelist.gl_pathv[nested_conffiles[current_nested_level].current_file], strerror(errno));
-					return LEX_ERROR;
-				}
-
-				yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ));
-
-				/* In case of recursive includes */
-				current_nested_level++;
-			}
-
-}
 
 {qstring}		{
@@ -234,5 +104,5 @@
 				if (ret != 1) {
 					/* No matching: an error occurred */
-					TRACE_DEBUG_ERROR("Unable to convert the value '%s' to a valid number: %s\n", yytext, strerror(errno));
+					fprintf(stderr, "Unable to convert the value '%s' to a valid number: %s\n", yytext, strerror(errno));
 					return LEX_ERROR; /* trig an error in yacc parser */
 					/* Maybe we could REJECT instead of failing here? */
@@ -276,6 +146,6 @@
 <*>[[:alnum:]]+		|	/* This rule is only useful to print a complete token in error messages */
 	/* Unrecognized character */
-<*>.			{
-				TRACE_DEBUG_ERROR("Unrecognized text on line %d col %d: '%s'.\n", yylloc->first_line, yylloc->first_column, yytext);
+<*>.			{ 
+				fprintf(stderr, "Unrecognized text on line %d col %d: '%s'.\n", yylloc->first_line, yylloc->first_column, yytext);
 			 	return LEX_ERROR; 
 			}
Index: libfdcore/fdd.y
===================================================================
--- libfdcore/fdd.y	(revision 937)
+++ libfdcore/fdd.y	(revision 808)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -62,11 +62,10 @@
 void yyerror (YYLTYPE *ploc, struct fd_config * conf, char const *s)
 {
-	if (ploc->first_line != ploc->last_line) {
-		TRACE_DEBUG_ERROR("%s:%d.%d-%d.%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
-	} else if (ploc->first_column != ploc->last_column) {
-		TRACE_DEBUG_ERROR("%s:%d.%d-%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_column, s);
-	} else {
-		TRACE_DEBUG_ERROR("%s:%d.%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, s);
-	}
+	if (ploc->first_line != ploc->last_line)
+		fprintf(stderr, "%s:%d.%d-%d.%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+	else if (ploc->first_column != ploc->last_column)
+		fprintf(stderr, "%s:%d.%d-%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, ploc->last_column, s);
+	else
+		fprintf(stderr, "%s:%d.%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, s);
 }
 
@@ -323,16 +322,14 @@
 						{ yyerror (&yylloc, conf, "Not enough memory"); YYERROR; } );
 					sprintf(fname, DEFAULT_EXTENSIONS_PATH "/%s", bkp);
+					free(bkp);
 					fd = fopen(fname, "r");
-					if (fd == NULL) {
-						free(fname);
-						fname = bkp;
-					} else {
-						free(bkp);
-					}
-				}
-				if (fd != NULL) {
-					fclose(fd);
-				} /* otherwise, LD_LIBRARY_PATH will be tested by dl_open. 
-				This should not give any security issue, otherwise we can add an "else fail" here. */
+				}
+				if (fd == NULL) {
+					int ret = errno;
+					TRACE_DEBUG(INFO, "Unable to open extension file %s for reading: %s\n", fname, strerror(ret));
+					yyerror (&yylloc, conf, "Error adding extension"); 
+					YYERROR;
+				}
+				fclose(fd);
 				
 				/* Try and open the configuration file (optional) */
@@ -504,5 +501,5 @@
 				if (fd == NULL) {
 					int ret = errno;
-					TRACE_DEBUG_ERROR("Unable to open certificate file %s for reading: %s\n", $3, strerror(ret));
+					TRACE_DEBUG(INFO, "Unable to open certificate file %s for reading: %s\n", $3, strerror(ret));
 					yyerror (&yylloc, conf, "Error on file name"); 
 					YYERROR;
@@ -512,5 +509,5 @@
 				if (fd == NULL) {
 					int ret = errno;
-					TRACE_DEBUG_ERROR("Unable to open private key file %s for reading: %s\n", $5, strerror(ret));
+					TRACE_DEBUG(INFO, "Unable to open private key file %s for reading: %s\n", $5, strerror(ret));
 					yyerror (&yylloc, conf, "Error on file name"); 
 					YYERROR;
@@ -535,5 +532,5 @@
 				if (fd == NULL) {
 					int ret = errno;
-					TRACE_DEBUG_ERROR("Unable to open CA file %s for reading: %s\n", $3, strerror(ret));
+					TRACE_DEBUG(INFO, "Unable to open CA file %s for reading: %s\n", $3, strerror(ret));
 					yyerror (&yylloc, conf, "Error on file name"); 
 					YYERROR;
@@ -575,5 +572,5 @@
 				if (fd == NULL) {
 					int ret = errno;
-					TRACE_DEBUG_ERROR("Unable to open CRL file %s for reading: %s\n", $3, strerror(ret));
+					TRACE_DEBUG(INFO, "Unable to open CRL file %s for reading: %s\n", $3, strerror(ret));
 					yyerror (&yylloc, conf, "Error on file name"); 
 					YYERROR;
@@ -618,5 +615,5 @@
 							&err_pos),
 						{ yyerror (&yylloc, conf, "Error setting Priority parameter.");
-						  TRACE_DEBUG_ERROR("Error at position : %s\n", err_pos);
+						  fprintf(stderr, "Error at position : %s\n", err_pos);
 						  YYERROR; } );
 			}
@@ -635,5 +632,5 @@
 				if (fd == NULL) {
 					int ret = errno;
-					TRACE_DEBUG_ERROR("Unable to open DH file %s for reading: %s\n", $3, strerror(ret));
+					TRACE_DEBUG(INFO, "Unable to open DH file %s for reading: %s\n", $3, strerror(ret));
 					yyerror (&yylloc, conf, "Error on file name"); 
 					YYERROR;
Index: libfdcore/messages.c
===================================================================
--- libfdcore/messages.c	(revision 928)
+++ libfdcore/messages.c	(revision 892)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -159,7 +159,4 @@
 	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! */
 	return 0;
@@ -287,5 +284,5 @@
 			hdr->msg_flags |= CMD_FLAG_ERROR;
 		else
-			hdr->msg_flags &= ~ CMD_FLAG_ERROR;
+			hdr->msg_flags &= ! CMD_FLAG_ERROR;
 	}
 	
Index: libfdcore/p_ce.c
===================================================================
--- libfdcore/p_ce.c	(revision 935)
+++ libfdcore/p_ce.c	(revision 837)
@@ -455,8 +455,8 @@
 				{
 					struct avp * inavp = NULL;
+					application_id_t aid = 0;
 					vendor_id_t vid = 0;
-					application_id_t auth_aid = 0;
-					application_id_t acct_aid = 0;
-					int invalid=0;
+					int auth = 0;
+					int acct = 0;
 
 					/* get the first child AVP */
@@ -482,35 +482,15 @@
 						switch (inhdr->avp_code) {
 							case AC_VENDOR_ID: /* Vendor-Id */
-								if (vid != 0)
-									invalid++; /* We already had one such AVP */
 								vid = inhdr->avp_value->u32;
 								break;
 							case AC_AUTH_APPLICATION_ID: /* Auth-Application-Id */
-								if (auth_aid != 0)
-									invalid++; /* We already had one such AVP */
-#ifndef WORKAROUND_ACCEPT_INVALID_VSAI
-								if (acct_aid != 0)
-									invalid++; /* Only 1 *-Application-Id AVP is allowed */
-#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */
-								auth_aid = inhdr->avp_value->u32;
+								aid = inhdr->avp_value->u32;
+								auth += 1;
 								break;
 							case AC_ACCT_APPLICATION_ID: /* Acct-Application-Id */
-								if (acct_aid != 0)
-									invalid++; /* We already had one such AVP */
-#ifndef WORKAROUND_ACCEPT_INVALID_VSAI
-								if (auth_aid != 0)
-									invalid++; /* Only 1 *-Application-Id AVP is allowed */
-#endif /* WORKAROUND_ACCEPT_INVALID_VSAI */
-								acct_aid = inhdr->avp_value->u32;
+								aid = inhdr->avp_value->u32;
+								acct += 1;
 								break;
 							/* ignore other AVPs */
-						}
-						
-						if (invalid) {
-							TRACE_DEBUG(FULL, "Invalid Vendor-Specific-Application-Id AVP received, ignored");
-							fd_msg_dump_one(FULL, avp);
-							error->pei_errcode = "DIAMETER_INVALID_AVP_VALUE";
-							error->pei_avp = avp;
-							return EINVAL;
 						}
 
@@ -520,10 +500,13 @@
 					}
 					
-					/* Add entry in the list */
-					if (auth_aid) {
-						CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, auth_aid, vid, 1, 0) );
-					}
-					if (acct_aid) {
-						CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, acct_aid, vid, 0, 1) );
+					if (auth + acct != 1) {
+						TRACE_DEBUG(FULL, "Invalid Vendor-Specific-Application-Id AVP received, ignored");
+						fd_msg_dump_one(FULL, avp);
+						error->pei_errcode = "DIAMETER_INVALID_AVP_VALUE";
+						error->pei_avp = avp;
+						return EINVAL;
+					} else {
+						/* Add an entry in the list */
+						CHECK_FCT( fd_app_merge(&peer->p_hdr.info.runtime.pir_apps, aid, vid, auth, acct) );
 					}
 				}
Index: libfdcore/p_cnx.c
===================================================================
--- libfdcore/p_cnx.c	(revision 931)
+++ libfdcore/p_cnx.c	(revision 897)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: libfdcore/p_out.c
===================================================================
--- libfdcore/p_out.c	(revision 931)
+++ libfdcore/p_out.c	(revision 895)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: libfdcore/p_psm.c
===================================================================
--- libfdcore/p_psm.c	(revision 931)
+++ libfdcore/p_psm.c	(revision 895)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: libfdcore/p_sr.c
===================================================================
--- libfdcore/p_sr.c	(revision 938)
+++ libfdcore/p_sr.c	(revision 837)
@@ -226,5 +226,4 @@
 	*req = NULL;
 	fd_list_insert_before(next, &sr->chain);
-	srlist->cnt++;
 	srl_dump("Saved new request, ", &srlist->srs);
 	
@@ -282,5 +281,4 @@
 		/* Unlink */
 		fd_list_unlink(&sr->chain);
-		srlist->cnt--;
 		fd_list_unlink(&sr->expire);
 		*req = sr->req;
@@ -302,5 +300,4 @@
 		struct sentreq * sr = (struct sentreq *)(srlist->srs.next);
 		fd_list_unlink(&sr->chain);
-		srlist->cnt--;
 		fd_list_unlink(&sr->expire);
 		if (fd_msg_is_routable(sr->req)) {
Index: libfdcore/peers.c
===================================================================
--- libfdcore/peers.c	(revision 939)
+++ libfdcore/peers.c	(revision 908)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -257,19 +257,4 @@
 }
 
-/* Return the value of srlist->cnt */
-int fd_peer_get_load_pending(struct peer_hdr *peer, int * load)
-{
-	struct fd_peer * p = (struct fd_peer *)peer;
-	TRACE_ENTRY("%p %p", peer, load);
-	CHECK_PARAMS(CHECK_PEER(peer) && load);
-	
-	CHECK_POSIX( pthread_mutex_lock(&p->p_sr.mtx) );
-	*load = p->p_sr.cnt;
-	CHECK_POSIX( pthread_mutex_unlock(&p->p_sr.mtx) );
-	
-	return 0;
-}
-
-
 /* Destroy a structure once cleanups have been performed (fd_psm_abord, ...) */
 int fd_peer_free(struct fd_peer ** ptr)
@@ -410,5 +395,5 @@
 	}
 
-	fd_log_debug(">  %s\t%s\t[%dsr]", STATE_STR(fd_peer_getstate(peer)), peer->p_hdr.info.pi_diamid, peer->p_sr.cnt);
+	fd_log_debug(">  %s\t%s", STATE_STR(fd_peer_getstate(peer)), peer->p_hdr.info.pi_diamid);
 	if (details > INFO) {
 		fd_log_debug("\t(rlm:%s)", peer->p_hdr.info.runtime.pir_realm ?: "<unknown>");
@@ -530,12 +515,10 @@
 		peer->p_flags.pf_delete = 1;
 		
-#ifndef DISABLE_PEER_EXPIRY
 		/* Set this peer to expire on inactivity */
 		peer->p_hdr.info.config.pic_flags.exp 	= PI_EXP_INACTIVE;
 		peer->p_hdr.info.config.pic_lft		= 3600;	/* 1 hour without any message 
 		-- RFC3539 states that this must not be inferior to BRINGDOWN_INTERVAL = 5 minutes */
-		
 		CHECK_FCT_DO( ret = fd_p_expi_update( peer ), goto out );
-#endif /* DISABLE_PEER_EXPIRY */
+
 		
 		/* Insert the new peer in the list (the PSM will take care of setting the expiry after validation) */
@@ -566,5 +549,5 @@
 	ev_data->validate = !found;
 	
-	CHECK_FCT_DO( ret = fd_event_send(peer->p_events, FDEVP_CNX_INCOMING, sizeof(*ev_data), ev_data), goto out );
+	CHECK_FCT_DO( ret = fd_event_send(peer->p_events, FDEVP_CNX_INCOMING, sizeof(ev_data), ev_data), goto out );
 	
 out:	
Index: libfdcore/routing_dispatch.c
===================================================================
--- libfdcore/routing_dispatch.c	(revision 934)
+++ libfdcore/routing_dispatch.c	(revision 754)
@@ -424,5 +424,5 @@
 
 /* The DISPATCH message processing */
-static int msg_dispatch(struct msg * msg)
+static int msg_dispatch(struct msg ** pmsg)
 {
 	struct msg_hdr * hdr;
@@ -432,8 +432,7 @@
 	char * ec = NULL;
 	char * em = NULL;
-	struct msg *msgptr = msg;
 
 	/* Read the message header */
-	CHECK_FCT( fd_msg_hdr(msg, &hdr) );
+	CHECK_FCT( fd_msg_hdr(*pmsg, &hdr) );
 	is_req = hdr->msg_flags & CMD_FLAG_REQUEST;
 	
@@ -442,14 +441,15 @@
 
 	/* At this point, we need to understand the message content, so parse it */
-	CHECK_FCT_DO( ret = fd_msg_parse_or_error( &msgptr ),
+	CHECK_FCT_DO( ret = fd_msg_parse_or_error( pmsg ),
 		{
 			/* in case of error */
-			if ((ret == EBADMSG) && (msgptr != NULL)) {
-				/* msgptr now contains the answer message to send back */
-				CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) );
-			}
-			if (msgptr) {	/* another error happen'd */
-				fd_msg_log( FD_MSG_LOG_DROPPED, msgptr,  "An unexpected error occurred while parsing the message (%s)", strerror(ret));
-				CHECK_FCT_DO( fd_msg_free(msgptr), /* continue */);
+			if ((ret == EBADMSG) && (*pmsg != NULL)) {
+				/* msg now contains the answer message to send back */
+				CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) );
+			}
+			if (*pmsg) {	/* another error happen'd */
+				fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg,  "An unexpected error occurred while parsing the message (%s)", strerror(ret));
+				CHECK_FCT_DO( fd_msg_free(*pmsg), /* continue */);
+				*pmsg = NULL;
 			}
 			/* We're done with this one */
@@ -464,5 +464,5 @@
 
 		/* Retrieve the corresponding query */
-		CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) );
+		CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );
 
 		/* Retrieve any registered handler */
@@ -473,23 +473,21 @@
 
 			TRACE_DEBUG(FULL, "Calling callback registered when query was sent (%p, %p)", anscb, data);
-			(*anscb)(data, &msgptr);
+			(*anscb)(data, pmsg);
 			
 			/* If the message is processed, we're done */
-			if (msgptr == NULL) {
+			if (*pmsg == NULL) {
 				return 0;
 			}
-			
-			/* otherwise continue the dispatching --hoping that the anscb callback did not mess with our message :) */
 		}
 	}
 	
 	/* Retrieve the session of the message */
-	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msgptr, &sess, NULL) );
+	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *pmsg, &sess, NULL) );
 
 	/* Now, call any callback registered for the message */
-	CHECK_FCT( fd_msg_dispatch ( &msgptr, sess, &action, &ec) );
+	CHECK_FCT( fd_msg_dispatch ( pmsg, sess, &action, &ec) );
 
 	/* Now, act depending on msg and action and ec */
-	if (msgptr) {
+	if (*pmsg)
 		switch ( action ) {
 			case DISP_ACT_CONT:
@@ -497,5 +495,5 @@
 				if (!fd_g_config->cnf_flags.no_fwd) {
 					/* requeue to fd_g_outgoing */
-					CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) );
+					CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) );
 					break;
 				}
@@ -511,18 +509,18 @@
 				
 				if (!is_req) {
-					fd_msg_log( FD_MSG_LOG_DROPPED, msgptr,  "Internal error: Answer received to locally issued request, but not handled by any handler.");
-					fd_msg_free(msgptr);
+					fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg,  "Internal error: Answer received to locally issued request, but not handled by any handler.");
+					fd_msg_free(*pmsg);
+					*pmsg = NULL;
 					break;
 				}
 				
 				/* Create an answer with the error code and message */
-				CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msgptr, 0 ) );
-				CHECK_FCT( fd_msg_rescode_set(msgptr, ec, em, NULL, 1 ) );
+				CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, pmsg, 0 ) );
+				CHECK_FCT( fd_msg_rescode_set(*pmsg, ec, em, NULL, 1 ) );
 				
 			case DISP_ACT_SEND:
 				/* Now, send the message */
-				CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) );
-		}
-	}
+				CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) );
+		}
 	
 	/* We're done with dispatching this message */
@@ -531,5 +529,5 @@
 
 /* The ROUTING-IN message processing */
-static int msg_rt_in(struct msg * msg)
+static int msg_rt_in(struct msg ** pmsg)
 {
 	struct msg_hdr * hdr;
@@ -538,8 +536,7 @@
 	DiamId_t qry_src = NULL;
 	size_t   qry_src_len = 0;
-	struct msg *msgptr = msg;
 
 	/* Read the message header */
-	CHECK_FCT( fd_msg_hdr(msg, &hdr) );
+	CHECK_FCT( fd_msg_hdr(*pmsg, &hdr) );
 	is_req = hdr->msg_flags & CMD_FLAG_REQUEST;
 	is_err = hdr->msg_flags & CMD_FLAG_ERROR;
@@ -547,5 +544,5 @@
 	/* Handle incorrect bits */
 	if (is_req && is_err) {
-		CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL) );
+		CHECK_FCT( return_error( pmsg, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL) );
 		return 0;
 	}
@@ -567,5 +564,5 @@
 			TRACE_DEBUG(INFO, "Received a routable message with application id 0 or " _stringize(AI_RELAY) " (relay),\n"
 					  " returning DIAMETER_APPLICATION_UNSUPPORTED");
-			CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL) );
+			CHECK_FCT( return_error( pmsg, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL) );
 			return 0;
 		} else {
@@ -576,5 +573,5 @@
 
 		/* Parse the message for Dest-Host and Dest-Realm */
-		CHECK_FCT(  fd_msg_browse(msgptr, MSG_BRW_FIRST_CHILD, &avp, NULL)  );
+		CHECK_FCT(  fd_msg_browse(*pmsg, MSG_BRW_FIRST_CHILD, &avp, NULL)  );
 		while (avp) {
 			struct avp_hdr * ahdr;
@@ -593,5 +590,5 @@
 							{
 								if (error_info.pei_errcode) {
-									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
 									return 0;
 								} else {
@@ -613,5 +610,5 @@
 							{
 								if (error_info.pei_errcode) {
-									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
 									return 0;
 								} else {
@@ -635,5 +632,5 @@
 							{
 								if (error_info.pei_errcode) {
-									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
 									return 0;
 								} else {
@@ -660,5 +657,5 @@
 		/* Handle the missing routing AVPs first */
 		if ( is_dest_realm == UNKNOWN ) {
-			CHECK_FCT( return_error( &msgptr, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL) );
+			CHECK_FCT( return_error( pmsg, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL) );
 			return 0;
 		}
@@ -668,8 +665,8 @@
 			if (is_local_app == YES) {
 				/* Ok, give the message to the dispatch thread */
-				CHECK_FCT( fd_fifo_post(fd_g_local, &msgptr) );
+				CHECK_FCT( fd_fifo_post(fd_g_local, pmsg) );
 			} else {
 				/* We don't support the application, reply an error */
-				CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) );
+				CHECK_FCT( return_error( pmsg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) );
 			}
 			return 0;
@@ -679,5 +676,5 @@
 		if ((is_dest_host == NO) || (is_dest_realm == NO)) {
 			if (fd_g_config->cnf_flags.no_fwd) {
-				CHECK_FCT( return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "I am not a Diameter agent", NULL) );
+				CHECK_FCT( return_error( pmsg, "DIAMETER_UNABLE_TO_DELIVER", "I am not a Diameter agent", NULL) );
 				return 0;
 			}
@@ -692,5 +689,5 @@
 					{
 						/* If the process failed, we assume it is because of the AVP format */
-						CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un) );
+						CHECK_FCT( return_error( pmsg, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un) );
 						return 0;
 					} );
@@ -699,5 +696,5 @@
 			if (is_nai) {
 				/* We have transformed the AVP, now submit it again in the queue */
-				CHECK_FCT(fd_fifo_post(fd_g_incoming, &msgptr) );
+				CHECK_FCT(fd_fifo_post(fd_g_incoming, pmsg) );
 				return 0;
 			}
@@ -705,5 +702,5 @@
 			if (is_local_app == YES) {
 				/* Handle localy since we are able to */
-				CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) );
+				CHECK_FCT(fd_fifo_post(fd_g_local, pmsg) );
 				return 0;
 			}
@@ -711,5 +708,5 @@
 			if (fd_g_config->cnf_flags.no_fwd) {
 				/* We return an error */
-				CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) );
+				CHECK_FCT( return_error( pmsg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) );
 				return 0;
 			}
@@ -723,10 +720,10 @@
 
 		/* Retrieve the corresponding query and its origin */
-		CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) );
+		CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );
 		CHECK_FCT( fd_msg_source_get( qry, &qry_src, &qry_src_len ) );
 
 		if ((!qry_src) && (!is_err)) {
 			/* The message is a normal answer to a request issued localy, we do not call the callbacks chain on it. */
-			CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) );
+			CHECK_FCT(fd_fifo_post(fd_g_local, pmsg) );
 			return 0;
 		}
@@ -743,5 +740,5 @@
 
 		/* requests: dir = 1 & 2 => in order; answers = 3 & 2 => in reverse order */
-		for (	li = (is_req ? rt_fwd_list.next : rt_fwd_list.prev) ; msgptr && (li != &rt_fwd_list) ; li = (is_req ? li->next : li->prev) ) {
+		for (	li = (is_req ? rt_fwd_list.next : rt_fwd_list.prev) ; *pmsg && (li != &rt_fwd_list) ; li = (is_req ? li->next : li->prev) ) {
 			struct rt_hdl * rh = (struct rt_hdl *)li;
 			int ret;
@@ -753,10 +750,10 @@
 
 			/* Ok, call this cb */
-			TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", msgptr, rh->rt_fwd_cb);
-			CHECK_FCT_DO( ret = (*rh->rt_fwd_cb)(rh->cbdata, &msgptr),
+			TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", *pmsg, rh->rt_fwd_cb);
+			CHECK_FCT_DO( ret = (*rh->rt_fwd_cb)(rh->cbdata, pmsg),
 				{
-					fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: a FWD routing callback returned an error (%s)", strerror(ret));
-					fd_msg_free(msgptr);
-					msgptr = NULL;
+					fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Internal error: a FWD routing callback returned an error (%s)", strerror(ret));
+					fd_msg_free(*pmsg);
+					*pmsg = NULL;
 				} );
 		}
@@ -766,5 +763,5 @@
 
 		/* If a callback has handled the message, we stop now */
-		if (!msgptr)
+		if (!*pmsg)
 			return 0;
 	}
@@ -772,7 +769,7 @@
 	/* Now pass the message to the next step: either forward to another peer, or dispatch to local extensions */
 	if (is_req || qry_src) {
-		CHECK_FCT(fd_fifo_post(fd_g_outgoing, &msgptr) );
+		CHECK_FCT(fd_fifo_post(fd_g_outgoing, pmsg) );
 	} else {
-		CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) );
+		CHECK_FCT(fd_fifo_post(fd_g_local, pmsg) );
 	}
 
@@ -783,5 +780,5 @@
 
 /* The ROUTING-OUT message processing */
-static int msg_rt_out(struct msg * msg)
+static int msg_rt_out(struct msg ** pmsg)
 {
 	struct rt_data * rtd = NULL;
@@ -792,8 +789,7 @@
 	struct avp * avp;
 	struct rtd_candidate * c;
-	struct msg *msgptr = msg;
 	
 	/* Read the message header */
-	CHECK_FCT( fd_msg_hdr(msgptr, &hdr) );
+	CHECK_FCT( fd_msg_hdr(*pmsg, &hdr) );
 	is_req = hdr->msg_flags & CMD_FLAG_REQUEST;
 	
@@ -807,5 +803,5 @@
 
 		/* Retrieve the corresponding query and its origin */
-		CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) );
+		CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );
 		CHECK_FCT( fd_msg_source_get( qry, &qry_src, &qry_src_len ) );
 
@@ -815,6 +811,7 @@
 		CHECK_FCT( fd_peer_getbyid( qry_src, qry_src_len, 0, (void *) &peer ) );
 		if (fd_peer_getstate(peer) != STATE_OPEN) {
-			fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Unable to forward answer to deleted / closed peer '%s'.", qry_src);
-			fd_msg_free(msgptr);
+			fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Unable to forward answer to deleted / closed peer '%s'.", qry_src);
+			fd_msg_free(*pmsg);
+			*pmsg = NULL;
 			return 0;
 		}
@@ -825,5 +822,5 @@
 
 		/* Push the message into this peer */
-		CHECK_FCT( fd_out_send(&msgptr, NULL, peer, 0) );
+		CHECK_FCT( fd_out_send(pmsg, NULL, peer, 0) );
 
 		/* We're done with this answer */
@@ -834,5 +831,5 @@
 
 	/* Get the routing data out of the message if any (in case of re-transmit) */
-	CHECK_FCT( fd_msg_rt_get ( msgptr, &rtd ) );
+	CHECK_FCT( fd_msg_rt_get ( *pmsg, &rtd ) );
 
 	/* If there is no routing data already, let's create it */
@@ -854,5 +851,5 @@
 
 		/* Now let's remove all peers from the Route-Records */
-		CHECK_FCT(  fd_msg_browse(msgptr, MSG_BRW_FIRST_CHILD, &avp, NULL)  );
+		CHECK_FCT(  fd_msg_browse(*pmsg, MSG_BRW_FIRST_CHILD, &avp, NULL)  );
 		while (avp) {
 			struct avp_hdr * ahdr;
@@ -865,5 +862,5 @@
 					{
 						if (error_info.pei_errcode) {
-							CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+							CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
 							return 0;
 						} else {
@@ -886,5 +883,5 @@
 	fd_rtd_candidate_extract(rtd, &candidates, FD_SCORE_INI);
 
-	/* Pass the list to registered callbacks (even if it is empty list) */
+	/* Pass the list to registered callbacks (even if it is empty) */
 	{
 		CHECK_FCT( pthread_rwlock_rdlock( &rt_out_lock ) );
@@ -895,10 +892,10 @@
 			struct rt_hdl * rh = (struct rt_hdl *)li;
 
-			TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", msgptr, rh->rt_out_cb, rh->prio);
-			CHECK_FCT_DO( ret = (*rh->rt_out_cb)(rh->cbdata, msgptr, candidates),
+			TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", *pmsg, rh->rt_out_cb, rh->prio);
+			CHECK_FCT_DO( ret = (*rh->rt_out_cb)(rh->cbdata, *pmsg, candidates),
 				{
-					fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: an OUT routing callback returned an error (%s)", strerror(ret));
-					fd_msg_free(msgptr);
-					msgptr = NULL;
+					fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Internal error: an OUT routing callback returned an error (%s)", strerror(ret));
+					fd_msg_free(*pmsg);
+					*pmsg = NULL;
 					break;
 				} );
@@ -909,5 +906,5 @@
 
 		/* If an error occurred, skip to the next message */
-		if (! msgptr) {
+		if (! *pmsg) {
 			if (rtd)
 				fd_rtd_free(&rtd);
@@ -920,5 +917,5 @@
 
 	/* Save the routing information in the message */
-	CHECK_FCT( fd_msg_rt_associate ( msgptr, &rtd ) );
+	CHECK_FCT( fd_msg_rt_associate ( *pmsg, &rtd ) );
 
 	/* Now try sending the message */
@@ -937,5 +934,5 @@
 		if (fd_peer_getstate(peer) == STATE_OPEN) {
 			/* Send to this one */
-			CHECK_FCT_DO( fd_out_send(&msgptr, NULL, peer, 0), continue );
+			CHECK_FCT_DO( fd_out_send(pmsg, NULL, peer, 0), continue );
 			
 			/* If the sending was successful */
@@ -945,7 +942,7 @@
 
 	/* If the message has not been sent, return an error */
-	if (msgptr) {
-		fd_msg_log( FD_MSG_LOG_NODELIVER, msgptr, "No suitable candidate to route the message to." );
-		return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL);
+	if (*pmsg) {
+		fd_msg_log( FD_MSG_LOG_NODELIVER, *pmsg, "No suitable candidate to route the message to." );
+		return_error( pmsg, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL);
 	}
 
@@ -980,5 +977,5 @@
 
 /* This is the common thread code (same for routing and dispatching) */
-static void * process_thr(void * arg, int (*action_cb)(struct msg * msg), struct fifo * queue, char * action_name)
+static void * process_thr(void * arg, int (*action_cb)(struct msg ** pmsg), struct fifo * queue, char * action_name)
 {
 	TRACE_ENTRY("%p %p %p %p", arg, action_cb, queue, action_name);
@@ -1043,5 +1040,5 @@
 		
 		/* Now process the message */
-		CHECK_FCT_DO( (*action_cb)(msg), goto fatal_error);
+		CHECK_FCT_DO( (*action_cb)(&msg), goto fatal_error);
 
 		/* We're done with this message */
Index: libfdcore/sctp.c
===================================================================
--- libfdcore/sctp.c	(revision 928)
+++ libfdcore/sctp.c	(revision 894)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -654,5 +654,5 @@
 		if (ep->sa.sa_family == AF_INET6)
 		#else /* SCTP_USE_MAPPED_ADDRESSES */
-		if (target_family == AF_INET6)
+		if (target_family == AF_INET6) {
 		#endif /* SCTP_USE_MAPPED_ADDRESSES */
 			sz = sizeof(sSA6);
@@ -1087,5 +1087,5 @@
 	/* We will loop while all data is not received. */
 incomplete:
-	while (datasize + sizeof(struct timespec) >= bufsz ) {
+	if (datasize == bufsz - sizeof(struct timespec)) {
 		/* The buffer is full, enlarge it */
 		bufsz += mempagesz;
Index: libfdcore/server.c
===================================================================
--- libfdcore/server.c	(revision 931)
+++ libfdcore/server.c	(revision 901)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: libfdproto/CMakeLists.txt
===================================================================
--- libfdproto/CMakeLists.txt	(revision 922)
+++ libfdproto/CMakeLists.txt	(revision 836)
@@ -6,5 +6,4 @@
 	fdproto-internal.h
 	dictionary.c
-	dictionary_functions.c
 	dispatch.c
 	fifo.c
Index: libfdproto/dictionary.c
===================================================================
--- libfdproto/dictionary.c	(revision 928)
+++ libfdproto/dictionary.c	(revision 910)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
Index: bfdproto/dictionary_functions.c
===================================================================
--- libfdproto/dictionary_functions.c	(revision 923)
+++ 	(revision )
@@ -1,331 +1,0 @@
-/*********************************************************************************************************
-* Software License Agreement (BSD License)                                                               *
-* Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
-*													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
-* All rights reserved.											 *
-* 													 *
-* Redistribution and use of this software in source and binary forms, with or without modification, are  *
-* permitted provided that the following conditions are met:						 *
-* 													 *
-* * Redistributions of source code must retain the above 						 *
-*   copyright notice, this list of conditions and the 							 *
-*   following disclaimer.										 *
-*    													 *
-* * Redistributions in binary form must reproduce the above 						 *
-*   copyright notice, this list of conditions and the 							 *
-*   following disclaimer in the documentation and/or other						 *
-*   materials provided with the distribution.								 *
-* 													 *
-* * Neither the name of the WIDE Project or NICT nor the 						 *
-*   names of its contributors may be used to endorse or 						 *
-*   promote products derived from this software without 						 *
-*   specific prior written permission of WIDE Project and 						 *
-*   NICT.												 *
-* 													 *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
-* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
-* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
-* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
-* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
-*********************************************************************************************************/
-
-#include "fdproto-internal.h"
-
-/* This file contains helpers functions to be reused as callbacks in the struct dict_type_data structure.
-There are three callbacks there:
-
- - type_encode    :
- - type_interpret :
- 	  Those two callbacks allow to manipulate more natural structures of data in the code, and to 
-	map transparently these natural structures with the AVP-encoded format by calling the functions
-	msg_avp_value_encode or msg_avp_value_interpret.
- - type_dump : 
- 	  This callback if provided gives a more human-readable debug information.
-
- */
-
-/****************************/
-/*    Address  AVP  type    */
-/****************************/
-
-/* The interpret and encode functions work with a "struct sockaddr_storage" pointer for mapping 
-the contents of the AVP */
-
-int fd_dictfct_Address_encode(void * data, union avp_value * avp_value)
-{
-	sSS * ss = (sSS *) data;
-	uint16_t AddressType = 0;
-	size_t	size = 0;
-	unsigned char * buf = NULL;
-	
-	TRACE_ENTRY("%p %p", data, avp_value);
-	CHECK_PARAMS( data && avp_value  );
-	
-	switch (ss->ss_family) {
-		case AF_INET:
-			{
-				/* We are encoding an IP address */
-				sSA4 * sin = (sSA4 *)ss;
-				
-				AddressType = 1;/* see http://www.iana.org/assignments/address-family-numbers/ */
-				size = 6;	/* 2 for AddressType + 4 for data */
-				
-				CHECK_MALLOC(  buf = malloc(size)  );
-				
-				/* may not work because of alignment: *(uint32_t *)(buf+2) = htonl(sin->sin_addr.s_addr); */
-				memcpy(buf + 2, &sin->sin_addr.s_addr, 4);
-			}
-			break;
-				
-		case AF_INET6:
-			{
-				/* We are encoding an IPv6 address */
-				sSA6 * sin6 = (sSA6 *)ss;
-				
-				AddressType = 2;/* see http://www.iana.org/assignments/address-family-numbers/ */
-				size = 18;	/* 2 for AddressType + 16 for data */
-				
-				CHECK_MALLOC(  buf = malloc(size)  );
-				
-				/* The order is already good here */
-				memcpy(buf + 2, &sin6->sin6_addr.s6_addr, 16);
-			}
-			break;
-				
-		default:
-			CHECK_PARAMS( AddressType = 0 );
-	}
-	
-	*(uint16_t *)buf = htons(AddressType);
-
-	avp_value->os.len = size;
-	avp_value->os.data = buf;
-	
-	return 0;
-}
-
-int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted)
-{
-	uint16_t AddressType = 0;
-	unsigned char * buf;
-	
-	TRACE_ENTRY("%p %p", avp_value, interpreted);
-	
-	CHECK_PARAMS( avp_value && interpreted && (avp_value->os.len >= 2)  );
-	
-	AddressType = ntohs(*(uint16_t *)avp_value->os.data);
-	buf = &avp_value->os.data[2];
-	
-	switch (AddressType) {
-		case 1 /* IP */:
-			{
-				sSA4 * sin = (sSA4 *)interpreted;
-				
-				CHECK_PARAMS(  avp_value->os.len == 6  );
-				
-				sin->sin_family = AF_INET;
-				/* sin->sin_addr.s_addr = ntohl( * (uint32_t *) buf); -- may not work because of bad alignment */
-				memcpy(&sin->sin_addr.s_addr, buf, 4);
-			}
-			break;
-				
-		case 2 /* IP6 */:
-			{
-				sSA6 * sin6 = (sSA6 *)interpreted;
-				
-				CHECK_PARAMS(  avp_value->os.len == 18  );
-				
-				sin6->sin6_family = AF_INET6;
-				memcpy(&sin6->sin6_addr.s6_addr, buf, 16);
-			}
-			break;
-				
-		default:
-			CHECK_PARAMS( AddressType = 0 );
-	}
-	
-	return 0;
-}
-
-/* Dump the content of an Address AVP */
-char * fd_dictfct_Address_dump(union avp_value * avp_value)
-{
-	char * ret;
-	#define STR_LEN	1024
-	union {
-		sSA	sa;
-		sSS	ss;
-		sSA4	sin;
-		sSA6	sin6;
-	} s;
-	uint16_t fam;
-	
-	memset(&s, 0, sizeof(s));
-	
-	CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );
-	
-	/* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */
-	if (avp_value->os.len < 2) {
-		snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len);
-		return ret;
-	}
-	
-	/* Following octets are the address in network byte order already */
-	fam = avp_value->os.data[0] << 8 | avp_value->os.data[1];
-	switch (fam) {
-		case 1:
-			/* IP */
-			s.sa.sa_family = AF_INET;
-			if (avp_value->os.len != 6) {
-				snprintf(ret, STR_LEN, "[invalid IP length: %zd]", avp_value->os.len);
-				return ret;
-			}
-			memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4);
-			break;
-		case 2:
-			/* IP6 */
-			s.sa.sa_family = AF_INET6;
-			if (avp_value->os.len != 18) {
-				snprintf(ret, STR_LEN, "[invalid IP6 length: %zd]", avp_value->os.len);
-				return ret;
-			}
-			memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16);
-			break;
-		default:
-			snprintf(ret, STR_LEN, "[unsupported family: 0x%hx]", fam);
-			return ret;
-	}
-	
-	{
-		int rc = getnameinfo(&s.sa, sSAlen(&s.sa), ret, STR_LEN, NULL, 0, NI_NUMERICHOST);
-		if (rc)
-			snprintf(ret, STR_LEN, "%s", (char *)gai_strerror(rc));
-	}
-	
-	return ret;
-}
-
-
-
-/*******************************/
-/*    UTF8String  AVP  type    */
-/*******************************/
-
-/* Dump the AVP in a natural human-readable format */
-char * fd_dictfct_UTF8String_dump(union avp_value * avp_value)
-{
-#define TRUNC_LEN	42 /* avoid very long strings */
-	char * ret = strndup((char *)avp_value->os.data, TRUNC_LEN); 
-	if (ret && (*ret != '\0')) {
-		/* We sanitize the returned string to avoid UTF8 boundary problem.
-		We do this whether the string is trucated at TRUNC_LEN or not, to avoid potential problem
-		with malformed AVP */
-
-		char * end = strchr(ret, '\0');
-		
-		while (end > ret) {
-			end--;
-			char b = *end;
-			/* after the position pointed by end, we have only \0s */
-			if ((b & 0x80) == 0) {
-				break; /* this is a single byte char, no problem */
-			} else {
-				/* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */
-				*end = '\0';
-				if (b & 0x40)
-					break; /* This was a start byte, we can stop the loop */
-			}
-		}
-	}	
-	return ret;
-}
-
-
-/*******************************/
-/*    Time  AVP  type    */
-/*******************************/
-
-/* The interpret and encode functions work with a "time_t" pointer for mapping 
-the contents of the AVP */
-
-/* Unix Epoch starts 1970-01-01, NTP 0 is at 1900-01-01 */
-#define DIFF_EPOCH_TO_NTP ((365*(1970-1900) + 17ul) * 24 * 60 * 60)
-
-static int diameter_string_to_time_t(const char *str, size_t len, time_t *result) {
-    time_t time_stamp;
-    CHECK_PARAMS(len == 4);
-   
-    time_stamp = (((unsigned long)(str[0]&0xff))<<24) + ((str[1]&0xff)<<16) + ((str[2]&0xff)<<8) + ((str[3]&0xff));
-    time_stamp -= DIFF_EPOCH_TO_NTP;
-#ifdef FIX__NEEDED_FOR_YEAR_2036_AND_LATER
-/* NTP overflows in 2036; after that, values start at zero again */
-#define NTP_OVERFLOW_CORRECTION (0x100000000ull)
-    /* XXX: debug and find correct conversion */
-    if (str[0] & 0x80 == 0x00) {
-        time_stamp += NTP_OVERFLOW_CORRECTION;
-    }
-#endif
-    *result = time_stamp;
-    return 0;
-}
-
-static int time_t_to_diameter_string(time_t time_stamp, char **result) {
-    uint64_t out = time_stamp;
-    char *conv;
-    /* XXX: 2036 fix */
-    out += DIFF_EPOCH_TO_NTP;
-    CHECK_PARAMS( (out & 0xffffffff00000000) == 0);
-
-    CHECK_MALLOC(conv=(char *)malloc(5));
-    
-    conv[0] = (out>>24) & 0xff;
-    conv[1] = (out>>16) & 0xff;
-    conv[2] = (out>> 8) & 0xff;
-    conv[3] =  out      & 0xff;
-    conv[4] = '\0';
-    *result = conv;
-    return 0;
-}
-
-int fd_dictfct_Time_encode(void * data, union avp_value * avp_value)
-{
-	char * buf;
-	size_t len;
-	
-	TRACE_ENTRY("%p %p", data, avp_value);
-	CHECK_PARAMS( data && avp_value  );
-	
-	CHECK_FCT( time_t_to_diameter_string( *((time_t *)data), &buf) );
-	/* FIXME: return len from the function above? */ len = 4;
-	
-	avp_value->os.len = len;
-	avp_value->os.data = buf;
-	return 0;
-}
-
-int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted)
-{
-	TRACE_ENTRY("%p %p", avp_value, interpreted);
-	
-	CHECK_PARAMS( avp_value && interpreted );
-	
-	return diameter_string_to_time_t(avp_value->os.data, avp_value->os.len, interpreted);
-}
-
-char * fd_dictfct_Time_dump(union avp_value * avp_value)
-{
-	char * ret;
-	CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );
-	if (avp_value->os.len != 4) {
-		snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len);
-		return ret;
-	}
-	/* TODO: display the time as human-readable */
-	snprintf(ret, STR_LEN, "[TODO Time dump: 0x%02hhx%02hhx%02hhx%02hhx]", avp_value->os.data[0], avp_value->os.data[1], avp_value->os.data[2], avp_value->os.data[3]);
-	return ret;
-}
-
Index: libfdproto/fdproto-internal.h
===================================================================
--- libfdproto/fdproto-internal.h	(revision 928)
+++ libfdproto/fdproto-internal.h	(revision 909)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -70,5 +70,4 @@
 int fd_sess_reclaim_msg ( struct session ** session );
 
-
 /* For dump routines into string buffers */
 #include <stdarg.h>
Index: libfdproto/log.c
===================================================================
--- libfdproto/log.c	(revision 928)
+++ libfdproto/log.c	(revision 941)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -44,4 +44,6 @@
 int fd_g_debug_lvl = INFO;
 
+static void fd_internal_logger( int, const char *, va_list );
+
 /* These may be used to pass specific debug requests via the command-line parameters */
 char * fd_debug_one_function = NULL;
@@ -53,12 +55,12 @@
 
 /* Allow passing of the log and debug information from base stack to extensions */
-void (*fd_external_logger)( const char * format, va_list *args ) = NULL;
+void (*fd_logger)( int loglevel, const char * format, va_list args ) = fd_internal_logger;
 
-/* Register an dexternal call back for tracing and debug */
-int fd_log_handler_register( void (*logger)(const char * format, va_list *args))
+/* Register an external call back for tracing and debug */
+int fd_log_handler_register( void (*logger)(int loglevel, const char * format, va_list args) )
 {
         CHECK_PARAMS( logger );
 
-        if ( fd_external_logger != NULL )
+        if ( fd_logger != fd_internal_logger )
         {
                return EALREADY; /* only one registration allowed */
@@ -66,6 +68,7 @@
         else
         {
-               fd_external_logger = logger;
+               fd_logger = logger;
         }
+
         return 0;
 }
@@ -74,5 +77,5 @@
 int fd_log_handler_unregister ( void )
 {
-        fd_external_logger = NULL;
+        fd_logger = fd_internal_logger;
         return 0; /* Successfull in all cases. */
 }
@@ -83,6 +86,17 @@
 }
 
+
+static void fd_internal_logger( int loglevel, const char *format, va_list ap )
+{
+    FILE *fstr = fd_g_debug_fstr ?: stdout;
+
+    /* logging has been decided by macros outside already */
+    vfprintf( fd_g_debug_fstr, format, ap);
+    fprintf(fd_g_debug_fstr, "\n");
+    fflush(fd_g_debug_fstr);
+}
+
 /* Log a debug message */
-void fd_log_debug_fstr ( FILE * fstr, const char * format, ... )
+void fd_log ( int loglevel, const char * format, ... )
 {
 	va_list ap;
@@ -93,13 +107,5 @@
 	
 	va_start(ap, format);
-        if ( fd_external_logger != NULL )
-        {
-               fd_external_logger( format, &ap );
-        }
-        else
-        {
-               vfprintf( fstr ?: stdout, format, ap);
-               fflush(fstr ?: stdout);
-        }
+	fd_logger(loglevel, format, ap);
 	va_end(ap);
 
@@ -107,4 +113,14 @@
 	
 	(void)pthread_mutex_unlock(&fd_log_lock);
+}
+
+/* Log debug message to file. */
+void fd_log_debug_fstr( FILE * fstr, const char * format, ... )
+{
+	va_list ap;
+	
+	va_start(ap, format);
+	vfprintf(fstr, format, ap);
+	va_end(ap);
 }
 
Index: libfdproto/messages.c
===================================================================
--- libfdproto/messages.c	(revision 928)
+++ libfdproto/messages.c	(revision 903)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -106,5 +106,5 @@
 #define _A(_x) ((struct avp *)(_x))
 /* Check the type and eyecatcher */
-#define CHECK_AVP(_x) ((_x) && (_C(_x)->type == MSG_AVP) && (_A(_x)->avp_eyec == MSG_AVP_EYEC))
+#define CHECK_AVP(_x) ((_C(_x)->type == MSG_AVP) && (_A(_x)->avp_eyec == MSG_AVP_EYEC))
 
 /* The following structure represents an instance of a message (command and children AVPs). */
@@ -239,5 +239,5 @@
 		if (new->avp_rawlen) {
 			CHECK_MALLOC(  new->avp_rawdata = malloc(new->avp_rawlen)  );
-			memset(new->avp_rawdata, 0x00, new->avp_rawlen);
+			memset(new->avp_rawdata, 0xFF, new->avp_rawlen);
 		}
 	}
@@ -1216,18 +1216,4 @@
 }
 
-/* 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 */
@@ -1275,11 +1261,6 @@
 	
 	/* Resolve the session and we are done */
-	if (avp->avp_public.avp_value->os.len > 0) {
-		CHECK_FCT( fd_sess_fromsid_msg ( avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len, &msg->msg_sess, new) );
-		*session = msg->msg_sess;
-	} else {
-		TRACE_DEBUG(FULL, "Session-Id AVP with 0-byte length found in message %p", msg);
-		*session = NULL;
-	}
+	CHECK_FCT( fd_sess_fromsid_msg ( avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len, &msg->msg_sess, new) );
+	*session = msg->msg_sess;
 	
 	return 0;
@@ -1667,5 +1648,5 @@
 		struct avp * avp;
 		
-		if (buflen - offset < AVPHDRSZ_NOVEND) {
+		if (buflen - offset <= AVPHDRSZ_NOVEND) {
 			TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes", buflen - offset);
 			return EBADMSG;
@@ -1685,5 +1666,5 @@
 		
 		if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
-			if (buflen - offset < 4) {
+			if (buflen - offset <= 4) {
 				TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes for vendor and data", buflen - offset);
 				free(avp);
@@ -1695,6 +1676,5 @@
 		
 		/* Check there is enough remaining data in the buffer */
-		if ( (avp->avp_public.avp_len > GETAVPHDRSZ(avp->avp_public.avp_flags))
-		&& (buflen - offset < avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags))) {
+		if (buflen - offset < avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)) {
 			TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes for data, and avp data size is %d", 
 					buflen - offset, 
Index: libfdproto/msg_log.c
===================================================================
--- libfdproto/msg_log.c	(revision 928)
+++ libfdproto/msg_log.c	(revision 908)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -162,5 +162,4 @@
 			break;
 		default:
-			break;
 	}
 	
@@ -201,6 +200,5 @@
 			break;
 		default:
-			break;
-	}
-}
-
+	}
+}
+
Index: libfdproto/sessions.c
===================================================================
--- libfdproto/sessions.c	(revision 928)
+++ libfdproto/sessions.c	(revision 788)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2012, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
@@ -360,5 +360,5 @@
 
 
-/* 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 */
+/* Create a new session object with the default timeout value, and link it */
 int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen )
 {
@@ -461,12 +461,6 @@
 	
 		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) {
@@ -475,6 +469,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 */
@@ -507,5 +501,5 @@
 
 out:
-	;
+	;	
 	pthread_cleanup_pop(0);
 	CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
@@ -518,6 +512,6 @@
 }
 
-/* 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)
+/* Find or create a session */
+int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
 {
 	int ret;
@@ -808,5 +802,5 @@
 
 /* For the messages module */
-int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
+int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
 {
 	TRACE_ENTRY("%p %zd %p %p", sid, len, session, new);
@@ -814,11 +808,9 @@
 	
 	/* Get the session object */
-	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) );
-		
+	CHECK_FCT( fd_sess_fromsid ( sid, len, session, new) );
+	
+	/* Increase count */
+	CHECK_FCT( fd_sess_ref_msg ( *session ) );
+	
 	/* Done */
 	return 0;
@@ -841,14 +833,8 @@
 {
 	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) );
@@ -857,9 +843,4 @@
 	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 ));
Index: tests/testmesg.c
===================================================================
--- tests/testmesg.c	(revision 931)
+++ tests/testmesg.c	(revision 892)
@@ -3,5 +3,5 @@
 * Author: Sebastien Decugis <sdecugis@freediameter.net>							 *
 *													 *
-* Copyright (c) 2013, WIDE Project and NICT								 *
+* Copyright (c) 2011, WIDE Project and NICT								 *
 * All rights reserved.											 *
 * 													 *
