aboutsummaryrefslogtreecommitdiffstats
path: root/common/rdr/TLSInStream.cxx
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2022-04-06 15:23:50 +0200
committerPierre Ossman <ossman@cendio.se>2022-04-06 15:31:15 +0200
commitcee5a417c8411adbeba7cee9e22c1bd519cf39c6 (patch)
tree7066034c7f4a3b35a17756cabf8b8f6d57987a47 /common/rdr/TLSInStream.cxx
parenta97e9b119e58dd2d59fa479b6c753c940d093e8f (diff)
downloadtigervnc-cee5a417c8411adbeba7cee9e22c1bd519cf39c6.tar.gz
tigervnc-cee5a417c8411adbeba7cee9e22c1bd519cf39c6.zip
Don't trust GNUTLS_E_AGAIN
Unfortunately this error can be given by GnuTLS even though the underlying stream still has data available. So stop trusting this value and keep track of the underlying stream explicitly.
Diffstat (limited to 'common/rdr/TLSInStream.cxx')
-rw-r--r--common/rdr/TLSInStream.cxx19
1 files changed, 16 insertions, 3 deletions
diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx
index 451855c7..014789e3 100644
--- a/common/rdr/TLSInStream.cxx
+++ b/common/rdr/TLSInStream.cxx
@@ -39,11 +39,13 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
TLSInStream* self= (TLSInStream*) str;
InStream *in = self->in;
+ self->streamEmpty = false;
delete self->saved_exception;
self->saved_exception = NULL;
try {
if (!in->hasData(1)) {
+ self->streamEmpty = true;
gnutls_transport_set_errno(self->session, EAGAIN);
return -1;
}
@@ -100,9 +102,20 @@ size_t TLSInStream::readTLS(U8* buf, size_t len)
{
int n;
- n = gnutls_record_recv(session, (void *) buf, len);
- if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
- return 0;
+ while (true) {
+ streamEmpty = false;
+ n = gnutls_record_recv(session, (void *) buf, len);
+ if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) {
+ // GnuTLS returns GNUTLS_E_AGAIN for a bunch of other scenarios
+ // other than the pull function returning EAGAIN, so we have to
+ // double check that the underlying stream really is empty
+ if (!streamEmpty)
+ continue;
+ else
+ return 0;
+ }
+ break;
+ };
if (n == GNUTLS_E_PULL_ERROR)
throw *saved_exception;