From: Tobias Brunner Date: Tue, 26 Nov 2013 13:47:28 +0000 (+0100) Subject: ike: Mark child-creating tasks if they are recreating CHILD_SAs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9731839dbe1a407e089d4ef3277d3cf40269aa45;p=thirdparty%2Fstrongswan.git ike: Mark child-creating tasks if they are recreating CHILD_SAs --- diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index f373675320..114783e4b0 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -596,7 +596,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, * Initiate */ child_cfg->get_ref(child_cfg); - if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) + if (ike_sa->initiate(ike_sa, child_cfg, 0, FALSE, NULL, NULL) != SUCCESS) { charon->bus->remove_listener(charon->bus, &priv->listener); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/jni/libandroidbridge/backend/android_service.c index ccf5ce8e72..9b0bb0f8a7 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_service.c @@ -612,7 +612,7 @@ static job_requeue_t initiate(private_android_service_t *this) /* get an additional reference because initiate consumes one */ child_cfg->get_ref(child_cfg); - if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) + if (ike_sa->initiate(ike_sa, child_cfg, 0, FALSE, NULL, NULL) != SUCCESS) { DBG1(DBG_CFG, "failed to initiate tunnel"); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c index c546da5446..1424859c79 100644 --- a/src/libcharon/control/controller.c +++ b/src/libcharon/control/controller.c @@ -361,7 +361,8 @@ METHOD(job_t, initiate_execute, job_requeue_t, } peer_cfg->destroy(peer_cfg); - if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS) + if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, FALSE, + NULL, NULL) == SUCCESS) { if (!listener->logger.callback) { diff --git a/src/libcharon/plugins/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c index f0f3105c4b..9716bdbf0c 100644 --- a/src/libcharon/plugins/maemo/maemo_service.c +++ b/src/libcharon/plugins/maemo/maemo_service.c @@ -382,7 +382,7 @@ static gboolean initiate_connection(private_maemo_service_t *this, /* get an additional reference because initiate consumes one */ child_cfg->get_ref(child_cfg); - if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) + if (ike_sa->initiate(ike_sa, child_cfg, 0, FALSE, NULL, NULL) != SUCCESS) { DBG1(DBG_CFG, "failed to initiate tunnel"); charon->bus->remove_listener(charon->bus, &this->public.listener); diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index d482f8b49c..15298a9dd7 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1152,7 +1152,7 @@ static void resolve_hosts(private_ike_sa_t *this) METHOD(ike_sa_t, initiate, status_t, private_ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid, - traffic_selector_t *tsi, traffic_selector_t *tsr) + bool recreate, traffic_selector_t *tsi, traffic_selector_t *tsr) { bool defer_initiate = FALSE; @@ -1221,7 +1221,7 @@ METHOD(ike_sa_t, initiate, status_t, { /* normal IKE_SA with CHILD_SA */ this->task_manager->queue_child(this->task_manager, child_cfg, reqid, - tsi, tsr); + recreate, tsi, tsr); #ifdef ME if (this->peer_cfg->get_mediated_by(this->peer_cfg)) { @@ -1254,7 +1254,7 @@ METHOD(ike_sa_t, retry_initiate, status_t, if (this->retry_initiate_queued) { this->retry_initiate_queued = FALSE; - return initiate(this, NULL, 0, NULL, NULL); + return initiate(this, NULL, 0, FALSE, NULL, NULL); } return SUCCESS; } @@ -1676,7 +1676,7 @@ METHOD(ike_sa_t, reestablish, status_t, #ifdef ME if (this->peer_cfg->is_mediation(this->peer_cfg)) { - status = new->initiate(new, NULL, 0, NULL, NULL); + status = new->initiate(new, NULL, 0, FALSE, NULL, NULL); } else #endif /* ME */ @@ -1722,7 +1722,8 @@ METHOD(ike_sa_t, reestablish, status_t, child_cfg->get_name(child_cfg)); child_cfg->get_ref(child_cfg); status = new->initiate(new, child_cfg, - child_sa->get_reqid(child_sa), NULL, NULL); + child_sa->get_reqid(child_sa), TRUE, + NULL, NULL); break; default: continue; @@ -1740,7 +1741,7 @@ METHOD(ike_sa_t, reestablish, status_t, other_tasks->adopt_child_tasks(other_tasks, this->task_manager); if (new->get_state(new) == IKE_CREATED) { - status = new->initiate(new, NULL, 0, NULL, NULL); + status = new->initiate(new, NULL, 0, FALSE, NULL, NULL); } } } diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 00c16c05e5..377eccebab 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Tobias Brunner + * Copyright (C) 2006-2013 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -706,7 +706,8 @@ struct ike_sa_t { * to the CHILD_SA. * * @param child_cfg child config to create CHILD from - * @param reqid reqid to use for CHILD_SA, 0 assigne uniquely + * @param reqid reqid to use for CHILD_SA, 0 assign uniquely + * @param recreate TRUE if recreating a previously established CHILD_SA * @param tsi source of triggering packet * @param tsr destination of triggering packet. * @return @@ -714,8 +715,8 @@ struct ike_sa_t { * - DESTROY_ME if initialization failed */ status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg, - u_int32_t reqid, traffic_selector_t *tsi, - traffic_selector_t *tsr); + u_int32_t reqid, bool recreate, + traffic_selector_t *tsi, traffic_selector_t *tsr); /** * Retry initiation of this IKE_SA after it got deferred previously. diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 597416e36c..a038b69ec3 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1086,7 +1086,7 @@ static status_t process_request(private_task_manager_t *this, "unestablished IKE_SA, ignored"); return FAILED; } - task = (task_t *)quick_mode_create(this->ike_sa, NULL, + task = (task_t *)quick_mode_create(this->ike_sa, NULL, FALSE, NULL, NULL); this->passive_tasks->insert_last(this->passive_tasks, task); break; @@ -1715,7 +1715,7 @@ METHOD(task_manager_t, queue_ike_reauth, void, enumerator->destroy(enumerator); } - if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME) + if (new->initiate(new, NULL, 0, FALSE, NULL, NULL) != DESTROY_ME) { charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); this->ike_sa->set_state(this->ike_sa, IKE_REKEYING); @@ -1760,11 +1760,11 @@ METHOD(task_manager_t, queue_mobike, void, METHOD(task_manager_t, queue_child, void, private_task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid, - traffic_selector_t *tsi, traffic_selector_t *tsr) + bool recreate, traffic_selector_t *tsi, traffic_selector_t *tsr) { quick_mode_t *task; - task = quick_mode_create(this->ike_sa, cfg, tsi, tsr); + task = quick_mode_create(this->ike_sa, cfg, recreate, tsi, tsr); task->use_reqid(task, reqid); queue_task(this, &task->task); @@ -1859,7 +1859,7 @@ METHOD(task_manager_t, queue_child_rekey, void, { child_sa->set_state(child_sa, CHILD_REKEYING); cfg = child_sa->get_config(child_sa); - task = quick_mode_create(this->ike_sa, cfg->get_ref(cfg), + task = quick_mode_create(this->ike_sa, cfg->get_ref(cfg), FALSE, get_first_ts(child_sa, TRUE), get_first_ts(child_sa, FALSE)); task->use_reqid(task, child_sa->get_reqid(child_sa)); task->rekey(task, child_sa->get_spi(child_sa, TRUE)); diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c index 605c10cea8..00fd3c2dbb 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.c +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c @@ -149,7 +149,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, case ACTION_RESTART: child_cfg->get_ref(child_cfg); this->ike_sa->initiate(this->ike_sa, child_cfg, - child_sa->get_reqid(child_sa), NULL, NULL); + child_sa->get_reqid(child_sa), TRUE, NULL, NULL); break; case ACTION_ROUTE: charon->traps->install(charon->traps, diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 12ee594b9b..c9e30a9b46 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2013 Tobias Brunner * Hochschule fuer Technik Rapperswil * * Copyright (C) 2011 Martin Willi @@ -175,6 +175,11 @@ struct private_quick_mode_t { */ bool udp; + /** + * TRUE if recreating a previously established CHILD_SA + */ + bool recreate; + /** states of quick mode */ enum { QM_INIT, @@ -1293,6 +1298,12 @@ METHOD(quick_mode_t, rekey, void, this->rekey = spi; } +METHOD(quick_mode_t, is_recreating, bool, + private_quick_mode_t *this) +{ + return this->recreate; +} + METHOD(task_t, migrate, void, private_quick_mode_t *this, ike_sa_t *ike_sa) { @@ -1340,7 +1351,8 @@ METHOD(task_t, destroy, void, * Described in header. */ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, - traffic_selector_t *tsi, traffic_selector_t *tsr) + bool recreate, traffic_selector_t *tsi, + traffic_selector_t *tsr) { private_quick_mode_t *this; @@ -1353,6 +1365,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, }, .use_reqid = _use_reqid, .rekey = _rekey, + .is_recreating = _is_recreating, }, .ike_sa = ike_sa, .initiator = config != NULL, @@ -1362,6 +1375,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, .tsi = tsi ? tsi->clone(tsi) : NULL, .tsr = tsr ? tsr->clone(tsr) : NULL, .proto = PROTO_ESP, + .recreate = recreate, ); if (config) diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.h b/src/libcharon/sa/ikev1/tasks/quick_mode.h index 0b80cb836e..377fc96d42 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.h +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2013 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2011 Martin Willi * Copyright (C) 2011 revosec AG * @@ -50,6 +53,11 @@ struct quick_mode_t { * @param spi spi of SA to rekey */ void (*rekey)(quick_mode_t *this, u_int32_t spi); + + /** + * Whether this task recreates a previously established CHILD_SA. + */ + bool (*is_recreating)(quick_mode_t *this); }; /** @@ -57,11 +65,13 @@ struct quick_mode_t { * * @param ike_sa IKE_SA this task works for * @param config child_cfg if task initiator, NULL if responder + * @param recreate TRUE if recreating a previously established CHILD_SA * @param tsi source of triggering packet, or NULL * @param tsr destination of triggering packet, or NULL * @return task to handle by the task_manager */ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, - traffic_selector_t *tsi, traffic_selector_t *tsr); + bool recreate, traffic_selector_t *tsi, + traffic_selector_t *tsr); #endif /** QUICK_MODE_H_ @}*/ diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 8e6da16096..2b8bc10621 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -769,7 +769,7 @@ static status_t process_request(private_task_manager_t *this, task = (task_t*)ike_config_create(this->ike_sa, FALSE); array_insert(this->passive_tasks, ARRAY_TAIL, task); task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE, - NULL, NULL); + FALSE, NULL, NULL); array_insert(this->passive_tasks, ARRAY_TAIL, task); task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE); array_insert(this->passive_tasks, ARRAY_TAIL, task); @@ -818,7 +818,7 @@ static status_t process_request(private_task_manager_t *this, else { task = (task_t*)child_create_create(this->ike_sa, NULL, - FALSE, NULL, NULL); + FALSE, FALSE, NULL, NULL); } } else @@ -1372,11 +1372,11 @@ METHOD(task_manager_t, queue_mobike, void, METHOD(task_manager_t, queue_child, void, private_task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid, - traffic_selector_t *tsi, traffic_selector_t *tsr) + bool recreate, traffic_selector_t *tsi, traffic_selector_t *tsr) { child_create_t *task; - task = child_create_create(this->ike_sa, cfg, FALSE, tsi, tsr); + task = child_create_create(this->ike_sa, cfg, FALSE, recreate, tsi, tsr); if (reqid) { task->use_reqid(task, reqid); diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 7cfa537a98..8dde28437d 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2013 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -178,6 +178,11 @@ struct private_child_create_t { * whether we are retrying with another DH group */ bool retry; + + /** + * whether we are recreating a previously establishd CHILD_SA + */ + bool recreate; }; /** @@ -1498,6 +1503,12 @@ METHOD(child_create_t, get_lower_nonce, chunk_t, } } +METHOD(child_create_t, is_recreating, bool, + private_child_create_t *this) +{ + return this->recreate; +} + METHOD(task_t, get_type, task_type_t, private_child_create_t *this) { @@ -1575,7 +1586,7 @@ METHOD(task_t, destroy, void, * Described in header. */ child_create_t *child_create_create(ike_sa_t *ike_sa, - child_cfg_t *config, bool rekey, + child_cfg_t *config, bool rekey, bool recreate, traffic_selector_t *tsi, traffic_selector_t *tsr) { private_child_create_t *this; @@ -1586,6 +1597,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, .set_config = _set_config, .get_lower_nonce = _get_lower_nonce, .use_reqid = _use_reqid, + .is_recreating = _is_recreating, .task = { .get_type = _get_type, .migrate = _migrate, @@ -1604,6 +1616,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, .ipcomp_received = IPCOMP_NONE, .rekey = rekey, .retry = FALSE, + .recreate = recreate, ); if (config) diff --git a/src/libcharon/sa/ikev2/tasks/child_create.h b/src/libcharon/sa/ikev2/tasks/child_create.h index d29ba3d987..896e7fcf18 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.h +++ b/src/libcharon/sa/ikev2/tasks/child_create.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -71,6 +72,11 @@ struct child_create_t { * @param cfg configuration to enforce, reference gets owned */ void (*set_config)(child_create_t *this, child_cfg_t *cfg); + + /** + * Whether this task recreates a previously established CHILD_SA. + */ + bool (*is_recreating)(child_create_t *this); }; /** @@ -79,12 +85,13 @@ struct child_create_t { * @param ike_sa IKE_SA this task works for * @param config child_cfg if task initiator, NULL if responder * @param rekey whether we do a rekey or not + * @param recreate whether we recreate a previous CHILD_SA * @param tsi source of triggering packet, or NULL * @param tsr destination of triggering packet, or NULL * @return child_create task to handle by the task_manager */ child_create_t *child_create_create(ike_sa_t *ike_sa, - child_cfg_t *config, bool rekey, + child_cfg_t *config, bool rekey, bool recreate, traffic_selector_t *tsi, traffic_selector_t *tsr); #endif /** CHILD_CREATE_H_ @}*/ diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c index e898efc88e..3f2f30d5b6 100644 --- a/src/libcharon/sa/ikev2/tasks/child_delete.c +++ b/src/libcharon/sa/ikev2/tasks/child_delete.c @@ -224,7 +224,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this) case ACTION_RESTART: child_cfg->get_ref(child_cfg); status = this->ike_sa->initiate(this->ike_sa, child_cfg, - reqid, NULL, NULL); + reqid, TRUE, NULL, NULL); break; case ACTION_ROUTE: charon->traps->install(charon->traps, diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index d2003bb452..0fa90545cd 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -179,8 +179,9 @@ METHOD(task_t, build_i, status_t, /* ... our CHILD_CREATE task does the hard work for us. */ if (!this->child_create) { - this->child_create = child_create_create(this->ike_sa, - config->get_ref(config), TRUE, NULL, NULL); + config = config->get_ref(config); + this->child_create = child_create_create(this->ike_sa, config, TRUE, + FALSE, NULL, NULL); } reqid = this->child_sa->get_reqid(this->child_sa); this->child_create->use_reqid(this->child_create, reqid); @@ -498,7 +499,8 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol, this->public.task.build = _build_r; this->public.task.process = _process_r; this->initiator = FALSE; - this->child_create = child_create_create(ike_sa, NULL, TRUE, NULL, NULL); + this->child_create = child_create_create(ike_sa, NULL, TRUE, FALSE, + NULL, NULL); } return &this->public; diff --git a/src/libcharon/sa/task_manager.h b/src/libcharon/sa/task_manager.h index a1ebb4117b..191ef1ddb0 100644 --- a/src/libcharon/sa/task_manager.h +++ b/src/libcharon/sa/task_manager.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 Tobias Brunner * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -157,11 +158,13 @@ struct task_manager_t { * * @param cfg CHILD_SA config to establish * @param reqid reqid to use for CHILD_SA + * @param recreate TRUE if recreating a previously established CHILD_SA * @param tsi initiator traffic selector, if packet-triggered * @param tsr responder traffic selector, if packet-triggered */ void (*queue_child)(task_manager_t *this, child_cfg_t *cfg, u_int32_t reqid, - traffic_selector_t *tsi, traffic_selector_t *tsr); + bool recreate, traffic_selector_t *tsi, + traffic_selector_t *tsr); /** * Queue CHILD_SA rekeying tasks. diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 7e55d6b0f5..79929f97d2 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -358,7 +358,8 @@ METHOD(trap_manager_t, acquire, void, * have a single TS that we can establish in a Quick Mode. */ src = dst = NULL; } - if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME) + if (ike_sa->initiate(ike_sa, child, reqid, FALSE, + src, dst) != DESTROY_ME) { /* make sure the entry is still there */ this->lock->read_lock(this->lock);