Browse Source

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.
tags/v1.12.90
Pierre Ossman 2 years ago
parent
commit
cee5a417c8
2 changed files with 17 additions and 3 deletions
  1. 16
    3
      common/rdr/TLSInStream.cxx
  2. 1
    0
      common/rdr/TLSInStream.h

+ 16
- 3
common/rdr/TLSInStream.cxx View File

TLSInStream* self= (TLSInStream*) str; TLSInStream* self= (TLSInStream*) str;
InStream *in = self->in; InStream *in = self->in;


self->streamEmpty = false;
delete self->saved_exception; delete self->saved_exception;
self->saved_exception = NULL; self->saved_exception = NULL;


try { try {
if (!in->hasData(1)) { if (!in->hasData(1)) {
self->streamEmpty = true;
gnutls_transport_set_errno(self->session, EAGAIN); gnutls_transport_set_errno(self->session, EAGAIN);
return -1; return -1;
} }
{ {
int n; 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) if (n == GNUTLS_E_PULL_ERROR)
throw *saved_exception; throw *saved_exception;

+ 1
- 0
common/rdr/TLSInStream.h View File

gnutls_session_t session; gnutls_session_t session;
InStream* in; InStream* in;


bool streamEmpty;
Exception* saved_exception; Exception* saved_exception;
}; };
}; };

Loading…
Cancel
Save