Nikos, Thanks for your reply.
On 8 Apr 2016, at 14:35, Nikos Mavrogiannopoulos <[email protected]> wrote: > On Fri, Apr 8, 2016 at 10:36 AM, Alex Bligh <[email protected]> wrote: >> Is there a simple, easy to reuse, example of gnu-tls acting like a >> proxy which is truly non-blocking? By truly non-blocking I mean using >> non-blocking writes as well as non-blocking reads. The danger I >> am concerned about is receiving a large amount of plain-text, >> gnutls converting that to cypher-text, attempting to write it >> but blocking because the remote side is not ready to receive it. >> The remote side is not ready to receive it because it has its >> own output blocked as gnutls is not polling for reads as >> it's blocked above, meaning deadlock. > > Blocking is a matter of the underlying socket functions. Perhaps I should have used the word 'asynchronous' > If you set > the sockets to non blocking mode gnutls operates in a non-blocking way > almost identically to berkeley sockets. Have you checked the manual? > https://www.gnutls.org/manual/html_node/Asynchronous-operation.html I had done, but it was not fantastically helpful. The manual says "GnuTLS does not keep a write buffer, thus when writing no additional actions are required." which I took to mean it was writing synchronously (but reading async). > The simplest example is mini-eagain.c from the test suite which > verifies the asynchronous operation of gnutls_record_send and recv. Thanks - that was helpful. But it doesn't do a select loop as far as I can tell. The examples there set their own push/pull functions, which I understand to be to read/write the crypted traffic. I was planning if possible to use straight sockets. Does a select loop now look something like the code below? (pseudo-code, error checking omitted) I'm guessing here, and an example would be really helpful. Also do I need to manually verify certificates after a handshake? src/cli.c seems to do this with its own callback functions, but I don't know whether that's for debugging purposes only? int tls_wr_interrupted = 0; while (1) { size_t buffered = gnutls_record_check_pending (); if (buffered) timeout = 0; // don't wait on select if we have buffered data else timeout = infinite; if (!bufIsEmpty (plainToCrypt) || tls_wr_interrupted) FD_SET (crypt, write_fd_set); if (!bufIsEmpty (cryptToPlain)) FD_SET (plain, write_fd_set); if (!bufIsFull (plainToCrypt)) FD_SET (plain, read_fd_set); if (!bufIsFull (cryptToPlain)) FD_SET (crypt, read_fd_set); select (read_fd_set, write_fd_set, 0, timeout); if (FD_IS_SET (crypt, read_fd_set) || buffered) buffer (cryptToPlain, gnutls_record_recv ( ...)); if (FD_IS_SET (crypt, write_fd_set)) { if tls_wr_interrupted { err = gnutls_record_send (NULL); } else { err = gnutls_record_send (unbuffer (plainToCrypt), ...); } tls_wr_interrupted = (err == GNUTLS_E_INTERRUPTED); } if (FD_IS_SET (plain, read_fd_set)) buffer (plainToCrypt, read (plain, ...)); if (FD_IS_SET (plain, write_fd_set)) write (plain, unbuffer (cryptToPlain) ...); } -- Alex Bligh _______________________________________________ Gnutls-help mailing list [email protected] http://lists.gnupg.org/mailman/listinfo/gnutls-help
