2 * Copyright (C) 2010 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "inactivity_job.h"
20 typedef struct private_inactivity_job_t private_inactivity_job_t
;
23 * Private data of an inactivity_job_t object.
25 struct private_inactivity_job_t
{
28 * Public inactivity_job_t interface.
30 inactivity_job_t
public;
33 * Reqid of CHILD_SA to check
43 * Close IKE_SA if last remaining CHILD inactive?
48 METHOD(job_t
, destroy
, void,
49 private_inactivity_job_t
*this)
54 METHOD(job_t
, execute
, job_requeue_t
,
55 private_inactivity_job_t
*this)
58 u_int32_t reschedule
= 0;
60 ike_sa
= charon
->ike_sa_manager
->checkout_by_id(charon
->ike_sa_manager
,
64 enumerator_t
*enumerator
;
67 protocol_id_t proto
= 0;
69 status_t status
= SUCCESS
;
71 enumerator
= ike_sa
->create_child_sa_enumerator(ike_sa
);
72 while (enumerator
->enumerate(enumerator
, (void**)&child_sa
))
74 if (child_sa
->get_reqid(child_sa
) == this->reqid
)
76 time_t in
, out
, install
, diff
;
78 child_sa
->get_usestats(child_sa
, TRUE
, &in
, NULL
, NULL
);
79 child_sa
->get_usestats(child_sa
, FALSE
, &out
, NULL
, NULL
);
80 install
= child_sa
->get_installtime(child_sa
);
82 diff
= time_monotonic(NULL
) - max(max(in
, out
), install
);
84 if (diff
>= this->timeout
)
86 delete = child_sa
->get_spi(child_sa
, TRUE
);
87 proto
= child_sa
->get_protocol(child_sa
);
91 reschedule
= this->timeout
- diff
;
96 enumerator
->destroy(enumerator
);
100 if (children
== 1 && this->close_ike
)
102 DBG1(DBG_JOB
, "deleting IKE_SA after %d seconds "
103 "of CHILD_SA inactivity", this->timeout
);
104 status
= ike_sa
->delete(ike_sa
);
108 DBG1(DBG_JOB
, "deleting CHILD_SA after %d seconds "
109 "of inactivity", this->timeout
);
110 status
= ike_sa
->delete_child_sa(ike_sa
, proto
, delete, FALSE
);
113 if (status
== DESTROY_ME
)
115 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
120 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
125 return JOB_RESCHEDULE(reschedule
);
127 return JOB_REQUEUE_NONE
;
130 METHOD(job_t
, get_priority
, job_priority_t
,
131 private_inactivity_job_t
*this)
133 return JOB_PRIO_MEDIUM
;
139 inactivity_job_t
*inactivity_job_create(u_int32_t reqid
, u_int32_t timeout
,
142 private_inactivity_job_t
*this;
148 .get_priority
= _get_priority
,
154 .close_ike
= close_ike
,
157 return &this->public;