diff options
author | Martin Willi <martin@revosec.ch> | 2012-01-02 15:40:31 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-03-20 17:31:31 +0100 |
commit | 3a925f74ab3cc43bafa409b89feaa32caeb33364 (patch) | |
tree | 22dbb61589d391aa028ff6137c274841c6672561 | |
parent | 07202a2bf1b4caf3ceabe016128c890ec27ccb91 (diff) | |
download | strongswan-3a925f74ab3cc43bafa409b89feaa32caeb33364.tar.bz2 strongswan-3a925f74ab3cc43bafa409b89feaa32caeb33364.tar.xz |
Do not query CHILD_SA during delete if they already expired
-rw-r--r-- | src/libcharon/control/controller.c | 2 | ||||
-rw-r--r-- | src/libcharon/kernel/kernel_handler.c | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_cache.c | 3 | ||||
-rw-r--r-- | src/libcharon/processing/jobs/delete_child_sa_job.c | 11 | ||||
-rw-r--r-- | src/libcharon/processing/jobs/delete_child_sa_job.h | 4 | ||||
-rw-r--r-- | src/libcharon/processing/jobs/inactivity_job.c | 2 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 5 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.h | 4 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/task_manager_v1.c | 7 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/informational.c | 2 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_delete.c | 41 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_delete.h | 3 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_mode.c | 2 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/task_manager_v2.c | 8 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/child_delete.c | 41 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/child_delete.h | 3 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/child_rekey.c | 2 | ||||
-rw-r--r-- | src/libcharon/sa/task_manager.h | 3 |
18 files changed, 99 insertions, 46 deletions
diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c index 4aded8f9d..11f40388f 100644 --- a/src/libcharon/control/controller.c +++ b/src/libcharon/control/controller.c @@ -368,7 +368,7 @@ METHOD(job_t, terminate_child_execute, void, charon->bus->set_sa(charon->bus, ike_sa); if (ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)) != DESTROY_ME) + child_sa->get_spi(child_sa, TRUE), FALSE) != DESTROY_ME) { charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); listener->status = SUCCESS; diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c index 51fccb1ac..aa5c4e059 100644 --- a/src/libcharon/kernel/kernel_handler.c +++ b/src/libcharon/kernel/kernel_handler.c @@ -84,7 +84,7 @@ METHOD(kernel_listener_t, expire, bool, protocol_id_names, proto, ntohl(spi), reqid); if (hard) { - job = (job_t*)delete_child_sa_job_create(reqid, proto, spi); + job = (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard); } else { diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c index 970a8a2b9..7b7a953e5 100644 --- a/src/libcharon/plugins/ha/ha_cache.c +++ b/src/libcharon/plugins/ha/ha_cache.c @@ -212,7 +212,8 @@ static status_t rekey_children(ike_sa_t *ike_sa) DBG1(DBG_CFG, "resyncing CHILD_SA using a delete"); status = ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + child_sa->get_spi(child_sa, TRUE), + FALSE); } else { diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c index bd8bb9562..ac1dfd663 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.c +++ b/src/libcharon/processing/jobs/delete_child_sa_job.c @@ -44,6 +44,11 @@ struct private_delete_child_sa_job_t { * inbound SPI of the CHILD_SA */ u_int32_t spi; + + /** + * Delete for an expired CHILD_SA + */ + bool expired; }; METHOD(job_t, destroy, void, @@ -66,7 +71,7 @@ METHOD(job_t, execute, void, } else { - ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi); + ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi, this->expired); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); } @@ -83,8 +88,7 @@ METHOD(job_t, get_priority, job_priority_t, * Described in header */ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, - protocol_id_t protocol, - u_int32_t spi) + protocol_id_t protocol, u_int32_t spi, bool expired) { private_delete_child_sa_job_t *this; @@ -99,6 +103,7 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, .reqid = reqid, .protocol = protocol, .spi = spi, + .expired = expired, ); return &this->public; diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h index fc0e2b518..be6d578bc 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.h +++ b/src/libcharon/processing/jobs/delete_child_sa_job.h @@ -50,10 +50,10 @@ struct delete_child_sa_job_t { * @param reqid reqid of the CHILD_SA, as used in kernel * @param protocol protocol of the CHILD_SA * @param spi security parameter index of the CHILD_SA + * @param expired TRUE if CHILD_SA already expired * @return delete_child_sa_job_t object */ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, - protocol_id_t protocol, - u_int32_t spi); + protocol_id_t protocol, u_int32_t spi, bool expired); #endif /** DELETE_CHILD_SA_JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c index 251b9ab03..55fc0093a 100644 --- a/src/libcharon/processing/jobs/inactivity_job.c +++ b/src/libcharon/processing/jobs/inactivity_job.c @@ -108,7 +108,7 @@ METHOD(job_t, execute, void, { DBG1(DBG_JOB, "deleting CHILD_SA after %d seconds " "of inactivity", this->timeout); - status = ike_sa->delete_child_sa(ike_sa, proto, delete); + status = ike_sa->delete_child_sa(ike_sa, proto, delete, FALSE); } } if (status == DESTROY_ME) diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 442eb7208..e5b2f8f66 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1256,9 +1256,10 @@ METHOD(ike_sa_t, rekey_child_sa, status_t, } METHOD(ike_sa_t, delete_child_sa, status_t, - private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi) + private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi, bool expired) { - this->task_manager->queue_child_delete(this->task_manager, protocol, spi); + this->task_manager->queue_child_delete(this->task_manager, + protocol, spi, expired); return this->task_manager->initiate(this->task_manager); } diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index e50356451..c5bf60b5d 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -845,11 +845,13 @@ struct ike_sa_t { * * @param protocol protocol of the SA * @param spi inbound SPI of the CHILD_SA + * @param expired TRUE if CHILD_SA is expired * @return * - NOT_FOUND, if IKE_SA has no such CHILD_SA * - SUCCESS, if delete message sent */ - status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi); + status_t (*delete_child_sa)(ike_sa_t *this, protocol_id_t protocol, + u_int32_t spi, bool expired); /** * Destroy a CHILD SA with the specified protocol/SPI. diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index ea4cb8a1b..3a6cf5163 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1141,7 +1141,7 @@ METHOD(task_manager_t, queue_ike_delete, void, { queue_task(this, (task_t*) quick_delete_create(this->ike_sa, child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE), FALSE)); + child_sa->get_spi(child_sa, TRUE), FALSE, FALSE)); } enumerator->destroy(enumerator); @@ -1190,10 +1190,11 @@ METHOD(task_manager_t, queue_child_rekey, void, } METHOD(task_manager_t, queue_child_delete, void, - private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi) + private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi, + bool expired) { queue_task(this, (task_t*)quick_delete_create(this->ike_sa, protocol, - spi, FALSE)); + spi, FALSE, expired)); } METHOD(task_manager_t, queue_dpd, void, diff --git a/src/libcharon/sa/ikev1/tasks/informational.c b/src/libcharon/sa/ikev1/tasks/informational.c index 9de5c2e71..999b497dc 100644 --- a/src/libcharon/sa/ikev1/tasks/informational.c +++ b/src/libcharon/sa/ikev1/tasks/informational.c @@ -108,7 +108,7 @@ METHOD(task_t, process_r, status_t, else { this->del = (task_t*)quick_delete_create(this->ike_sa, - PROTO_NONE, 0, FALSE); + PROTO_NONE, 0, FALSE, FALSE); } } break; diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c index bb7d20bdc..9a502f58c 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.c +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c @@ -54,6 +54,11 @@ struct private_quick_delete_t { * Send delete even if SA does not exist */ bool force; + + /** + * SA already expired? + */ + bool expired; }; /** @@ -78,16 +83,29 @@ static bool delete_child(private_quick_delete_t *this, child_sa->set_state(child_sa, CHILD_DELETING); - child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in); - child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out); - - DBG0(DBG_IKE, "closing CHILD_SA %s{%d} " - "with SPIs %.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), - ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, - ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, - child_sa->get_traffic_selectors(child_sa, TRUE), - child_sa->get_traffic_selectors(child_sa, FALSE)); + if (this->expired) + { + DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} " + "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", + child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + ntohl(child_sa->get_spi(child_sa, TRUE)), + ntohl(child_sa->get_spi(child_sa, FALSE)), + child_sa->get_traffic_selectors(child_sa, TRUE), + child_sa->get_traffic_selectors(child_sa, FALSE)); + } + else + { + child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in); + child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out); + + DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs " + "%.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", + child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, + ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, + child_sa->get_traffic_selectors(child_sa, TRUE), + child_sa->get_traffic_selectors(child_sa, FALSE)); + } charon->bus->child_updown(charon->bus, child_sa, FALSE); @@ -190,7 +208,7 @@ METHOD(task_t, destroy, void, * Described in header. */ quick_delete_t *quick_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, - u_int32_t spi, bool force) + u_int32_t spi, bool force, bool expired) { private_quick_delete_t *this; @@ -206,6 +224,7 @@ quick_delete_t *quick_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, .protocol = protocol, .spi = spi, .force = force, + .expired = expired, ); if (protocol != PROTO_NONE) diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.h b/src/libcharon/sa/ikev1/tasks/quick_delete.h index 1cdf07c48..864262392 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.h +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.h @@ -46,9 +46,10 @@ struct quick_delete_t { * @param protocol protocol of CHILD_SA to delete, PROTO_NONE as responder * @param spi inbound SPI of CHILD_SA to delete * @param force send delete even if SA does not exist + * @param expired TRUE if SA already expired * @return quick_delete task to handle by the task_manager */ quick_delete_t *quick_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, - u_int32_t spi, bool force); + u_int32_t spi, bool force, bool expired); #endif /** QUICK_DELETE_H_ @}*/ diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index b9acdb054..dc0a01099 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -773,7 +773,7 @@ METHOD(task_t, process_r, status_t, this->ike_sa->queue_task(this->ike_sa, (task_t*)quick_delete_create(this->ike_sa, this->proposal->get_protocol(this->proposal), - this->spi_i, TRUE)); + this->spi_i, TRUE, TRUE)); return ALREADY_DONE; } return SUCCESS; diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 23ef054fb..36252a81d 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -825,7 +825,7 @@ static status_t process_request(private_task_manager_t *this, else { task = (task_t*)child_delete_create(this->ike_sa, - PROTO_NONE, 0); + PROTO_NONE, 0, FALSE); } break; } @@ -1308,9 +1308,11 @@ METHOD(task_manager_t, queue_child_rekey, void, } METHOD(task_manager_t, queue_child_delete, void, - private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi) + private_task_manager_t *this, protocol_id_t protocol, u_int32_t spi, + bool expired) { - queue_task(this, (task_t*)child_delete_create(this->ike_sa, protocol, spi)); + queue_task(this, (task_t*)child_delete_create(this->ike_sa, + protocol, spi, expired)); } METHOD(task_manager_t, queue_dpd, void, diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c index c5151abf1..644af782c 100644 --- a/src/libcharon/sa/ikev2/tasks/child_delete.c +++ b/src/libcharon/sa/ikev2/tasks/child_delete.c @@ -62,6 +62,11 @@ struct private_child_delete_t { bool rekeyed; /** + * CHILD_SA already expired? + */ + bool expired; + + /** * CHILD_SAs which get deleted */ linked_list_t *child_sas; @@ -247,16 +252,29 @@ static void log_children(private_child_delete_t *this) enumerator = this->child_sas->create_enumerator(this->child_sas); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { - child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in); - child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out); - - DBG0(DBG_IKE, "closing CHILD_SA %s{%d} " - "with SPIs %.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), - ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, - ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, - child_sa->get_traffic_selectors(child_sa, TRUE), - child_sa->get_traffic_selectors(child_sa, FALSE)); + if (this->expired) + { + DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} " + "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", + child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + ntohl(child_sa->get_spi(child_sa, TRUE)), + ntohl(child_sa->get_spi(child_sa, FALSE)), + child_sa->get_traffic_selectors(child_sa, TRUE), + child_sa->get_traffic_selectors(child_sa, FALSE)); + } + else + { + child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in); + child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out); + + DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs %.8x_i " + "(%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", + child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, + ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, + child_sa->get_traffic_selectors(child_sa, TRUE), + child_sa->get_traffic_selectors(child_sa, FALSE)); + } } enumerator->destroy(enumerator); } @@ -356,7 +374,7 @@ METHOD(task_t, destroy, void, * Described in header. */ child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, - u_int32_t spi) + u_int32_t spi, bool expired) { private_child_delete_t *this; @@ -373,6 +391,7 @@ child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, .child_sas = linked_list_create(), .protocol = protocol, .spi = spi, + .expired = expired, ); if (protocol != PROTO_NONE) diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.h b/src/libcharon/sa/ikev2/tasks/child_delete.h index 34d399ce3..4c8b3498a 100644 --- a/src/libcharon/sa/ikev2/tasks/child_delete.h +++ b/src/libcharon/sa/ikev2/tasks/child_delete.h @@ -52,9 +52,10 @@ struct child_delete_t { * @param ike_sa IKE_SA this task works for * @param protocol protocol of CHILD_SA to delete, PROTO_NONE as responder * @param spi inbound SPI of CHILD_SA to delete + * @param expired TRUE if CHILD_SA already expired * @return child_delete task to handle by the task_manager */ child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, - u_int32_t spi); + u_int32_t spi, bool expired); #endif /** CHILD_DELETE_H_ @}*/ diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index 50a8aad95..28de072c0 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -352,7 +352,7 @@ METHOD(task_t, process_i, status_t, protocol = to_delete->get_protocol(to_delete); /* rekeying done, delete the obsolete CHILD_SA using a subtask */ - this->child_delete = child_delete_create(this->ike_sa, protocol, spi); + this->child_delete = child_delete_create(this->ike_sa, protocol, spi, FALSE); this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_delete; this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_delete; diff --git a/src/libcharon/sa/task_manager.h b/src/libcharon/sa/task_manager.h index 5602069b1..b49c9a96b 100644 --- a/src/libcharon/sa/task_manager.h +++ b/src/libcharon/sa/task_manager.h @@ -177,9 +177,10 @@ struct task_manager_t { * * @param protocol CHILD_SA protocol, AH|ESP * @param spi CHILD_SA SPI to rekey + * @param expired TRUE if SA already expired */ void (*queue_child_delete)(task_manager_t *this, protocol_id_t protocol, - u_int32_t spi); + u_int32_t spi, bool expired); /** * Queue liveness checking tasks. |