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 <[email protected]>
Committer: Andrei Pelinescu-Onciul <[email protected]>
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: */


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to