changeset 935:6072619402a3

New CMake option WORKAROUND_ACCEPT_INVALID_VSAI for those invalids Vendor-Specific-Application-Id out there
author Sebastien Decugis <sdecugis@freediameter.net>
date Sat, 09 Mar 2013 15:43:33 +0100
parents 977a5375543c
children 8ee9f8183ab8
files include/freeDiameter/CMakeLists.txt include/freeDiameter/freeDiameter-host.h.in libfdcore/p_ce.c
diffstat 3 files changed, 39 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/include/freeDiameter/CMakeLists.txt	Thu Mar 07 16:13:50 2013 +0100
+++ b/include/freeDiameter/CMakeLists.txt	Sat Mar 09 15:43:33 2013 +0100
@@ -28,8 +28,12 @@
 # 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)
+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)
 
 ########################
 ### System checks part
--- a/include/freeDiameter/freeDiameter-host.h.in	Thu Mar 07 16:13:50 2013 +0100
+++ b/include/freeDiameter/freeDiameter-host.h.in	Sat Mar 09 15:43:33 2013 +0100
@@ -59,6 +59,7 @@
 #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
 #cmakedefine GNUTLS_VERSION_310
--- a/libfdcore/p_ce.c	Thu Mar 07 16:13:50 2013 +0100
+++ b/libfdcore/p_ce.c	Sat Mar 09 15:43:33 2013 +0100
@@ -454,10 +454,10 @@
 			case AC_VENDOR_SPECIFIC_APPLICATION_ID: /* Vendor-Specific-Application-Id (grouped)*/
 				{
 					struct avp * inavp = NULL;
-					application_id_t aid = 0;
 					vendor_id_t vid = 0;
-					int auth = 0;
-					int acct = 0;
+					application_id_t auth_aid = 0;
+					application_id_t acct_aid = 0;
+					int invalid=0;
 
 					/* get the first child AVP */
 					CHECK_FCT(  fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &inavp, NULL)  );
@@ -481,33 +481,50 @@
 						}
 						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 */
-								aid = inhdr->avp_value->u32;
-								auth += 1;
+								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;
 								break;
 							case AC_ACCT_APPLICATION_ID: /* Acct-Application-Id */
-								aid = inhdr->avp_value->u32;
-								acct += 1;
+								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;
 								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;
+						}
 
 					innext:			
 						/* Go to next in AVP */
 						CHECK_FCT( fd_msg_browse(inavp, MSG_BRW_NEXT, &inavp, NULL) );
 					}
 					
-					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) );
+					/* 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) );
 					}
 				}
 				break;
"Welcome to our mercurial repository"