Martin,
 
Just one caution with changing the buffer sizes. During handshake, if the SSL engine gets a certificate chain, you should have space to handle it! If you do the changes I have done you may not even have to worry about changing the buffer sizes.
 
I use memory BIOS, and the way you free the buffers and allocate them may depend on the BIO you use. When you do SSL_connect or SSL_accept, you could know whether the handshake is complete from the function SSL_is_init_finished(pSSL_m). While doing handshake, you could feed the received data to SSL engine and call SSL_connect or SSL_accept based on the client or server. You could use "SSL_get_error(pSSL_m, n)" to see whether the handshake is complete after calling SSL_connect/SSL_accept. The prototype code would look like this:
 
1. Receive data
2. Check whether the connection is complete by calling SSL_is_init_finished(pSSL_m).
3. If no, feed the data to SSL engine and call SSL_accept or SSL_connect and then call SSL_get_error. If SSL_get_error returns SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE handshake is still in progress or else the handshake is complete and you could free the buffer.
 
The tricky part is to handle boundary conditions. When you act as a server, you want to make sure to check whether the handshake is complete once you have flushed the last finished message. Also, when you act as a client you got to make sure to check the state after you have received the last finished message.
 
You could apply similar strategy when you send or receive application data.
 
You also have to handle the case with SSLv2 (the easiet thing is to disable SSLv2).
 
These changes may sound complicated. However, they are very easy to do. Just to give you confidence, I was able to do these changes within a day!
 
-Prashant.
 
 
Martin Del Vecchio <[EMAIL PROTECTED]> wrote:

Thanks for getting back to me.

I understand your strategy, and I like it a lot, and I have started to implement it.  I was hoping
that you could point out all the places in OpenSSL that I need to check, to save me a little
of the grief.

Where are you calling SSL_is_init_finished() to determine if the handshake is complete?  In
SSL_accept() and SSL_connect()?  Couldn't you also check the return codes in those functions,
and say that (for example) when SSL_accept() returns 1, that the handshake is complete?

Similarly, In SSL_read() and SSL_write(), I am testing the return codes; when each returns
success (> 0), I believe it is safe to free the corresponding buffer.

Also, if you still want to decrease the size of the buffers, here is what I have found and
tested:

1) On the write side, the buffer simply doesn't need to be 16384 bytes + all the padding.  I
   took the definition for SSL3_RT_MAX_PLAIN_LENGTH (16384) and split it into two; one for
   Tx and one for Rx.  I changed the Tx value to 2048, and now my code sends records of 2048
   bytes max, instead of 16384.

2) As for the padding; both the Tx and Rx buffers add 1024 bytes for compression expansion:

   #define SSL3_RT_MAX_ENCRYPTED_LENGTH   (1024+SSL3_RT_MAX_COMPRESSED_LENGTH)

   There is a build option called OPENSSL_NO_COMP.  It is not very well supported, so once I
   turned it on, I had to fix a lot of compiler errors and warnings.  But once I got that
   fixed, I changed this definition so that it doesn't add the 1024 bytes if compression is
   disabled.  So there's another 2048 bytes/connection.

These changes are less important given your strategy.  But I plan to implement both so that I
don't have to port to MatrixSSL. 

Thanks again!






-----Original Message-----
From: Prashant Kumar [mailto:[EMAIL PROTECTED]]
Sent: Mon 9/26/2005 10:09 AM
To: Martin Del Vecchio; openssl-users@openssl.org
Subject: Re: SSL per session memory usage

Martin,

When I was looking at this, I found that the OpenSsl code uses s3->rbuf and s3->wbuf as scratch buffer. So, what I found is that, once the handshake is complete I could free these buffers safely until we have to send/receive any data on that SSL session. I reallocate s3->rbuf and s3->wbuf when I have to receive/send data on that session and free them as soon as the operation is over. I allocate these buffers from my memory pool which reduces any overhead associated with allocating and freeing buffers.

The changes I have done to achieve this are completely outside the OpenSsl code because I wanted to keep changes to OpenSsl minimum. However, OpenSsl code could be changed to have the same behavior.

You could use the function SSL_is_init_finished(pSSL_m) to determine whether the handshake is complete or not.

Look at the function "ssl3_setup_buffers" to see how these buffers are allocated.

Hopefully, this is helpful. Please feel free to send me a mail if you have more questions.

- Prashant.


Martin Del Vecchio <[EMAIL PROTECTED]> wrote:
In May, you posted a series of messages to the openssl-dev mailing list about per-session memory usage.

I am running into the exact same problems, and I would love to get your patches to try them out.

Thanks.


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


Yahoo! for Good
Click here to donate to the Hurricane Katrina relief effort.

Reply via email to