Concurrent gnutls_record_send and gnutls_record_recv

Sam Varshavchik mrsam at
Wed Dec 16 01:29:53 CET 2009

I want my application to be able to read/write from a TLS session 
concurrently, which requires non-blocking socket transport, and I am trying 
to figure out how to use the API correctly. I see that the documentation 
indicates the gnutls is thread safe; but does that mean that one thread can 
be using gnutls_record_send() while another thread be using 
gnutls_record_recv() at the same time? That's one approach that I am 
considering. If not, and I have to multiplex a single thread between reading 
and writing, I am trying to figure out how to use the API correctly. So far, 
I have:

* If there's something waiting to be written, call gnutls_record_send. If 
gnutls_record_send returned GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN, call 
gnutls_record_get_direction(), and note its return value. If 
gnutls_record_send wrote something, and there's more left to write, take it 
from the top.

* Call gnutls_record_recv. If something was read, process the read data, and 
take it from the top again. If gnutls_record_recv came back with 
GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN, call gnutls_record_get_direction(), 
combine its return value with the return value after gnutls_record_send() 
(if applicable), computing the corresponding combination of POLLIN and 
POLLOUT, then call poll() to wait for the required I/O state.

Also, in an established TLS session, after the handshake completes, if 
gnutls_record_recv() or gnutls_record_send() returns GNUTLS_E_INTERRUPTED or 
GNUTLS_E_AGAIN, will gnutls_record_get_direction() always return 0 after 
gnutls_record_recv and 1 after gnutls_record_send(), or are there situations 
where gnutls_record_recv() would need to write to the underlying transport, 
and gnutls_record_send() would need to read from the underlying transport, 
and how would that be squared away with the application's simultaneous usage 
of gnutls_record_send() and gnutls_record_recv()? If, say, after 
gnutls_record_recv() returns GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, and 
gnutls_record_get_direction returns 1 (indicating write I/O is required), 
must I subsequently call gnutls_record_recv() again, after I/O is available, 
and calling gnutls gnutls_record_send() (as my I/O loop does) would mess 
things up?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: </pipermail/attachments/20091215/9c1300cc/attachment.pgp>

More information about the Gnutls-help mailing list