further work for rekeying:
get liftimes from policy added new state initiation of rekeying done proposal redone: removed support for AH+ESP proposals
This commit is contained in:
@@ -187,7 +187,7 @@ static payload_rule_t informational_r_payload_rules[] = {
|
||||
/**
|
||||
* Message rule for CREATE_CHILD_SA from initiator.
|
||||
*/
|
||||
static payload_rule_t create_child_sa_r_payload_rules[] = {
|
||||
static payload_rule_t create_child_sa_i_payload_rules[] = {
|
||||
{NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
|
||||
{SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
|
||||
{NONCE,1,1,TRUE,FALSE},
|
||||
@@ -200,7 +200,7 @@ static payload_rule_t create_child_sa_r_payload_rules[] = {
|
||||
/**
|
||||
* Message rule for CREATE_CHILD_SA from responder.
|
||||
*/
|
||||
static payload_rule_t create_child_sa_i_payload_rules[] = {
|
||||
static payload_rule_t create_child_sa_r_payload_rules[] = {
|
||||
{NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
|
||||
{SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
|
||||
{NONCE,1,1,TRUE,FALSE},
|
||||
@@ -220,7 +220,9 @@ static message_rule_t message_rules[] = {
|
||||
{IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules},
|
||||
{IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules},
|
||||
{INFORMATIONAL,TRUE,TRUE,(sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),informational_i_payload_rules},
|
||||
{INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules}
|
||||
{INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules},
|
||||
{CREATE_CHILD_SA,TRUE,TRUE,(sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),create_child_sa_i_payload_rules},
|
||||
{CREATE_CHILD_SA,FALSE,TRUE,(sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),create_child_sa_r_payload_rules},
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -173,12 +173,25 @@ encoding_rule_t notify_payload_encodings[] = {
|
||||
*/
|
||||
static status_t verify(private_notify_payload_t *this)
|
||||
{
|
||||
if (this->protocol_id > 3)
|
||||
switch (this->protocol_id)
|
||||
{
|
||||
/* reserved for future use */
|
||||
return FAILED;
|
||||
case PROTO_IKE:
|
||||
if (this->spi.len != 8)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
case PROTO_AH:
|
||||
case PROTO_ESP:
|
||||
if (this->spi.len != 4)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Check all kinds of notify */
|
||||
|
||||
if (this->notify_message_type == INVALID_KE_PAYLOAD)
|
||||
@@ -265,9 +278,7 @@ static void compute_length (private_notify_payload_t *this)
|
||||
{
|
||||
length += this->spi.len;
|
||||
}
|
||||
|
||||
this->payload_length = length;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +300,7 @@ static void set_protocol_id(private_notify_payload_t *this, u_int8_t protocol_id
|
||||
/**
|
||||
* Implementation of notify_payload_t.get_notify_message_type.
|
||||
*/
|
||||
static u_int16_t get_notify_message_type(private_notify_payload_t *this)
|
||||
static notify_message_type_t get_notify_message_type(private_notify_payload_t *this)
|
||||
{
|
||||
return this->notify_message_type;
|
||||
}
|
||||
@@ -305,32 +316,42 @@ static void set_notify_message_type(private_notify_payload_t *this, u_int16_t no
|
||||
/**
|
||||
* Implementation of notify_payload_t.get_spi.
|
||||
*/
|
||||
static chunk_t get_spi(private_notify_payload_t *this)
|
||||
static u_int64_t get_spi(private_notify_payload_t *this)
|
||||
{
|
||||
return (this->spi);
|
||||
switch (this->protocol_id)
|
||||
{
|
||||
case PROTO_IKE:
|
||||
return *((u_int64_t*)this->spi.ptr);
|
||||
case PROTO_AH:
|
||||
case PROTO_ESP:
|
||||
return *((u_int32_t*)this->spi.ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.set_spi.
|
||||
*/
|
||||
static void set_spi(private_notify_payload_t *this, chunk_t spi)
|
||||
static void set_spi(private_notify_payload_t *this, u_int64_t spi)
|
||||
{
|
||||
/* destroy existing data first */
|
||||
if (this->spi.ptr != NULL)
|
||||
chunk_free(&this->spi);
|
||||
switch (this->protocol_id)
|
||||
{
|
||||
/* free existing value */
|
||||
free(this->spi.ptr);
|
||||
this->spi.ptr = NULL;
|
||||
this->spi.len = 0;
|
||||
|
||||
case PROTO_IKE:
|
||||
this->spi = chunk_alloc(8);
|
||||
*((u_int64_t*)this->spi.ptr) = spi;
|
||||
break;
|
||||
case PROTO_AH:
|
||||
case PROTO_ESP:
|
||||
this->spi = chunk_alloc(4);
|
||||
*((u_int32_t*)this->spi.ptr) = spi;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this->spi.ptr = clalloc(spi.ptr,spi.len);
|
||||
|
||||
this->spi.len = spi.len;
|
||||
this->spi_size = spi.len;
|
||||
this->spi_size = this->spi.len;
|
||||
this->compute_length(this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +397,6 @@ static status_t destroy(private_notify_payload_t *this)
|
||||
{
|
||||
free(this->spi.ptr);
|
||||
}
|
||||
|
||||
free(this);
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -400,10 +420,10 @@ notify_payload_t *notify_payload_create()
|
||||
/* public functions */
|
||||
this->public.get_protocol_id = (u_int8_t (*) (notify_payload_t *)) get_protocol_id;
|
||||
this->public.set_protocol_id = (void (*) (notify_payload_t *,u_int8_t)) set_protocol_id;
|
||||
this->public.get_notify_message_type = (u_int16_t (*) (notify_payload_t *)) get_notify_message_type;
|
||||
this->public.set_notify_message_type = (void (*) (notify_payload_t *,u_int16_t)) set_notify_message_type;
|
||||
this->public.get_spi = (chunk_t (*) (notify_payload_t *)) get_spi;
|
||||
this->public.set_spi = (void (*) (notify_payload_t *,chunk_t)) set_spi;
|
||||
this->public.get_notify_message_type = (notify_message_type_t (*) (notify_payload_t *)) get_notify_message_type;
|
||||
this->public.set_notify_message_type = (void (*) (notify_payload_t *,notify_message_type_t)) set_notify_message_type;
|
||||
this->public.get_spi = (u_int64_t (*) (notify_payload_t *)) get_spi;
|
||||
this->public.set_spi = (void (*) (notify_payload_t *,u_int64_t)) set_spi;
|
||||
this->public.get_notification_data = (chunk_t (*) (notify_payload_t *)) get_notification_data;
|
||||
this->public.set_notification_data = (void (*) (notify_payload_t *,chunk_t)) set_notification_data;
|
||||
this->public.destroy = (void (*) (notify_payload_t *)) destroy;
|
||||
|
||||
@@ -64,7 +64,8 @@ enum notify_message_type_t {
|
||||
INVALID_SELECTORS = 39,
|
||||
|
||||
INITIAL_CONTACT = 16384,
|
||||
SET_WINDOW_SIZE = 16385
|
||||
SET_WINDOW_SIZE = 16385,
|
||||
REKEY_SA = 16393,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -107,46 +108,42 @@ struct notify_payload_t {
|
||||
/**
|
||||
* @brief Sets the protocol id of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param protocol_id protocol id to set
|
||||
* @param this calling notify_payload_t object
|
||||
* @param protocol_id protocol id to set
|
||||
*/
|
||||
void (*set_protocol_id) (notify_payload_t *this, u_int8_t protocol_id);
|
||||
|
||||
/**
|
||||
* @brief Gets the notify message type of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @return notify message type of this payload
|
||||
* @param this calling notify_payload_t object
|
||||
* @return notify message type of this payload
|
||||
*/
|
||||
u_int16_t (*get_notify_message_type) (notify_payload_t *this);
|
||||
notify_message_type_t (*get_notify_message_type) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets notify message type of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param notify_message_type notify message type to set
|
||||
* @param this calling notify_payload_t object
|
||||
* @param type notify message type to set
|
||||
*/
|
||||
void (*set_notify_message_type) (notify_payload_t *this, u_int16_t notify_message_type);
|
||||
void (*set_notify_message_type) (notify_payload_t *this, notify_message_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set spi of this payload.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @return chunk_t pointing to the value
|
||||
* @return SPI value
|
||||
*/
|
||||
chunk_t (*get_spi) (notify_payload_t *this);
|
||||
u_int64_t (*get_spi) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the spi of this payload.
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param spi chunk_t pointing to the value to set
|
||||
* @param this calling notify_payload_t object
|
||||
* @param spi SPI value
|
||||
*/
|
||||
void (*set_spi) (notify_payload_t *this, chunk_t spi);
|
||||
void (*set_spi) (notify_payload_t *this, u_int64_t spi);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set notification data of payload.
|
||||
@@ -163,7 +160,7 @@ struct notify_payload_t {
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param this calling notify_payload_t object
|
||||
* @param notification_data chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_notification_data) (notify_payload_t *this, chunk_t notification_data);
|
||||
|
||||
@@ -61,7 +61,7 @@ struct private_proposal_substructure_t {
|
||||
/**
|
||||
* Proposal number.
|
||||
*/
|
||||
u_int8_t proposal_number;
|
||||
u_int8_t proposal_number;
|
||||
|
||||
/**
|
||||
* Protocol ID.
|
||||
@@ -404,14 +404,17 @@ static size_t get_spi_size (private_proposal_substructure_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.add_to_proposal.
|
||||
* Implementation of proposal_substructure_t.get_proposal.
|
||||
*/
|
||||
void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
|
||||
proposal_t* get_proposal(private_proposal_substructure_t *this)
|
||||
{
|
||||
iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
|
||||
u_int32_t spi;
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
u_int64_t spi;
|
||||
|
||||
proposal = proposal_create(this->protocol_id);
|
||||
|
||||
iterator = this->transforms->create_iterator(this->transforms, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
transform_substructure_t *transform;
|
||||
@@ -425,13 +428,24 @@ void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal
|
||||
transform_id = transform->get_transform_id(transform);
|
||||
transform->get_key_length(transform, &key_length);
|
||||
|
||||
proposal->add_algorithm(proposal, this->protocol_id, transform_type, transform_id, key_length);
|
||||
proposal->add_algorithm(proposal, transform_type, transform_id, key_length);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
spi = *((u_int32_t*)this->spi.ptr);
|
||||
switch (this->spi.len)
|
||||
{
|
||||
case 4:
|
||||
spi = *((u_int32_t*)this->spi.ptr);
|
||||
break;
|
||||
case 8:
|
||||
spi = *((u_int64_t*)this->spi.ptr);
|
||||
break;
|
||||
default:
|
||||
spi = 0;
|
||||
}
|
||||
proposal->set_spi(proposal, spi);
|
||||
|
||||
proposal->set_spi(proposal, this->protocol_id, spi);
|
||||
return proposal;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,7 +541,7 @@ proposal_substructure_t *proposal_substructure_create()
|
||||
this->public.get_protocol_id = (u_int8_t (*) (proposal_substructure_t *)) get_protocol_id;
|
||||
this->public.get_info_for_transform_type = (status_t (*) (proposal_substructure_t *,transform_type_t,u_int16_t *, u_int16_t *))get_info_for_transform_type;
|
||||
this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_proposal;
|
||||
this->public.add_to_proposal = (void (*) (proposal_substructure_t*,proposal_t*))add_to_proposal;
|
||||
this->public.get_proposal = (proposal_t* (*) (proposal_substructure_t*))get_proposal;
|
||||
this->public.set_spi = (void (*) (proposal_substructure_t *,chunk_t))set_spi;
|
||||
this->public.get_spi = (chunk_t (*) (proposal_substructure_t *)) get_spi;
|
||||
this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count;
|
||||
@@ -556,7 +570,7 @@ proposal_substructure_t *proposal_substructure_create()
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto)
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal)
|
||||
{
|
||||
private_proposal_substructure_t *this = (private_proposal_substructure_t*)proposal_substructure_create();
|
||||
iterator_t *iterator;
|
||||
@@ -564,7 +578,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
||||
transform_substructure_t *transform;
|
||||
|
||||
/* encryption algorithm is only availble in ESP */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, ENCRYPTION_ALGORITHM);
|
||||
iterator = proposal->create_algorithm_iterator(proposal, ENCRYPTION_ALGORITHM);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
@@ -574,7 +588,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* integrity algorithms */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, INTEGRITY_ALGORITHM);
|
||||
iterator = proposal->create_algorithm_iterator(proposal, INTEGRITY_ALGORITHM);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
@@ -585,7 +599,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* prf algorithms */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, PSEUDO_RANDOM_FUNCTION);
|
||||
iterator = proposal->create_algorithm_iterator(proposal, PSEUDO_RANDOM_FUNCTION);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
@@ -596,7 +610,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* dh groups */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, DIFFIE_HELLMAN_GROUP);
|
||||
iterator = proposal->create_algorithm_iterator(proposal, DIFFIE_HELLMAN_GROUP);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
@@ -607,7 +621,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* extended sequence numbers */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, EXTENDED_SEQUENCE_NUMBERS);
|
||||
iterator = proposal->create_algorithm_iterator(proposal, EXTENDED_SEQUENCE_NUMBERS);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
@@ -618,12 +632,19 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* take over general infos */
|
||||
this->spi_size = proto == PROTO_IKE ? 8 : 4;
|
||||
this->spi_size = proposal->get_protocol(proposal) == PROTO_IKE ? 8 : 4;
|
||||
this->spi.len = this->spi_size;
|
||||
this->spi.ptr = malloc(this->spi_size);
|
||||
*((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal, proto);
|
||||
this->proposal_number = proposal->get_number(proposal);
|
||||
this->protocol_id = proto;
|
||||
if (this->spi_size == 8)
|
||||
{
|
||||
*((u_int64_t*)this->spi.ptr) = proposal->get_spi(proposal);
|
||||
}
|
||||
else
|
||||
{
|
||||
*((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal);
|
||||
}
|
||||
this->proposal_number = 0;
|
||||
this->protocol_id = proposal->get_protocol(proposal);
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
|
||||
@@ -174,16 +174,12 @@ struct proposal_substructure_t {
|
||||
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
|
||||
|
||||
/**
|
||||
* @brief Add this proposal_substructure to a proposal.
|
||||
*
|
||||
* Since a proposal_t may contain the data of multiple
|
||||
* proposal_sbustructure_t's, it may be necessary to call
|
||||
* the function multiple times with the same proposal.
|
||||
* @brief Get a proposal_t from the propsal_substructure_t.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param proposal proposal where the data should be added
|
||||
* @return proposal_t
|
||||
*/
|
||||
void (*add_to_proposal) (proposal_substructure_t *this, proposal_t *proposal);
|
||||
proposal_t * (*get_proposal) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Clones an proposal_substructure_t object.
|
||||
@@ -211,21 +207,14 @@ struct proposal_substructure_t {
|
||||
proposal_substructure_t *proposal_substructure_create(void);
|
||||
|
||||
/**
|
||||
* @brief Creates a proposal substructure from a proposal.
|
||||
*
|
||||
* Since a child proposal may contain data for both AH and ESP,
|
||||
* the protocol must be specified. If the proposal does not contain
|
||||
* data for proto, NULL is returned. Call twice, once with AH, once
|
||||
* with ESP, with the same proposal to build the two substructures
|
||||
* for it.
|
||||
*
|
||||
* @brief Creates a proposal_substructure_t from a proposal_t.
|
||||
*
|
||||
* @param proposal proposal to build a substruct out of it
|
||||
* @param proto for which protocol the substructure should be built
|
||||
* @return proposal_substructure_t object, or NULL
|
||||
* @return proposal_substructure_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto);
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal);
|
||||
|
||||
|
||||
#endif /*PROPOSAL_SUBSTRUCTURE_H_*/
|
||||
|
||||
@@ -232,18 +232,20 @@ static iterator_t *create_proposal_substructure_iterator (private_sa_payload_t *
|
||||
/**
|
||||
* Implementation of sa_payload_t.add_proposal_substructure.
|
||||
*/
|
||||
static void add_proposal_substructure (private_sa_payload_t *this,proposal_substructure_t *proposal)
|
||||
static void add_proposal_substructure(private_sa_payload_t *this,proposal_substructure_t *proposal)
|
||||
{
|
||||
status_t status;
|
||||
if (this->proposals->get_count(this->proposals) > 0)
|
||||
u_int proposal_count = this->proposals->get_count(this->proposals);
|
||||
|
||||
if (proposal_count > 0)
|
||||
{
|
||||
proposal_substructure_t *last_proposal;
|
||||
status = this->proposals->get_last(this->proposals,(void **) &last_proposal);
|
||||
/* last transform is now not anymore last one */
|
||||
last_proposal->set_is_last_proposal(last_proposal,FALSE);
|
||||
last_proposal->set_is_last_proposal(last_proposal, FALSE);
|
||||
}
|
||||
proposal->set_is_last_proposal(proposal,TRUE);
|
||||
|
||||
proposal->set_is_last_proposal(proposal, TRUE);
|
||||
proposal->set_proposal_number(proposal, proposal_count + 1);
|
||||
this->proposals->insert_last(this->proposals,(void *) proposal);
|
||||
this->compute_length(this);
|
||||
}
|
||||
@@ -254,19 +256,9 @@ static void add_proposal_substructure (private_sa_payload_t *this,proposal_subst
|
||||
static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
|
||||
{
|
||||
proposal_substructure_t *substructure;
|
||||
protocol_id_t proto[2];
|
||||
u_int i;
|
||||
|
||||
/* build the substructures for every protocol */
|
||||
proposal->get_protocols(proposal, proto);
|
||||
for (i = 0; i<2; i++)
|
||||
{
|
||||
if (proto[i] != PROTO_NONE)
|
||||
{
|
||||
substructure = proposal_substructure_create_from_proposal(proposal, proto[i]);
|
||||
add_proposal_substructure(this, substructure);
|
||||
}
|
||||
}
|
||||
substructure = proposal_substructure_create_from_proposal(proposal);
|
||||
add_proposal_substructure(this, substructure);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,30 +266,44 @@ static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
|
||||
*/
|
||||
static linked_list_t *get_proposals(private_sa_payload_t *this)
|
||||
{
|
||||
int proposal_struct_number = 0;
|
||||
int struct_number = 0;
|
||||
int ignore_struct_number = 0;
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
linked_list_t *proposal_list;
|
||||
|
||||
/* this list will hold our proposals */
|
||||
proposal_list = linked_list_create();
|
||||
|
||||
/* iterate over structures, one OR MORE structures will result in a proposal */
|
||||
iterator = this->proposals->create_iterator(this->proposals,TRUE);
|
||||
/* we do not support proposals split up to two proposal substructures, as
|
||||
* AH+ESP bundles are not supported in RFC4301 anymore.
|
||||
* To handle such structures safely, we just skip proposals with multiple
|
||||
* protocols.
|
||||
*/
|
||||
iterator = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
proposal_t *proposal;
|
||||
proposal_substructure_t *proposal_struct;
|
||||
iterator->current(iterator,(void **)&(proposal_struct));
|
||||
|
||||
if (proposal_struct->get_proposal_number(proposal_struct) > proposal_struct_number)
|
||||
iterator->current(iterator, (void **)&proposal_struct);
|
||||
/* check if a proposal has a single protocol */
|
||||
if (proposal_struct->get_proposal_number(proposal_struct) == struct_number)
|
||||
{
|
||||
if (ignore_struct_number < struct_number)
|
||||
{
|
||||
/* remova an already added, if first of series */
|
||||
proposal_list->remove_last(proposal_list, (void**)proposal);
|
||||
proposal->destroy(proposal);
|
||||
ignore_struct_number = struct_number;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
struct_number++;
|
||||
proposal = proposal_struct->get_proposal(proposal_struct);
|
||||
if (proposal)
|
||||
{
|
||||
/* here starts a new proposal, create a new one and add it to the list */
|
||||
proposal_struct_number = proposal_struct->get_proposal_number(proposal_struct);
|
||||
proposal = proposal_create(proposal_struct_number);
|
||||
proposal_list->insert_last(proposal_list, proposal);
|
||||
}
|
||||
/* proposal_substructure_t does the dirty work and builds up the proposal */
|
||||
proposal_struct->add_to_proposal(proposal_struct, proposal);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return proposal_list;
|
||||
@@ -354,7 +360,7 @@ sa_payload_t *sa_payload_create()
|
||||
this->payload_length = SA_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
this->proposals = linked_list_create();
|
||||
return (&(this->public));
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user