implemented ike_down() bus hook
This commit is contained in:
+72
-58
@@ -513,64 +513,6 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa,
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of bus_t.ike_updown
|
||||
*/
|
||||
static void ike_updown(private_bus_t *this, ike_sa_t *ike_sa, bool up)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
bool keep;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->listeners->create_enumerator(this->listeners);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->calling || !entry->listener->ike_updown)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->ike_updown(entry->listener, ike_sa, up);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
unregister_listener(this, entry, enumerator);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of bus_t.ike_rekey
|
||||
*/
|
||||
static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
bool keep;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->listeners->create_enumerator(this->listeners);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->calling || !entry->listener->ike_rekey)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->ike_rekey(entry->listener, old, new);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
unregister_listener(this, entry, enumerator);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of bus_t.child_updown
|
||||
*/
|
||||
@@ -636,6 +578,78 @@ static void child_rekey(private_bus_t *this, child_sa_t *old, child_sa_t *new)
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of bus_t.ike_updown
|
||||
*/
|
||||
static void ike_updown(private_bus_t *this, ike_sa_t *ike_sa, bool up)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
bool keep;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->listeners->create_enumerator(this->listeners);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->calling || !entry->listener->ike_updown)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->ike_updown(entry->listener, ike_sa, up);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
unregister_listener(this, entry, enumerator);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
/* a down event for IKE_SA implicitly downs all CHILD_SAs */
|
||||
if (!up)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
child_sa_t *child_sa;
|
||||
|
||||
iterator = ike_sa->create_child_sa_iterator(ike_sa);
|
||||
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||
{
|
||||
child_updown(this, child_sa, FALSE);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of bus_t.ike_rekey
|
||||
*/
|
||||
static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
bool keep;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->listeners->create_enumerator(this->listeners);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->calling || !entry->listener->ike_rekey)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->ike_rekey(entry->listener, old, new);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
unregister_listener(this, entry, enumerator);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of bus_t.authorize
|
||||
*/
|
||||
|
||||
@@ -1554,6 +1554,17 @@ static void flush(private_ike_sa_manager_t *this)
|
||||
while (enumerator->enumerate(enumerator, &entry, &segment))
|
||||
{
|
||||
charon->bus->set_sa(charon->bus, entry->ike_sa);
|
||||
/* 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);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
@@ -220,6 +220,10 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
|
||||
{
|
||||
DBG1(DBG_IKE, "giving up after %d retransmits",
|
||||
this->initiating.retransmitted - 1);
|
||||
if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
|
||||
{
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
}
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
@@ -240,6 +244,7 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
|
||||
{
|
||||
DBG1(DBG_IKE, "giving up after %d path probings",
|
||||
this->initiating.retransmitted - 1);
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
@@ -431,6 +436,12 @@ static status_t build_request(private_task_manager_t *this)
|
||||
break;
|
||||
case FAILED:
|
||||
default:
|
||||
if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
|
||||
{
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
}
|
||||
/* FALL */
|
||||
case DESTROY_ME:
|
||||
/* critical failure, destroy IKE_SA */
|
||||
iterator->destroy(iterator);
|
||||
message->destroy(message);
|
||||
@@ -451,6 +462,7 @@ static status_t build_request(private_task_manager_t *this)
|
||||
* close the SA */
|
||||
message->destroy(message);
|
||||
flush(this);
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
@@ -474,6 +486,7 @@ static status_t process_response(private_task_manager_t *this,
|
||||
DBG1(DBG_IKE, "received %N response, but expected %N",
|
||||
exchange_type_names, message->get_exchange_type(message),
|
||||
exchange_type_names, this->initiating.type);
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
@@ -494,6 +507,9 @@ static status_t process_response(private_task_manager_t *this,
|
||||
break;
|
||||
case FAILED:
|
||||
default:
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
/* FALL */
|
||||
case DESTROY_ME:
|
||||
/* critical failure, destroy IKE_SA */
|
||||
iterator->remove(iterator);
|
||||
iterator->destroy(iterator);
|
||||
@@ -604,6 +620,9 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
|
||||
break;
|
||||
case FAILED:
|
||||
default:
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
/* FALL */
|
||||
case DESTROY_ME:
|
||||
/* destroy IKE_SA, but SEND response first */
|
||||
delete = TRUE;
|
||||
break;
|
||||
@@ -631,6 +650,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
|
||||
message->destroy(message);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
@@ -832,6 +852,9 @@ static status_t process_request(private_task_manager_t *this,
|
||||
break;
|
||||
case FAILED:
|
||||
default:
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
/* FALL */
|
||||
case DESTROY_ME:
|
||||
/* critical failure, destroy IKE_SA */
|
||||
iterator->remove(iterator);
|
||||
iterator->destroy(iterator);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
typedef struct private_ike_delete_t private_ike_delete_t;
|
||||
|
||||
/**file
|
||||
/**
|
||||
* Private members of a ike_delete_t task.
|
||||
*/
|
||||
struct private_ike_delete_t {
|
||||
@@ -41,6 +41,11 @@ struct private_ike_delete_t {
|
||||
*/
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* are we deleting a rekeyed SA?
|
||||
*/
|
||||
bool rekeyed;
|
||||
|
||||
/**
|
||||
* are we responding to a delete, but have initated our own?
|
||||
*/
|
||||
@@ -64,6 +69,11 @@ static status_t build_i(private_ike_delete_t *this, message_t *message)
|
||||
|
||||
delete_payload = delete_payload_create(PROTO_IKE);
|
||||
message->add_payload(message, (payload_t*)delete_payload);
|
||||
|
||||
if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
|
||||
{
|
||||
this->rekeyed = TRUE;
|
||||
}
|
||||
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
|
||||
|
||||
DBG1(DBG_IKE, "sending DELETE for IKE_SA %s[%d]",
|
||||
@@ -79,8 +89,12 @@ static status_t build_i(private_ike_delete_t *this, message_t *message)
|
||||
static status_t process_i(private_ike_delete_t *this, message_t *message)
|
||||
{
|
||||
DBG0(DBG_IKE, "IKE_SA deleted");
|
||||
/* completed, delete IKE_SA by returning FAILED */
|
||||
return FAILED;
|
||||
if (!this->rekeyed)
|
||||
{ /* invoke ike_down() hook if SA has not been rekeyed */
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
}
|
||||
/* completed, delete IKE_SA by returning DESTROY_ME */
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,14 +120,17 @@ static status_t process_r(private_ike_delete_t *this, message_t *message)
|
||||
case IKE_ESTABLISHED:
|
||||
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
|
||||
this->ike_sa->reestablish(this->ike_sa);
|
||||
return NEED_MORE;
|
||||
case IKE_REKEYING:
|
||||
this->rekeyed = TRUE;
|
||||
break;
|
||||
case IKE_DELETING:
|
||||
this->simultaneous = TRUE;
|
||||
/* FALL */
|
||||
break;
|
||||
default:
|
||||
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
|
||||
break;
|
||||
}
|
||||
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
@@ -129,8 +146,12 @@ static status_t build_r(private_ike_delete_t *this, message_t *message)
|
||||
/* wait for peer's response for our delete request, but set a timeout */
|
||||
return SUCCESS;
|
||||
}
|
||||
/* completed, delete IKE_SA by returning FAILED */
|
||||
return FAILED;
|
||||
if (!this->rekeyed)
|
||||
{ /* invoke ike_down() hook if SA has not been rekeyed */
|
||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||
}
|
||||
/* completed, delete IKE_SA by returning DESTROY_ME */
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,6 +203,7 @@ ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator)
|
||||
|
||||
this->ike_sa = ike_sa;
|
||||
this->initiator = initiator;
|
||||
this->rekeyed = FALSE;
|
||||
this->simultaneous = FALSE;
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -100,7 +100,8 @@ struct task_t {
|
||||
*
|
||||
* @param message message to add payloads to
|
||||
* @return
|
||||
* - FAILED if a critical error occured
|
||||
* - FAILED if a critical error occured
|
||||
* - DESTROY_ME if IKE_SA has been properly deleted
|
||||
* - NEED_MORE if another call to build/process needed
|
||||
* - SUCCESS if task completed
|
||||
*/
|
||||
@@ -112,6 +113,7 @@ struct task_t {
|
||||
* @param message message to read payloads from
|
||||
* @return
|
||||
* - FAILED if a critical error occured
|
||||
* - DESTROY_ME if IKE_SA has been properly deleted
|
||||
* - NEED_MORE if another call to build/process needed
|
||||
* - SUCCESS if task completed
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user