SSL_read, SSL_write error handling

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

SSL_read, SSL_write error handling

Alex Hultman
If SSL_write returns the error SSL_ERROR_WANT_READ, am I then allowed to call SSL_read before I have called SSL_write?

What I'm trying to figure out is, can I handle SSL_ERROR_WANT_READ with one or many calls to SSL_read, and can I handle SSL_ERROR_WANT_WRITE with one or many calls to SSL_write - despite the fact that the error was thrown by the opposite SSL_* function call?

Does an SSL_ERROR_WANT_READ have to be handled by the SSL_* function that caused the error, or will any of the two (SSL_read, SSL_write) functions handle this desire?

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: SSL_read, SSL_write error handling

Viktor Dukhovni
On Thu, Sep 15, 2016 at 05:07:22AM +0200, Alex Hultman wrote:

> If SSL_write returns the error SSL_ERROR_WANT_READ, am I then allowed to
> call SSL_read before I have called SSL_write?

WANT_READ means that OpenSSL *internally* needs to read some (often
ciphertext) bytes from the peer, and that since the socket is
non-blocking or you're using BIO_pairs, ... the application must
wait for data to arrive (poll(), select(), ...) and then retry
the call once the socket becomes readable.

It is not an invitation to read *application* layer data, which
would typically also fail for lack anything to read at that
moment.

    * WANT_READ -- Select the socket for read, and retry
      the original function (hanshake, read or write) once
      the socket is readable.

    * WANT_READ -- Select the socket for write, and retry
      the original function (hanshake, read or write) once
      the socket becomes writable.

Again, these are not a request for the application to *consume*
data, rather the application needs to retry once the socket is
ready for the requested operation.  OpenSSL will internally
read or write to the socket.

--
        Viktor.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: SSL_read, SSL_write error handling

Alex Hultman
I did find a very good explanation here: https://mta.openssl.org/pipermail/openssl-users/2015-March/000709.html

The idea of "what SSL wants" and "what the app wants" is a very good explanation. This is the pseudocode I'm working with currently:

    io_callback(events) {
        if (messages_to_send && (events & OS_WRITABLE)) {
            SSL_write(.....);
            if (error) {
                if (error_is_want_read) {
                    system_poll &= OS_READABLE;
                } else if (error_is_want_write) {
                    system_poll &= OS_WRITABLE;
                }
                update_os_poll(system_poll);
                return;
            } else {
                // emit send success to app
            }
        } else if (app_wants_data && (events & OS_READABLE)) {
            SSL_read(.....);
            if (error) {
                if (error_is_want_read) {
                    system_poll &= OS_READABLE;
                } else if (error_is_want_write) {
                    system_poll &= OS_WRITABLE;
                }
                update_os_poll(system_poll);
                return;
            } else {
                // emit the data to app
            }
        }
    }

This code is probably not 100% correct, but should show my design pretty clear. One needs to do what YOU want, combined with what SSL wants.

However, question still remains - it is ALLOWED to perform SSL_read before SSL_write, when a previous call to SSL_write failed with WANT_READ?

2016-09-15 7:01 GMT+02:00 Viktor Dukhovni <[hidden email]>:
On Thu, Sep 15, 2016 at 05:07:22AM +0200, Alex Hultman wrote:

> If SSL_write returns the error SSL_ERROR_WANT_READ, am I then allowed to
> call SSL_read before I have called SSL_write?

WANT_READ means that OpenSSL *internally* needs to read some (often
ciphertext) bytes from the peer, and that since the socket is
non-blocking or you're using BIO_pairs, ... the application must
wait for data to arrive (poll(), select(), ...) and then retry
the call once the socket becomes readable.

It is not an invitation to read *application* layer data, which
would typically also fail for lack anything to read at that
moment.

    * WANT_READ -- Select the socket for read, and retry
      the original function (hanshake, read or write) once
      the socket is readable.

    * WANT_READ -- Select the socket for write, and retry
      the original function (hanshake, read or write) once
      the socket becomes writable.

Again, these are not a request for the application to *consume*
data, rather the application needs to retry once the socket is
ready for the requested operation.  OpenSSL will internally
read or write to the socket.

--
        Viktor.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: SSL_read, SSL_write error handling

Viktor Dukhovni
On Thu, Sep 15, 2016 at 07:18:52AM +0200, Alex Hultman wrote:

>     io_callback(events) {
>         if (messages_to_send && (events & OS_WRITABLE)) {
>             SSL_write(.....);
>             if (error) {
>                 if (error_is_want_read) {
>                     system_poll &= OS_READABLE;
>                 } else if (error_is_want_write) {
>                     system_poll &= OS_WRITABLE;
>                 }

For what it's worth, you probably meant "|=" not "&=".

--
        Viktor.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users