In this sample code:
BIO *bio1 = BIO_new(BIO_s_mem());
BIO *bio2 = BIO_new(BIO_s_mem());
SSL_set_bio(ssl, bio1, bio1开发者_JAVA技巧);
SSL_set_bio(ssl, bio2, bio2);
the last call to SSL_set_bio automatically calls BIO_free(bio1). Is there anyway to tell OpenSSL not to do so?
I know that upon creating a memory bio with BIO_new(BIO_s_mem()) I can tell OpenSSL not to free it's memory buffer with BIO_set_close(bio, BIO_NOCLOSE). Is there anything similar for my case?
There's no way to prevent SSL_set_bio
from freeing the current BIO in the public API. You can see in the source code that it simply checks whether each bio is not null and then frees it.
The main idea is that after you call SSL_set_bio
, OpenSSL owns the BIO and is responsible for it.
void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
{
/* If the output buffering BIO is still in place, remove it
*/
if (s->bbio != NULL)
{
if (s->wbio == s->bbio)
{
s->wbio=s->wbio->next_bio;
s->bbio->next_bio=NULL;
}
}
if ((s->rbio != NULL) && (s->rbio != rbio))
BIO_free_all(s->rbio);
if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
BIO_free_all(s->wbio);
s->rbio=rbio;
s->wbio=wbio;
}
If I had a legitimate reason to keep the bio buffer around in production code, I would write my own bio and use that. It's not as hard as it sounds. Just copy <openssl source>/crypto/bio/bss_mem.c
, rename the functions and mem_method
table, and then replace the behavior of mem_free()
. Then instead of BIO_s_mem
, pass BIO_custom_mem_bio
or whatever you name the accessor function for your bio.
If I needed it for debugging purposes and not production code, I'd probably just grovel into the internals of the ssl_st
struct (SSL *
) and make all the bios NULL before calling SSL_set_bio
. But I wouldn't do that in production code because future SSL versions may break that code.
You can use BIO_up_ref()
to increase the reference count.
BIO_free()
would decrease the count, but not free it.
精彩评论