#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;
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)
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)