changeset 129:f185f65e213f

Changed transport prototype for security extensions
author Sebastien Decugis <sdecugis@nict.go.jp>
date Mon, 18 Aug 2008 18:28:22 +0900
parents 21a5b37c6f35
children 641999eb7a1d
files extensions/sec_nosec/sns_recv_unprotect.c extensions/sec_nosec/sns_send_protect.c extensions/sec_tls_gnutls/gnutls_sctp_wrapper.h include/waaad/security-api.h
diffstat 4 files changed, 110 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/sec_nosec/sns_recv_unprotect.c	Mon Aug 18 14:54:40 2008 +0900
+++ b/extensions/sec_nosec/sns_recv_unprotect.c	Mon Aug 18 18:28:22 2008 +0900
@@ -39,26 +39,55 @@
 
 #include "sec_nosec.h"
 
+static int sns_recv_unprotect_tcp (sec_session_t * session, void ** data, size_t *length);
+static int sns_recv_unprotect_sctp(sec_session_t * session, void ** data, size_t *length);
+
 /* We just receive the buffer "as is" on the connection object, and rebuild a message (boundaries are lost with TCP) 
  * Note that we may be cancelled in any of the recv call.
  */
 int sns_recv_unprotect (sec_session_t * session, void ** ext_session, void ** data, size_t *length)
 {
+	ssize_t ret = 0;
+	
+	TRACE_ENTRY("%p %p %p %p", session, ext_session, data, length);
+	
+	if (!session || !session->conn || !data || !length) {
+		TRACE_DEBUG(INFO, "Invalid argument");
+		return EINVAL;
+	}
+	
+	switch (session->proto) {
+		case IPPROTO_TCP:
+			ret = sns_recv_unprotect_tcp(session, data, length);
+			break;
+
+		case IPPROTO_SCTP:
+			ret = sns_recv_unprotect_sctp(session, data, length);
+			break;
+
+		default:
+			TRACE_DEBUG(INFO, "Invalid proto");
+			return EINVAL;
+	}
+	
+	if (ret != 0) {
+		TRACE_DEBUG(INFO, "sns_recv_unprotect_<proto> failed: %s", strerror(ret));
+	}
+	
+	return ret;
+}
+
+/* Receive from a TCP connection: rebuild the message boundaries */
+static int sns_recv_unprotect_tcp (sec_session_t * session, void ** data, size_t *length)
+{
 	unsigned char header[4];
 	unsigned char * newmsg;
 	ssize_t ret = 0;
 	size_t	received = 0;
 	
-	TRACE_ENTRY("%p %p %p %p", session, ext_session, data, length);
-	
-	if (!session || !session->recv_data || !data || !length) {
-		TRACE_DEBUG(INFO, "Invalid argument");
-		return EINVAL;
-	}
-	
 	/* First, receive only a message header. */
 	while (received < sizeof(header)) {
-		ret = (*session->recv_data) (session->conn, &header[received], sizeof(header) - received);
+		ret = (*session->cbs.tcp.recv_data) (session->conn, &header[received], sizeof(header) - received);
 		if (ret == 0) {
 			/* Shutdown in progress */
 			TRACE_DEBUG(INFO, "The recv_data function returned 0");
@@ -94,7 +123,7 @@
 	memcpy(newmsg, header, sizeof(header));
 	while (received < *length) {
 		pthread_cleanup_push(free, newmsg); /* In case we are canceled, clean the partialy built buffer */
-		ret = (*session->recv_data) (session->conn, newmsg + received, (*length) - received);
+		ret = (*session->cbs.tcp.recv_data) (session->conn, newmsg + received, (*length) - received);
 		pthread_cleanup_pop(0);
 	
 		if (ret == 0) {
@@ -118,3 +147,27 @@
 	
 	return 0;
 }
+
+/* Receive from a SCTP connection: the message boundaries are preserved, so we have very few to do here */
+static int sns_recv_unprotect_sctp (sec_session_t * session, void ** data, size_t *length)
+{
+	ssize_t ret = 0;
+	int stream = 0;
+	
+	ret = (*session->cbs.sctp.recv_data) (session->conn, &stream, data, length);
+	if (ret == 0) {
+		/* Shutdown in progress */
+		TRACE_DEBUG(INFO, "The recv_data function returned 0");
+		return ENOTCONN;
+	}
+	if (ret < 0) {
+		/* Error */
+		ret = errno;
+		TRACE_DEBUG(INFO, "The recv_data function failed: %s", strerror(ret));
+		return ret;
+	}
+	
+	TRACE_DEBUG(FULL, "Received a message of %d bytes on stream %d", *length, stream);
+	return 0;
+}
+	
--- a/extensions/sec_nosec/sns_send_protect.c	Mon Aug 18 14:54:40 2008 +0900
+++ b/extensions/sec_nosec/sns_send_protect.c	Mon Aug 18 18:28:22 2008 +0900
@@ -45,16 +45,30 @@
 {
 	ssize_t ret = 0;
 	size_t sent = 0;
+	int  stream = -1;
 	
 	TRACE_ENTRY("%p %p %p %d", session, ext_session, data, length);
 	
-	if (!session || !session->send_data) {
+	if (!session || !session->conn) {
 		TRACE_DEBUG(INFO, "Invalid argument");
 		return EINVAL;
 	}
 	
 	while (sent < length) {
-		ret = (*session->send_data) (session->conn, ((char *)data) + sent, length - sent);
+		switch (session->proto) {
+			case IPPROTO_TCP:
+				ret = (*session->cbs.tcp.send_data) (session->conn, ((char *)data) + sent, length - sent);
+				break;
+				
+			case IPPROTO_SCTP:
+				ret = (*session->cbs.sctp.send_data) (session->conn, &stream, ((char *)data) + sent, length - sent);
+				break;
+			
+			default:
+				TRACE_DEBUG(INFO, "Invalid proto");
+				return EINVAL;
+		}
+				
 		if (ret == -1) {
 			ret = errno;
 			TRACE_DEBUG(INFO, "The send_data callback failed: %s", strerror(ret));
--- a/extensions/sec_tls_gnutls/gnutls_sctp_wrapper.h	Mon Aug 18 14:54:40 2008 +0900
+++ b/extensions/sec_tls_gnutls/gnutls_sctp_wrapper.h	Mon Aug 18 18:28:22 2008 +0900
@@ -167,7 +167,7 @@
  *  socket  : The socket on which to receive the next message.
  *  event   : if an event is received, it is stored here.
  *  streamid: if relevant, the stream id on which data or event is received.
- *  data    : a buffer continaing the received data.
+ *  data    : a buffer containing the received data.
  *  len     : the size of the data buffer
  *  init    : the initial size of the buffer
  *
--- a/include/waaad/security-api.h	Mon Aug 18 14:54:40 2008 +0900
+++ b/include/waaad/security-api.h	Mon Aug 18 18:28:22 2008 +0900
@@ -98,14 +98,30 @@
 /* The following type represents a "connection" object (for example, a socket) */
 typedef void sec_conn_t;
 
-/* This is the prototype of the function that the daemon uses to send data on a connection (TCP or SCTP) */
+/* This is the prototype of the function that the daemon uses to send data on a TCP */
+/* This function may be blocking. */
 /* The parameters and return values are the same as the send() function defined in POSIX. */
-typedef ssize_t (*sec_send_data_fct_t) (sec_conn_t *, void *, size_t);
+typedef ssize_t (*sec_send_tcp_cb) (sec_conn_t *, void *, size_t);
 
-/* This is the prototype of the function that the daemon uses to receive data from a connection (TCP or SCTP). 
+/* This is the prototype of the function that the daemon uses to receive data from a TCP connection. 
  * This function may be blocking. */
 /* The parameters and return values are the same as the recv() function defined in POSIX. */
-typedef ssize_t (*sec_recv_data_fct_t) (sec_conn_t *, void *, size_t);
+typedef ssize_t (*sec_recv_tcp_cb) (sec_conn_t *, void *, size_t);
+
+/* This is the prototype of the function that the daemon uses to send data on an SCTP connection */
+/* The second parameter is the stream id on which the message is sent. 
+    -1 means autorotate the streams, in which case the value is updated to the actual stream it was sent to.
+    otherwise the value is unchanged. */
+typedef ssize_t (*sec_send_sctp_cb) (sec_conn_t *, int *, void *, size_t);
+
+/* This is the prototype of the function that the daemon uses to receive data from an SCTP connection. 
+ * This function may be blocking. */
+/* The first argument is a connection handle.
+ * the second argument receives the stream id of a message on return.
+ * the third argument is the data on return. it must be freed after use.
+ * the last argument is the length of data.
+ */
+typedef ssize_t (*sec_recv_sctp_cb) (sec_conn_t *, int *, void **, size_t*);
 
 /* The following enum represents the possible states of a peer with regards to the security module (PSS = peer security state) */
 typedef enum {
@@ -121,8 +137,17 @@
 	
 	/* The next 3 fields are valid only in the PSS_INITIAL and PSS_CONNECTED states */
 	sec_conn_t		*conn;		/* The connection for sending/receiving to/from this peer */
-	sec_send_data_fct_t	 send_data;	/* The callback function to send data to the peer */
-	sec_recv_data_fct_t	 recv_data;	/* The callback function to receive data from the peer */
+	int			 proto;		/* IPPROTO_TCP or IPPROTO_SCTP */
+	union {
+		struct {
+			sec_send_tcp_cb	 send_data;	/* The callback function to send data to the peer */
+			sec_recv_tcp_cb	 recv_data;	/* The callback function to receive data from the peer */
+		} tcp;
+		struct {
+			sec_send_sctp_cb send_data;	/* The callback function to send data to the peer */
+			sec_recv_sctp_cb recv_data;	/* The callback function to receive data from the peer */
+		} sctp;
+	} cbs;
 } sec_session_t;
 
 
"Welcome to our mercurial repository"