aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c47
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.h6
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.c14
3 files changed, 33 insertions, 34 deletions
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index a1c58afb6..66fa8997b 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -650,18 +650,35 @@ static void add_to_proposal_v1_esp(proposal_t *proposal,
transform->get_transform_id(transform), key_length);
}
-METHOD(proposal_substructure_t, get_proposal, proposal_t*,
- private_proposal_substructure_t *this)
+METHOD(proposal_substructure_t, get_proposals, void,
+ private_proposal_substructure_t *this, linked_list_t *proposals)
{
transform_substructure_t *transform;
enumerator_t *enumerator;
- proposal_t *proposal;
+ proposal_t *proposal = NULL;
+ u_int64_t spi = 0;
- proposal = proposal_create(this->protocol_id, this->proposal_number);
+ 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:
+ break;
+ }
enumerator = this->transforms->create_enumerator(this->transforms);
while (enumerator->enumerate(enumerator, &transform))
{
+ if (!proposal)
+ {
+ proposal = proposal_create(this->protocol_id, this->proposal_number);
+ proposal->set_spi(proposal, spi);
+ proposals->insert_last(proposals, proposal);
+ }
if (this->type == PROPOSAL_SUBSTRUCTURE)
{
add_to_proposal_v2(proposal, transform);
@@ -679,27 +696,11 @@ METHOD(proposal_substructure_t, get_proposal, proposal_t*,
default:
break;
}
- /* TODO-IKEv1: We currently accept the first set of transforms
- * in a substructure only. We need to return multiple proposals,
- * but this messes up proposal numbering, as we don't support
- * transform numbering. */
- break;
+ /* create a new proposal for each transform in IKEv1 */
+ proposal = NULL;
}
}
enumerator->destroy(enumerator);
-
- switch (this->spi.len)
- {
- case 4:
- proposal->set_spi(proposal, *((u_int32_t*)this->spi.ptr));
- break;
- case 8:
- proposal->set_spi(proposal, *((u_int64_t*)this->spi.ptr));
- break;
- default:
- break;
- }
- return proposal;
}
METHOD(proposal_substructure_t, create_substructure_enumerator, enumerator_t*,
@@ -741,7 +742,7 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type)
.set_protocol_id = _set_protocol_id,
.get_protocol_id = _get_protocol_id,
.set_is_last_proposal = _set_is_last_proposal,
- .get_proposal = _get_proposal,
+ .get_proposals = _get_proposals,
.create_substructure_enumerator = _create_substructure_enumerator,
.set_spi = _set_spi,
.get_spi = _get_spi,
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.h b/src/libcharon/encoding/payloads/proposal_substructure.h
index 79a6ca238..496a352ca 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.h
+++ b/src/libcharon/encoding/payloads/proposal_substructure.h
@@ -96,11 +96,11 @@ struct proposal_substructure_t {
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
/**
- * Get a proposal_t from the propsal_substructure_t.
+ * Get proposals contained in a propsal_substructure_t.
*
- * @return proposal_t
+ * @param list list to add created proposals to
*/
- proposal_t * (*get_proposal) (proposal_substructure_t *this);
+ void (*get_proposals) (proposal_substructure_t *this, linked_list_t *list);
/**
* Create an enumerator over transform substructures.
diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c
index becc4243d..05695fce2 100644
--- a/src/libcharon/encoding/payloads/sa_payload.c
+++ b/src/libcharon/encoding/payloads/sa_payload.c
@@ -297,8 +297,8 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
int ignore_struct_number = 0;
enumerator_t *enumerator;
proposal_substructure_t *substruct;
- linked_list_t *list;
proposal_t *proposal;
+ linked_list_t *list;
if (this->type == SECURITY_ASSOCIATION_V1)
{ /* IKEv1 proposals start with 0 */
@@ -320,18 +320,16 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
if (ignore_struct_number < struct_number)
{
/* remove an already added, if first of series */
- list->remove_last(list, (void**)&proposal);
- proposal->destroy(proposal);
+ if (list->remove_last(list, (void**)&proposal) == SUCCESS)
+ {
+ proposal->destroy(proposal);
+ }
ignore_struct_number = struct_number;
}
continue;
}
struct_number++;
- proposal = substruct->get_proposal(substruct);
- if (proposal)
- {
- list->insert_last(list, proposal);
- }
+ substruct->get_proposals(substruct, list);
}
enumerator->destroy(enumerator);
return list;