implemented ike_down() bus hook

This commit is contained in:
Martin Willi
2009-07-09 15:25:16 +02:00
parent fa1d3c6629
commit 977ec0c316
5 changed files with 138 additions and 66 deletions
+72 -58
View File
@@ -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
*/
+11
View File
@@ -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);
+23
View File
@@ -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);
+29 -7
View File
@@ -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;
+3 -1
View File
@@ -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
*/