Darryl Miles wrote:

> > Kernel objects are the exception, only because we cannot allow a
> > program
> > (broken or valid) to screw up kernel objects. So the kernel has no
> > choice
> > but to "overserialize".

> FYI modern kernel's do not need to serialize (let alone
> "overserialize",
> whatever that means, is that a computer science term?).  I.e. the
> read()
> write() code paths for the same file-descriptor/handle can be called
> simultaneously from two or more threads without any harm to the kernel.

The kernel must be designed such that a non-privileged application can do
anything, even things that don't make logical sense, without harm to the
kernel. So the kernel has to handle even cases that make no sense at all,
such as two concurrent multi-byte 'write' operations to the same TCP socket.
It does this by extensive internal synchronization code that would normally
not be required.

Because OpenSSL doesn't have this issue, there is no reason it should have
that type of synchronization. As has already been pointed out in this
thread, it is perfectly fine if OpenSSL crashes if there are two concurrent
SSL_write calls to the same SSL connection. There is no sensible reason to
do that, and OpenSSL has nothing to defend (like the kernel does). So making
this work would be overserialization -- locking just to "permit" what is not
sane anyway.

> Sure fine grained serialization of the workings inside the kernel
> might take place, but thats is implementation detail, irrelevant to the
> contract the kernel API provides its users.

The contract the kernel API provides is that nothing the user does can mess
the kernel up, even if the user does something insane.
 
> This is merely a result of prudent multi-threaded coding inside the
> kernel presumably as a result of a "performance centric usage case"
> that
> customers/users want.

No, it's kernel self-defense. User-space libraries generally do not have
that kind of self defense. Try to read from a string in one thread while you
write to it in another and see what happens.
 
> I advocate that some users would find it useful to be able to invoke
> SSL_read() and SSL_write() from exactly two threads on the same 'SSL *'
> simultaneously.  There is merit in this and as things stands OpenSSL
> does not allow it due to a design choice (aka "design limitation").

Right, but it's due to the fact that OpenSSL is like pretty much every other
thread-safe library. It doesn't permit concurrent access to the same object
from multiple threads unless that's a pure read access that doesn't change
any state. The lack of a useful feature that is atypical of libraries is not
a design flaw or unusual quirk.

> There is no reason why OpenSSL can not allow two threaded operation if
> it were designed differently.  So I stand by my usage of the word
> "limitation".

Fine, it's a limitation of OpenSSL that it's like pretty much every other
thread-safe, user-space library.
 
> >> Your application then also has to evaluate its intent to send data,
> you
> >> don't always have something more to send.  If you do then you need
> to
> >> indicate to the OS to wake me up if I can push more data down into
> the
> >> kernel buffer.

> > No, that is not how OpenSSL works.
 
> Who was talking about OpenSSL here ?  "Your application ...." is the
> clue here, see if you can get a clue, try reading it again in context
> was the topic being discussed.

You were talking about how an application interacts with OpenSSL (look back
two paragraphs from the one you quoted). And that's not how an application
interacts with OpenSSL. You do not go to the OS when you want to do
something, like you would with TCP.

An application that wants to write data to an SSL connection calls SSL_write
whether or not it is possible to send data on the underlying SSL connection.
An application that wants to read data from an SSL connection calls SSL_read
whether or not there's data available to be read on the socket.

As I explained, operating as you describe will cause deadlocks. The data you
are waiting for may have already arrived and been processed by OpenSSL. An
OpenSSL-using application should not try to "look through" the SSL state
machine except when told to look at the socket by OpenSSL (by
WANT_READ/WANT_WRITE indications).

And, to be helpful, I would suggest that the simplest solution for your
application, assuming it doesn't need to handle large numbers of SSL
connections, would be to wrap the SSL connection in a service thread. That
service thread would have its own read/write state machine that tracks the
SSL state machine, issues SSL_read/SSL_write operations, blocks on the
socket when told to do so by OpenSSL, and so on. That way, you can emulate
blocking read/write operations if you want (blocking until the service
thread wakes you).

DS



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to