Rajeswari K wrote:
In our application we open "non blocking socket" for read and write
operation and pass the fd to openssl through BOI API's like this
bio = BIO_new(BIO_s_socket());
BIO_set_fd(bio, socket_fd, BIO_NOCLOSE);
And
we update this bio to SSL using SSL_set_bio() function.
My query is do we need to update SSL_CTX with these modes when we use
"non blocking sockets"?
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
Or without setting this also non blocking sockets work?
If you want belt and braces approach then set both of these flags, since
setting them will not cause any observable effect that you don't already
deal with(*) and will provide peace of mind over the question.
NOTE(*) non-blocking already deals with partial write concerns, which
you may see if you are trying to send large enough buffers (around
>16Mb/>32Mb)
Did you research this already ?
http://markmail.org/message/coiqiqkuim3k4ys5 [read the whole thread]
Obviously the emails above relate to the version of OpenSSL at the time.
Basically the purpose of SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is more
folklore than any practical purpose.
I would be grateful if someone can counter my statement above by citing
where openssl changes behaviour (somewhere other than the self-serving
error return, explained below) based on
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER being set/not-set.
Naive proof of my claim (along with some details of why) :
[openssl-1.0.1f]$ find -type f -exec fgrep -Hn
"ACCEPT_MOVING_WRITE_BUFFER" {} \;
./CHANGES:8746: SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist
that SSL_write
./ssl/s2_pkt.c:478: !(s->mode &
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
./ssl/ssl.h:637:#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
./ssl/s3_pkt.c:868: !(s->mode &
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
./doc/ssl/SSL_CTX_set_mode.pod:44:=item SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
If you take a look at the *.c code, there is a self-serving check there.
When you don't set this flag you might get an error, when you do set
this flag you never get the error.
Now the challenge is to find the line of code that actively does
something different when the SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER flag is
changed (other than the lines I point out above).
It is possible there is a magic number check for s->mode somewhere in
the code. If there is such a thing this code should be changed (to use
macro as value!) and better documented, by using
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER instead of the magic number 0x00000002L.
Otherwise all applications should set
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER and the true purpose of this flag is
to "suppress the self-serving error check".
My claim is there is no other active purpose of this flag.
This would mean the lines I point out above can be safely removed from
the OpenSSL project. Removing the *.h macro definition will break
peoples code so I guess in another 15 years a new major release might be
rolled to do this.
[openssl-1.0.1f]$ find -type f -exec fgrep -Hn "ENABLE_PARTIAL_WRITE" {} \;
./demos/easy_tls/easy-tls.c:667: SSL_CTX_set_mode(ret,
SSL_MODE_ENABLE_PARTIAL_WRITE);
./CHANGES:8744: SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to
report success when
./ssl/s2_pkt.c:458: (s->mode &
SSL_MODE_ENABLE_PARTIAL_WRITE))
./ssl/ssl.h:632:#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L
./ssl/s3_pkt.c:618: (s->mode &
SSL_MODE_ENABLE_PARTIAL_WRITE)))
./doc/ssl/SSL_write.pod:53:can be changed with the
SSL_MODE_ENABLE_PARTIAL_WRITE option of
./doc/ssl/SSL_CTX_set_mode.pod:35:=item SSL_MODE_ENABLE_PARTIAL_WRITE
This one is more tricky to understand why it is also a nonsense feature
the SSL_MODE_ENABLE_PARTIAL_WRITE only makes sense for blocking sockets.
With non-blocking socket the do_ssl3_write() call that takes place will
return -1/WANT_WRITE and cause immediate return, or it will take an
amount of data presented to it that maybe clipped by the
s->max_send_fragment size.
Non-blocking I/O accepts that partial writes are normal when flow
control is engaged stopping data from being pushed down to lower layers.
But with a blocking socket, it is possible for the kernel (or lower
level BIO) to accept a smaller amount of data out of some larger size
presented to write. The first attempt to write to the blocking socket
will block. (for an indeterminate amount of time - the definition of
blocking).
This is kind of an instruction to flush some more data, but only give
the lower layer one chance to take what it can, then return control back
to caller. But this chance has the right to block.
This feature serves no obvious (to me at least!) useful purpose.
An application programmer either wants non-blocking or is happy to block
until the entire write being performed is complete.
Why would a programmer want blocking with partial write ? This feature
is nonsense. Blocking partial writes only make sense when the
application programmer can control how long the API call will block for
by passing a timeout value. Now that would be a useful feature with
practical purpose.
Note also that SSL uses chunking, it is not possible to send huge
(>32Mb) writes as one fragment (by the protocol size/record length
limitations).
So another caveat of turning it on might be that if you are sending huge
writes you observe each write you may hit maximum SSL record length
limits and return control back to the application.
Again this is not a useful feature but something that maybe observable
if you watch closely.
HTH
--
Darryl
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org