diff libfdcore/cnxctx.c @ 1217:1e8267ad057c

Implemented early version of sctp_dtls.c, for debug
author Sebastien Decugis <sdecugis@freediameter.net>
date Tue, 18 Jun 2013 12:46:01 +0800
parents 76ac4bb75f0e
children 33ad82ffbdde
line wrap: on
line diff
--- a/libfdcore/cnxctx.c	Mon Jun 17 10:11:57 2013 +0800
+++ b/libfdcore/cnxctx.c	Tue Jun 18 12:46:01 2013 +0800
@@ -88,6 +88,7 @@
 
 	CHECK_MALLOC_DO( conn = malloc(sizeof(struct cnxctx)), return NULL );
 	memset(conn, 0, sizeof(struct cnxctx));
+	fd_list_init(&conn->cc_sctp_dtls_data.chunks, NULL);
 
 	if (full) {
 		CHECK_FCT_DO( fd_fifo_new ( &conn->cc_incoming, 5 ), return NULL );
@@ -946,7 +947,7 @@
 
 
 /* Returns 0 on error, received data size otherwise (always >= 0). This is not used for DTLS-protected associations. */
-static ssize_t fd_tls_recv_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
+ssize_t fd_tls_recv_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
 {
 	ssize_t ret;
 again:	
@@ -976,6 +977,14 @@
 					TRACE_DEBUG(FULL, "Got 0 size while reading the socket, probably connection closed...");
 					break;
 				
+				case GNUTLS_E_WARNING_ALERT_RECEIVED:
+					LOG_N("Received TLS WARNING ALERT: %s", gnutls_alert_get_name(gnutls_alert_get(session)) ?: "<unknown alert>");
+					goto again;
+					
+				case GNUTLS_E_FATAL_ALERT_RECEIVED:
+					LOG_E("Received TLS FATAL ALERT: %s", gnutls_alert_get_name(gnutls_alert_get(session)) ?: "<unknown alert>");
+					break;
+					
 				default:
 					if (gnutls_error_is_fatal (ret) == 0) {
 						LOG_N("Ignoring non-fatal GNU TLS error: %s", gnutls_strerror (ret));
@@ -995,7 +1004,7 @@
 }
 
 /* Wrapper around gnutls_record_send to handle some error codes. This is also used for DTLS-protected associations */
-static ssize_t fd_tls_send_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
+ssize_t fd_tls_send_handle_error(struct cnxctx * conn, gnutls_session_t session, void * data, size_t sz)
 {
 	ssize_t ret;
 	struct timespec ts, now;
@@ -1043,13 +1052,7 @@
 
 
 /* The function that receives TLS data and re-builds a Diameter message -- it exits only on error or cancelation */
-/* 	   For the case of DTLS, since we are not using SCTP_UNORDERED, the messages over a single stream are ordered.
-	   Furthermore, as long as messages are shorter than the MTU [2^14 = 16384 bytes], they are delivered in a single
-	   record, as far as I understand. 
-	   For larger messages, however, it is possible that pieces of messages coming from different streams can get interleaved. 
-	   As a result, we do not use the following function for DTLS reception, because we use the sequence number to rebuild the
-	   messages. */
-int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session)
+int fd_tls_rcvthr_core(struct cnxctx * conn, gnutls_session_t session, int dtls)
 {
 	/* No guarantee that GnuTLS preserves the message boundaries, so we re-build it as in TCP. */
 	do {
@@ -1060,7 +1063,10 @@
 		size_t	received = 0;
 
 		do {
-			ret = fd_tls_recv_handle_error(conn, session, &header[received], sizeof(header) - received);
+			if (!dtls)
+				ret = fd_tls_recv_handle_error(conn, session, &header[received], sizeof(header) - received);
+			else
+				ret = fd_dtls_recv_handle_error(conn, session, &header[received], sizeof(header) - received);
 			if (ret <= 0) {
 				/* The connection is closed */
 				goto out;
@@ -1085,7 +1091,10 @@
 
 		while (received < rcv_data.length) {
 			pthread_cleanup_push(free_rcvdata, &rcv_data); /* In case we are canceled, clean the partialy built buffer */
-			ret = fd_tls_recv_handle_error(conn, session, rcv_data.buffer + received, rcv_data.length - received);
+			if (!dtls)
+				ret = fd_tls_recv_handle_error(conn, session, rcv_data.buffer + received, rcv_data.length - received);
+			else
+				ret = fd_dtls_recv_handle_error(conn, session, rcv_data.buffer + received, rcv_data.length - received);
 			pthread_cleanup_pop(0);
 
 			if (ret <= 0) {
@@ -1130,8 +1139,8 @@
 	ASSERT( fd_cnx_target_queue(conn) );
 
 	/* The next function only returns when there is an error on the socket */	
-	CHECK_FCT_DO(fd_tls_rcvthr_core(conn, conn->cc_tls_para.session), /* continue */);
-
+	CHECK_FCT_DO(fd_tls_rcvthr_core(conn, conn->cc_tls_para.session, 0), /* continue */);
+	
 	TRACE_DEBUG(FULL, "Thread terminated");	
 	return NULL;
 }
@@ -1935,8 +1944,7 @@
 				}
 			} else {
 				/* DTLS */
-				/* Multistream is handled at lower layer in the push/pull function */
-				CHECK_FCT( send_simple(conn, buf, len) );
+				CHECK_FCT( fd_sctp_dtls_send(conn, buf, len) );
 			}
 		}
 		break;
"Welcome to our mercurial repository"