Index: include/freeDiameter/libfdproto.h
===================================================================
--- include/freeDiameter/libfdproto.h	(revision 899)
+++ include/freeDiameter/libfdproto.h	(revision 903)
@@ -1331,10 +1331,28 @@
 	AVP_BY_CODE = 50,	/* "what" points to an avp_code_t, vendor is always 0 */
 	AVP_BY_NAME,		/* "what" points to a char *, vendor is always 0 */
+	AVP_BY_NAME_ALL_VENDORS,/* "what" points to a string. Might be quite slow... */
+	AVP_BY_STRUCT,		/* "what" points to a struct dict_avp_request_ex (see bellow) */
+			
+	/* kept for backward compatibility, better use AVP_BY_STRUCT above instead */
 	AVP_BY_CODE_AND_VENDOR,	/* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_code are set */
-	AVP_BY_NAME_AND_VENDOR,	/* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_name are set */
-	AVP_BY_NAME_ALL_VENDORS /* "what" points to a string. Might be quite slow... */
+	AVP_BY_NAME_AND_VENDOR	/* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_name are set */
 };
 
 /* Struct used for some researchs */
+struct dict_avp_request_ex {
+	struct {
+		/* Only one of the following fields must be set. */
+		struct dict_object * 	vendor;		/* most efficient if already known, set to NULL to ignore */
+		vendor_id_t	 	vendor_id; 	/* set to 0 to ignore -- prefer AVP_BY_CODE or AVP_BY_NAME for vendor 0 */
+		char *			vendor_name;	/* set to NULL to ignore */
+	} avp_vendor;
+	
+	struct {
+		/* Only one of the following fields must be set */
+		avp_code_t	 avp_code; /* set to 0 to ignore */
+		char *		 avp_name; /* set to NULL to ignore */
+	} avp_data;
+};
+
 struct dict_avp_request {
 	vendor_id_t	 avp_vendor;
@@ -1342,4 +1360,5 @@
 	char *		 avp_name;
 };
+
 
 
Index: libfdproto/dictionary.c
===================================================================
--- libfdproto/dictionary.c	(revision 834)
+++ libfdproto/dictionary.c	(revision 903)
@@ -977,4 +977,41 @@
 			break;
 		
+		case AVP_BY_STRUCT:
+			{
+				struct dict_avp_request_ex * _what = (struct dict_avp_request_ex *) what;
+				struct dict_object * vendor = NULL;
+				
+				CHECK_PARAMS( _what->avp_vendor.vendor || _what->avp_vendor.vendor_id || _what->avp_vendor.vendor_name );
+				CHECK_PARAMS( _what->avp_data.avp_code || _what->avp_data.avp_name );
+				
+				/* Now look for the vendor first */
+				if (_what->avp_vendor.vendor) {
+					CHECK_PARAMS( ! _what->avp_vendor.vendor_id && ! _what->avp_vendor.vendor_name );
+					vendor = _what->avp_vendor.vendor;
+				} else if (_what->avp_vendor.vendor_id) {
+					CHECK_PARAMS( ! _what->avp_vendor.vendor_name );
+					CHECK_FCT( search_vendor( dict, VENDOR_BY_ID, &_what->avp_vendor.vendor_id, &vendor ) );
+				} else {
+					CHECK_FCT( search_vendor( dict, VENDOR_BY_NAME, &_what->avp_vendor.vendor_name, &vendor ) );
+				}
+				
+				if (vendor == NULL) {
+					if (result)
+						*result = NULL;
+					else
+						ret = ENOENT;
+					goto end;
+				}
+				
+				/* We now have our vendor = head of the appropriate avp list */
+				if (_what->avp_data.avp_code) {
+					CHECK_PARAMS( ! _what->avp_data.avp_name );
+					SEARCH_scalar( _what->avp_data.avp_code, &vendor->list[1], avp.avp_code, 1, (struct dict_object *)NULL );
+				} else {
+					SEARCH_os0( _what->avp_data.avp_name, &vendor->list[2], avp.avp_name, 1);
+				}
+			}
+			break;
+		
 		case AVP_BY_NAME_ALL_VENDORS:
 			{
Index: libfdproto/messages.c
===================================================================
--- libfdproto/messages.c	(revision 895)
+++ libfdproto/messages.c	(revision 903)
@@ -1791,8 +1791,9 @@
 	/* Now try and resolve the model from the avp code and vendor */
 	if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
-		struct dict_avp_request avpreq;
-		avpreq.avp_vendor = avp->avp_public.avp_vendor;
-		avpreq.avp_code = avp->avp_public.avp_code;
-		CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE_AND_VENDOR, &avpreq, &avp->avp_model, 0));
+		struct dict_avp_request_ex avpreq;
+		memset(&avpreq, 0, sizeof(avpreq));
+		avpreq.avp_vendor.vendor_id = avp->avp_public.avp_vendor;
+		avpreq.avp_data.avp_code = avp->avp_public.avp_code;
+		CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_STRUCT, &avpreq, &avp->avp_model, 0));
 	} else {
 		/* no vendor */
