On 5/10/2011 2:10 AM, John Hollingum wrote:

I have a service written in Perl, running on Linux that presents a very
simple SSL listener. When this service is hit, it identifies the
connecting node from its certificate/peer address and just sends some
xml to them containing data from some files in the queue directory that
contains their data.

All the client does is to open a socket and start reading.

This works, but it is susceptible to problems which I believe are caused
by clients with bad internet connections (the pathology suggests this).
It seems that something unpleasant occurs in the SSL handshake process
which causes the socket to hang indefinitely. Nobody else can connect
when this has happened.

Well, that's what happens if you take a single-threaded listener and tell it complete the SSL handshake.

But that's all a distraction. The fact is that the service shouldn't be
susceptible to the vagaries of what stupid clients or bad networks do.

Right, that's why a single-threaded listener that *ever* waits for a client is a terrible design.

Pretty much immediately after the accept the program forks a handler,
but the rogue clients must be glomming onto the main process before the
SSL negotiation is complete.

Calling 'fork' with an accepted SSL connection has all kinds of known issues. The fundamental problem is that there are many operations that must occur both before and after the 'fork', for different reasons, and obviously can't do both.

I can't help thinking that I should be able to tell SSL to have some
sensible (fairly aggressive) timeouts on connections that fail to
complete an SSL handshake. Is this possible? Does it sound like I'm even
identifying the problem correctly?

It wouldn't help, since it's not SSL that needs to time out but the socket itself. If you want to timeout the socket operations, you have to do it. OpenSSL just reads and writes to and from the BIOs and thus the socket.

I'm wondering if I could get more control by using accept in
non-blocking mode. Is this worth looking into?

That would help if your issue was blocking in 'accept'. Since you are a single-threaded listener that has to handle multiple clients, why are you doing *anything* with blocking sockets calls? That's an obvious red flag.

Blocking socket operations only exist to allow sockets to behave like terminals or files for applications that don't know anything specific about sockets. Your application not only is sockets-specific fundamentally but has to do something very unusual that requires non-blocking operations.

Timeouts are a possible fix, so long as you only accept connections from trusted clients in the first place. Otherwise, you create a trivial DoS attack.

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