> So the question is whether it is legal for the server to send data while
> renegotiation is in progress?

        The server is not supposed to be required to track whether 
renegotiation is
in progress or not. If you try to send data while a renegotiation is in
progress, the OpenSSL library is obligated to do the right thing. That
probably means returning an "I can't do that until something else happens"
error. However, it must first try to do whatever it is that needs to be done
(that was its job in the first place!) and that may mean blocking if the
socket is blocking.

> I don't know... but as far as I can tell
> I'm not doing anything illegal as an application programmer.  I don't
> think I'm supposed to wait for rehandshake to finish (it doesn't
> even have
> to happen as far as I understand).

        Well, if you do need to wait for it to finish, the OpenSSL should
accurately report that to you, perhaps by returning a WANT_READ if it needs
to read data before it can send some. However, it is perfectly legal for it
to try the operation before it concludes that it cannot do it. That can
block if the socket is blocking.

> The socket on the server is blocking (don't tell David!)

        As I've said, operations on blocking sockets can block. The server 
cannot
ensure that it does not block unless it saves the blocking state of the
socket, changes it to non-blocking, and then changes it back. All of this
would be pointless because you specifically told the library to block -- why
should it go out of its way to refuse to do what you asked it to do?

> I hope I'm answering your question.
> I've looked at the ssl3_read_internal() code a couple of times but there
> is no way I can understand it without spending at least half a day,
> preferrably with a debugger, and I didn't have time to do that.
>
> I can probably build a simple server to reproduce the problem.  Should I?

        The situation seems to be very complex. That is where corner cases poke
their ugly heads.

        If you do a blocking 'SSL_write', and it has to read what it knows is
protocol data before it can even try writing, what do you think should
happen? What if you refuse to call 'SSL_read' because you *know* that there
cannot be application data to read because the application protocol requires
the other side to send first? (This would make 'SSL_write' *nothing* like a
regular TCP write.)

        I think it's really clear what correct operation is. A blocking 
'SSL_read'
should block until data can be read, whether that means blocking in 'read'
or 'write'. A blocking SSL_write should block until data can be written,
whether that means blocking in 'read' or 'write'. Non-blocking operations
should, ideally, make as much forward progress as is possible without
blocking, whether this means calling 'read', 'write', or both. This will
match TCP semantics very well whether the application wishes to block or
not. (Though my view of ideal semantics doesn't have much of anything to do
with this discussion, except as a wish for what saner people might have done
with the benefit of hindsight.)

        Forcing a client that does a blocking 'SSL_read' to call 'SSL_write' 
even
though it has no application-level data to send strikes me as *really* odd.
Without this, how can you ensure a call to 'SSL_read' doesn't block if it
gets protocol data instead of negotiation data? Clearly, a blocking
'SSL_read' can never call 'write' and a blocking 'SSL_read' could never call
'read'. This means they cannot block for application data, which is the
reason the application asked for blocking behavior.

        You keep trying to make bricks without straw. It simply cannot be done.

        DS


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to