Merge branch 'initiate-cancel'

Allow proper shutdown if a deadlock is caused by too many concurrent
blocking initiation requests.

References strongswan/strongswan#2776
This commit is contained in:
Tobias Brunner 2025-05-19 17:21:57 +02:00
commit 688b9e27d5
2 changed files with 24 additions and 12 deletions

View File

@ -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 ||

View File

@ -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;
}
}