changeset 1002:7ca81c10ba06

Merged
author Sebastien Decugis <sdecugis@freediameter.net>
date Thu, 21 Mar 2013 15:07:23 +0100
parents 632913581c37 (current diff) d03f7e3805ad (diff)
children e0a716b7647a
files
diffstat 5 files changed, 57 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/include/freeDiameter/libfdproto.h	Tue Mar 19 16:15:38 2013 +0100
+++ b/include/freeDiameter/libfdproto.h	Thu Mar 21 15:07:23 2013 +0100
@@ -311,7 +311,7 @@
 int fd_breakhere(void);
 
 /* Helper for tracing the CHECK_* macros below -- very very verbose code execution! */
-#define TRACE_DEBUG_ALL( str ) 	\
+#define TRACE_DEBUG_ALL( str... ) 	\
 	TRACE_DEBUG(CALL, str );
 
 /* For development only, to keep track of TODO locations in the code */
@@ -478,22 +478,22 @@
 /* Check the return value of a system function and execute fallback in case of error */
 #define CHECK_SYS_DO( __call__, __fallback__  ) { 					\
 	int __ret__;									\
-	TRACE_DEBUG_ALL( "Check SYS: " #__call__ );					\
+	TRACE_DEBUG_ALL( "Check SYS: %s", #__call__ );					\
 	__ret__ = (__call__);								\
 	if (__ret__ < 0) {								\
 		int __err__ = errno;	/* We may handle EINTR here */			\
-		TRACE_ERROR("ERROR: in '" #__call__ "' :\t%s", strerror(__err__));\
+		TRACE_ERROR("ERROR: in '%s' :\t%s",  #__call__ , strerror(__err__));    \
 		__fallback__;								\
 	}										\
 }
 /* Check the return value of a system function, return error code on error */
 #define CHECK_SYS( __call__  ) { 							\
 	int __ret__;									\
-	TRACE_DEBUG_ALL( "Check SYS: " #__call__ );					\
+	TRACE_DEBUG_ALL( "Check SYS: %s", #__call__ );					\
 	__ret__ = (__call__);								\
 	if (__ret__ < 0) {								\
 		int __err__ = errno;	/* We may handle EINTR here */			\
-		TRACE_ERROR("ERROR: in '" #__call__ "' :\t%s", strerror(__err__));\
+		TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__err__));     \
 		return __err__;								\
 	}										\
 }
@@ -501,13 +501,13 @@
 /* Check the return value of a POSIX function and execute fallback in case of error or special value */
 #define CHECK_POSIX_DO2( __call__, __speval__, __fallback1__, __fallback2__ ) {			\
 	int __ret__;										\
-	TRACE_DEBUG_ALL( "Check POSIX: " #__call__ );						\
+	TRACE_DEBUG_ALL( "Check POSIX: %s", #__call__ );					\
 	__ret__ = (__call__);									\
 	if (__ret__ != 0) {									\
 		if (__ret__ == (__speval__)) {							\
 			__fallback1__;								\
 		} else {									\
-			TRACE_ERROR("ERROR: in '" #__call__ "':\t%s", strerror(__ret__));	\
+			TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__ret__));	\
 			__fallback2__;								\
 		}										\
 	}											\
@@ -526,11 +526,11 @@
 /* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */
 #define CHECK_MALLOC_DO( __call__, __fallback__ ) { 					\
 	void *  __ret__;								\
-	TRACE_DEBUG_ALL( "Check MALLOC: " #__call__ );					\
+	TRACE_DEBUG_ALL( "Check MALLOC: %s", #__call__ );				\
 	__ret__ = (void *)( __call__ );							\
 	if (__ret__ == NULL) {								\
 		int __err__ = errno;							\
-		TRACE_ERROR("ERROR: in '" #__call__ "':\t%s", strerror(__err__));	\
+		TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__err__));	\
 		__fallback__;								\
 	}										\
 }
@@ -542,9 +542,9 @@
 
 /* Check parameters at function entry, execute fallback on error */
 #define CHECK_PARAMS_DO( __bool__, __fallback__ )						\
-	TRACE_DEBUG_ALL( "Check PARAMS: " #__bool__ );						\
+	TRACE_DEBUG_ALL( "Check PARAMS: %s", #__bool__ );					\
 	if ( ! (__bool__) ) {									\
-		TRACE_ERROR("Warning: Invalid parameter received in '" #__bool__ "'");	\
+		TRACE_ERROR("Warning: Invalid parameter received in '%s'", #__bool__);		\
 		__fallback__;									\
 	}
 /* Check parameters at function entry, return EINVAL if the boolean is false (similar to assert) */
@@ -554,10 +554,10 @@
 /* Check the return value of an internal function, log and propagate */
 #define CHECK_FCT_DO( __call__, __fallback__ ) {					\
 	int __ret__;									\
-	TRACE_DEBUG_ALL( "Check FCT: " #__call__ );					\
+	TRACE_DEBUG_ALL( "Check FCT: %s", #__call__ );					\
 	__ret__ = (__call__);								\
 	if (__ret__ != 0) {								\
-		TRACE_ERROR("ERROR: in '" #__call__ "':\t%s", strerror(__ret__));	\
+		TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__ret__));	\
 		__fallback__;								\
 	}										\
 }
--- a/libfdcore/cnxctx.c	Tue Mar 19 16:15:38 2013 +0100
+++ b/libfdcore/cnxctx.c	Thu Mar 21 15:07:23 2013 +0100
@@ -1207,7 +1207,7 @@
 				char buf[1024];
 				snprintf(buf, sizeof(buf), "\t - Certificate serial number: ");
 				for (j = 0; j < size; j++) {
-					snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02.2hhx", serial[j]);
+					snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02hhx", serial[j]);
 				}
 				fd_log_debug(buf);
 			}
--- a/libfdproto/lists.c	Tue Mar 19 16:15:38 2013 +0100
+++ b/libfdproto/lists.c	Thu Mar 21 15:07:23 2013 +0100
@@ -74,12 +74,16 @@
 /* Move all elements of list senti at the end of list ref */
 void fd_list_move_end(struct fd_list * ref, struct fd_list * senti)
 {
+	struct fd_list * li;
 	ASSERT(ref->head == ref);
 	ASSERT(senti->head == senti);
 	
 	if (senti->next == senti)
 		return;
 	
+	for (li = senti->next; li != senti; li = li->next)
+		li->head = ref;
+	
 	senti->next->prev = ref->prev;
 	ref->prev->next   = senti->next;
 	senti->prev->next = ref;
--- a/libfdproto/messages.c	Tue Mar 19 16:15:38 2013 +0100
+++ b/libfdproto/messages.c	Thu Mar 21 15:07:23 2013 +0100
@@ -302,6 +302,8 @@
 
 static int bufferize_avp(unsigned char * buffer, size_t buflen, size_t * offset,  struct avp * avp);
 static int parsebuf_list(unsigned char * buf, size_t buflen, struct fd_list * head);
+static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info);
+
 
 /* Create answer from a request */
 int fd_msg_new_answer_from_req ( struct dictionary * dict, struct msg ** msg, int flags )
@@ -365,6 +367,9 @@
 	/* Add all Proxy-Info AVPs from the query if any */
 	if (! (flags & MSGFL_ANSW_NOPROXYINFO)) {
 		struct avp * avp;
+		struct fd_pei pei;
+		struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist);
+		
 		CHECK_FCT(  fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL)  );
 		while (avp) {
 			if ( (avp->avp_public.avp_code   == AC_PROXY_INFO)
@@ -375,20 +380,26 @@
 				unsigned char * buf = NULL;
 				size_t offset = 0;
 
+				/* Create a buffer with the content of the AVP. This is easier than going through the list */
 				CHECK_FCT(  fd_msg_update_length(avp)  );
 				CHECK_MALLOC(  buf = malloc(avp->avp_public.avp_len)  );
 				CHECK_FCT( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp)  );
 
-				/* Now we directly parse this buffer into the new message list */
-				CHECK_FCT( parsebuf_list(buf, avp->avp_public.avp_len, &ans->msg_chain.children) );
+				/* Now we parse this buffer to create a copy AVP */
+				CHECK_FCT( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist) );
+				
+				/* Parse dictionary objects now to remove the dependency on the buffer */
+				CHECK_FCT( parsedict_do_chain(dict, &avpcpylist, 0, &pei) );
 
 				/* Done for this AVP */
 				free(buf);
+
+				/* We move this AVP now so that we do not parse again in next loop */
+				fd_list_move_end(&ans->msg_chain.children, &avpcpylist);
 			}
 			/* move to next AVP in the message, we can have several Proxy-Info instances */
 			CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
 		}
-		CHECK_FCT( fd_msg_parse_dict( ans, dict, NULL ) );
 	}
 
 	/* associate with query */
@@ -1557,15 +1568,15 @@
 		/* In the case where we don't know the type of AVP, just copy the raw data or source */
 		CHECK_PARAMS( avp->avp_source || avp->avp_rawdata );
 		
-		if ( avp->avp_source != NULL ) {
+		if ( avp->avp_rawdata != NULL ) {
+			/* the content was stored in rawdata */
+			memcpy(&buffer[*offset], avp->avp_rawdata, avp->avp_rawlen);
+			*offset += PAD4(avp->avp_rawlen);
+		} else {
 			/* the message was not parsed completely */
 			size_t datalen = avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags);
 			memcpy(&buffer[*offset], avp->avp_source, datalen);
 			*offset += PAD4(datalen);
-		} else {
-			/* the content was stored in rawdata */
-			memcpy(&buffer[*offset], avp->avp_rawdata, avp->avp_rawlen);
-			*offset += PAD4(avp->avp_rawlen);
 		}
 		
 	} else {
@@ -1812,14 +1823,13 @@
  * For command, if the dictionary model is not found, an error is returned.
  */
 
-static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info);
-
 static char error_message[256];
 
 /* Process an AVP. If we are not in recheck, the avp_source must be set. */
 static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mandatory, struct fd_pei *error_info)
 {
 	struct dict_avp_data dictdata;
+	uint8_t * source;
 	
 	TRACE_ENTRY("%p %p %d %p", dict, avp, mandatory, error_info);
 	
@@ -1912,13 +1922,16 @@
 		return EBADMSG;
 	}
 	
+	source = avp->avp_source;
+	avp->avp_source = NULL;
+
 	/* Now get the value inside */
 	switch (dictdata.avp_basetype) {
 		case AVP_TYPE_GROUPED: {
 			int ret;
 			
 			/* This is a grouped AVP, so let's parse the list of AVPs inside */
-			CHECK_FCT_DO(  ret = parsebuf_list(avp->avp_source, avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ), &avp->avp_chain.children),
+			CHECK_FCT_DO(  ret = parsebuf_list(source, avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ), &avp->avp_chain.children),
 				{
 					if ((ret == EBADMSG) && (error_info)) {
 						error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE";
@@ -1926,6 +1939,7 @@
 						snprintf(error_message, sizeof(error_message), "I cannot parse this AVP as a Grouped AVP");
 						error_info->pei_message = error_message;
 					}
+					avp->avp_source = source;
 					return ret;
 				}  );
 			
@@ -1940,36 +1954,37 @@
 						error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH";
 						error_info->pei_avp = avp;
 					}
+					avp->avp_source = source;
 					return EBADMSG;
 				} );
 			avp->avp_storage.os.len = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags );
-			CHECK_MALLOC(  avp->avp_storage.os.data = os0dup(avp->avp_source, avp->avp_storage.os.len)  );
+			CHECK_MALLOC(  avp->avp_storage.os.data = os0dup(source, avp->avp_storage.os.len)  );
 			avp->avp_mustfreeos = 1;
 			break;
 		
 		case AVP_TYPE_INTEGER32:
-			avp->avp_storage.i32 = (int32_t)ntohl(*(uint32_t *)avp->avp_source);
+			avp->avp_storage.i32 = (int32_t)ntohl(*(uint32_t *)source);
 			break;
 	
 		case AVP_TYPE_INTEGER64:
 			/* the storage might not be aligned on 64b boundary, so no direct indirection here is possible */
 			{
 				uint64_t __stor;
-				memcpy(&__stor, avp->avp_source, sizeof(__stor));
+				memcpy(&__stor, source, sizeof(__stor));
 				avp->avp_storage.i64 = (int64_t)ntohll(__stor);
 			}
 			break;
 	
 		case AVP_TYPE_UNSIGNED32:
 		case AVP_TYPE_FLOAT32: /* For float, we must not cast, or the value is changed. Instead we use implicit cast by changing the member of the union */
-			avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)avp->avp_source);
+			avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)source);
 			break;
 	
 		case AVP_TYPE_UNSIGNED64:
 		case AVP_TYPE_FLOAT64: /* same as 32 bits */
 			{
 				uint64_t __stor;
-				memcpy(&__stor, avp->avp_source, sizeof(__stor));
+				memcpy(&__stor, source, sizeof(__stor));
 				avp->avp_storage.u64 = (uint64_t)ntohll(__stor);
 			}
 			break;
--- a/tests/tests.h	Tue Mar 19 16:15:38 2013 +0100
+++ b/tests/tests.h	Thu Mar 21 15:07:23 2013 +0100
@@ -68,13 +68,13 @@
 /* Define the macro to fail a test with a message */
 #define FAILTEST( message... ){				\
 	TRACE_ERROR(message);				\
-	TRACE_NOTICE("Test %s failed", __FILE__);	\
+	TRACE_ERROR("FAILED: %s ", __STRIPPED_FILE__);	\
 	exit(FAIL);					\
 }
 
 /* Define the macro to pass a test */
 #define PASSTEST( ){					\
-	TRACE_NOTICE("Test %s passed", __FILE__);	\
+	TRACE_NOTICE("PASS: %s", __STRIPPED_FILE__);	\
 	(void)fd_core_shutdown();			\
 	(void)fd_core_wait_shutdown_complete();		\
 	(void)fd_thr_term(&signal_thr);			\
@@ -88,16 +88,14 @@
 /* Define the standard check routines */
 #define CHECK( _val, _assert ){				\
 	if (test_verbo > 0) {				\
-		TRACE_DEBUG(INFO,			\
-			"%s:%-4d: CHECK( " #_assert " == "\
-				#_val " )",		\
-			__FILE__, 			\
-			__LINE__);			\
+		TRACE_NOTICE("CHECK( %s == %s )",	\
+				#_assert,		\
+				#_val);			\
 	}{						\
 	__typeof__ (_val) __ret = (_assert);		\
 	if (__ret != (_val)) {				\
 		FAILTEST( "%s:%d: CHECK FAILED : %s == %lx != %lx",	\
-			__FILE__,			\
+			__STRIPPED_FILE__,		\
 			__LINE__,			\
 			#_assert,			\
 			(unsigned long)__ret,		\
@@ -198,7 +196,7 @@
 	
 	CHECK( 0, fd_libproto_init() );
 	
-	fd_log_threadname(basename(fname));
+	fd_log_threadname(fname);
 	
 	/* Parse the command line */
 	parse_cmdline(argc, argv);
@@ -228,6 +226,6 @@
 	
 	return;
 }
-#define INIT_FD()  test_init(argc, argv, __FILE__);
+#define INIT_FD()  test_init(argc, argv, __STRIPPED_FILE__)
 
 #endif /* _TESTS_H */
"Welcome to our mercurial repository"