Gives us a more meaningful error rather than just "Error in push/pull function".tags/v1.11.90
@@ -39,6 +39,9 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size) | |||
TLSInStream* self= (TLSInStream*) str; | |||
InStream *in = self->in; | |||
delete self->saved_exception; | |||
self->saved_exception = NULL; | |||
try { | |||
if (!in->hasData(1)) { | |||
gnutls_transport_set_errno(self->session, EAGAIN); | |||
@@ -54,10 +57,12 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size) | |||
} catch (SystemException &e) { | |||
vlog.error("Failure reading TLS data: %s", e.str()); | |||
gnutls_transport_set_errno(self->session, e.err); | |||
self->saved_exception = new SystemException(e); | |||
return -1; | |||
} catch (Exception& e) { | |||
vlog.error("Failure reading TLS data: %s", e.str()); | |||
gnutls_transport_set_errno(self->session, EINVAL); | |||
self->saved_exception = new Exception(e); | |||
return -1; | |||
} | |||
@@ -65,7 +70,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size) | |||
} | |||
TLSInStream::TLSInStream(InStream* _in, gnutls_session_t _session) | |||
: session(_session), in(_in) | |||
: session(_session), in(_in), saved_exception(NULL) | |||
{ | |||
gnutls_transport_ptr_t recv, send; | |||
@@ -77,6 +82,8 @@ TLSInStream::TLSInStream(InStream* _in, gnutls_session_t _session) | |||
TLSInStream::~TLSInStream() | |||
{ | |||
gnutls_transport_set_pull_function(session, NULL); | |||
delete saved_exception; | |||
} | |||
bool TLSInStream::fillBuffer(size_t maxSize) | |||
@@ -97,7 +104,11 @@ size_t TLSInStream::readTLS(U8* buf, size_t len) | |||
if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) | |||
return 0; | |||
if (n < 0) throw TLSException("readTLS", n); | |||
if (n == GNUTLS_E_PULL_ERROR) | |||
throw *saved_exception; | |||
if (n < 0) | |||
throw TLSException("readTLS", n); | |||
if (n == 0) | |||
throw EndOfStream(); |
@@ -43,6 +43,8 @@ namespace rdr { | |||
gnutls_session_t session; | |||
InStream* in; | |||
Exception* saved_exception; | |||
}; | |||
}; | |||
@@ -42,16 +42,21 @@ ssize_t TLSOutStream::push(gnutls_transport_ptr_t str, const void* data, | |||
TLSOutStream* self= (TLSOutStream*) str; | |||
OutStream *out = self->out; | |||
delete self->saved_exception; | |||
self->saved_exception = NULL; | |||
try { | |||
out->writeBytes(data, size); | |||
out->flush(); | |||
} catch (SystemException &e) { | |||
vlog.error("Failure sending TLS data: %s", e.str()); | |||
gnutls_transport_set_errno(self->session, e.err); | |||
self->saved_exception = new SystemException(e); | |||
return -1; | |||
} catch (Exception& e) { | |||
vlog.error("Failure sending TLS data: %s", e.str()); | |||
gnutls_transport_set_errno(self->session, EINVAL); | |||
self->saved_exception = new Exception(e); | |||
return -1; | |||
} | |||
@@ -59,7 +64,8 @@ ssize_t TLSOutStream::push(gnutls_transport_ptr_t str, const void* data, | |||
} | |||
TLSOutStream::TLSOutStream(OutStream* _out, gnutls_session_t _session) | |||
: session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0) | |||
: session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0), | |||
saved_exception(NULL) | |||
{ | |||
gnutls_transport_ptr_t recv, send; | |||
@@ -82,6 +88,7 @@ TLSOutStream::~TLSOutStream() | |||
gnutls_transport_set_push_function(session, NULL); | |||
delete [] start; | |||
delete saved_exception; | |||
} | |||
size_t TLSOutStream::length() | |||
@@ -134,6 +141,9 @@ size_t TLSOutStream::writeTLS(const U8* data, size_t length) | |||
if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) | |||
return 0; | |||
if (n == GNUTLS_E_PUSH_ERROR) | |||
throw *saved_exception; | |||
if (n < 0) | |||
throw TLSException("writeTLS", n); | |||
@@ -51,6 +51,8 @@ namespace rdr { | |||
size_t bufSize; | |||
U8* start; | |||
size_t offset; | |||
Exception* saved_exception; | |||
}; | |||
}; | |||