-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
I'm creating a HTTP request with evhttp_request_new
, which is made using a HTTP connection associated to a bufferevent. As I understand, this will ultimately trigger an event chain in bufferevent, which can invoke events even after we call evhttp_connection_free
(which in turn calls bufferevent_free
). If I'm not mistaken, this is also true even if we are doing evhttp_connection_free_on_completion
, to avoid manually freeing stuff.
You can see my code here, which is based on this sample.
As you can see in the code, to keep things simple, I am storing all mbedtls context in a struct that is passed as an argument to evhttp_request_new
. This allows for a context-free rest header.
Then, my first idea was to free that context later in its callback, which will cause a crash because of the mentioned chain of events that might be invoked after the callback and even after evhttp_connection_free
. This is the context:
typedef struct {
mbedtls_x509_crt cacert;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
mbedtls_ssl_config config;
struct bufferevent *bev;
struct evhttp_connection *evcon;
mbedtls_dyncontext *ssl;
} mbedtls_ctx_t;
Specifically, the crash is happening because of doing this...:
mbedtls_x509_crt_free(&ctx->cacert);
mbedtls_ssl_config_free(&ctx->config);
mbedtls_ctr_drbg_free(&ctx->ctr_drbg);
mbedtls_entropy_free(&ctx->entropy);
free(ctx);
...before, internally, the library executing bufferevent_finalize_cb_
, which is calling some destruct pointer function that ends up calling bufferevent_mbedtls_dyncontext_free
.
To solve this, I ended up adding a new callback that is executed once bufferevent has finished all of its chain of events (I think) and once bufferevent_mbedtls_dyncontext_free
has been executed by the library (that's for sure). See the patch here.
Is this a good approach to solve this problem or am I overkilling it?