old child_sa gets deleted after rekeying
rekeying almost complete, but: IKE_SA get in an invalid state when both initiate rekeying at the same time,
This commit is contained in:
@@ -71,6 +71,11 @@ struct private_delete_payload_t {
|
||||
* The contained SPI's.
|
||||
*/
|
||||
chunk_t spis;
|
||||
|
||||
/**
|
||||
* List containing u_int32_t spis
|
||||
*/
|
||||
linked_list_t *spi_list;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -121,23 +126,30 @@ encoding_rule_t delete_payload_encodings[] = {
|
||||
*/
|
||||
static status_t verify(private_delete_payload_t *this)
|
||||
{
|
||||
if ((this->protocol_id == 0) ||
|
||||
(this->protocol_id > 3))
|
||||
switch (this->protocol_id)
|
||||
{
|
||||
/* reserved IDs */
|
||||
return FAILED;
|
||||
case PROTO_AH:
|
||||
case PROTO_ESP:
|
||||
if (this->spi_size != 4)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
case PROTO_IKE:
|
||||
case 0:
|
||||
/* IKE deletion has no spi assigned! */
|
||||
if (this->spi_size != 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FAILED;
|
||||
}
|
||||
if (this->spis.len != (this->spi_count * this->spi_size))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
if ((this->protocol_id == PROTO_IKE) && (this->spis.len != 0))
|
||||
{
|
||||
/* IKE deletion has no spi assigned! */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -225,16 +237,15 @@ static void set_spi_count (private_delete_payload_t *this, u_int16_t spi_count)
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_spi_count.
|
||||
*/
|
||||
static u_int16_t get_spi_count (private_delete_payload_t *this)
|
||||
static u_int16_t get_spi_count(private_delete_payload_t *this)
|
||||
{
|
||||
return (this->spi_count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.set_spis.
|
||||
*/
|
||||
static void set_spis (private_delete_payload_t *this, chunk_t spis)
|
||||
static void set_spis(private_delete_payload_t *this, chunk_t spis)
|
||||
{
|
||||
if (this->spis.ptr != NULL)
|
||||
{
|
||||
@@ -254,18 +265,41 @@ static chunk_t get_spis (private_delete_payload_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_spis_clone.
|
||||
* Implementation of delete_payload_t.add_spi.
|
||||
*/
|
||||
static chunk_t get_spis_clone (private_delete_payload_t *this)
|
||||
static void add_spi(private_delete_payload_t *this, u_int32_t spi)
|
||||
{
|
||||
chunk_t cloned_spis;
|
||||
if (this->spis.ptr == NULL)
|
||||
/* only add SPIs if AH|ESP, ignore others */
|
||||
if (this->protocol_id == PROTO_AH || this->protocol_id == PROTO_ESP)
|
||||
{
|
||||
return (this->spis);
|
||||
this->spi_count += 1;
|
||||
this->spis.len += this->spi_size;
|
||||
this->spis.ptr = realloc(this->spis.ptr, this->spis.len);
|
||||
*(u_int32_t*)(this->spis.ptr + (this->spis.len / this->spi_size - 1)) = spi;
|
||||
}
|
||||
cloned_spis.ptr = clalloc(this->spis.ptr,this->spis.len);
|
||||
cloned_spis.len = this->spis.len;
|
||||
return cloned_spis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.create_spi_iterator.
|
||||
*/
|
||||
static iterator_t* create_spi_iterator(private_delete_payload_t *this)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (this->spi_list == NULL)
|
||||
{
|
||||
this->spi_list = linked_list_create();
|
||||
/* only parse SPIs if AH|ESP */
|
||||
if (this->protocol_id == PROTO_AH || this->protocol_id == PROTO_ESP)
|
||||
{
|
||||
for (i = 0; i < this->spi_count; i++)
|
||||
{
|
||||
u_int32_t spi = *(u_int32_t*)(this->spis.ptr + i * this->spi_size);
|
||||
this->spi_list->insert_last(this->spi_list, (void*)spi);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this->spi_list->create_iterator(this->spi_list, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,16 +309,19 @@ static void destroy(private_delete_payload_t *this)
|
||||
{
|
||||
if (this->spis.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->spis));
|
||||
chunk_free(&this->spis);
|
||||
}
|
||||
if (this->spi_list)
|
||||
{
|
||||
this->spi_list->destroy(this->spi_list);
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
delete_payload_t *delete_payload_create()
|
||||
delete_payload_t *delete_payload_create(protocol_id_t protocol_id)
|
||||
{
|
||||
private_delete_payload_t *this = malloc_thing(private_delete_payload_t);
|
||||
|
||||
@@ -306,17 +343,19 @@ delete_payload_t *delete_payload_create()
|
||||
this->public.set_spi_count = (void (*) (delete_payload_t *,u_int16_t)) set_spi_count;
|
||||
this->public.get_spi_count = (u_int16_t (*) (delete_payload_t *)) get_spi_count;
|
||||
this->public.set_spis = (void (*) (delete_payload_t *,chunk_t)) set_spis;
|
||||
this->public.get_spis_clone = (chunk_t (*) (delete_payload_t *)) get_spis_clone;
|
||||
this->public.get_spis = (chunk_t (*) (delete_payload_t *)) get_spis;
|
||||
this->public.add_spi = (void (*) (delete_payload_t *,u_int32_t))add_spi;
|
||||
this->public.create_spi_iterator = (iterator_t* (*) (delete_payload_t *)) create_spi_iterator;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =DELETE_PAYLOAD_HEADER_LENGTH;
|
||||
this->protocol_id = PROTO_NONE;
|
||||
this->spi_size = 0;
|
||||
this->payload_length = DELETE_PAYLOAD_HEADER_LENGTH;
|
||||
this->protocol_id = protocol_id;
|
||||
this->spi_size = protocol_id == PROTO_AH || protocol_id == PROTO_ESP ? 4 : 0;
|
||||
this->spi_count = 0;
|
||||
this->spis = CHUNK_INITIALIZER;
|
||||
this->spi_list = NULL;
|
||||
|
||||
return (&(this->public));
|
||||
return (&this->public);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ struct delete_payload_t {
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param protocol_id protocol ID
|
||||
*
|
||||
* @deprecated is set by constructor
|
||||
*/
|
||||
void (*set_protocol_id) (delete_payload_t *this, protocol_id_t protocol_id);
|
||||
|
||||
@@ -74,10 +76,11 @@ struct delete_payload_t {
|
||||
|
||||
/**
|
||||
* @brief Set the SPI size.
|
||||
*
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param spi_size SPI size
|
||||
*
|
||||
* @deprecated is set by constructor
|
||||
*/
|
||||
void (*set_spi_size) (delete_payload_t *this, u_int8_t spi_size);
|
||||
|
||||
@@ -94,6 +97,8 @@ struct delete_payload_t {
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param spi_count SPI count
|
||||
*
|
||||
* @deprecated is incremented via add_spi
|
||||
*/
|
||||
void (*set_spi_count) (delete_payload_t *this, u_int16_t spi_count);
|
||||
|
||||
@@ -112,19 +117,11 @@ struct delete_payload_t {
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param data SPI's as chunk_t
|
||||
*
|
||||
* @deprecated use add_spi
|
||||
*/
|
||||
void (*set_spis) (delete_payload_t *this, chunk_t spis);
|
||||
|
||||
/**
|
||||
* @brief Get the SPI's.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return SPI's chunk_t
|
||||
*/
|
||||
chunk_t (*get_spis_clone) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the SPI's.
|
||||
*
|
||||
@@ -132,9 +129,30 @@ struct delete_payload_t {
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return SPI's as chunk_t
|
||||
*
|
||||
* @deprecated use create_spi_iterator
|
||||
*/
|
||||
chunk_t (*get_spis) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Add an SPI to the list of deleted SAs.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param spi spi to add
|
||||
*/
|
||||
void (*add_spi) (delete_payload_t *this, u_int32_t spi);
|
||||
|
||||
/**
|
||||
* @brief Get an iterator over the SPIs.
|
||||
*
|
||||
* The resulting interators current() function returns
|
||||
* u_int32_t SPIs directly.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return iterator over SPIs
|
||||
*/
|
||||
iterator_t *(*create_spi_iterator) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an delete_payload_t object.
|
||||
*
|
||||
@@ -146,11 +164,11 @@ struct delete_payload_t {
|
||||
/**
|
||||
* @brief Creates an empty delete_payload_t object.
|
||||
*
|
||||
* @return delete_payload_t object
|
||||
* @param protocol_id protocol, such as AH|ESP
|
||||
* @return delete_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
delete_payload_t *delete_payload_create(void);
|
||||
|
||||
delete_payload_t *delete_payload_create(protocol_id_t protocol_id);
|
||||
|
||||
#endif /* DELETE_PAYLOAD_H_ */
|
||||
|
||||
@@ -113,7 +113,7 @@ payload_t *payload_create(payload_type_t type)
|
||||
case NOTIFY:
|
||||
return (payload_t*)notify_payload_create();
|
||||
case DELETE:
|
||||
return (payload_t*)delete_payload_create();
|
||||
return (payload_t*)delete_payload_create(0);
|
||||
case VENDOR_ID:
|
||||
return (payload_t*)vendor_id_payload_create();
|
||||
case CONFIGURATION:
|
||||
|
||||
Reference in New Issue
Block a user