summaryrefslogtreecommitdiffstats
path: root/demos/tunala/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'demos/tunala/buffer.c')
-rw-r--r--demos/tunala/buffer.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/demos/tunala/buffer.c b/demos/tunala/buffer.c
index e9a4e5b030..2915f2c67b 100644
--- a/demos/tunala/buffer.c
+++ b/demos/tunala/buffer.c
@@ -101,6 +101,37 @@ int buffer_to_fd(buffer_t *buf, int fd)
#ifndef NO_OPENSSL
+static void int_ssl_check(SSL *s, int ret)
+{
+ int e = SSL_get_error(s, ret);
+ switch(e) {
+ /* These seem to be harmless and already "dealt with" by our
+ * non-blocking environment. NB: "ZERO_RETURN" is the clean
+ * "error" indicating a successfully closed SSL tunnel. We let
+ * this happen because our IO loop should not appear to have
+ * broken on this condition - and outside the IO loop, the
+ * "shutdown" state is checked. */
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ case SSL_ERROR_ZERO_RETURN:
+ return;
+ /* These seem to be indications of a genuine error that should
+ * result in the SSL tunnel being regarded as "dead". */
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ SSL_set_app_data(s, (char *)1);
+ return;
+ default:
+ break;
+ }
+ /* For any other errors that (a) exist, and (b) crop up - we need to
+ * interpret what to do with them - so "politely inform" the caller that
+ * the code needs updating here. */
+ abort();
+}
+
void buffer_from_SSL(buffer_t *buf, SSL *ssl)
{
int ret;
@@ -109,6 +140,8 @@ void buffer_from_SSL(buffer_t *buf, SSL *ssl)
ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
if(ret > 0)
buf->used += ret;
+ if(ret < 0)
+ int_ssl_check(ssl, ret);
}
void buffer_to_SSL(buffer_t *buf, SSL *ssl)
@@ -119,6 +152,8 @@ void buffer_to_SSL(buffer_t *buf, SSL *ssl)
ret = SSL_write(ssl, buf->data, buf->used);
if(ret > 0)
buffer_takedata(buf, NULL, ret);
+ if(ret < 0)
+ int_ssl_check(ssl, ret);
}
void buffer_from_BIO(buffer_t *buf, BIO *bio)