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); 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 * 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); 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 * 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)) while (enumerator->enumerate(enumerator, &entry, &segment))
{ {
charon->bus->set_sa(charon->bus, entry->ike_sa); 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); entry->ike_sa->delete(entry->ike_sa);
} }
enumerator->destroy(enumerator); 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", DBG1(DBG_IKE, "giving up after %d retransmits",
this->initiating.retransmitted - 1); 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; 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", DBG1(DBG_IKE, "giving up after %d path probings",
this->initiating.retransmitted - 1); this->initiating.retransmitted - 1);
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -431,6 +436,12 @@ static status_t build_request(private_task_manager_t *this)
break; break;
case FAILED: case FAILED:
default: 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 */ /* critical failure, destroy IKE_SA */
iterator->destroy(iterator); iterator->destroy(iterator);
message->destroy(message); message->destroy(message);
@@ -451,6 +462,7 @@ static status_t build_request(private_task_manager_t *this)
* close the SA */ * close the SA */
message->destroy(message); message->destroy(message);
flush(this); flush(this);
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
return DESTROY_ME; 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", DBG1(DBG_IKE, "received %N response, but expected %N",
exchange_type_names, message->get_exchange_type(message), exchange_type_names, message->get_exchange_type(message),
exchange_type_names, this->initiating.type); exchange_type_names, this->initiating.type);
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -494,6 +507,9 @@ static status_t process_response(private_task_manager_t *this,
break; break;
case FAILED: case FAILED:
default: default:
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
/* FALL */
case DESTROY_ME:
/* critical failure, destroy IKE_SA */ /* critical failure, destroy IKE_SA */
iterator->remove(iterator); iterator->remove(iterator);
iterator->destroy(iterator); iterator->destroy(iterator);
@@ -604,6 +620,9 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
break; break;
case FAILED: case FAILED:
default: default:
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
/* FALL */
case DESTROY_ME:
/* destroy IKE_SA, but SEND response first */ /* destroy IKE_SA, but SEND response first */
delete = TRUE; delete = TRUE;
break; break;
@@ -631,6 +650,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
message->destroy(message); message->destroy(message);
if (status != SUCCESS) if (status != SUCCESS)
{ {
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -832,6 +852,9 @@ static status_t process_request(private_task_manager_t *this,
break; break;
case FAILED: case FAILED:
default: default:
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
/* FALL */
case DESTROY_ME:
/* critical failure, destroy IKE_SA */ /* critical failure, destroy IKE_SA */
iterator->remove(iterator); iterator->remove(iterator);
iterator->destroy(iterator); iterator->destroy(iterator);
+29 -7
View File
@@ -21,7 +21,7 @@
typedef struct private_ike_delete_t private_ike_delete_t; typedef struct private_ike_delete_t private_ike_delete_t;
/**file /**
* Private members of a ike_delete_t task. * Private members of a ike_delete_t task.
*/ */
struct private_ike_delete_t { struct private_ike_delete_t {
@@ -41,6 +41,11 @@ struct private_ike_delete_t {
*/ */
bool initiator; bool initiator;
/**
* are we deleting a rekeyed SA?
*/
bool rekeyed;
/** /**
* are we responding to a delete, but have initated our own? * 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); delete_payload = delete_payload_create(PROTO_IKE);
message->add_payload(message, (payload_t*)delete_payload); 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); this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
DBG1(DBG_IKE, "sending DELETE for IKE_SA %s[%d]", 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) static status_t process_i(private_ike_delete_t *this, message_t *message)
{ {
DBG0(DBG_IKE, "IKE_SA deleted"); DBG0(DBG_IKE, "IKE_SA deleted");
/* completed, delete IKE_SA by returning FAILED */ if (!this->rekeyed)
return FAILED; { /* 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: case IKE_ESTABLISHED:
this->ike_sa->set_state(this->ike_sa, IKE_DELETING); this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
this->ike_sa->reestablish(this->ike_sa); this->ike_sa->reestablish(this->ike_sa);
return NEED_MORE;
case IKE_REKEYING:
this->rekeyed = TRUE;
break; break;
case IKE_DELETING: case IKE_DELETING:
this->simultaneous = TRUE; this->simultaneous = TRUE;
/* FALL */ break;
default: default:
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
break; break;
} }
this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
return NEED_MORE; 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 */ /* wait for peer's response for our delete request, but set a timeout */
return SUCCESS; return SUCCESS;
} }
/* completed, delete IKE_SA by returning FAILED */ if (!this->rekeyed)
return FAILED; { /* 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->ike_sa = ike_sa;
this->initiator = initiator; this->initiator = initiator;
this->rekeyed = FALSE;
this->simultaneous = FALSE; this->simultaneous = FALSE;
return &this->public; return &this->public;
+3 -1
View File
@@ -100,7 +100,8 @@ struct task_t {
* *
* @param message message to add payloads to * @param message message to add payloads to
* @return * @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 * - NEED_MORE if another call to build/process needed
* - SUCCESS if task completed * - SUCCESS if task completed
*/ */
@@ -112,6 +113,7 @@ struct task_t {
* @param message message to read payloads from * @param message message to read payloads from
* @return * @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 * - NEED_MORE if another call to build/process needed
* - SUCCESS if task completed * - SUCCESS if task completed
*/ */