diff freeDiameter/cnxctx.c @ 29:5ba91682f0bc

Added a test for cnxctx (tbc) and fixed some bugs
author Sebastien Decugis <sdecugis@nict.go.jp>
date Wed, 28 Oct 2009 15:19:50 +0900
parents b3a1773e9f46
children bca243c65b56
line wrap: on
line diff
--- a/freeDiameter/cnxctx.c	Mon Oct 26 18:07:24 2009 +0900
+++ b/freeDiameter/cnxctx.c	Wed Oct 28 15:19:50 2009 +0900
@@ -396,6 +396,20 @@
 	return conn->cc_id;
 }
 
+/* Return the protocol of a connection */
+int fd_cnx_getproto(struct cnxctx * conn)
+{
+	CHECK_PARAMS_DO( conn, return 0 );
+	return conn->cc_proto;
+}
+
+/* Return the TLS state of a connection */
+int fd_cnx_getTLS(struct cnxctx * conn)
+{
+	CHECK_PARAMS_DO( conn, return 0 );
+	return conn->cc_tls;
+}
+
 /* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */
 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote)
 {
@@ -473,8 +487,15 @@
 	struct cnxctx * conn = arg;
 	
 	TRACE_ENTRY("%p", arg);
+	CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out);
 	
-	CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out);
+	/* Set the thread name */
+	{
+		char buf[48];
+		snprintf(buf, sizeof(buf), "Receiver (%d) TCP/noTLS)", conn->cc_socket);
+		fd_log_threadname ( buf );
+	}
+	
 	ASSERT( conn->cc_proto == IPPROTO_TCP );
 	ASSERT( conn->cc_tls == 0 );
 	ASSERT( Target_Queue(conn) );
@@ -547,8 +568,15 @@
 	int	  event;
 	
 	TRACE_ENTRY("%p", arg);
+	CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out);
 	
-	CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out);
+	/* Set the thread name */
+	{
+		char buf[48];
+		snprintf(buf, sizeof(buf), "Receiver (%d) SCTP/noTLS)", conn->cc_socket);
+		fd_log_threadname ( buf );
+	}
+	
 	ASSERT( conn->cc_proto == IPPROTO_SCTP );
 	ASSERT( conn->cc_tls == 0 );
 	ASSERT( Target_Queue(conn) );
@@ -606,7 +634,7 @@
 /* The function that receives TLS data and re-builds a Diameter message -- it exits only on error or cancelation */
 int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session)
 {
-	/* No guaranty that GnuTLS preserves the message boundaries, so we re-build it as in TCP */
+	/* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP */
 	do {
 		uint8_t header[4];
 		uint8_t * newmsg;
@@ -615,7 +643,7 @@
 		size_t	received = 0;
 
 		do {
-			ret = fd_tls_recv_handle_error(conn, conn->cc_tls_para.session, &header[received], sizeof(header) - received);
+			ret = fd_tls_recv_handle_error(conn, session, &header[received], sizeof(header) - received);
 			if (ret == 0) {
 				/* The connection is closed */
 				goto out;
@@ -639,7 +667,7 @@
 
 		while (received < length) {
 			pthread_cleanup_push(free, newmsg); /* In case we are canceled, clean the partialy built buffer */
-			ret = fd_tls_recv_handle_error(conn, conn->cc_tls_para.session, newmsg + received, length - received);
+			ret = fd_tls_recv_handle_error(conn, session, newmsg + received, length - received);
 			pthread_cleanup_pop(0);
 
 			if (ret == 0) {
@@ -663,8 +691,15 @@
 	struct cnxctx * conn = arg;
 	
 	TRACE_ENTRY("%p", arg);
+	CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto error);
 	
-	CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto error);
+	/* Set the thread name */
+	{
+		char buf[48];
+		snprintf(buf, sizeof(buf), "Receiver (%d) TLS/ single stream)", conn->cc_socket);
+		fd_log_threadname ( buf );
+	}
+	
 	ASSERT( conn->cc_tls == 1 );
 	ASSERT( Target_Queue(conn) );
 	
@@ -708,7 +743,7 @@
 }
 
 /* Prepare a gnutls session object for handshake */
-int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority)
+int fd_tls_prepare(gnutls_session_t * session, int mode, char * priority, void * alt_creds)
 {
 	/* Create the master session context */
 	CHECK_GNUTLS_DO( gnutls_init (session, mode), return ENOMEM );
@@ -723,7 +758,7 @@
 	}
 
 	/* Set the credentials of this side of the connection */
-	CHECK_GNUTLS_DO( gnutls_credentials_set (*session, GNUTLS_CRD_CERTIFICATE, fd_g_config->cnf_sec_data.credentials), return EINVAL );
+	CHECK_GNUTLS_DO( gnutls_credentials_set (*session, GNUTLS_CRD_CERTIFICATE, alt_creds ?: fd_g_config->cnf_sec_data.credentials), return EINVAL );
 
 	/* Request the remote credentials as well */
 	if (mode == GNUTLS_SERVER) {
@@ -734,7 +769,7 @@
 }
 
 /* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */
-int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority)
+int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt_creds)
 {
 	TRACE_ENTRY( "%p %d", conn, mode);
 	CHECK_PARAMS( conn && (!conn->cc_tls) && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) && (!conn->cc_loop) );
@@ -749,7 +784,7 @@
 	conn->cc_loop = 1;
 	
 	/* Prepare the master session credentials and priority */
-	CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, priority) );
+	CHECK_FCT( fd_tls_prepare(&conn->cc_tls_para.session, mode, priority, alt_creds) );
 
 	/* Special case: multi-stream TLS is not natively managed in GNU TLS, we use a wrapper library */
 	if (conn->cc_sctp_para.pairs > 1) {
@@ -800,16 +835,22 @@
 	if (conn->cc_sctp_para.pairs > 1) {
 #ifndef DISABLE_SCTP
 		/* Resume all additional sessions from the master one. */
-		CHECK_FCT(fd_sctps_handshake_others(conn, priority));
+		CHECK_FCT(fd_sctps_handshake_others(conn, priority, alt_creds));
 		
+		/* Mark the connection as protected from here */
+		conn->cc_tls = 1;
+
 		/* Start decrypting the messages from all threads and queuing them in target queue */
 		CHECK_FCT(fd_sctps_startthreads(conn));
 #endif /* DISABLE_SCTP */
 	} else {
+		/* Mark the connection as protected from here */
+		conn->cc_tls = 1;
+
 		/* Start decrypting the data */
 		CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, rcvthr_tls_single, conn ) );
 	}
-
+	
 	return 0;
 }
 
"Welcome to our mercurial repository"