aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/charon/sa/trap_manager.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/src/charon/sa/trap_manager.c b/src/charon/sa/trap_manager.c
index c9090250d..ec68e94d0 100644
--- a/src/charon/sa/trap_manager.c
+++ b/src/charon/sa/trap_manager.c
@@ -303,37 +303,64 @@ static void acquire(private_trap_manager_t *this, u_int32_t reqid,
}
/**
- * Implementation of listener_t.ike_state_change
+ * Complete the acquire, if successful or failed
*/
-static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
- ike_sa_state_t state)
+static void complete(private_trap_manager_t *this, ike_sa_t *ike_sa,
+ child_sa_t *child_sa)
{
- private_trap_manager_t *this;
enumerator_t *enumerator;
entry_t *entry;
- switch (state)
- {
- case IKE_ESTABLISHED:
- case IKE_DESTROYING:
- break;
- default:
- return TRUE;
- }
-
- this = listener->traps;
this->lock->read_lock(this->lock);
enumerator = this->traps->create_enumerator(this->traps);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->pending == ike_sa)
+ if (entry->pending != ike_sa)
+ {
+ continue;
+ }
+ if (child_sa && child_sa->get_reqid(child_sa) !=
+ entry->child_sa->get_reqid(entry->child_sa))
{
- entry->pending = NULL;
+ continue;
}
+ entry->pending = NULL;
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- return TRUE;
+}
+
+/**
+ * Implementation of listener_t.ike_state_change
+ */
+static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
+ ike_sa_state_t state)
+{
+ switch (state)
+ {
+ case IKE_DESTROYING:
+ complete(listener->traps, ike_sa, NULL);
+ return TRUE;
+ default:
+ return TRUE;
+ }
+}
+
+/**
+ * Implementation of listener_t.child_state_change
+ */
+static bool child_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
+ child_sa_t *child_sa, child_sa_state_t state)
+{
+ switch (state)
+ {
+ case CHILD_INSTALLED:
+ case CHILD_DESTROYING:
+ complete(listener->traps, ike_sa, child_sa);
+ return TRUE;
+ default:
+ return TRUE;
+ }
}
/**
@@ -368,6 +395,7 @@ trap_manager_t *trap_manager_create()
this->listener.traps = this;
memset(&this->listener.listener, 0, sizeof(listener_t));
this->listener.listener.ike_state_change = (void*)ike_state_change;
+ this->listener.listener.child_state_change = (void*)child_state_change;
charon->bus->add_listener(charon->bus, &this->listener.listener);
return &this->public;