Topic: Code improvement suggestion for dynamic output buffer: wolfssl-3.9.0

Hello and thanks for your work on wolfSSL!

I have one suggestion for your current code:
in the internal.c file
SendBuffered method ends with these 3 lines:

    if (ssl->buffers.outputBuffer.dynamicFlag)
         ShrinkOutputBuffer(ssl);

    return 0;

It looks like shrinking the output buffer here is not a best idea here; I just commented out these two lines:

    if (ssl->buffers.outputBuffer.dynamicFlag)
         ShrinkOutputBuffer(ssl);

and got much better performance.

What you are doing right now is allocating and deleting the output buffer on every write operation. When commenting out these two lines, you will only delete and allocate when your new write needs a bigger buffer than you already have. Good optimization. This is helpful when you are sending out variable-size chunks. Also, it allows us to send directly from your output buffer (we are using callbacks, of course, for reading and for writing, because we use overlapped socket IO with completion ports). With the current code one must copy from your output buffer to his own buffer inside of his write callback.

Hope this makes sense to you and please correct me if I am wrong.

Dude 777

Share

Re: Code improvement suggestion for dynamic output buffer: wolfssl-3.9.0

Hi,

Thanks for looking at and working with wolfSSL!

By default, wolfSSL uses dynamic Input/Output buffers that start at 5 bytes each then grow and shrink as necessary to accommodate SSL/TLS/DTLS records.  Shrinking the buffer back down after use is done in order to minimize dynamic resource use.  On many embedded systems, that same heap memory could potentially need to be used by other tasks/areas of the app.

Now, moving past our default configuration, we have several ways that I/O memory usage can be customized by the user which may be helpful if trying to optimize for minimum resource use, performance, or to align to design/project requirements.  Some of those include:

1.  Custom Memory Handlers - wolfSSL includes a memory abstraction layer that allows users to write and register their own malloc, realloc, and free functions.  You can define XMALLOC, XFREE, and XREALLOC to your own custom functions.  Using this, you could write your own memory functions that watch for the DYNAMIC_TYPE_IN_BUFFER and DYNAMIC_TYPE_OUT_BUFFER heap hints.  This would let you allocate one memory block for each and hand the same buffer back if the allocator requests it.  In your case, if you wanted to skip shrinking the buffer, your custom realloc() function could opt to not free that buffer.

2.  Defining LARGE_STATIC_BUFFERS when compiling wolfSSL dynamically allocates a fixed size 17K Input buffer and a fixed size 17K output buffer, increasing the size of the WOLFSSL object by about 34K. The maximum TLS record size is 16K plus some overhead, so LARGE_STATIC_BUFFERS allows someone to get all possible memory upfront and not have to worry about a low memory situation during the handshake for example.

Best Regards,
Chris