help-gnutls
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-gnutls] Behavior of gnutls_record_recv()


From: Laurent Birtz
Subject: [Help-gnutls] Behavior of gnutls_record_recv()
Date: Fri, 04 Jan 2008 15:17:51 -0500
User-agent: Mozilla-Thunderbird 2.0.0.4 (X11/20070622)

Hello,

I am considering using GnuTLS as a replacement of openssl for securing
communications between two processes, A and B. However, I am not using a
typical client-server model, where the server waits for a query from the
client and the client waits for the reply from the server. Instead, A
and B are peer processes, and each one can independently decide at any
time to send a message to the other side.

It is possible that one process fill up its input or output queue
because the two processes are not operating at the same speed.
Therefore, read and write quenching must be supported. For instance, if
the input queue of a process is full, then this process must stop
reading data from the other side but continue writing data to the other
side.

Can I use GnuTLS to fullfill these requirements? I am especially
concerned with the gnutls_record_recv() and gnutls_record_send()
functions that can return GNUTLS_E_REHANDSHAKE, GNUTLS_E_INTERRUPTED or
GNUTLS_E_AGAIN (I am using non-blocking sockets). The documentation says
that handshake requests can be ignored. For my quenching scheme to be
implementable, it is important that after a call to gnutls_record_send()
that returns GNUTLS_E_AGAIN, gnutls_record_get_direction() only returns
1, i.e. wait for socket to be writable. Otherwise, if
gnutls_record_get_direction() returns 0, then this means that more data
will need to be received from the remote side, and this will bust my
buffer capacity (in that case, the GnuTLS internal buffer might keep
growing indefinitely).

Pseudo-code showing my application logic:

loop:
int must_read = 0, must_write = 0;

if (! input_queue.is_full()) {
   int error = gnutls_record_recv(...);
if (! error) {
       input_queue.push(...);
       /* Read again later. */
       must_read = 1;
   }
else if (error == GNUTLS_E_INTERRUPTED || error == GNUTLS_E_AGAIN) {
       /* This must hold!! */
       assert(gnutls_record_get_direction(...) == 0);
       must_read = 1;
   }
... handle other errors ...
}

if (! output_queue.is_empty()) {
   int error = gnutls_record_send(...);
if (! error) {
       /* Write again later. */
       must_write = 1;
   }
else if (error == GNUTLS_E_INTERRUPTED || error == GNUTLS_E_AGAIN) {
       /* This must hold!! */
       assert(gnutls_record_get_direction(...) == 1);
       must_write = 1;
   }
... handle other errors ...
}

select() according to must_read and must_write;
goto loop;


Thanks a lot for your time,
Laurent Birtz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]