David Schwartz wrote:
What return value makes sense with your model? If it says it sent
everything, you will not call into SSL again unless you have something to
write or expect to read something. If neither is the case, when will OpenSSL
get the chance to send those C bytes left over?
If the SSL implementation works in this way then trying to shoe-horn SSL
into a similar 3 argument API as the kernel was a bad design decision.
int SSL_write(SSL *ssl, const void *buf, int buflen, int *committedlenptr);
If you stand back from the problem a minute its easy to see there are 2
things that should be returned with a successful operation:
* The amount of data from the original application buffer that was
committed. i.e. there is no need for the application to represent this
data and any bytes beyond this maybe changed for the next call. So
committedlenptr would always be set to something between 0 and buflen.
* The status of the flush operation to the next layer down, passed as
the return value (and through the SSL_get_error() mechanism). Which
would retain the error of WANT_WRITE or return the entire length
presented in buflen.
Additional to the above an API call (pick your choice of naming)
SSL_write_{has_pending,needs_flush}(SSL *) to return a boolean state of
if there is anything to be flushed.
Then making the call SSL_write(ssl, NULL, 0, NULL) a valid call which
would simply flush the left over data but not commit any new application
data. It would return a new error SSL_ERROR_FLUSHED (or reuse
SSL_ERROR_NONE) when there was no more data to be flushed. It would
retain the WANT_WRITE error when there is data. This would allow the
write machinery to be serviced. This call could also be used in
situations where your peer decided it wanted to renegotiate and you
implicit response was sent.
Think of the above as the direct opposite of SSL_peek(SSL *ssl, void
*buf, int buflen)
Its probably a bit late in the game to go changing the SSL_write() call
so maybe SSL_write_foobar() could be implemented over the top of the
existing protocol infrastructure.
The problem of partial writes seen from an application are much less of
a headache than this witch-craft and voodoo of MOVING_WRITE_BUFFERS and
working with the requirement of having to represent the same data (with
no adequate quality/test mechanism to ensure the API user is complying
with this requirement). What I mean by this is that its possible for
someone to write a seemingly well behaved application but it fails
rarely under load with no specific reason given.
It would make sense to store the previous write address, the previous
length and checksum the previous data and validate all these things in a
debugging build of OpenSSL so that no application designer could get
away with misusing the API because OpenSSL validates the usage rules.
This way the error is given at the point when the error was made not at
some unspecified point in time later.
This is not rocket science the problem with the existing design is
simply down to poor choices, probably seemed right at the time but for a
general purpose library fraught with danger.
Darryl
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [EMAIL PROTECTED]