gnutls_record_check_pending() returning non-0 but gnutls_record_recv() gives no data

Nikos Mavrogiannopoulos nmav at
Sun Apr 8 13:55:03 CEST 2012

On 04/07/2012 02:46 PM, Wilmer van der Gaast wrote:

> Hello,
> /* My ref: */
> I seem to have a problem with GnuTLS 3.0.x, from what I can see this
> is a bug (but please correct me if I'm wrong). I have a function that
> receives data from a HTTPS server. This is all done with async and
> non-blocking I/O. Before returning from the read event handler,
> gnutls_record_check_pending() is called to check if there's any more
> unencrypted data waiting.


> When trying to query some servers (in this case MSN Messenger HTTPS 
> servers), gnutls_record_check_pending() will return a non-0 number
> (goes all the way up to 8KB at times), but when I try to read this
> data I get -28 which seems to be GNUTLS_E_AGAIN.
> From what I know, that error code means "I would block but this is a
> non-blocking socket, so come back later".

Note that return value of gnutls_record_check_pending() is not the
actual number of bytes to be received. Especially in the DTLS case
it might be that no application data are available for reading. In that
case, the call to record_recv() will not block but return eagain as you

> This seems to be a violation of what is promised in the manpage of 
> gnutls_record_check_pending(): DESCRIPTION This  function checks if
> there are unread data in the gnutls buffers. If the return value is
> non-zero the next call to gnutls_record_recv() is guarranteed not to
> block.

Since you received eagain, I think that the promise is kept, there was
no blocking. However, this scenario should be improbable in normal TLS.
I'd be interested to see the reason of the eagain. Could you provide
debugging information of level 2 or more for your scenario? Is the
version you are using 3.0.18?


More information about the Gnutls-help mailing list