diff libfdcore/config.c @ 706:4ffbc9f1e922

Large UNTESTED commit with the following changes: * Improved DiameterIdentity handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7) * Cleanup in the session module to free only unreferenced sessions (#16) * Removed fd_cpu_flush_cache(), replaced by more robust alternatives. * Improved peer state machine algorithm to counter SCTP multistream race condition.
author Sebastien Decugis <sdecugis@nict.go.jp>
date Wed, 09 Feb 2011 15:26:58 +0900
parents f83d9878bf66
children 4a9f08d6b6ba
line wrap: on
line diff
--- a/libfdcore/config.c	Mon Jan 31 17:22:21 2011 +0900
+++ b/libfdcore/config.c	Wed Feb 09 15:26:58 2011 +0900
@@ -145,6 +145,7 @@
 int fd_conf_parse()
 {
 	extern FILE * fddin;
+	char * orig = NULL;
 	
 	/* Attempt to find the configuration file */
 	if (!fd_g_config->cnf_file)
@@ -153,14 +154,22 @@
 	fddin = fopen(fd_g_config->cnf_file, "r");
 	if ((fddin == NULL) && (*fd_g_config->cnf_file != '/')) {
 		/* We got a relative path, attempt to add the default directory prefix */
-		char * bkp = fd_g_config->cnf_file;
-		CHECK_MALLOC( fd_g_config->cnf_file = malloc(strlen(bkp) + strlen(DEFAULT_CONF_PATH) + 2) ); /* we will not free it, but not important */
-		sprintf( fd_g_config->cnf_file, DEFAULT_CONF_PATH "/%s", bkp );
+		orig = fd_g_config->cnf_file;
+		CHECK_MALLOC( fd_g_config->cnf_file = malloc(strlen(orig) + strlen(DEFAULT_CONF_PATH) + 2) ); /* we will not free it, but not important */
+		sprintf( fd_g_config->cnf_file, DEFAULT_CONF_PATH "/%s", orig );
 		fddin = fopen(fd_g_config->cnf_file, "r");
 	}
 	if (fddin == NULL) {
 		int ret = errno;
-		fprintf(stderr, "Unable to open configuration file %s for reading: %s\n", fd_g_config->cnf_file, strerror(ret));
+		if (orig) {
+			fprintf(stderr, "Unable to open configuration file for reading\n"
+					"Tried the following locations:\n"
+					" - %s\n"
+					" - %s\n"
+					"Error: %s\n", orig, fd_g_config->cnf_file, strerror(ret));
+		} else {
+			fprintf(stderr, "Unable to open '%s' for reading: %s\n", fd_g_config->cnf_file, strerror(ret));
+		}
 		return ret;
 	}
 	
@@ -177,11 +186,22 @@
 		return EINVAL;
 	}
 	
+	/* If the CA is not provided, let's use the same file (assuming self-signed certificate) */
+	if (! fd_g_config->cnf_sec_data.ca_file) {
+		CHECK_MALLOC( fd_g_config->cnf_sec_data.ca_file = strdup(fd_g_config->cnf_sec_data.cert_file) );
+		CHECK_GNUTLS_DO( fd_g_config->cnf_sec_data.ca_file_nr += gnutls_certificate_set_x509_trust_file( 
+					fd_g_config->cnf_sec_data.credentials,
+					fd_g_config->cnf_sec_data.ca_file,
+					GNUTLS_X509_FMT_PEM),
+				{ 
+					TRACE_DEBUG(INFO, "Unable to use the local certificate as trusted security anchor (CA), please provide a valid TLS_CA='...' directive.");
+					return EINVAL;
+				} );
+	}
+	
+	
 	/* Resolve hostname if not provided */
 	if (fd_g_config->cnf_diamid == NULL) {
-#ifndef HOST_NAME_MAX
-#define HOST_NAME_MAX 1024
-#endif /* HOST_NAME_MAX */
 		char buf[HOST_NAME_MAX + 1];
 		struct addrinfo hints, *info;
 		int ret;
@@ -201,13 +221,13 @@
 					buf, gai_strerror(ret));
 			return EINVAL;
 		}
-		CHECK_MALLOC( fd_g_config->cnf_diamid = strdup(info->ai_canonname) );
+		fd_g_config->cnf_diamid = info->ai_canonname;
+		CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamid, &fd_g_config->cnf_diamid_len, 1) );
 		freeaddrinfo(info);
+	} else {
+		CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamid, &fd_g_config->cnf_diamid_len, 0) );
 	}
 	
-	/* cache the length of the diameter id for the session module */
-	fd_g_config->cnf_diamid_len = strlen(fd_g_config->cnf_diamid);
-	
 	/* Handle the realm part */
 	if (fd_g_config->cnf_diamrlm == NULL) {
 		char * start = NULL;
@@ -219,11 +239,13 @@
 					"Please fix your Identity setting or provide Realm.\n",
 					fd_g_config->cnf_diamid);
 			return EINVAL;
-		}		
+		}
 		
-		CHECK_MALLOC( fd_g_config->cnf_diamrlm = strdup( start + 1 )  ); 
+		fd_g_config->cnf_diamrlm = start + 1;
+		CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamrlm, &fd_g_config->cnf_diamrlm_len, 1) );
+	} else {
+		CHECK_FCT( fd_os_validate_DiameterIdentity(&fd_g_config->cnf_diamrlm, &fd_g_config->cnf_diamrlm_len, 0) );
 	}
-	fd_g_config->cnf_diamrlm_len = strlen(fd_g_config->cnf_diamrlm);
 	
 	/* Validate some flags */
 	if (fd_g_config->cnf_flags.no_ip4 && fd_g_config->cnf_flags.no_ip6) {
"Welcome to our mercurial repository"