[openssl-users] Polling fd before SSL_read() and renegotiations
Tomas Mraz
tmraz at redhat.com
Tue Jun 5 11:26:10 UTC 2018
On Mon, 2018-06-04 at 18:51 +0200, Stefan via openssl-users wrote:
> Hi everybody!
>
> I am working on a program where each peer may write at any time, so
> the other side has to be able to read incoming data when it gets
> available. If the peer sent nothing my program must be able to call
> SSL_write() to send its own data to the other side.
>
> My code currently does this using non-blocking I/O like this:
>
> 1. If the underlying socket is not readable go to #2 immediately to
> be
> able to send data. If the socket is reported to be readable, call
> SSL_read() to get that data. If that call cannot be completed due
> to SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE, poll the fd until
> that
> condition is met. Then repeat calling SSL_read(). So I'm
> repeatedly
> calling SSL_read() until it reports SSL_ERROR_NONE. With this I
> satisfy the requirement of the OpenSSL-API to repeat an incomplete
> call until it completes. Although I did not read that exactly in
> the man-pages, the non-blocking-example in "Network Security with
> OpenSSL" by Viega et al. takes care not to interleave the calls to
> SSL_write()/SSL_read().
>
> 2. (The program reaches here only after SSL_read() has succeeded or
> if
> it has not even tried to call SSL_read() as the socket was not
> readable) If the peer has data that needs to be sent to the other
> side, call SSL_write() for it. If that function returns with
> SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE poll the fd
> accordingly
> and repeat SSL_write() until it ends with SSL_ERROR_NONE. Then go
> to #1 to check for incoming data.
>
> The code above does what I want - except for renegotiations!
>
> If the peer receives a renegotiation-request its socket becomes
> readable just like if it received a normal SSL-record with user-data.
> Thus my program enters #1 and repeats SSL_read() until SSL_ERROR_NONE
> is returned. But this never happens in that case, because the other
> peer just sent the renegotiation-packet(s) but no other data. So I'm
> stuck in repeating SSL_read() and won't enter #2 until the peer that
> forced the renegotiation has sent any other data to make SSL_read()
> finish (which may take very long in my program).
You've basically answered your question yourself - you cannot do it
like this - switching phases #1 and #2, but instead you need to go to
the writing phase (i.e. start writing if you have anything to pass to
SSL_write) whenever you need to wait on data to be read to appear in
the socket.
--
Tomáš Mráz
No matter how far down the wrong road you've gone, turn back.
Turkish proverb
[You'll know whether the road is wrong if you carefully listen to your
conscience.]
More information about the openssl-users
mailing list