reuse an existing IKE_SA to set up additional CHILD_SAs
This commit is contained in:
@@ -110,6 +110,16 @@ struct private_child_sa_t {
|
||||
*/
|
||||
u_int32_t reqid;
|
||||
|
||||
/**
|
||||
* encryption algorithm used for this SA
|
||||
*/
|
||||
algorithm_t encryption;
|
||||
|
||||
/**
|
||||
* integrity protection algorithm used for this SA
|
||||
*/
|
||||
algorithm_t integrity;
|
||||
|
||||
/**
|
||||
* time, on which SA was installed
|
||||
*/
|
||||
@@ -358,6 +368,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
|
||||
enc_algo, int_algo,
|
||||
prf_plus, natt, mine);
|
||||
|
||||
this->encryption = *enc_algo;
|
||||
this->integrity = *int_algo;
|
||||
this->install_time = time(NULL);
|
||||
|
||||
return status;
|
||||
@@ -574,6 +586,8 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
|
||||
char use_in_str[12] = "unused";
|
||||
char use_out_str[12] = "unused";
|
||||
char rekey_str[12] = "disabled";
|
||||
char enc_str[32] = "";
|
||||
char int_str[32] = "";
|
||||
u_int32_t use_in, use_out, use_fwd, now, rekeying;
|
||||
status_t status;
|
||||
|
||||
@@ -604,10 +618,38 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
|
||||
snprintf(rekey_str, sizeof(rekey_str), "%ds", (int)rekeying);
|
||||
}
|
||||
|
||||
/* algorithms used */
|
||||
if (this->protocol == PROTO_ESP)
|
||||
{
|
||||
if (this->encryption.key_size)
|
||||
{
|
||||
snprintf(enc_str, sizeof(enc_str), "%s-%d,",
|
||||
mapping_find(encryption_algorithm_m, this->encryption.algorithm),
|
||||
this->encryption.key_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(enc_str, sizeof(enc_str), "%s,",
|
||||
mapping_find(encryption_algorithm_m, this->encryption.algorithm));
|
||||
}
|
||||
}
|
||||
if (this->integrity.key_size)
|
||||
{
|
||||
snprintf(int_str, sizeof(int_str), "%s-%d",
|
||||
mapping_find(integrity_algorithm_m, this->integrity.algorithm),
|
||||
this->integrity.key_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(int_str, sizeof(int_str), "%s",
|
||||
mapping_find(integrity_algorithm_m, this->integrity.algorithm));
|
||||
}
|
||||
|
||||
logger->log(logger, CONTROL|LEVEL1,
|
||||
" \"%s\": using %s, SPIs (in/out): 0x%x/0x%x, reqid: %d",
|
||||
" \"%s\": %s (%s%s), SPIs (in/out): 0x%x/0x%x, reqid: %d",
|
||||
name,
|
||||
this->protocol == PROTO_ESP ? "ESP" : "AH",
|
||||
enc_str, int_str,
|
||||
htonl(this->me.spi), htonl(this->other.spi),
|
||||
this->reqid);
|
||||
logger->log(logger, CONTROL|LEVEL1,
|
||||
@@ -898,6 +940,10 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
|
||||
this->state = CHILD_CREATED;
|
||||
/* reuse old reqid if we are rekeying an existing CHILD_SA */
|
||||
this->reqid = rekey ? rekey : ++reqid;
|
||||
this->encryption.algorithm = ENCR_UNDEFINED;
|
||||
this->encryption.key_size = 0;
|
||||
this->integrity.algorithm = AUTH_UNDEFINED;
|
||||
this->encryption.key_size = 0;
|
||||
this->policies = linked_list_create();
|
||||
this->my_ts = linked_list_create();
|
||||
this->other_ts = linked_list_create();
|
||||
|
||||
+47
-15
@@ -782,23 +782,53 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
|
||||
static status_t initiate(private_ike_sa_t *this,
|
||||
connection_t *connection, policy_t *policy)
|
||||
{
|
||||
ike_sa_init_t *ike_sa_init;
|
||||
|
||||
set_name(this, connection->get_name(connection));
|
||||
|
||||
/* apply hosts from connection */
|
||||
this->my_host = connection->get_my_host(connection);
|
||||
this->my_host = this->my_host->clone(this->my_host);
|
||||
this->other_host = connection->get_other_host(connection);
|
||||
this->other_host = this->other_host->clone(this->other_host);
|
||||
|
||||
this->message_id_out = 1;
|
||||
ike_sa_init = ike_sa_init_create(&this->public);
|
||||
ike_sa_init->set_config(ike_sa_init, connection, policy);
|
||||
return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
|
||||
switch (this->state)
|
||||
{
|
||||
case IKE_CREATED:
|
||||
{
|
||||
/* in state CREATED, we must do the ike_sa_init
|
||||
* and ike_auth transactions. Along with these,
|
||||
* a CHILD_SA with the supplied policy is set up.
|
||||
*/
|
||||
ike_sa_init_t *ike_sa_init;
|
||||
|
||||
set_name(this, connection->get_name(connection));
|
||||
this->my_host = connection->get_my_host(connection);
|
||||
this->my_host = this->my_host->clone(this->my_host);
|
||||
this->other_host = connection->get_other_host(connection);
|
||||
this->other_host = this->other_host->clone(this->other_host);
|
||||
|
||||
this->message_id_out = 1;
|
||||
ike_sa_init = ike_sa_init_create(&this->public);
|
||||
ike_sa_init->set_config(ike_sa_init, connection, policy);
|
||||
return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
|
||||
}
|
||||
case IKE_DELETING:
|
||||
{
|
||||
/* if we are in DELETING, we deny set up of a policy. */
|
||||
policy->destroy(policy);
|
||||
connection->destroy(connection);
|
||||
return FAILED;
|
||||
}
|
||||
case IKE_CONNECTING:
|
||||
case IKE_ESTABLISHED:
|
||||
{
|
||||
/* if we are ESTABLISHED or CONNECTING,we queue the
|
||||
* transaction to create the CHILD_SA. It gets processed
|
||||
* when the IKE_SA is ready to do so. We don't need the
|
||||
* connection, as the IKE_SA is already established/establishing.
|
||||
*/
|
||||
create_child_sa_t *create_child;
|
||||
|
||||
connection->destroy(connection);
|
||||
create_child = create_child_sa_create(&this->public);
|
||||
create_child->set_policy(create_child, policy);
|
||||
return queue_transaction(this, (transaction_t*)create_child, FALSE);
|
||||
}
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.acquire.
|
||||
*/
|
||||
@@ -990,6 +1020,7 @@ static identification_t* get_my_id(private_ike_sa_t *this)
|
||||
*/
|
||||
static void set_my_id(private_ike_sa_t *this, identification_t *me)
|
||||
{
|
||||
DESTROY_IF(this->my_id);
|
||||
this->my_id = me;
|
||||
}
|
||||
|
||||
@@ -1006,6 +1037,7 @@ static identification_t* get_other_id(private_ike_sa_t *this)
|
||||
*/
|
||||
static void set_other_id(private_ike_sa_t *this, identification_t *other)
|
||||
{
|
||||
DESTROY_IF(this->other_id);
|
||||
this->other_id = other;
|
||||
}
|
||||
|
||||
|
||||
+131
-109
@@ -333,6 +333,34 @@ static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *ent
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until no other thread is using an IKE_SA, return FALSE if entry not
|
||||
* acquireable
|
||||
*/
|
||||
static bool wait_for_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *entry)
|
||||
{
|
||||
if (entry->driveout_new_threads)
|
||||
{
|
||||
/* we are not allowed to get this */
|
||||
return FALSE;
|
||||
}
|
||||
while (entry->checked_out && !entry->driveout_waiting_threads)
|
||||
{
|
||||
/* so wait until we can get it for us.
|
||||
* we register us as waiting. */
|
||||
entry->waiting_threads++;
|
||||
pthread_cond_wait(&(entry->condvar), &(this->mutex));
|
||||
entry->waiting_threads--;
|
||||
}
|
||||
/* hm, a deletion request forbids us to get this SA, get next one */
|
||||
if (entry->driveout_waiting_threads)
|
||||
{
|
||||
/* we must signal here, others may be waiting on it, too */
|
||||
pthread_cond_signal(&(entry->condvar));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_ike_sa_manager_t.get_next_spi.
|
||||
@@ -349,48 +377,92 @@ static u_int64_t get_next_spi(private_ike_sa_manager_t *this)
|
||||
/**
|
||||
* Implementation of of ike_sa_manager.create_and_checkout.
|
||||
*/
|
||||
static void create_and_checkout(private_ike_sa_manager_t *this,ike_sa_t **ike_sa)
|
||||
static ike_sa_t* checkout_by_ids(private_ike_sa_manager_t *this,
|
||||
identification_t *my_id,
|
||||
identification_t *other_id)
|
||||
{
|
||||
u_int64_t initiator_spi;
|
||||
ike_sa_entry_t *new_ike_sa_entry;
|
||||
ike_sa_id_t *new_ike_sa_id;
|
||||
|
||||
initiator_spi = this->get_next_spi(this);
|
||||
new_ike_sa_id = ike_sa_id_create(0, 0, TRUE);
|
||||
new_ike_sa_id->set_initiator_spi(new_ike_sa_id, initiator_spi);
|
||||
|
||||
/* create entry */
|
||||
new_ike_sa_entry = ike_sa_entry_create(new_ike_sa_id);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||
"created IKE_SA %llx:%llx, role %s",
|
||||
new_ike_sa_id->get_initiator_spi(new_ike_sa_id),
|
||||
new_ike_sa_id->get_responder_spi(new_ike_sa_id),
|
||||
new_ike_sa_id->is_initiator(new_ike_sa_id) ? "initiator" : "responder");
|
||||
new_ike_sa_id->destroy(new_ike_sa_id);
|
||||
|
||||
/* each access is locked */
|
||||
iterator_t *iterator;
|
||||
ike_sa_t *ike_sa = NULL;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
|
||||
|
||||
/* check ike_sa out */
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||
"new IKE_SA created and added to list of known IKE_SA's");
|
||||
new_ike_sa_entry->checked_out = TRUE;
|
||||
*ike_sa = new_ike_sa_entry->ike_sa;
|
||||
|
||||
iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
ike_sa_entry_t *entry;
|
||||
identification_t *found_my_id, *found_other_id;
|
||||
int wc;
|
||||
|
||||
iterator->current(iterator, (void**)&entry);
|
||||
if (!wait_for_entry(this, entry))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
|
||||
found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
|
||||
|
||||
if (!found_my_id || !found_other_id)
|
||||
{
|
||||
/* IKE_SA has no IDs yet, so we can't use it */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (found_my_id->matches(found_my_id, my_id, &wc) &&
|
||||
found_other_id->matches(found_other_id, other_id, &wc))
|
||||
{
|
||||
/* looks good, we take this one */
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||
"found an existing IKE_SA for IDs %s - %s",
|
||||
my_id->get_string(my_id), other_id->get_string(other_id));
|
||||
entry->checked_out = TRUE;
|
||||
ike_sa = entry->ike_sa;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
if (!ike_sa)
|
||||
{
|
||||
u_int64_t initiator_spi;
|
||||
ike_sa_entry_t *new_ike_sa_entry;
|
||||
ike_sa_id_t *new_ike_sa_id;
|
||||
|
||||
initiator_spi = this->get_next_spi(this);
|
||||
new_ike_sa_id = ike_sa_id_create(0, 0, TRUE);
|
||||
new_ike_sa_id->set_initiator_spi(new_ike_sa_id, initiator_spi);
|
||||
|
||||
/* create entry */
|
||||
new_ike_sa_entry = ike_sa_entry_create(new_ike_sa_id);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||
"created IKE_SA %llx:%llx, role %s",
|
||||
new_ike_sa_id->get_initiator_spi(new_ike_sa_id),
|
||||
new_ike_sa_id->get_responder_spi(new_ike_sa_id),
|
||||
new_ike_sa_id->is_initiator(new_ike_sa_id) ? "initiator" : "responder");
|
||||
new_ike_sa_id->destroy(new_ike_sa_id);
|
||||
|
||||
this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
|
||||
|
||||
/* check ike_sa out */
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||
"new IKE_SA created for IDs %s - %s",
|
||||
my_id->get_string(my_id), other_id->get_string(other_id));
|
||||
new_ike_sa_entry->checked_out = TRUE;
|
||||
ike_sa = new_ike_sa_entry->ike_sa;
|
||||
}
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
|
||||
return ike_sa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of of ike_sa_manager.checkout.
|
||||
*/
|
||||
static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_t **ike_sa)
|
||||
static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
|
||||
{
|
||||
bool responder_spi_set;
|
||||
bool initiator_spi_set;
|
||||
bool original_initiator;
|
||||
status_t retval;
|
||||
ike_sa_t *ike_sa = NULL;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||
"checkout IKE_SA %llx:%llx, role %s",
|
||||
@@ -418,56 +490,25 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id,
|
||||
/* look for the entry */
|
||||
if (this->get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
|
||||
{
|
||||
/* can we give this ike_sa out to new requesters?*/
|
||||
if (entry->driveout_new_threads)
|
||||
if (wait_for_entry(this, entry))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||
"drive out new thread for existing IKE_SA");
|
||||
/* no we can't */
|
||||
retval = NOT_FOUND;
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||
"IKE_SA successfully checked out");
|
||||
/* ok, this IKE_SA is finally ours */
|
||||
entry->checked_out = TRUE;
|
||||
ike_sa = entry->ike_sa;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* is this IKE_SA already checked out ??
|
||||
* are we welcome to get this SA ? */
|
||||
while (entry->checked_out && !entry->driveout_waiting_threads)
|
||||
{
|
||||
/* so wait until we can get it for us.
|
||||
* we register us as waiting.
|
||||
*/
|
||||
entry->waiting_threads++;
|
||||
pthread_cond_wait(&(entry->condvar), &(this->mutex));
|
||||
entry->waiting_threads--;
|
||||
}
|
||||
|
||||
/* hm, a deletion request forbids us to get this SA, go home */
|
||||
if (entry->driveout_waiting_threads)
|
||||
{
|
||||
/* we must signal here, others are interested that we leave */
|
||||
pthread_cond_signal(&(entry->condvar));
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||
"drive out waiting thread for existing IKE_SA");
|
||||
retval = NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||
"IKE SA successfully checked out");
|
||||
/* ok, this IKE_SA is finally ours */
|
||||
entry->checked_out = TRUE;
|
||||
*ike_sa = entry->ike_sa;
|
||||
/* DON'T use return, we must unlock the mutex! */
|
||||
retval = SUCCESS;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||
"IKE_SA found, but not allowed to check it out");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1,
|
||||
"IKE SA not stored in known IKE_SA list");
|
||||
"IKE_SA not stored in list");
|
||||
/* looks like there is no such IKE_SA, better luck next time... */
|
||||
/* DON'T use return, we must unlock the mutex! */
|
||||
retval = NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else if ((initiator_spi_set && !responder_spi_set) && (!original_initiator))
|
||||
@@ -496,23 +537,18 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id,
|
||||
|
||||
/* check ike_sa out */
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||
"IKE_SA added to list of known IKE_SA's");
|
||||
"IKE_SA added to list of known IKE_SAs");
|
||||
new_ike_sa_entry->checked_out = TRUE;
|
||||
*ike_sa = new_ike_sa_entry->ike_sa;
|
||||
|
||||
retval = SUCCESS;
|
||||
ike_sa = new_ike_sa_entry->ike_sa;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* responder set, initiator not: here is something seriously wrong! */
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "invalid IKE_SA SPI's");
|
||||
/* DON'T use return, we must unlock the mutex! */
|
||||
retval = INVALID_ARG;
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "invalid IKE_SA SPIs");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
/* OK, unlocked... */
|
||||
return retval;
|
||||
return ike_sa;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -533,34 +569,17 @@ static status_t checkout_by_child(private_ike_sa_manager_t *this,
|
||||
ike_sa_entry_t *entry;
|
||||
|
||||
iterator->current(iterator, (void**)&entry);
|
||||
if (entry->driveout_new_threads)
|
||||
if (wait_for_entry(this, entry))
|
||||
{
|
||||
/* we are not allowed to get this, get next one */
|
||||
continue;
|
||||
}
|
||||
while (entry->checked_out && !entry->driveout_waiting_threads)
|
||||
{
|
||||
/* so wait until we can get it for us.
|
||||
* we register us as waiting. */
|
||||
entry->waiting_threads++;
|
||||
pthread_cond_wait(&(entry->condvar), &(this->mutex));
|
||||
entry->waiting_threads--;
|
||||
}
|
||||
/* hm, a deletion request forbids us to get this SA, get next one */
|
||||
if (entry->driveout_waiting_threads)
|
||||
{
|
||||
/* we must signal here, others may be waiting on it, too */
|
||||
pthread_cond_signal(&(entry->condvar));
|
||||
continue;
|
||||
}
|
||||
/* ok, access is exclusive for us, check for child */
|
||||
if (entry->ike_sa->get_child_sa(entry->ike_sa, protocol, spi, TRUE) != NULL)
|
||||
{
|
||||
/* match */
|
||||
entry->checked_out = TRUE;
|
||||
*ike_sa = entry->ike_sa;
|
||||
status = SUCCESS;
|
||||
break;
|
||||
/* ok, access is exclusive for us, check for child */
|
||||
if (entry->ike_sa->get_child_sa(entry->ike_sa, protocol, spi, TRUE) != NULL)
|
||||
{
|
||||
/* match */
|
||||
entry->checked_out = TRUE;
|
||||
*ike_sa = entry->ike_sa;
|
||||
status = SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
@@ -638,9 +657,12 @@ static void log_status(private_ike_sa_manager_t* this, logger_t* logger, char* n
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
ike_sa_entry_t *entry;
|
||||
|
||||
|
||||
iterator->current(iterator, (void**)&entry);
|
||||
entry->ike_sa->log_status(entry->ike_sa, logger, name);
|
||||
if (wait_for_entry(this, entry))
|
||||
{
|
||||
entry->ike_sa->log_status(entry->ike_sa, logger, name);
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
@@ -891,8 +913,8 @@ ike_sa_manager_t *ike_sa_manager_create()
|
||||
|
||||
/* assign public functions */
|
||||
this->public.destroy = (void(*)(ike_sa_manager_t*))destroy;
|
||||
this->public.create_and_checkout = (void(*)(ike_sa_manager_t*,ike_sa_t**))create_and_checkout;
|
||||
this->public.checkout = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t*,ike_sa_t**))checkout;
|
||||
this->public.checkout_by_ids = (ike_sa_t*(*)(ike_sa_manager_t*,identification_t*,identification_t*))checkout_by_ids;
|
||||
this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout;
|
||||
this->public.checkout_by_child = (status_t(*)(ike_sa_manager_t*,protocol_id_t,u_int32_t,ike_sa_t**))checkout_by_child;
|
||||
this->public.get_ike_sa_list = (linked_list_t*(*)(ike_sa_manager_t*))get_ike_sa_list;
|
||||
this->public.get_ike_sa_list_by_name = (linked_list_t*(*)(ike_sa_manager_t*,const char*))get_ike_sa_list_by_name;
|
||||
|
||||
@@ -52,8 +52,8 @@ struct ike_sa_manager_t {
|
||||
/**
|
||||
* @brief Checkout an IKE_SA, create it when necesarry.
|
||||
*
|
||||
* Checks out a SA by its ID. An SA will be created, when:
|
||||
* - Responder SPI is not set (when received an IKE_SA_INIT from initiator)
|
||||
* Checks out a SA by its ID. An SA will be created, when the responder
|
||||
* SPI is not set (when received an IKE_SA_INIT from initiator).
|
||||
* Management of SPIs is the managers job, he will set it.
|
||||
* This function blocks until SA is available for checkout.
|
||||
*
|
||||
@@ -62,24 +62,27 @@ struct ike_sa_manager_t {
|
||||
*
|
||||
* @param this the manager object
|
||||
* @param[in/out] ike_sa_id the SA identifier, will be updated
|
||||
* @param[out] ike_sa checked out SA
|
||||
* @returns
|
||||
* - SUCCESS if checkout successful
|
||||
* - NOT_FOUND when no such SA is available
|
||||
* - CREATED if a new IKE_SA got created
|
||||
* - checked out IKE_SA if found
|
||||
* - NULL, if no such IKE_SA available
|
||||
*/
|
||||
status_t (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id, ike_sa_t **ike_sa);
|
||||
ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id);
|
||||
|
||||
/**
|
||||
* @brief Create and checkout an IKE_SA as original initator.
|
||||
*
|
||||
* Creates and checks out a SA as initiator.
|
||||
* Management of SPIs is the managers job, he will set it.
|
||||
*
|
||||
* @brief Checkout an IKE_SA by two identifications.
|
||||
*
|
||||
* Allows the lookup of an IKE_SA by two user IDs. It returns the
|
||||
* first found occurence, if there are multiple canddates. Supplied IDs
|
||||
* may contain wildcards. If no IKE_SA is found, a new one is created.
|
||||
*
|
||||
* @param this the manager object
|
||||
* @param[out] ike_sa checked out SA
|
||||
* @param my_id ID used by us
|
||||
* @param other_id ID used by other
|
||||
* @return checked out/created IKE_SA
|
||||
*/
|
||||
void (*create_and_checkout) (ike_sa_manager_t* this,ike_sa_t **ike_sa);
|
||||
ike_sa_t* (*checkout_by_ids) (ike_sa_manager_t* this,
|
||||
identification_t *my_id,
|
||||
identification_t *other_id);
|
||||
|
||||
/**
|
||||
* @brief Check out an IKE_SA by protocol and SPI of one of its CHILD_SA.
|
||||
@@ -102,7 +105,7 @@ struct ike_sa_manager_t {
|
||||
/**
|
||||
* @brief Get a list of all IKE_SA SAs currently set up.
|
||||
*
|
||||
* The resulting list with all IDs must be destroyd by
|
||||
* The resulting list with all IDs must be destroyed by
|
||||
* the caller. There is no guarantee an ike_sa with the
|
||||
* corrensponding ID really exists, since it may be deleted
|
||||
* in the meantime by another thread.
|
||||
@@ -153,7 +156,7 @@ struct ike_sa_manager_t {
|
||||
* @brief Delete a SA, which was not checked out.
|
||||
*
|
||||
* If the state allows it, the IKE SA is destroyed immediately. If it is
|
||||
* in the state ike_sa_established or further, a delete message
|
||||
* in the state ESTABLSIHED, a delete message
|
||||
* is sent to the remote peer, which has to be acknowledged.
|
||||
*
|
||||
* @warning do not use this when the SA is already checked out, this will
|
||||
|
||||
@@ -228,7 +228,6 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
|
||||
{ /* build ID payload */
|
||||
my_id_payload = id_payload_create_from_identification(TRUE, my_id);
|
||||
request->add_payload(request, (payload_t*)my_id_payload);
|
||||
this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
|
||||
}
|
||||
|
||||
{ /* TODO: build certreq payload */
|
||||
@@ -889,6 +888,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
|
||||
configured_other_id->get_string(configured_other_id));
|
||||
return DESTROY_ME;
|
||||
}
|
||||
/* update other ID. It was already set, but may contain wildcards */
|
||||
this->ike_sa->set_other_id(this->ike_sa, other_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ static status_t get_request(private_ike_sa_init_t *this, message_t **result)
|
||||
{
|
||||
message_t *request;
|
||||
host_t *me, *other;
|
||||
identification_t *my_id, *other_id;
|
||||
|
||||
/* check if we already have built a message (retransmission) */
|
||||
if (this->message)
|
||||
@@ -280,6 +281,13 @@ static status_t get_request(private_ike_sa_init_t *this, message_t **result)
|
||||
me = this->connection->get_my_host(this->connection);
|
||||
other = this->connection->get_other_host(this->connection);
|
||||
|
||||
/* we already set up the IDs. Mine is already fully qualified, other
|
||||
* will be updated in the ike_auth transaction */
|
||||
my_id = this->policy->get_my_id(this->policy);
|
||||
other_id = this->policy->get_other_id(this->policy);
|
||||
this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
|
||||
this->ike_sa->set_other_id(this->ike_sa, other_id->clone(other_id));
|
||||
|
||||
/* build the request */
|
||||
request = message_create();
|
||||
request->set_source(request, me->clone(me));
|
||||
|
||||
Reference in New Issue
Block a user