aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2006-05-30 06:14:23 +0000
committerMartin Willi <martin@strongswan.org>2006-05-30 06:14:23 +0000
commitdb66c624bfbc2d7a827b6433a64f53e5ecc1a5b6 (patch)
treee2f29d07816a6ee438ad3f17b880a4c75be60cc6
parent139ce7871f1a1117ea1c71ec170b7b35698cea48 (diff)
downloadstrongswan-db66c624bfbc2d7a827b6433a64f53e5ecc1a5b6.tar.bz2
strongswan-db66c624bfbc2d7a827b6433a64f53e5ecc1a5b6.tar.xz
- fixed daemon destruction order to prevent
crashes on termination
-rw-r--r--src/charon/daemon.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index c3d7ed766..f04595eed 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -196,30 +196,36 @@ static void initialize(private_daemon_t *this)
*/
static void destroy(private_daemon_t *this)
{
- if (this->public.ike_sa_manager != NULL)
- {
- this->public.ike_sa_manager->destroy(this->public.ike_sa_manager);
- }
- if (this->public.kernel_interface != NULL)
- {
- this->public.kernel_interface->destroy(this->public.kernel_interface);
- }
+ /* destruction is a non trivial task, we need to follow
+ * a strict order to prevent threading issues!
+ * Kill active threads first, except the sender, as
+ * the killed IKE_SA want to send delete messages.
+ */
if (this->public.receiver != NULL)
- {
+ { /* we don't want to receive anything... */
this->public.receiver->destroy(this->public.receiver);
}
+ if (this->public.stroke != NULL)
+ { /* ignore all incoming user requests */
+ this->public.stroke->destroy(this->public.stroke);
+ }
if (this->public.scheduler != NULL)
- {
+ { /* stop scheduing jobs */
this->public.scheduler->destroy(this->public.scheduler);
}
- if (this->public.sender != NULL)
- {
- this->public.sender->destroy(this->public.sender);
- }
if (this->public.thread_pool != NULL)
- {
+ { /* stop processing jobs */
this->public.thread_pool->destroy(this->public.thread_pool);
}
+ if (this->public.ike_sa_manager != NULL)
+ { /* shut down manager with all IKE SAs */
+ this->public.ike_sa_manager->destroy(this->public.ike_sa_manager);
+ }
+ if (this->public.kernel_interface != NULL)
+ { /* all child SAs should be down now, so kill kernel interface */
+ this->public.kernel_interface->destroy(this->public.kernel_interface);
+ }
+ /* destroy other infrastructure */
if (this->public.job_queue != NULL)
{
this->public.job_queue->destroy(this->public.job_queue);
@@ -228,14 +234,6 @@ static void destroy(private_daemon_t *this)
{
this->public.event_queue->destroy(this->public.event_queue);
}
- if (this->public.send_queue != NULL)
- {
- this->public.send_queue->destroy(this->public.send_queue);
- }
- if (this->public.socket != NULL)
- {
- this->public.socket->destroy(this->public.socket);
- }
if (this->public.configuration != NULL)
{
this->public.configuration->destroy(this->public.configuration);
@@ -252,9 +250,19 @@ static void destroy(private_daemon_t *this)
{
this->public.policies->destroy(this->public.policies);
}
- if (this->public.stroke != NULL)
+ /* we hope the sender could send the outstanding deletes, but
+ * we shut down here at any cost */
+ if (this->public.sender != NULL)
{
- this->public.stroke->destroy(this->public.stroke);
+ this->public.sender->destroy(this->public.sender);
+ }
+ if (this->public.send_queue != NULL)
+ {
+ this->public.send_queue->destroy(this->public.send_queue);
+ }
+ if (this->public.socket != NULL)
+ {
+ this->public.socket->destroy(this->public.socket);
}
free(this);
}