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);
|
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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user