Index: freeDiameter/cnxctx.c
===================================================================
--- freeDiameter/cnxctx.c	(revision 27)
+++ freeDiameter/cnxctx.c	(revision 29)
@@ -397,4 +397,18 @@
 }
 
+/* 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)
@@ -474,6 +488,13 @@
 	
 	TRACE_ENTRY("%p", arg);
-	
 	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 );
@@ -548,6 +569,13 @@
 	
 	TRACE_ENTRY("%p", arg);
-	
 	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 );
@@ -607,5 +635,5 @@
 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];
@@ -616,5 +644,5 @@
 
 		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 */
@@ -640,5 +668,5 @@
 		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);
 
@@ -664,6 +692,13 @@
 	
 	TRACE_ENTRY("%p", arg);
-	
 	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) );
@@ -709,5 +744,5 @@
 
 /* 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 */
@@ -724,5 +759,5 @@
 
 	/* 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 */
@@ -735,5 +770,5 @@
 
 /* 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);
@@ -750,5 +785,5 @@
 	
 	/* 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 */
@@ -801,14 +836,20 @@
 #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;
 }
