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 944)
@@ -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,6 +52,5 @@
 	yylloc->first_column = yylloc->last_column + 1; 		\
 	yylloc->last_column = yylloc->first_column + yyleng - 1;	\
-	fd_log_debug(	 						\
-		"(%d:%d-%d:%d) matched rule %d, length=%d, txt='%s'\n",	\
+	TRACE_DEBUG_ERROR("(%d:%d-%d:%d) matched rule %d, length=%d, txt='%s'\n",	\
 		yylloc->first_line, yylloc->first_column, 		\
 		yylloc->last_line, yylloc->last_column, 		\
@@ -67,25 +66,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 +72,9 @@
 %option nounput
 
-%x in_include
-
 /* Quoted string. Multilines do not match. */
 qstring		\"[^\"\n]*\"
 
 %%
+
 <*>\n			{ 
 				/* Update the line count */
@@ -109,112 +86,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}		{
@@ -276,5 +145,5 @@
 <*>[[: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);
 			 	return LEX_ERROR; 
Index: libfdcore/fdd.y
===================================================================
--- libfdcore/fdd.y	(revision 937)
+++ libfdcore/fdd.y	(revision 944)
@@ -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.											 *
 * 													 *
@@ -323,16 +323,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 +502,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 +510,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 +533,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 +573,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 +616,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 +633,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.											 *
 * 													 *
