changeset 1230:e72c9dad62ac

Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
author Sebastien Decugis <sdecugis@freediameter.net>
date Sun, 21 Jul 2013 11:57:39 +0200
parents 4e52f009861a
children d9c48b0e8d97
files include/freeDiameter/libfdproto.h libfdcore/messages.c libfdcore/p_ce.c libfdcore/routing_dispatch.c libfdproto/messages.c
diffstat 5 files changed, 23 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/include/freeDiameter/libfdproto.h	Thu Jul 18 16:08:54 2013 +0200
+++ b/include/freeDiameter/libfdproto.h	Sun Jul 21 11:57:39 2013 +0200
@@ -2698,6 +2698,7 @@
 struct fd_pei {
 	char *		pei_errcode;	/* name of the error code to use */
 	struct avp *	pei_avp;	/* pointer to invalid (in original message) or missing AVP (to be freed) */
+	int		pei_avp_free;	/* Set to 1 if the pei_avp must be freed */
 	char *		pei_message;	/* Overwrite default message if needed */
 	int		pei_protoerr; 	/* do we set the 'E' bit in the error message ? */
 };
--- a/libfdcore/messages.c	Thu Jul 18 16:08:54 2013 +0200
+++ b/libfdcore/messages.c	Sun Jul 21 11:57:39 2013 +0200
@@ -388,6 +388,11 @@
 		/* Set the error code */
 		CHECK_FCT( fd_msg_rescode_set(m, pei.pei_errcode, pei.pei_message, pei.pei_avp, 1 ) );
 		
+		/* free the pei AVP to avoid memory leak */
+		if (pei.pei_avp_free) {
+			fd_msg_free(pei.pei_avp);
+		}
+		
 		*msg = NULL;
 		*error = m;
 		
--- a/libfdcore/p_ce.c	Thu Jul 18 16:08:54 2013 +0200
+++ b/libfdcore/p_ce.c	Sun Jul 21 11:57:39 2013 +0200
@@ -636,6 +636,10 @@
 	CHECK_FCT_DO( fd_msg_rescode_set(*cer, error->pei_errcode, error->pei_message, error->pei_avp, 1 ), goto destroy );
 	CHECK_FCT_DO( fd_out_send(cer, *recv_cnx, NULL), goto destroy );
 	
+	if (error->pei_avp_free) {
+		fd_msg_free(error->pei_avp);
+	}
+	
 	/* And now destroy this connection */
 destroy:
 	fd_cnx_destroy(*recv_cnx);
--- a/libfdcore/routing_dispatch.c	Thu Jul 18 16:08:54 2013 +0200
+++ b/libfdcore/routing_dispatch.c	Sun Jul 21 11:57:39 2013 +0200
@@ -609,6 +609,7 @@
 								if (error_info.pei_errcode) {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Destination-Host AVP", fd_msg_pmdl_get(msgptr));
@@ -631,6 +632,7 @@
 								if (error_info.pei_errcode) {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Destination-Realm AVP", fd_msg_pmdl_get(msgptr));
@@ -655,6 +657,7 @@
 								if (error_info.pei_errcode) {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing User-Name AVP", fd_msg_pmdl_get(msgptr));
@@ -673,6 +676,7 @@
 								if (error_info.pei_errcode) {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, "Unspecified error while parsing Route-Record AVP", fd_msg_pmdl_get(msgptr));
@@ -931,6 +935,7 @@
 					{
 						if (error_info.pei_errcode) {
 							CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+							if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 							return 0;
 						} else {
 							return ret;
--- a/libfdproto/messages.c	Thu Jul 18 16:08:54 2013 +0200
+++ b/libfdproto/messages.c	Sun Jul 21 11:57:39 2013 +0200
@@ -2370,12 +2370,16 @@
 	/* Type of the AVP */
 	CHECK_FCT_DO( fd_dict_getval(model_avp, &avp_info), return NULL );
 	
+	/* Set an initial size */
+	avp->avp_public.avp_len = GETAVPHDRSZ( avp->avp_public.avp_flags ) + avp_value_sizes[avp_info.avp_basetype];
+	
 	/* Prepare the empty value */
 	memset(&val, 0, sizeof(val));
 	switch (avp_info.avp_basetype) {
 		case AVP_TYPE_OCTETSTRING:
 			val.os.data = os;
 			val.os.len  = sizeof(os);
+			avp->avp_public.avp_len += val.os.len;
 		case AVP_TYPE_INTEGER32:
 		case AVP_TYPE_INTEGER64:
 		case AVP_TYPE_UNSIGNED32:
@@ -2439,6 +2443,7 @@
 		if (pr_data->pei) {
 			pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP";
 			pr_data->pei->pei_avp = empty_avp(rule->rule_avp);
+			pr_data->pei->pei_avp_free = 1;
 		}
 		return EBADMSG;
 	}
@@ -2452,6 +2457,7 @@
 			else
 				pr_data->pei->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES";
 			pr_data->pei->pei_avp = empty_avp(rule->rule_avp); /* Well we are supposed to return the (max + 1)th instance of the AVP instead... Pfff... */ TODO("Improve...");
+			pr_data->pei->pei_avp_free = 1;
 		}
 		return EBADMSG;
 	}
@@ -2471,6 +2477,7 @@
 					pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP";
 					pr_data->pei->pei_message = "AVP was not in its fixed position";
 					pr_data->pei->pei_avp = empty_avp(rule->rule_avp);
+					pr_data->pei->pei_avp_free = 1;
 				}
 				return EBADMSG;
 			}
@@ -2484,6 +2491,7 @@
 					pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP";
 					pr_data->pei->pei_message = "AVP was not in its fixed position";
 					pr_data->pei->pei_avp = empty_avp(rule->rule_avp);
+					pr_data->pei->pei_avp_free = 1;
 				}
 				return EBADMSG;
 			}
"Welcome to our mercurial repository"