[sr-dev] git:andrei/tcp_tls_changes: tls: tls_bio ctrl cmd support, fixes and debug

Andrei Pelinescu-Onciul andrei at iptel.org
Thu May 20 17:58:07 CEST 2010


Module: sip-router
Branch: andrei/tcp_tls_changes
Commit: c6a9ffb4f6a7b2e9f777ed47e87749eacf9782b6
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c6a9ffb4f6a7b2e9f777ed47e87749eacf9782b6

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Thu May 20 17:44:13 2010 +0200

tls: tls_bio ctrl cmd support, fixes and debug

- proper return code for some BIO_ctrl commands used internally by SSL_*.
 (BIO_CTRL_DUP, BIO_CTRL_FLUSH)
- when the attached memory buffer is null and read or write is
  attempted, behave similar to socket bio on EAGAIN
  (BIO_set_retry_read(b)).
- fixed tls_bio_mbuf_read bug (switched params in memcpy).
- added tls_mbuf_init(...)
- extended debug messages if TLS_BIO_DEBUG is defined.

---

 modules/tls/tls_bio.c |   87 +++++++++++++++++++++++++++++++++++++++++++++----
 modules/tls/tls_bio.h |   24 ++++++++++++--
 2 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/modules/tls/tls_bio.c b/modules/tls/tls_bio.c
index a7ba50d..c82fe64 100644
--- a/modules/tls/tls_bio.c
+++ b/modules/tls/tls_bio.c
@@ -24,6 +24,8 @@
  * History:
  * --------
  *  2010-03-25  initial version (andrei)
+ *  2010-05-20  emulate EAGAIN on null rd/wr memory buffer; handle some
+ *              needed commands in ctrl; debug support (TLS_BIO_DBG) (andrei)
 */
 
 #include "tls_bio.h"
@@ -35,6 +37,26 @@
    internal defined BIO is 23) */
 #define BIO_TYPE_TLS_MBUF	(BIO_TYPE_SOURCE_SINK | 0xf2)
 
+/* debugging */
+#ifndef NO_TLS_BIO_DEBUG
+#define TLS_BIO_DEBUG
+#endif
+#ifdef TLS_BIO_DEBUG
+	#ifdef __SUNPRO_C
+		#define TLS_BIO_DBG(...) \
+			LOG_(DEFAULT_FACILITY, L_INFO, "tls_BIO: " LOC_INFO, __VA_ARGS__)
+	#else
+		#define TLS_BIO_DBG(fmt, args...) \
+			LOG_(DEFAULT_FACILITY, L_INFO, "tls_BIO: " LOC_INFO, fmt, ## args)
+	#endif /* __SUNPRO_c */
+#else /* TLS_BIO_DEBUG */
+	#ifdef __SUNPRO_C
+		#define TLS_BIO_DBG(...)
+	#else
+		#define TLS_BIO_DBG(fmt, args...)
+	#endif /* __SUNPRO_c */
+#endif /* TLS_BIO_DEBUG */
+
 
 static int tls_bio_mbuf_new(BIO* b);
 static int tls_bio_mbuf_free(BIO* b);
@@ -73,6 +95,7 @@ BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr)
 {
 	BIO* ret;
 	
+	TLS_BIO_DBG("tls_BIO_new_mbuf called (%p, %p)\n", rd, wr);
 	ret = BIO_new(tls_BIO_mbuf());
 	if (unlikely(ret == 0))
 		return 0;
@@ -92,6 +115,7 @@ int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr)
 {
 	struct tls_bio_mbuf_data* d;
 	
+	TLS_BIO_DBG("tls_BIO_muf_set called (%p, %p)\n", rd, wr);
 	if (unlikely(b->ptr == 0)){
 		BUG("null BIO ptr\n");
 		return 0;
@@ -113,6 +137,7 @@ static int tls_bio_mbuf_new(BIO* b)
 {
 	struct tls_bio_mbuf_data* d;
 	
+	TLS_BIO_DBG("tls_bio_mbuf_new called (%p)\n", b);
 	b->init = 0; /* not initialized yet */
 	b->num = 0;
 	b->ptr = 0;
@@ -134,6 +159,7 @@ static int tls_bio_mbuf_new(BIO* b)
  */
 static int tls_bio_mbuf_free(BIO* b)
 {
+	TLS_BIO_DBG("tls_bio_mbuf_free called (%p)\n", b);
 	if (unlikely( b == 0))
 			return 0;
 	if (likely(b->ptr)){
@@ -164,19 +190,30 @@ static int tls_bio_mbuf_read(BIO* b, char* dst, int dst_len)
 		if (unlikely(d == 0 || d->rd->buf == 0)) {
 			if (d == 0)
 				BUG("tls_BIO_mbuf %p: read called with null b->ptr\n", b);
-			else
-				BUG("tls_BIO_mbuf %p: read called with null read buffer\n", b);
+			else {
+				/* this form of calling read with a null buffer is used
+				   as a shortcut when no data is available =>
+				   simulate EAGIAN/WANT_READ */
+				TLS_BIO_DBG("read (%p, %p, %d) called with null read buffer"
+						" => simulating EAGAIN/WANT_READ\n", b, dst, dst_len);
+				BIO_set_retry_read(b);
+			}
 			return -1;
 		}
 		rd = d->rd;
 		if (unlikely(rd->used == rd->pos && dst_len)) {
 			/* mimic non-blocking read behaviour */
+			TLS_BIO_DBG("read (%p, %p, %d) called with full rd (%d)"
+						" => simulating EAGAIN/WANT_READ\n",
+						b, dst, dst_len, rd->used);
 			BIO_set_retry_read(b);
 			return -1;
 		}
 		ret = MIN_int(rd->used - rd->pos, dst_len);
 		/* copy data from rd.buf into dst */
-		memcpy(rd->buf+rd->pos, dst, ret);
+		memcpy(dst, rd->buf+rd->pos, ret);
+		TLS_BIO_DBG("read(%p, %p, %d) called with rd=%p pos=%d => %d bytes\n",
+						b, dst, dst_len, rd->buf, rd->pos, ret);
 		rd->pos += ret;
 /*		if (unlikely(rd->pos < rd->used))
 			BIO_set_retry_read(b);
@@ -204,13 +241,21 @@ static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len)
 	if (unlikely(d == 0 || d->wr->buf == 0)) {
 		if (d == 0)
 			BUG("tls_BIO_mbuf %p: write called with null b->ptr\n", b);
-		else
-			BUG("tls_BIO_mbuf %p: write called with null read buffer\n", b);
+		else {
+			/* this form of calling write with a null buffer is used
+			   as a shortcut when no data is available =>
+			   simulate EAGAIN/WANT_WRITE */
+			TLS_BIO_DBG("write (%p, %p, %d) called with null buffer"
+					" => simulating WANT_WRITE\n", b, src, src_len);
+			BIO_set_retry_write(b);
+		}
 		return -1;
 	}
 	wr = d->wr;
 	if (unlikely(wr->size == wr->used && src_len)) {
 		/* mimic non-blocking socket behaviour */
+		TLS_BIO_DBG("write (%p, %p, %d) called with full wr buffer (%d)"
+					" => simulating WANT_WRITE\n", b, src, src_len, wr->used);
 		BIO_set_retry_write(b);
 		return -1;
 	}
@@ -220,6 +265,7 @@ static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len)
 /*	if (unlikely(ret < src_len))
 		BIO_set_retry_write();
 */
+	TLS_BIO_DBG("write called (%p, %p, %d) => %d\n", b, src, src_len, ret);
 	return ret;
 }
 
@@ -227,8 +273,34 @@ static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len)
 
 static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2)
 {
-	/* no cmd supported */
-	return 0;
+	long ret;
+	ret=0;
+	switch(cmd) {
+		case BIO_C_SET_FD:
+		case BIO_C_GET_FD:
+			ret = -1; /* error, not supported */
+			break;
+		case BIO_CTRL_GET_CLOSE:
+		case BIO_CTRL_SET_CLOSE:
+			ret = 0;
+			break;
+		case BIO_CTRL_DUP:
+		case BIO_CTRL_FLUSH:
+			ret = 1;
+			break;
+		case BIO_CTRL_RESET:
+		case BIO_C_FILE_SEEK:
+		case BIO_C_FILE_TELL:
+		case BIO_CTRL_INFO:
+		case BIO_CTRL_PENDING:
+		case BIO_CTRL_WPENDING:
+		default:
+			ret = 0;
+			break;
+	}
+	TLS_BIO_DBG("ctrl called (%p, %d, %ld, %p) => %ld\n",
+				b, cmd, arg1, arg2, ret);
+	return ret;
 }
 
 
@@ -237,6 +309,7 @@ static int tls_bio_mbuf_puts(BIO* b, const char* s)
 {
 	int len;
 	
+	TLS_BIO_DBG("puts called (%p, %s)\n", b, s);
 	len=strlen(s);
 	return tls_bio_mbuf_write(b, s, len);
 }
diff --git a/modules/tls/tls_bio.h b/modules/tls/tls_bio.h
index 78d5a47..5336d6b 100644
--- a/modules/tls/tls_bio.h
+++ b/modules/tls/tls_bio.h
@@ -34,9 +34,9 @@
 /* memory buffer used for tls I/O */
 struct tls_mbuf {
 	unsigned char* buf;
-	int pos;  /* current position in the buffer while reading*/
-	int used; /* how much it's used */
-	int size; /* total buffer size (fixed) */
+	int pos;  /**< current position in the buffer while reading or writing*/
+	int used; /**< how much it's used  (read or write)*/
+	int size; /**< total buffer size (fixed) */
 };
 
 struct tls_bio_mbuf_data {
@@ -49,6 +49,24 @@ BIO_METHOD* tls_BIO_mbuf(void);
 BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr);
 int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr);
 
+
+
+/** intialize an mbuf structure.
+ * @param mb - struct tls_mbuf pointer that will be intialized.
+ * @param b  - buffer (unsigned char*).
+ * @param sz - suze of the buffer (int).
+ * WARNING: the buffer will not be copied, but referenced.
+ */
+#define tls_mbuf_init(mb, b, sz) \
+	do { \
+		(mb)->buf = (b); \
+		(mb)->size = (sz); \
+		(mb)->pos = 0; \
+		(mb)->used = 0; \
+	} while(0)
+
+
+
 #endif /*__tls_bio_h*/
 
 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */




More information about the sr-dev mailing list