[openssl-users] Find size of available data prior to ssl_read

Michael Wojcik Michael.Wojcik at microfocus.com
Thu Dec 17 18:00:45 UTC 2015

> From: openssl-users [mailto:openssl-users-bounces at openssl.org] On Behalf
> Of counterpoint
> Sent: Thursday, December 17, 2015 11:35
> Thanks, that makes sense. My ability to optimise is constrained - the system
> is a product so I do not know what the actual pattern of usage will be. But
> there is a limit on buffer size within the system. It's a defined symbol, so
> can be altered from the default of 32 KB, but only by recompiling the
> system. I rely on a working assumption that people who change definitions
> and recompile know what they're doing.

Fair enough.

> The system is threaded, but it is designed to operate with a relatively
> small number of highly active threads, so grabbing 32 KB on the stack for a
> short period shouldn't be too much of an issue.

It's not really a matter of how many threads there are (except indirectly), or of how long the item is on the stack. It's a question of how much space is available on the thread's stack when you try to allocate the buffer (which, assuming we're talking C or C++, is when you enter the function / method).

A thread's stack size is typically set at creation time, with a default that may be fixed in the threading implementation or set at link time. How much space is available when you allocate that 32 KB buffer depends on how deep your call chain is and how much data each of those frames adds to the stack.

If the stack is too small to accommodate the buffer and can't be expanded, you'll get some kind of run-time failure, like a Windows exception or a UNIX signal.

Note that stack space is an address-space resource, not (generally) a virtual memory one - that is, stack-space is unlikely to be constrained because the system is running short on virtual memory. It'll happen because most language implementations use contiguous stacks for performance (rather than, say, displays or other non-contiguous structures), and if the stack runs into something else in the process address space, it can't grow any further. So if your process is 64-bit, you should be able to specify ridiculously large thread stacks and not worry about it.

If the process is 32-bit, take a look at your thread stack sizes and do a quick estimate on how much space you expect will be there. You can determine this for a specific thread, in a specific run, in a debugger by looking at the address of an automatic variable at the bottom of the thread's stack (in the thread's initial function) and the address of one in your data-receiving function. (Technically comparing those addresses isn't authorized by the language standard, but it's valid on most of the platforms OpenSSL supports.)

So I'd say try it in some test runs and see if it looks like stack space might be getting tight; if so, you can likely increase the stack size you specify when creating your threads, since you don't have many of them.

> One remaining point leaves me uncertain. Supposing an SSL write gets the
> response SSL_ERROR_WANT_READ. Then there is a POLLIN event. I take it
> the
> first thing that must happen is a retry of the write. Assuming that works,
> do I need to assume that there could be data to be read?  Or will a further
> event occur, so that I should return to looking out for events?  I guess the
> answer to the last question is probably no, but am unsure.

There could be data to be read. Consider this scenario:

1. The peer decides it wants to renegotiate during the conversation.
2. In the middle of the handshake, you call SSL_write. The handshake hasn't completed, and the local side is waiting for a message from the peer, so SSL_write returns SSL_ERROR_WANT_READ.
3. You wait for POLLIN, then call SSL_write again.
4. Before SSL_write returns, the peer has time to respond to the request you just sent. Or it sends something else immediately after completing the handshake, if your application doesn't use a strict switched-duplex request-response protocol.

So I'd recommend going ahead and trying a non-blocking SSL_read at that point. The overhead is tiny and you won't miss any inbound-data events.

Michael Wojcik
Technology Specialist, Micro Focus

More information about the openssl-users mailing list