}
peer_cfg->destroy(peer_cfg);
- if (ike_sa->initiate(ike_sa, listener->child_cfg) != SUCCESS)
+ if (ike_sa->initiate(ike_sa, listener->child_cfg) == SUCCESS)
{
- return charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return SUCCESS;
}
- return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return FAILED;
}
/**
ike_sa_t *ike_sa = listener->ike_sa;
charon->bus->set_sa(charon->bus, ike_sa);
- if (ike_sa->delete(ike_sa) == DESTROY_ME)
+
+ if (ike_sa->delete(ike_sa) != DESTROY_ME)
{
- return charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ /* delete failed */
+ return FAILED;
}
- return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return SUCCESS;
}
/**
charon->bus->set_sa(charon->bus, ike_sa);
if (ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE)) == DESTROY_ME)
+ child_sa->get_spi(child_sa, TRUE)) != DESTROY_ME)
{
- return charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return SUCCESS;
}
- return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return FAILED;
}
/**
ike_sa_t *ike_sa = listener->ike_sa;
charon->bus->set_sa(charon->bus, ike_sa);
- if (ike_sa->route(ike_sa, listener->child_cfg) == DESTROY_ME)
+ if (ike_sa->route(ike_sa, listener->child_cfg) != DESTROY_ME)
{
- return charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return SUCCESS;
}
- return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return FAILED;
}
/**
interface_listener_t *listener = &job->listener;
ike_sa_t *ike_sa = listener->ike_sa;
- if (ike_sa->unroute(ike_sa, listener->id) == DESTROY_ME)
+ if (ike_sa->unroute(ike_sa, listener->id) != DESTROY_ME)
{
- return charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return SUCCESS;
}
- return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return SUCCESS;
}
/**
/**
* Creates a new entry for the ike_sa_t list.
*/
-static entry_t *entry_create(ike_sa_id_t *ike_sa_id)
+static entry_t *entry_create()
{
entry_t *this = malloc_thing(entry_t);
this->half_open = FALSE;
this->my_id = NULL;
this->other_id = NULL;
+ this->ike_sa_id = NULL;
+ this->ike_sa = NULL;
- /* ike_sa_id is always cloned */
- this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
-
- /* create new ike_sa */
- this->ike_sa = ike_sa_create(ike_sa_id);
-
return this;
}
static void lock_single_segment(private_ike_sa_manager_t *this, u_int index)
{
mutex_t *lock = this->segments[index & this->segment_mask].mutex;
-
+
lock->lock(lock);
}
static void unlock_single_segment(private_ike_sa_manager_t *this, u_int index)
{
mutex_t *lock = this->segments[index & this->segment_mask].mutex;
-
+
lock->unlock(lock);
}
static void lock_all_segments(private_ike_sa_manager_t *this)
{
u_int i;
-
+
for (i = 0; i < this->segment_count; ++i)
{
this->segments[i].mutex->lock(this->segments[i].mutex);
static void unlock_all_segments(private_ike_sa_manager_t *this)
{
u_int i;
-
+
for (i = 0; i < this->segment_count; ++i)
{
this->segments[i].mutex->unlock(this->segments[i].mutex);
static ike_sa_t *checkout_new(private_ike_sa_manager_t* this, bool initiator)
{
entry_t *entry;
- ike_sa_id_t *id;
u_int segment;
+ entry = entry_create();
if (initiator)
{
- id = ike_sa_id_create(get_next_spi(this), 0, TRUE);
+ entry->ike_sa_id = ike_sa_id_create(get_next_spi(this), 0, TRUE);
}
else
{
- id = ike_sa_id_create(0, get_next_spi(this), FALSE);
+ entry->ike_sa_id = ike_sa_id_create(0, get_next_spi(this), FALSE);
}
- entry = entry_create(id);
- id->destroy(id);
+ entry->ike_sa = ike_sa_create(entry->ike_sa_id);
segment = put_entry(this, entry);
entry->checked_out = TRUE;
{
/* no IKE_SA found, create a new one */
id->set_responder_spi(id, get_next_spi(this));
- entry = entry_create(id);
+ entry = entry_create();
+ entry->ike_sa = ike_sa_create(id);
+ entry->ike_sa_id = id->clone(id);
segment = put_entry(this, entry);
entry->checked_out = TRUE;
if (!ike_sa)
{
- entry_t *new_entry;
- ike_sa_id_t *new_ike_sa_id;
-
- new_ike_sa_id = ike_sa_id_create(get_next_spi(this), 0, TRUE);
+ entry = entry_create();
+ entry->ike_sa_id = ike_sa_id_create(get_next_spi(this), 0, TRUE);
+ entry->ike_sa = ike_sa_create(entry->ike_sa_id);
- /* create entry */
- new_entry = entry_create(new_ike_sa_id);
- new_ike_sa_id->destroy(new_ike_sa_id);
-
- segment = put_entry(this, new_entry);
+ segment = put_entry(this, entry);
/* check ike_sa out */
DBG2(DBG_MGR, "new IKE_SA created for IDs [%D]...[%D]", my_id, other_id);
- new_entry->checked_out = TRUE;
- ike_sa = new_entry->ike_sa;
+ entry->checked_out = TRUE;
+ ike_sa = entry->ike_sa;
unlock_single_segment(this, segment);
}
charon->bus->set_sa(charon->bus, ike_sa);
/**
* Implementation of ike_sa_manager_t.checkin.
*/
-static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
+static void checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
{
/* to check the SA back in, we look for the pointer of the ike_sa
* in all entries.
* on reception of a IKE_SA_INIT response) the lookup will work but
* updating of the SPI MAY be necessary...
*/
- status_t retval;
entry_t *entry;
ike_sa_id_t *ike_sa_id;
host_t *other;
u_int segment;
ike_sa_id = ike_sa->get_id(ike_sa);
+ my_id = ike_sa->get_my_id(ike_sa);
+ other_id = ike_sa->get_other_id(ike_sa);
+ other = ike_sa->get_other_host(ike_sa);
DBG2(DBG_MGR, "checkin IKE_SA");
entry->checked_out = FALSE;
entry->message_id = -1;
/* check if this SA is half-open */
- other = ike_sa->get_other_host(ike_sa);
if (entry->half_open && ike_sa->get_state(ike_sa) != IKE_CONNECTING)
{
/* not half open anymore */
put_half_open(this, entry);
}
/* apply identities for duplicate test */
- my_id = ike_sa->get_my_id(ike_sa);
- other_id = ike_sa->get_other_id(ike_sa);
if (!entry->my_id ||
entry->my_id->get_type(entry->my_id) == ID_ANY)
{
}
DBG2(DBG_MGR, "check-in of IKE_SA successful.");
entry->condvar->signal(entry->condvar);
- retval = SUCCESS;
unlock_single_segment(this, segment);
}
else
{
- DBG2(DBG_MGR, "tried to check in nonexisting IKE_SA");
- /* this SA is no more, this REALLY should not happen */
- retval = NOT_FOUND;
+ entry = entry_create();
+ entry->ike_sa_id = ike_sa_id->clone(ike_sa_id);
+ entry->ike_sa = ike_sa;
+ entry->my_id = my_id->clone(my_id);
+ entry->other_id = other_id->clone(other_id);
+
+ unlock_single_segment(this, put_entry(this, entry));
}
charon->bus->set_sa(charon->bus, NULL);
- return retval;
}
-
/**
* Implementation of ike_sa_manager_t.checkin_and_destroy.
*/
-static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
+static void checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
{
/* deletion is a bit complex, we must ensure that no thread is waiting for
* this SA.
* are in the condvar.
*/
entry_t *entry;
- status_t retval;
ike_sa_id_t *ike_sa_id;
u_int segment;
ike_sa_id = ike_sa->get_id(ike_sa);
DBG2(DBG_MGR, "checkin and destroy IKE_SA");
-
+
if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS)
{
/* drive out waiting threads, as we are in hurry */
{
remove_half_open(this, entry);
}
-
+
remove_entry(this, entry);
entry_destroy(entry);
unlock_single_segment(this, segment);
DBG2(DBG_MGR, "check-in and destroy of IKE_SA successful");
- retval = SUCCESS;
}
else
{
- DBG2(DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
- retval = NOT_FOUND;
+ DBG1(DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
+ ike_sa->destroy(ike_sa);
}
charon->bus->set_sa(charon->bus, NULL);
- return retval;
}
/**
if ((list = this->half_open_table[row]) != NULL)
{
half_open_t *current;
+
if (list->find_first(list, (linked_list_match_t)half_open_match,
(void**)¤t, &addr) == SUCCESS)
{
else
{
u_int segment;
+
for (segment = 0; segment < this->segment_count; ++segment)
{
rwlock_t *lock;
static u_int get_nearest_powerof2(u_int n)
{
u_int i;
-
+
--n;
for (i = 1; i < sizeof(u_int) * 8; i <<= 1)
{
this->public.checkout_by_name = (ike_sa_t*(*)(ike_sa_manager_t*,char*,bool))checkout_by_name;
this->public.checkout_duplicate = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_t *ike_sa))checkout_duplicate;
this->public.create_enumerator = (enumerator_t*(*)(ike_sa_manager_t*))create_enumerator;
- this->public.checkin = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin;
- this->public.checkin_and_destroy = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy;
+ this->public.checkin = (void(*)(ike_sa_manager_t*,ike_sa_t*))checkin;
+ this->public.checkin_and_destroy = (void(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy;
this->public.get_half_open_count = (int(*)(ike_sa_manager_t*,host_t*))get_half_open_count;
/* initialize private variables */