listener->ike_sa = ike_sa;
listener->lock->unlock(listener->lock);
- if (ike_sa->delete(ike_sa) != DESTROY_ME)
+ if (ike_sa->delete(ike_sa, FALSE) != DESTROY_ME)
{ /* delete failed */
listener->status = FAILED;
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
if (this->delete_if_established)
{
- if (ike_sa->delete(ike_sa) == DESTROY_ME)
+ if (ike_sa->delete(ike_sa, FALSE) == DESTROY_ME)
{
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, ike_sa);
{
DBG1(DBG_JOB, "deleting IKE_SA after %d seconds "
"of CHILD_SA inactivity", this->timeout);
- status = ike_sa->delete(ike_sa);
+ status = ike_sa->delete(ike_sa, FALSE);
}
else
{
/*
- * Copyright (C) 2006-2017 Tobias Brunner
+ * Copyright (C) 2006-2018 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
}
METHOD(ike_sa_t, delete_, status_t,
- private_ike_sa_t *this)
+ private_ike_sa_t *this, bool force)
{
+ status_t status = DESTROY_ME;
+
switch (this->state)
{
case IKE_ESTABLISHED:
charon->bus->alert(charon->bus, ALERT_IKE_SA_EXPIRED);
}
this->task_manager->queue_ike_delete(this->task_manager);
- return this->task_manager->initiate(this->task_manager);
+ status = this->task_manager->initiate(this->task_manager);
+ break;
case IKE_CREATED:
DBG1(DBG_IKE, "deleting unestablished IKE_SA");
break;
case IKE_PASSIVE:
break;
default:
- DBG1(DBG_IKE, "destroying IKE_SA in state %N "
- "without notification", ike_sa_state_names, this->state);
- charon->bus->ike_updown(charon->bus, &this->public, FALSE);
+ DBG1(DBG_IKE, "destroying IKE_SA in state %N without notification",
+ ike_sa_state_names, this->state);
+ force = TRUE;
break;
}
- return DESTROY_ME;
+
+ if (force)
+ {
+ status = DESTROY_ME;
+
+ if (this->version == IKEV2)
+ { /* for IKEv1 we trigger this in the ISAKMP delete task */
+ switch (this->state)
+ {
+ case IKE_ESTABLISHED:
+ case IKE_REKEYING:
+ case IKE_DELETING:
+ charon->bus->ike_updown(charon->bus, &this->public, FALSE);
+ default:
+ break;
+ }
+ }
+ }
+ return status;
}
METHOD(ike_sa_t, rekey, status_t,
/*
- * Copyright (C) 2006-2017 Tobias Brunner
+ * Copyright (C) 2006-2018 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
*
* Sends a delete message to the remote peer and waits for
* its response. If the response comes in, or a timeout occurs,
- * the IKE SA gets deleted.
+ * the IKE SA gets destroyed, unless force is TRUE then the IKE_SA is
+ * destroyed immediately without waiting for a response.
*
+ * @param force whether to immediately destroy the IKE_SA afterwards
+ * without waiting for a response
* @return
* - SUCCESS if deletion is initialized
- * - DESTROY_ME, if the IKE_SA is not in
- * an established state and can not be
- * deleted (but destroyed).
+ * - DESTROY_ME, if destroying is forced, or the IKE_SA
+ * is not in an established state and can not be
+ * deleted (but destroyed)
*/
- status_t (*delete) (ike_sa_t *this);
+ status_t (*delete) (ike_sa_t *this, bool force);
/**
* Update IKE_SAs after network interfaces have changed.
}
DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer '%Y' due to "
"uniqueness policy", other);
- return duplicate->delete(duplicate);
+ return duplicate->delete(duplicate, FALSE);
}
METHOD(ike_sa_manager_t, check_uniqueness, bool,
while (enumerator->enumerate(enumerator, &entry, &segment))
{
charon->bus->set_sa(charon->bus, entry->ike_sa);
- if (entry->ike_sa->get_version(entry->ike_sa) == IKEV2)
- { /* as the delete never gets processed, fire down events */
- switch (entry->ike_sa->get_state(entry->ike_sa))
- {
- case IKE_ESTABLISHED:
- case IKE_REKEYING:
- case IKE_DELETING:
- charon->bus->ike_updown(charon->bus, entry->ike_sa, FALSE);
- break;
- default:
- break;
- }
- }
- entry->ike_sa->delete(entry->ike_sa);
+ entry->ike_sa->delete(entry->ike_sa, TRUE);
}
enumerator->destroy(enumerator);
/* IKE_SAs in state IKE_REKEYED are silently deleted, so we use
* IKE_REKEYING */
this->new_sa->set_state(this->new_sa, IKE_REKEYING);
- if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
+ if (this->new_sa->delete(this->new_sa, FALSE) == DESTROY_ME)
{
this->new_sa->destroy(this->new_sa);
}
}
call_ikesa(a, delete_child_sa, PROTO_ESP, spi_a, FALSE);
assert_child_sa_state(a, spi_a, CHILD_DELETING);
- call_ikesa(b, delete);
+ call_ikesa(b, delete, FALSE);
assert_ike_sa_state(b, IKE_DELETING);
/* RFC 7296, 2.25.2 does not explicitly state what the behavior SHOULD be if
&a, &b, NULL);
}
initiate_rekey(a, spi_a);
- call_ikesa(b, delete);
+ call_ikesa(b, delete, FALSE);
assert_ike_sa_state(b, IKE_DELETING);
/* this should never get called as there is no successful rekeying on
}
assert_hook_not_called(ike_updown);
assert_hook_not_called(child_updown);
- call_ikesa(a, delete);
+ call_ikesa(a, delete, FALSE);
assert_ike_sa_state(a, IKE_DELETING);
assert_hook();
assert_hook();
assert_hook_not_called(ike_updown);
assert_hook_not_called(child_updown);
- call_ikesa(a, delete);
+ call_ikesa(a, delete, FALSE);
assert_ike_sa_state(a, IKE_DELETING);
- call_ikesa(b, delete);
+ call_ikesa(b, delete, FALSE);
assert_ike_sa_state(b, IKE_DELETING);
assert_hook();
assert_hook();
assert_hook_not_called(ike_rekey);
initiate_rekey(a);
- call_ikesa(b, delete);
+ call_ikesa(b, delete, FALSE);
assert_ike_sa_state(b, IKE_DELETING);
/* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
assert_hook_not_called(ike_rekey);
initiate_rekey(a);
- call_ikesa(b, delete);
+ call_ikesa(b, delete, FALSE);
assert_ike_sa_state(b, IKE_DELETING);
/* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that