From: Martin Willi Date: Wed, 7 Oct 2009 08:14:18 +0000 (+0200) Subject: Catch CHILD_SA state changes during acquire X-Git-Tag: 4.3.5rc1~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=991f7ccd6c3887286645821a5c295710cf05f156;p=thirdparty%2Fstrongswan.git Catch CHILD_SA state changes during acquire If an acquire fails due to a TS_UNACCEPTABLE or other CHILD_SA only errors, we have to reset the pending state in the trap manager. --- diff --git a/src/charon/sa/trap_manager.c b/src/charon/sa/trap_manager.c index c9090250db..ec68e94d05 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;