diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c index 027f48e93..4e778ed63 100644 --- a/src/libcharon/control/controller.c +++ b/src/libcharon/control/controller.c @@ -400,6 +400,8 @@ METHOD(job_t, destroy_job, void, { this->listener.lock->destroy(this->listener.lock); DESTROY_IF(this->listener.done); + DESTROY_IF(this->listener.child_cfg); + DESTROY_IF(this->listener.peer_cfg); free(this); } } @@ -416,14 +418,11 @@ METHOD(job_t, initiate_execute, job_requeue_t, { ike_sa_t *ike_sa; interface_listener_t *listener = &job->listener; - peer_cfg_t *peer_cfg = listener->peer_cfg; ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, - peer_cfg); - peer_cfg->destroy(peer_cfg); + listener->peer_cfg); if (!ike_sa) { - DESTROY_IF(listener->child_cfg); listener->status = FAILED; listener_done(listener); return JOB_REQUEUE_NONE; @@ -449,7 +448,6 @@ METHOD(job_t, initiate_execute, job_requeue_t, "%d exceeds limit of %d", half_open, limit_half_open); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); - DESTROY_IF(listener->child_cfg); listener->status = INVALID_STATE; listener_done(listener); return JOB_REQUEUE_NONE; @@ -468,7 +466,6 @@ METHOD(job_t, initiate_execute, job_requeue_t, "limit of %d", jobs, limit_job_load); charon->ike_sa_manager->checkin_and_destroy( charon->ike_sa_manager, ike_sa); - DESTROY_IF(listener->child_cfg); listener->status = INVALID_STATE; listener_done(listener); return JOB_REQUEUE_NONE; @@ -476,6 +473,10 @@ METHOD(job_t, initiate_execute, job_requeue_t, } } + if (listener->child_cfg) + { + listener->child_cfg->get_ref(listener->child_cfg); + } if (ike_sa->initiate(ike_sa, listener->child_cfg, NULL) == SUCCESS) { if (!listener->logger.callback || diff --git a/src/libcharon/plugins/vici/vici_socket.c b/src/libcharon/plugins/vici/vici_socket.c index 39d34e4d3..1016633ab 100644 --- a/src/libcharon/plugins/vici/vici_socket.c +++ b/src/libcharon/plugins/vici/vici_socket.c @@ -480,6 +480,15 @@ static bool do_read(private_vici_socket_t *this, entry_t *entry, return TRUE; } +/** + * Clear the given chunk and free it + */ +static void destroy_request_chunk(chunk_t *chunk) +{ + chunk_clear(chunk); + free(chunk); +} + /** * Callback processing incoming requests in strict order */ @@ -487,7 +496,7 @@ CALLBACK(process_queue, job_requeue_t, entry_selector_t *sel) { entry_t *entry; - chunk_t chunk; + chunk_t *chunk; bool found; u_int id; @@ -499,7 +508,8 @@ CALLBACK(process_queue, job_requeue_t, break; } - found = array_remove(entry->queue, ARRAY_HEAD, &chunk); + INIT(chunk); + found = array_remove(entry->queue, ARRAY_HEAD, chunk); if (!found) { entry->has_processor = FALSE; @@ -508,11 +518,12 @@ CALLBACK(process_queue, job_requeue_t, put_entry(sel->this, entry, TRUE, FALSE); if (!found) { + free(chunk); break; } - thread_cleanup_push((void*)chunk_clear, &chunk); - sel->this->inbound(sel->this->user, id, chunk); + thread_cleanup_push((void*)destroy_request_chunk, chunk); + sel->this->inbound(sel->this->user, id, *chunk); thread_cleanup_pop(TRUE); } return JOB_REQUEUE_NONE; @@ -552,8 +563,8 @@ CALLBACK(on_read, bool, .id = entry->id, ); lib->processor->queue_job(lib->processor, - (job_t*)callback_job_create(process_queue, - sel, free, NULL)); + (job_t*)callback_job_create(process_queue, sel, + free, callback_job_cancel_thread)); entry->has_processor = TRUE; } }