diff --git a/src/server/close_conn.c b/src/server/close_conn.c index 33d2dd4..ab5d9d1 100644 --- a/src/server/close_conn.c +++ b/src/server/close_conn.c @@ -39,6 +39,7 @@ serverCloseConn(Server this, unsigned int i) if (NULL != st && STREAM_SSL == st->type) { SSL_shutdown((st->handle).ssl); SSL_free((st->handle).ssl); + (st->handle).ssl = NULL; } delete(st); diff --git a/src/stream/read.c b/src/stream/read.c index 9b697f5..7bfbdca 100644 --- a/src/stream/read.c +++ b/src/stream/read.c @@ -66,10 +66,29 @@ streamRead(Stream this, void * buf, size_t count) case STREAM_SSL: done = SSL_read((this->handle).ssl, buf, count); - if (0 >= done) { + if (0 == done) { + done = -2; + } else if (0 > done) { switch (SSL_get_error((this->handle).ssl, done)) { + case SSL_ERROR_SYSCALL: + { + switch (errno) { + case EINTR: + case ENOBUFS: + case ENOMEM: + done = 0; + break; + case (EAGAIN|EWOULDBLOCK): + done = -1; + break; + default: + done = -1; + break; + } + } + break; + case SSL_ERROR_SSL: - case SSL_ERROR_SYSCALL: { unsigned long err; @@ -91,7 +110,7 @@ streamRead(Stream this, void * buf, size_t count) break; default: - done = 0; + done = -2; break; } diff --git a/src/stream/write.c b/src/stream/write.c index f8e5899..00aa9aa 100644 --- a/src/stream/write.c +++ b/src/stream/write.c @@ -63,12 +63,36 @@ streamWrite(Stream this, void * buf, size_t count) break; case STREAM_SSL: + /* + * @TODO I got a segfault in this call under unclear + * circumstances. Most likely it has to do with a + * write on a closed connection. + */ done = SSL_write((this->handle).ssl, buf, count); - if (0 >= done) { + if (0 == done) { + done = -2; + } else if (0 > done) { switch (SSL_get_error((this->handle).ssl, done)) { - case SSL_ERROR_SSL: case SSL_ERROR_SYSCALL: + { + switch (errno) { + case EINTR: + case ENOBUFS: + case ENOMEM: + done = 0; + break; + case (EAGAIN|EWOULDBLOCK): + done = -1; + break; + default: + done = -2; + break; + } + } + break; + + case SSL_ERROR_SSL: { unsigned long err; @@ -90,7 +114,7 @@ streamWrite(Stream this, void * buf, size_t count) break; default: - done = 0; + done = -2; break; }