问题
I've written a networking server that uses OpenSSL for SSL/TLS. The server sends and receives large blocks of data and performs various transformations in between. For performance reasons, transformations are done mainly using vector information (see iovec from POSIX) that avoids expensive memory moves (memcpy() etc.). When data are ready to be sent, I use writev() POSIX function that gathers data from the memory using these vectors and it sends that usually as one network packet.
Now with OpenSSL, it is not entirely possible because OpenSSL offers only SSL_write() function as far as I know. That means I have to call this function for every vector entry I want to send. It, unfortunately, causes that every vectored chunk of data is transmitted in its own SSL frame, and that introduces unwanted and unnecessary network overhead.
My question is: Is there SSL_writev() equivalent of writev()? Or in general, is there a technique how I can tell to OpenSSL to stash SSL_write() data into a one SSL application record (type 22) without sending it (and then of course some kind of flush() function)?
Edit: As discussed below, a viable approach is to consolidate vectored data into a big chunk prior a final single SSL_write() call. There is however connected overhead with 2 copies (1st during consolidation, 2nd when SSL_write() performs AES encryption). Theoretical SSL_writev() call doesn't introduce this overhead.
回答1:
You can use a BIO_f_buffer()
to achieve this. Wrap your network layer BIO in a BIO_f_buffer()
filter BIO and set that as the write BIO for your SSL object. This will cause all data written out to stay in the buffer until you issue a flush on it.
来源:https://stackoverflow.com/questions/38198638/openssl-ssl-write-from-multiple-buffers-ssl-writev