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=c6a9ffb…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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: */