Give plugins more control of which configuration attributes to request, and pass received attributes back to the requesting handler
This commit is contained in:
parent
e6cf060275
commit
b5a2055fb1
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -38,17 +38,17 @@ struct private_configuration_attribute_t {
|
|||
/**
|
||||
* Type of the attribute.
|
||||
*/
|
||||
u_int16_t attribute_type;
|
||||
u_int16_t type;
|
||||
|
||||
/**
|
||||
* Length of the attribute.
|
||||
*/
|
||||
u_int16_t attribute_length;
|
||||
u_int16_t length;
|
||||
|
||||
/**
|
||||
* Attribute value as chunk.
|
||||
*/
|
||||
chunk_t attribute_value;
|
||||
chunk_t value;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -56,17 +56,16 @@ struct private_configuration_attribute_t {
|
|||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_configuration_attribute_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t configuration_attribute_encodings[] = {
|
||||
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* type of the attribute as 15 bit unsigned integer */
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_configuration_attribute_t, attribute_type) },
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_configuration_attribute_t, type) },
|
||||
/* Length of attribute value */
|
||||
{ CONFIGURATION_ATTRIBUTE_LENGTH, offsetof(private_configuration_attribute_t, attribute_length)},
|
||||
{ CONFIGURATION_ATTRIBUTE_LENGTH, offsetof(private_configuration_attribute_t, length) },
|
||||
/* Value of attribute if attribute format flag is zero */
|
||||
{ CONFIGURATION_ATTRIBUTE_VALUE, offsetof(private_configuration_attribute_t, attribute_value)}
|
||||
{ CONFIGURATION_ATTRIBUTE_VALUE, offsetof(private_configuration_attribute_t, value) }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -88,13 +87,13 @@ static status_t verify(private_configuration_attribute_t *this)
|
|||
{
|
||||
bool failed = FALSE;
|
||||
|
||||
if (this->attribute_length != this->attribute_value.len)
|
||||
if (this->length != this->value.len)
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid attribute length");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
switch (this->attribute_type)
|
||||
switch (this->type)
|
||||
{
|
||||
case INTERNAL_IP4_ADDRESS:
|
||||
case INTERNAL_IP4_NETMASK:
|
||||
|
@ -102,20 +101,20 @@ static status_t verify(private_configuration_attribute_t *this)
|
|||
case INTERNAL_IP4_NBNS:
|
||||
case INTERNAL_ADDRESS_EXPIRY:
|
||||
case INTERNAL_IP4_DHCP:
|
||||
if (this->attribute_length != 0 && this->attribute_length != 4)
|
||||
if (this->length != 0 && this->length != 4)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case INTERNAL_IP4_SUBNET:
|
||||
if (this->attribute_length != 0 && this->attribute_length != 8)
|
||||
if (this->length != 0 && this->length != 8)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case INTERNAL_IP6_ADDRESS:
|
||||
case INTERNAL_IP6_SUBNET:
|
||||
if (this->attribute_length != 0 && this->attribute_length != 17)
|
||||
if (this->length != 0 && this->length != 17)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
|
@ -123,13 +122,13 @@ static status_t verify(private_configuration_attribute_t *this)
|
|||
case INTERNAL_IP6_DNS:
|
||||
case INTERNAL_IP6_NBNS:
|
||||
case INTERNAL_IP6_DHCP:
|
||||
if (this->attribute_length != 0 && this->attribute_length != 16)
|
||||
if (this->length != 0 && this->length != 16)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case SUPPORTED_ATTRIBUTES:
|
||||
if (this->attribute_length % 2)
|
||||
if (this->length % 2)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
|
@ -139,15 +138,14 @@ static status_t verify(private_configuration_attribute_t *this)
|
|||
break;
|
||||
default:
|
||||
DBG1(DBG_ENC, "unknown attribute type %N",
|
||||
configuration_attribute_type_names, this->attribute_type);
|
||||
configuration_attribute_type_names, this->type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid attribute length %d for %N",
|
||||
this->attribute_length, configuration_attribute_type_names,
|
||||
this->attribute_type);
|
||||
this->length, configuration_attribute_type_names, this->type);
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
@ -156,7 +154,8 @@ static status_t verify(private_configuration_attribute_t *this)
|
|||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_configuration_attribute_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
static void get_encoding_rules(private_configuration_attribute_t *this,
|
||||
encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = configuration_attribute_encodings;
|
||||
*rule_count = sizeof(configuration_attribute_encodings) / sizeof(encoding_rule_t);
|
||||
|
@ -175,13 +174,14 @@ static payload_type_t get_type(private_configuration_attribute_t *this)
|
|||
*/
|
||||
static payload_type_t get_next_type(private_configuration_attribute_t *this)
|
||||
{
|
||||
return (NO_PAYLOAD);
|
||||
return NO_PAYLOAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_configuration_attribute_t *this,payload_type_t type)
|
||||
static void set_next_type(private_configuration_attribute_t *this,
|
||||
payload_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -190,68 +190,32 @@ static void set_next_type(private_configuration_attribute_t *this,payload_type_t
|
|||
*/
|
||||
static size_t get_length(private_configuration_attribute_t *this)
|
||||
{
|
||||
return (this->attribute_value.len + CONFIGURATION_ATTRIBUTE_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.set_value.
|
||||
*/
|
||||
static void set_value(private_configuration_attribute_t *this, chunk_t value)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
chunk_free(&(this->attribute_value));
|
||||
}
|
||||
|
||||
this->attribute_value.ptr = clalloc(value.ptr,value.len);
|
||||
this->attribute_value.len = value.len;
|
||||
|
||||
this->attribute_length = this->attribute_value.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_value.
|
||||
*/
|
||||
static chunk_t get_value (private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->attribute_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.set_type.
|
||||
*/
|
||||
static void set_attribute_type (private_configuration_attribute_t *this, u_int16_t type)
|
||||
{
|
||||
this->attribute_type = type & 0x7FFF;
|
||||
return this->value.len + CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_type.
|
||||
*/
|
||||
static u_int16_t get_attribute_type (private_configuration_attribute_t *this)
|
||||
static configuration_attribute_type_t get_configuration_attribute_type(
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->attribute_type;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_length.
|
||||
* Implementation of configuration_attribute_t.get_value.
|
||||
*/
|
||||
static u_int16_t get_attribute_length (private_configuration_attribute_t *this)
|
||||
static chunk_t get_value(private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->attribute_length;
|
||||
return this->value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.destroy and payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_configuration_attribute_t *this)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
free(this->attribute_value.ptr);
|
||||
}
|
||||
free(this->value.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
@ -260,29 +224,41 @@ static void destroy(private_configuration_attribute_t *this)
|
|||
*/
|
||||
configuration_attribute_t *configuration_attribute_create()
|
||||
{
|
||||
private_configuration_attribute_t *this = malloc_thing(private_configuration_attribute_t);
|
||||
private_configuration_attribute_t *this;
|
||||
|
||||
/* payload interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
this = malloc_thing(private_configuration_attribute_t);
|
||||
this->public.payload_interface.verify = (status_t(*)(payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void(*)(payload_t *, encoding_rule_t **, size_t *) )get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t(*)(payload_t *))get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t(*)(payload_t *))get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void(*)(payload_t *,payload_type_t))set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t(*)(payload_t *))get_type;
|
||||
this->public.payload_interface.destroy = (void(*)(payload_t*))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.set_value = (void (*) (configuration_attribute_t *,chunk_t)) set_value;
|
||||
this->public.get_value = (chunk_t (*) (configuration_attribute_t *)) get_value;
|
||||
this->public.set_type = (void (*) (configuration_attribute_t *,u_int16_t type)) set_attribute_type;
|
||||
this->public.get_type = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_type;
|
||||
this->public.get_length = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_length;
|
||||
this->public.destroy = (void (*) (configuration_attribute_t *)) destroy;
|
||||
this->public.get_value = (chunk_t(*)(configuration_attribute_t *))get_value;
|
||||
this->public.get_type = (configuration_attribute_type_t(*)(configuration_attribute_t *))get_configuration_attribute_type;
|
||||
this->public.destroy = (void (*)(configuration_attribute_t*))destroy;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->attribute_type = 0;
|
||||
this->attribute_value = chunk_empty;
|
||||
this->attribute_length = 0;
|
||||
this->type = 0;
|
||||
this->value = chunk_empty;
|
||||
this->length = 0;
|
||||
|
||||
return (&(this->public));
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create_value(
|
||||
configuration_attribute_type_t type, chunk_t value)
|
||||
{
|
||||
private_configuration_attribute_t *this;
|
||||
|
||||
this = (private_configuration_attribute_t*)configuration_attribute_create();
|
||||
this->type = ((u_int16_t)type) & 0x7FFF;
|
||||
this->value = chunk_clone(value);
|
||||
this->length = value.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -28,7 +28,6 @@ typedef struct configuration_attribute_t configuration_attribute_t;
|
|||
#include <attributes/attributes.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
|
||||
/**
|
||||
* Configuration attribute header length in bytes.
|
||||
*/
|
||||
|
@ -40,50 +39,26 @@ typedef struct configuration_attribute_t configuration_attribute_t;
|
|||
* The CONFIGURATION ATTRIBUTE format is described in RFC section 3.15.1.
|
||||
*/
|
||||
struct configuration_attribute_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
* Implements payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* Returns the currently set value of the attribute.
|
||||
* Get the type of the attribute.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
* @return type of the configuration attribute
|
||||
*/
|
||||
configuration_attribute_type_t (*get_type)(configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Returns the value of the attribute.
|
||||
*
|
||||
* @return chunk_t pointing to the value
|
||||
* @return chunk_t pointing to the internal value
|
||||
*/
|
||||
chunk_t (*get_value) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Sets the value of the attribute.
|
||||
*
|
||||
* Value is getting copied.
|
||||
*
|
||||
* @param value chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_value) (configuration_attribute_t *this, chunk_t value);
|
||||
|
||||
/**
|
||||
* Sets the type of the attribute.
|
||||
*
|
||||
* @param type type to set (most significant bit is set to zero)
|
||||
*/
|
||||
void (*set_type) (configuration_attribute_t *this, u_int16_t type);
|
||||
|
||||
/**
|
||||
* get the type of the attribute.
|
||||
*
|
||||
* @return type of the value
|
||||
*/
|
||||
u_int16_t (*get_type) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* get the length of an attribute.
|
||||
*
|
||||
* @return type of the value
|
||||
*/
|
||||
u_int16_t (*get_length) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an configuration_attribute_t object.
|
||||
*/
|
||||
|
@ -91,10 +66,20 @@ struct configuration_attribute_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates an empty configuration_attribute_t object.
|
||||
* Creates an empty configuration attribute.
|
||||
*
|
||||
* @return created configuration_attribute_t object
|
||||
* @return created configuration attribute
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create(void);
|
||||
configuration_attribute_t *configuration_attribute_create();
|
||||
|
||||
/**
|
||||
* Creates a configuration attribute with type and value.
|
||||
*
|
||||
* @param type type of configuration attribute
|
||||
* @param value value, gets cloned
|
||||
* @return created configuration attribute
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create_value(
|
||||
configuration_attribute_type_t type, chunk_t value);
|
||||
|
||||
#endif /** CONFIGURATION_ATTRIBUTE_H_ @}*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -56,14 +56,14 @@ struct private_cp_payload_t {
|
|||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Configuration Attributes in this payload are stored in a linked_list_t.
|
||||
* List of attributes, as configuration_attribute_t
|
||||
*/
|
||||
linked_list_t * attributes;
|
||||
linked_list_t *attributes;
|
||||
|
||||
/**
|
||||
* Config Type.
|
||||
*/
|
||||
u_int8_t config_type;
|
||||
u_int8_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -90,7 +90,7 @@ encoding_rule_t cp_payload_encodings[] = {
|
|||
{ PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
|
||||
/* Proposals are stored in a proposal substructure,
|
||||
offset points to a linked_list_t pointer */
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, config_type) },
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, type) },
|
||||
{ RESERVED_BYTE,0 },
|
||||
{ RESERVED_BYTE,0 },
|
||||
{ RESERVED_BYTE,0 },
|
||||
|
@ -117,26 +117,27 @@ encoding_rule_t cp_payload_encodings[] = {
|
|||
static status_t verify(private_cp_payload_t *this)
|
||||
{
|
||||
status_t status = SUCCESS;
|
||||
iterator_t *iterator;
|
||||
configuration_attribute_t *attribute;
|
||||
enumerator_t *enumerator;
|
||||
payload_t *attribute;
|
||||
|
||||
iterator = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
while(iterator->iterate(iterator, (void**)&attribute))
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &attribute))
|
||||
{
|
||||
status = attribute->payload_interface.verify(&attribute->payload_interface);
|
||||
status = attribute->verify(attribute);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
enumerator->destroy(enumerator);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_cp_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
static void get_encoding_rules(private_cp_payload_t *this,
|
||||
encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = cp_payload_encodings;
|
||||
*rule_count = sizeof(cp_payload_encodings) / sizeof(encoding_rule_t);
|
||||
|
@ -155,7 +156,7 @@ static payload_type_t get_type(private_cp_payload_t *this)
|
|||
*/
|
||||
static payload_type_t get_next_type(private_cp_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
return this->next_payload;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,18 +172,17 @@ static void set_next_type(private_cp_payload_t *this,payload_type_t type)
|
|||
*/
|
||||
static void compute_length(private_cp_payload_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
payload_t *current_attribute;
|
||||
size_t length = CP_PAYLOAD_HEADER_LENGTH;
|
||||
enumerator_t *enumerator;
|
||||
payload_t *attribute;
|
||||
|
||||
iterator = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
while (iterator->iterate(iterator, (void**)¤t_attribute))
|
||||
this->payload_length = CP_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &attribute))
|
||||
{
|
||||
length += current_attribute->get_length(current_attribute);
|
||||
this->payload_length += attribute->get_length(attribute);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
this->payload_length = length;
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,41 +190,33 @@ static void compute_length(private_cp_payload_t *this)
|
|||
*/
|
||||
static size_t get_length(private_cp_payload_t *this)
|
||||
{
|
||||
compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.create_configuration_attribute_iterator.
|
||||
* Implementation of cp_payload_t.create_attribute_enumerator.
|
||||
*/
|
||||
static iterator_t *create_attribute_iterator (private_cp_payload_t *this)
|
||||
static enumerator_t *create_attribute_enumerator(private_cp_payload_t *this)
|
||||
{
|
||||
return this->attributes->create_iterator(this->attributes, TRUE);
|
||||
return this->attributes->create_enumerator(this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.add_proposal_substructure.
|
||||
* Implementation of cp_payload_t.add_attribute.
|
||||
*/
|
||||
static void add_configuration_attribute (private_cp_payload_t *this,configuration_attribute_t *attribute)
|
||||
static void add_attribute(private_cp_payload_t *this,
|
||||
configuration_attribute_t *attribute)
|
||||
{
|
||||
this->attributes->insert_last(this->attributes,(void *) attribute);
|
||||
this->attributes->insert_last(this->attributes, attribute);
|
||||
compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.set_config_type.
|
||||
* Implementation of cp_payload_t.get_type.
|
||||
*/
|
||||
static void set_config_type (private_cp_payload_t *this,config_type_t config_type)
|
||||
static config_type_t get_config_type(private_cp_payload_t *this)
|
||||
{
|
||||
this->config_type = config_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.get_config_type.
|
||||
*/
|
||||
static config_type_t get_config_type (private_cp_payload_t *this)
|
||||
{
|
||||
return this->config_type;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,7 +225,7 @@ static config_type_t get_config_type (private_cp_payload_t *this)
|
|||
static void destroy(private_cp_payload_t *this)
|
||||
{
|
||||
this->attributes->destroy_offset(this->attributes,
|
||||
offsetof(configuration_attribute_t, destroy));
|
||||
offsetof(configuration_attribute_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
@ -244,7 +236,6 @@ cp_payload_t *cp_payload_create()
|
|||
{
|
||||
private_cp_payload_t *this = malloc_thing(private_cp_payload_t);
|
||||
|
||||
/* public interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
|
@ -253,18 +244,30 @@ cp_payload_t *cp_payload_create()
|
|||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.create_attribute_iterator = (iterator_t* (*) (cp_payload_t *)) create_attribute_iterator;
|
||||
this->public.add_configuration_attribute = (void (*) (cp_payload_t *,configuration_attribute_t *)) add_configuration_attribute;
|
||||
this->public.set_config_type = (void (*) (cp_payload_t *, config_type_t)) set_config_type;
|
||||
this->public.get_config_type = (config_type_t (*) (cp_payload_t *)) get_config_type;
|
||||
this->public.destroy = (void (*) (cp_payload_t *)) destroy;
|
||||
this->public.create_attribute_enumerator = (enumerator_t*(*)(cp_payload_t *))create_attribute_enumerator;
|
||||
this->public.add_attribute = (void (*) (cp_payload_t *,configuration_attribute_t*))add_attribute;
|
||||
this->public.get_type = (config_type_t (*) (cp_payload_t *))get_config_type;
|
||||
this->public.destroy = (void (*)(cp_payload_t *))destroy;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = CP_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
this->attributes = linked_list_create();
|
||||
return (&(this->public));
|
||||
this->type = CFG_REQUEST;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
cp_payload_t *cp_payload_create_type(config_type_t type)
|
||||
{
|
||||
private_cp_payload_t *this = (private_cp_payload_t*)cp_payload_create();
|
||||
|
||||
this->type = type;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -28,7 +28,7 @@ typedef struct cp_payload_t cp_payload_t;
|
|||
#include <library.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/configuration_attribute.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/enumerator.h>
|
||||
|
||||
/**
|
||||
* CP_PAYLOAD length in bytes without any proposal substructure.
|
||||
|
@ -56,6 +56,7 @@ extern enum_name_t *config_type_names;
|
|||
* The CP Payload format is described in RFC section 3.15.
|
||||
*/
|
||||
struct cp_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
|
@ -64,36 +65,24 @@ struct cp_payload_t {
|
|||
/**
|
||||
* Creates an iterator of stored configuration_attribute_t objects.
|
||||
*
|
||||
* When deleting an attribute using this iterator, the length of this
|
||||
* configuration_attribute_t has to be refreshed by calling get_length()!
|
||||
*
|
||||
* @return created iterator_t object
|
||||
* @return enumerator over configration_attribute_T
|
||||
*/
|
||||
iterator_t *(*create_attribute_iterator) (cp_payload_t *this);
|
||||
enumerator_t *(*create_attribute_enumerator) (cp_payload_t *this);
|
||||
|
||||
/**
|
||||
* Adds a configuration_attribute_t object to this object.
|
||||
* Adds a configuration attribute to the configuration payload.
|
||||
*
|
||||
* The added configuration_attribute_t object is getting destroyed in
|
||||
* destroy function of cp_payload_t.
|
||||
*
|
||||
* @param attribute configuration_attribute_t object to add
|
||||
* @param attribute attribute to add
|
||||
*/
|
||||
void (*add_configuration_attribute) (cp_payload_t *this, configuration_attribute_t *attribute);
|
||||
void (*add_attribute)(cp_payload_t *this,
|
||||
configuration_attribute_t *attribute);
|
||||
|
||||
/**
|
||||
* Set the config type.
|
||||
* Get the configuration payload type.
|
||||
*
|
||||
* @param config_type config_type_t to set
|
||||
* @return type of configuration payload
|
||||
*/
|
||||
void (*set_config_type) (cp_payload_t *this,config_type_t config_type);
|
||||
|
||||
/**
|
||||
* Get the config type.
|
||||
*
|
||||
* @return config_type_t
|
||||
*/
|
||||
config_type_t (*get_config_type) (cp_payload_t *this);
|
||||
config_type_t (*get_type) (cp_payload_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an cp_payload_t object.
|
||||
|
@ -102,10 +91,18 @@ struct cp_payload_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates an empty cp_payload_t object
|
||||
* Creates an empty configuration payload
|
||||
*
|
||||
* @return cp_payload_t object
|
||||
* @return empty configuration payload
|
||||
*/
|
||||
cp_payload_t *cp_payload_create(void);
|
||||
cp_payload_t *cp_payload_create();
|
||||
|
||||
/**
|
||||
* Creates an cp_payload_t with type and value
|
||||
*
|
||||
* @param type type of configuration payload to create
|
||||
* @return created configuration payload
|
||||
*/
|
||||
cp_payload_t *cp_payload_create_type(config_type_t config_type);
|
||||
|
||||
#endif /** CP_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -61,12 +61,16 @@ static bool attr_enum_filter(void *null, attribute_entry_t **in,
|
|||
/**
|
||||
* Implementation of attribute_provider_t.create_attribute_enumerator
|
||||
*/
|
||||
static enumerator_t* create_attribute_enumerator(
|
||||
private_attr_provider_t *this, identification_t *id)
|
||||
static enumerator_t* create_attribute_enumerator(private_attr_provider_t *this,
|
||||
identification_t *id, host_t *vip)
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
if (vip)
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
this->attributes->create_enumerator(this->attributes),
|
||||
(void*)attr_enum_filter, NULL, NULL);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +142,7 @@ attr_provider_t *attr_provider_create(database_t *db)
|
|||
|
||||
this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))return_null;
|
||||
this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))return_false;
|
||||
this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))create_attribute_enumerator;
|
||||
this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id, host_t *vip))create_attribute_enumerator;
|
||||
this->public.destroy = (void(*)(attr_provider_t*))destroy;
|
||||
|
||||
this->attributes = linked_list_create();
|
||||
|
|
|
@ -67,6 +67,50 @@ static bool handle(private_nm_handler_t *this, identification_t *server,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of create_attribute_enumerator().enumerate() for WINS
|
||||
*/
|
||||
static bool enumerate_nbns(enumerator_t *this,
|
||||
configuration_attribute_type_t *type, chunk_t *data)
|
||||
{
|
||||
*type = INTERNAL_IP4_NBNS;
|
||||
*data = chunk_empty;
|
||||
/* done */
|
||||
this->enumerate = (void*)return_false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of create_attribute_enumerator().enumerate() for DNS
|
||||
*/
|
||||
static bool enumerate_dns(enumerator_t *this,
|
||||
configuration_attribute_type_t *type, chunk_t *data)
|
||||
{
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
*data = chunk_empty;
|
||||
/* enumerate WINS server as next attribute ... */
|
||||
this->enumerate = (void*)enumerate_nbns;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of attribute_handler_t.create_attribute_enumerator
|
||||
*/
|
||||
static enumerator_t* create_attribute_enumerator(private_nm_handler_t *this,
|
||||
identification_t *server, host_t *vip)
|
||||
{
|
||||
if (vip && vip->get_family(vip) == AF_INET)
|
||||
{ /* no IPv6 attributes yet */
|
||||
enumerator_t *enumerator = malloc_thing(enumerator_t);
|
||||
/* enumerate DNS attribute first ... */
|
||||
enumerator->enumerate = (void*)enumerate_dns;
|
||||
enumerator->destroy = (void*)free;
|
||||
|
||||
return enumerator;
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* convert plain byte ptrs to handy chunk during enumeration
|
||||
*/
|
||||
|
@ -136,6 +180,7 @@ nm_handler_t *nm_handler_create()
|
|||
|
||||
this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
|
||||
this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))nop;
|
||||
this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator;
|
||||
this->public.create_enumerator = (enumerator_t*(*)(nm_handler_t*, configuration_attribute_type_t type))create_enumerator;
|
||||
this->public.reset = (void(*)(nm_handler_t*))reset;
|
||||
this->public.destroy = (void(*)(nm_handler_t*))destroy;
|
||||
|
|
|
@ -163,6 +163,59 @@ static void release(private_resolve_handler_t *this, identification_t *server,
|
|||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute enumerator implementation
|
||||
*/
|
||||
typedef struct {
|
||||
/** implements enumerator_t interface */
|
||||
enumerator_t public;
|
||||
/** virtual IP we are requesting */
|
||||
host_t *vip;
|
||||
} attribute_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of create_attribute_enumerator().enumerate()
|
||||
*/
|
||||
static bool attribute_enumerate(attribute_enumerator_t *this,
|
||||
configuration_attribute_type_t *type, chunk_t *data)
|
||||
{
|
||||
switch (this->vip->get_family(this->vip))
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
*data = chunk_empty;
|
||||
/* enumerate only once */
|
||||
this->public.enumerate = (void*)return_false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of attribute_handler_t.create_attribute_enumerator
|
||||
*/
|
||||
static enumerator_t* create_attribute_enumerator(private_resolve_handler_t *this,
|
||||
identification_t *server, host_t *vip)
|
||||
{
|
||||
if (vip)
|
||||
{
|
||||
attribute_enumerator_t *enumerator;
|
||||
|
||||
enumerator = malloc_thing(attribute_enumerator_t);
|
||||
enumerator->public.enumerate = (void*)attribute_enumerate;
|
||||
enumerator->public.destroy = (void*)free;
|
||||
enumerator->vip = vip;
|
||||
|
||||
return &enumerator->public;
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of resolve_handler_t.destroy.
|
||||
*/
|
||||
|
@ -181,6 +234,7 @@ resolve_handler_t *resolve_handler_create()
|
|||
|
||||
this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
|
||||
this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release;
|
||||
this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator;
|
||||
this->public.destroy = (void(*)(resolve_handler_t*))destroy;
|
||||
|
||||
this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
|
||||
|
|
|
@ -531,7 +531,7 @@ stroke_attribute_t *stroke_attribute_create()
|
|||
|
||||
this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,host_t *))acquire_address;
|
||||
this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
|
||||
this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
|
||||
this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id, host_t *vip))enumerator_create_empty;
|
||||
this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool;
|
||||
this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool;
|
||||
this->public.create_pool_enumerator = (enumerator_t*(*)(stroke_attribute_t*))create_pool_enumerator;
|
||||
|
|
|
@ -1843,22 +1843,16 @@ static status_t roam(private_ike_sa_t *this, bool address)
|
|||
* Implementation of ike_sa_t.add_configuration_attribute
|
||||
*/
|
||||
static void add_configuration_attribute(private_ike_sa_t *this,
|
||||
attribute_handler_t *handler,
|
||||
configuration_attribute_type_t type, chunk_t data)
|
||||
{
|
||||
attribute_entry_t *entry;
|
||||
attribute_handler_t *handler;
|
||||
attribute_entry_t *entry = malloc_thing(attribute_entry_t);
|
||||
|
||||
handler = lib->attributes->handle(lib->attributes, this->other_id,
|
||||
type, data);
|
||||
if (handler)
|
||||
{
|
||||
entry = malloc_thing(attribute_entry_t);
|
||||
entry->handler = handler;
|
||||
entry->type = type;
|
||||
entry->data = chunk_clone(data);
|
||||
entry->handler = handler;
|
||||
entry->type = type;
|
||||
entry->data = chunk_clone(data);
|
||||
|
||||
this->attributes->insert_last(this->attributes, entry);
|
||||
}
|
||||
this->attributes->insert_last(this->attributes, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2091,7 +2085,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||
this->public.get_unique_id = (u_int32_t (*)(ike_sa_t*))get_unique_id;
|
||||
this->public.set_virtual_ip = (void (*)(ike_sa_t*,bool,host_t*))set_virtual_ip;
|
||||
this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip;
|
||||
this->public.add_configuration_attribute = (void(*)(ike_sa_t*, configuration_attribute_type_t type, chunk_t data))add_configuration_attribute;
|
||||
this->public.add_configuration_attribute = (void(*)(ike_sa_t*, attribute_handler_t *handler,configuration_attribute_type_t type, chunk_t data))add_configuration_attribute;
|
||||
this->public.set_kmaddress = (void (*)(ike_sa_t*,host_t*,host_t*))set_kmaddress;
|
||||
#ifdef ME
|
||||
this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server;
|
||||
|
|
|
@ -855,6 +855,7 @@ struct ike_sa_t {
|
|||
* @param data associated attribute data
|
||||
*/
|
||||
void (*add_configuration_attribute)(ike_sa_t *this,
|
||||
attribute_handler_t *handler,
|
||||
configuration_attribute_type_t type, chunk_t data);
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
#include <daemon.h>
|
||||
#include <encoding/payloads/cp_payload.h>
|
||||
|
||||
#define DNS_SERVER_MAX 2
|
||||
#define NBNS_SERVER_MAX 2
|
||||
|
||||
typedef struct private_ike_config_t private_ike_config_t;
|
||||
|
||||
/**
|
||||
|
@ -48,21 +45,34 @@ struct private_ike_config_t {
|
|||
* virtual ip
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
|
||||
/**
|
||||
* list of attributes requested and its handler, entry_t
|
||||
*/
|
||||
linked_list_t *requested;
|
||||
};
|
||||
|
||||
/**
|
||||
* build INTERNAL_IPV4/6_ADDRESS from virtual ip
|
||||
* Entry for a requested attribute and the requesting handler
|
||||
*/
|
||||
static void build_vip(private_ike_config_t *this, host_t *vip, cp_payload_t *cp)
|
||||
{
|
||||
configuration_attribute_t *ca;
|
||||
chunk_t chunk, prefix;
|
||||
typedef struct {
|
||||
/** attribute requested */
|
||||
configuration_attribute_type_t type;
|
||||
/** handler requesting this attribute */
|
||||
attribute_handler_t *handler;
|
||||
} entry_t;
|
||||
|
||||
ca = configuration_attribute_create();
|
||||
/**
|
||||
* build INTERNAL_IPV4/6_ADDRESS attribute from virtual ip
|
||||
*/
|
||||
static configuration_attribute_t *build_vip(host_t *vip)
|
||||
{
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t chunk, prefix;
|
||||
|
||||
if (vip->get_family(vip) == AF_INET)
|
||||
{
|
||||
ca->set_type(ca, INTERNAL_IP4_ADDRESS);
|
||||
type = INTERNAL_IP4_ADDRESS;
|
||||
if (vip->is_anyaddr(vip))
|
||||
{
|
||||
chunk = chunk_empty;
|
||||
|
@ -74,7 +84,7 @@ static void build_vip(private_ike_config_t *this, host_t *vip, cp_payload_t *cp)
|
|||
}
|
||||
else
|
||||
{
|
||||
ca->set_type(ca, INTERNAL_IP6_ADDRESS);
|
||||
type = INTERNAL_IP6_ADDRESS;
|
||||
if (vip->is_anyaddr(vip))
|
||||
{
|
||||
chunk = chunk_empty;
|
||||
|
@ -87,8 +97,41 @@ static void build_vip(private_ike_config_t *this, host_t *vip, cp_payload_t *cp)
|
|||
chunk = chunk_cata("cc", chunk, prefix);
|
||||
}
|
||||
}
|
||||
ca->set_value(ca, chunk);
|
||||
cp->add_configuration_attribute(cp, ca);
|
||||
return configuration_attribute_create_value(type, chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a received attribute as initiator
|
||||
*/
|
||||
static void handle_attribute(private_ike_config_t *this,
|
||||
configuration_attribute_t *ca)
|
||||
{
|
||||
attribute_handler_t *handler = NULL;
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
|
||||
/* find the handler which requested this attribute */
|
||||
enumerator = this->requested->create_enumerator(this->requested);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->type == ca->get_type(ca))
|
||||
{
|
||||
handler = entry->handler;
|
||||
this->requested->remove_at(this->requested, enumerator);
|
||||
free(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* and pass it to the handle function */
|
||||
handler = lib->attributes->handle(lib->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), handler,
|
||||
ca->get_type(ca), ca->get_value(ca));
|
||||
if (handler)
|
||||
{
|
||||
this->ike_sa->add_configuration_attribute(this->ike_sa,
|
||||
handler, ca->get_type(ca), ca->get_value(ca));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,15 +173,12 @@ static void process_attribute(private_ike_config_t *this,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (this->initiator)
|
||||
{
|
||||
this->ike_sa->add_configuration_attribute(this->ike_sa,
|
||||
ca->get_type(ca), ca->get_value(ca));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we do not handle attribute requests other than for VIPs */
|
||||
handle_attribute(this, ca);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,8 +187,7 @@ static void process_attribute(private_ike_config_t *this,
|
|||
*/
|
||||
static void process_payloads(private_ike_config_t *this, message_t *message)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
iterator_t *attributes;
|
||||
enumerator_t *enumerator, *attributes;
|
||||
payload_t *payload;
|
||||
|
||||
enumerator = message->create_payload_enumerator(message);
|
||||
|
@ -158,13 +197,14 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
|
|||
{
|
||||
cp_payload_t *cp = (cp_payload_t*)payload;
|
||||
configuration_attribute_t *ca;
|
||||
switch (cp->get_config_type(cp))
|
||||
|
||||
switch (cp->get_type(cp))
|
||||
{
|
||||
case CFG_REQUEST:
|
||||
case CFG_REPLY:
|
||||
{
|
||||
attributes = cp->create_attribute_iterator(cp);
|
||||
while (attributes->iterate(attributes, (void**)&ca))
|
||||
attributes = cp->create_attribute_enumerator(cp);
|
||||
while (attributes->enumerate(attributes, &ca))
|
||||
{
|
||||
process_attribute(this, ca);
|
||||
}
|
||||
|
@ -173,7 +213,7 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
|
|||
}
|
||||
default:
|
||||
DBG1(DBG_IKE, "ignoring %N config payload",
|
||||
config_type_names, cp->get_config_type(cp));
|
||||
config_type_names, cp->get_type(cp));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +228,12 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
|
|||
{
|
||||
if (message->get_message_id(message) == 1)
|
||||
{ /* in first IKE_AUTH only */
|
||||
cp_payload_t *cp = NULL;
|
||||
enumerator_t *enumerator;
|
||||
attribute_handler_t *handler;
|
||||
peer_cfg_t *config;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t data;
|
||||
host_t *vip;
|
||||
|
||||
/* reuse virtual IP if we already have one */
|
||||
|
@ -199,26 +244,37 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
|
|||
vip = config->get_virtual_ip(config);
|
||||
}
|
||||
if (vip)
|
||||
{
|
||||
cp = cp_payload_create_type(CFG_REQUEST);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
}
|
||||
|
||||
enumerator = lib->attributes->create_initiator_enumerator(lib->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vip);
|
||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
||||
{
|
||||
configuration_attribute_t *ca;
|
||||
cp_payload_t *cp;
|
||||
entry_t *entry;
|
||||
|
||||
cp = cp_payload_create();
|
||||
cp->set_config_type(cp, CFG_REQUEST);
|
||||
|
||||
build_vip(this, vip, cp);
|
||||
|
||||
/* we currently always add a DNS request if we request an IP */
|
||||
ca = configuration_attribute_create();
|
||||
if (vip->get_family(vip) == AF_INET)
|
||||
/* create configuration attribute */
|
||||
ca = configuration_attribute_create_value(type, data);
|
||||
if (!cp)
|
||||
{
|
||||
ca->set_type(ca, INTERNAL_IP4_DNS);
|
||||
cp = cp_payload_create_type(CFG_REQUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
ca->set_type(ca, INTERNAL_IP6_DNS);
|
||||
}
|
||||
cp->add_configuration_attribute(cp, ca);
|
||||
cp->add_attribute(cp, ca);
|
||||
|
||||
/* save handler along with requested type */
|
||||
entry = malloc_thing(entry_t);
|
||||
entry->type = type;
|
||||
entry->handler = handler;
|
||||
|
||||
this->requested->insert_last(this->requested, entry);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
}
|
||||
}
|
||||
|
@ -244,17 +300,16 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
|
|||
{
|
||||
if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
|
||||
{ /* in last IKE_AUTH exchange */
|
||||
peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t value;
|
||||
host_t *vip = NULL;
|
||||
cp_payload_t *cp = NULL;
|
||||
peer_cfg_t *config;
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (config && this->virtual_ip)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
configuration_attribute_t *ca;
|
||||
chunk_t value;
|
||||
cp_payload_t *cp;
|
||||
host_t *vip = NULL;
|
||||
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
||||
if (config->get_pool(config))
|
||||
{
|
||||
|
@ -274,26 +329,29 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
|
|||
DBG1(DBG_IKE, "assigning virtual IP %H to peer", vip);
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
|
||||
|
||||
cp = cp_payload_create();
|
||||
cp->set_config_type(cp, CFG_REPLY);
|
||||
cp = cp_payload_create_type(CFG_REPLY);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
}
|
||||
|
||||
build_vip(this, vip, cp);
|
||||
vip->destroy(vip);
|
||||
|
||||
/* if we add an IP, we also look for other attributes */
|
||||
enumerator = lib->attributes->create_attribute_enumerator(
|
||||
lib->attributes, this->ike_sa->get_other_id(this->ike_sa));
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
/* query registered providers for additional attributes to include */
|
||||
enumerator = lib->attributes->create_responder_enumerator(
|
||||
lib->attributes, this->ike_sa->get_other_id(this->ike_sa), vip);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
if (!cp)
|
||||
{
|
||||
ca = configuration_attribute_create();
|
||||
ca->set_type(ca, type);
|
||||
ca->set_value(ca, value);
|
||||
cp->add_configuration_attribute(cp, ca);
|
||||
cp = cp_payload_create_type(CFG_REPLY);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
cp->add_attribute(cp,
|
||||
configuration_attribute_create_value(type, value));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
}
|
||||
DESTROY_IF(vip);
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
|
@ -335,6 +393,8 @@ static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa)
|
|||
|
||||
this->ike_sa = ike_sa;
|
||||
this->virtual_ip = NULL;
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->requested = linked_list_create();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,6 +403,7 @@ static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa)
|
|||
static void destroy(private_ike_config_t *this)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
@ -360,6 +421,7 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
|
|||
this->initiator = initiator;
|
||||
this->ike_sa = ike_sa;
|
||||
this->virtual_ip = NULL;
|
||||
this->requested = linked_list_create();
|
||||
|
||||
if (initiator)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define ATTRIBUTE_HANDLER_H_
|
||||
|
||||
#include <chunk.h>
|
||||
#include <utils/host.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
#include "attributes.h"
|
||||
|
@ -56,6 +57,16 @@ struct attribute_handler_t {
|
|||
*/
|
||||
void (*release)(attribute_handler_t *this, identification_t *server,
|
||||
configuration_attribute_type_t type, chunk_t data);
|
||||
|
||||
/**
|
||||
* Enumerate attributes to request from a server.
|
||||
*
|
||||
* @param server server identity to request attributes from
|
||||
* @param vip virtual IP we are requesting, if any
|
||||
* @return enumerator (configuration_attribute_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this,
|
||||
identification_t *server, host_t *vip);
|
||||
};
|
||||
|
||||
#endif /** ATTRIBUTE_HANDLER_H_ @}*/
|
||||
|
|
|
@ -47,6 +47,16 @@ struct private_attribute_manager_t {
|
|||
rwlock_t *lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* Data to pass to enumerator filters
|
||||
*/
|
||||
typedef struct {
|
||||
/** server/peer identity */
|
||||
identification_t *id;
|
||||
/** requesting/assigned virtual IP */
|
||||
host_t *vip;
|
||||
} enum_data_t;
|
||||
|
||||
/**
|
||||
* Implementation of attribute_manager_t.acquire_address.
|
||||
*/
|
||||
|
@ -108,25 +118,29 @@ static void release_address(private_attribute_manager_t *this,
|
|||
}
|
||||
|
||||
/**
|
||||
* inner enumerator constructor for attributes
|
||||
* inner enumerator constructor for responder attributes
|
||||
*/
|
||||
static enumerator_t *attrib_enum_create(attribute_provider_t *provider,
|
||||
identification_t *id)
|
||||
static enumerator_t *responder_enum_create(attribute_provider_t *provider,
|
||||
enum_data_t *data)
|
||||
{
|
||||
return provider->create_attribute_enumerator(provider, id);
|
||||
return provider->create_attribute_enumerator(provider, data->id, data->vip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of attribute_manager_t.create_attribute_enumerator
|
||||
* Implementation of attribute_manager_t.create_responder_enumerator
|
||||
*/
|
||||
static enumerator_t* create_attribute_enumerator(
|
||||
private_attribute_manager_t *this, identification_t *id)
|
||||
static enumerator_t* create_responder_enumerator(
|
||||
private_attribute_manager_t *this, identification_t *id, host_t *vip)
|
||||
{
|
||||
enum_data_t *data = malloc_thing(enum_data_t);
|
||||
|
||||
data->id = id;
|
||||
data->vip = vip;
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_cleaner(
|
||||
enumerator_create_nested(
|
||||
this->providers->create_enumerator(this->providers),
|
||||
(void*)attrib_enum_create, id, NULL),
|
||||
(void*)responder_enum_create, data, free),
|
||||
(void*)this->lock->unlock, this->lock);
|
||||
}
|
||||
|
||||
|
@ -156,24 +170,38 @@ static void remove_provider(private_attribute_manager_t *this,
|
|||
* Implementation of attribute_manager_t.handle
|
||||
*/
|
||||
static attribute_handler_t* handle(private_attribute_manager_t *this,
|
||||
identification_t *server,
|
||||
configuration_attribute_type_t type,
|
||||
chunk_t data)
|
||||
identification_t *server, attribute_handler_t *handler,
|
||||
configuration_attribute_type_t type, chunk_t data)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
attribute_handler_t *current, *handled = NULL;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
|
||||
/* try to find the passed handler */
|
||||
enumerator = this->handlers->create_enumerator(this->handlers);
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
if (current->handle(current, server, type, data))
|
||||
if (current == handler && current->handle(current, server, type, data))
|
||||
{
|
||||
handled = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!handled)
|
||||
{ /* handler requesting this attribute not found, try any other */
|
||||
enumerator = this->handlers->create_enumerator(this->handlers);
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
if (current->handle(current, server, type, data))
|
||||
{
|
||||
handled = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
if (!handled)
|
||||
|
@ -209,6 +237,33 @@ static void release(private_attribute_manager_t *this,
|
|||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* inner enumerator constructor for initiator attributes
|
||||
*/
|
||||
static enumerator_t *initiator_enum_create(attribute_handler_t *handler,
|
||||
enum_data_t *data)
|
||||
{
|
||||
return handler->create_attribute_enumerator(handler, data->id, data->vip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of attribute_manager_t.create_initiator_enumerator
|
||||
*/
|
||||
static enumerator_t* create_initiator_enumerator(
|
||||
private_attribute_manager_t *this, identification_t *id, host_t *vip)
|
||||
{
|
||||
enum_data_t *data = malloc_thing(enum_data_t);
|
||||
|
||||
data->id = id;
|
||||
data->vip = vip;
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_cleaner(
|
||||
enumerator_create_nested(
|
||||
this->handlers->create_enumerator(this->handlers),
|
||||
(void*)initiator_enum_create, data, free),
|
||||
(void*)this->lock->unlock, this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of attribute_manager_t.add_handler
|
||||
*/
|
||||
|
@ -251,11 +306,12 @@ attribute_manager_t *attribute_manager_create()
|
|||
|
||||
this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address;
|
||||
this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address;
|
||||
this->public.create_attribute_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*))create_attribute_enumerator;
|
||||
this->public.create_responder_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*, host_t*))create_responder_enumerator;
|
||||
this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
|
||||
this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
|
||||
this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
|
||||
this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*,identification_t*, attribute_handler_t*, configuration_attribute_type_t, chunk_t))handle;
|
||||
this->public.release = (void(*)(attribute_manager_t*, attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release;
|
||||
this->public.create_initiator_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*, host_t*))create_initiator_enumerator;
|
||||
this->public.add_handler = (void(*)(attribute_manager_t*, attribute_handler_t*))add_handler;
|
||||
this->public.remove_handler = (void(*)(attribute_manager_t*, attribute_handler_t*))remove_handler;
|
||||
this->public.destroy = (void(*)(attribute_manager_t*))destroy;
|
||||
|
|
|
@ -62,10 +62,11 @@ struct attribute_manager_t {
|
|||
* Create an enumerator over attributes to hand out to a peer.
|
||||
*
|
||||
* @param id peer identity to hand out attributes to
|
||||
* @param vip virtual IP to assign to peer, if any
|
||||
* @return enumerator (configuration_attribute_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_attribute_enumerator)(attribute_manager_t *this,
|
||||
identification_t *id);
|
||||
enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this,
|
||||
identification_t *id, host_t *vip);
|
||||
|
||||
/**
|
||||
* Register an attribute provider to the manager.
|
||||
|
@ -86,13 +87,14 @@ struct attribute_manager_t {
|
|||
* Handle a configuration attribute by passing them to the handlers.
|
||||
*
|
||||
* @param server server from which the attribute was received
|
||||
* @param handler handler we requested the attribute for, if any
|
||||
* @param type type of configuration attribute
|
||||
* @param data associated attribute data
|
||||
* @return handler which handled this attribute, NULL if none
|
||||
*/
|
||||
attribute_handler_t* (*handle)(attribute_manager_t *this,
|
||||
identification_t *server,
|
||||
configuration_attribute_type_t type, chunk_t data);
|
||||
identification_t *server, attribute_handler_t *handler,
|
||||
configuration_attribute_type_t type, chunk_t data);
|
||||
|
||||
/**
|
||||
* Release an attribute previously handle()d by a handler.
|
||||
|
@ -107,6 +109,16 @@ struct attribute_manager_t {
|
|||
configuration_attribute_type_t type,
|
||||
chunk_t data);
|
||||
|
||||
/**
|
||||
* Create an enumerator over attributes to request from server.
|
||||
*
|
||||
* @param id server identity to hand out attributes to
|
||||
* @param vip virtual IP going to request, if any
|
||||
* @return enumerator (attribute_handler_t, ca_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this,
|
||||
identification_t *id, host_t *vip);
|
||||
|
||||
/**
|
||||
* Register an attribute handler to the manager.
|
||||
*
|
||||
|
|
|
@ -57,10 +57,11 @@ struct attribute_provider_t {
|
|||
* Create an enumerator over attributes to hand out to a peer.
|
||||
*
|
||||
* @param id peer ID
|
||||
* @param vip virtual IP to assign to peer, if any
|
||||
* @return enumerator (configuration_attribute_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
|
||||
identification_t *id);
|
||||
identification_t *id, host_t *vip);
|
||||
};
|
||||
|
||||
#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
|
||||
|
|
|
@ -341,7 +341,7 @@ sql_attribute_t *sql_attribute_create(database_t *db)
|
|||
|
||||
this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))acquire_address;
|
||||
this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
|
||||
this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
|
||||
this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id, host_t *host))enumerator_create_empty;
|
||||
this->public.destroy = (void(*)(sql_attribute_t*))destroy;
|
||||
|
||||
this->db = db;
|
||||
|
|
Loading…
Reference in New Issue