attr: Only enumerate attributes matching the IKE version of the current IKE_SA
Numerically configured attributes are currently sent for both versions.
This commit is contained in:
@@ -54,6 +54,8 @@ struct attribute_entry_t {
|
||||
configuration_attribute_type_t type;
|
||||
/** attribute value */
|
||||
chunk_t value;
|
||||
/** associated IKE version */
|
||||
ike_version_t ike;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -65,27 +67,52 @@ static void attribute_destroy(attribute_entry_t *this)
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data for attribute enumerator
|
||||
*/
|
||||
typedef struct {
|
||||
rwlock_t *lock;
|
||||
ike_version_t ike;
|
||||
} enumerator_data_t;
|
||||
|
||||
/**
|
||||
* convert enumerator value from attribute_entry
|
||||
*/
|
||||
static bool attr_enum_filter(void *null, attribute_entry_t **in,
|
||||
static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in,
|
||||
configuration_attribute_type_t *type, void* none, chunk_t *value)
|
||||
{
|
||||
*type = (*in)->type;
|
||||
*value = (*in)->value;
|
||||
return TRUE;
|
||||
if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike)
|
||||
{
|
||||
*type = (*in)->type;
|
||||
*value = (*in)->value;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(attr_enum_destroy, void,
|
||||
enumerator_data_t *data)
|
||||
{
|
||||
data->lock->unlock(data->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_attr_provider_t *this, linked_list_t *pools,
|
||||
ike_sa_t *ike_sa, linked_list_t *vips)
|
||||
{
|
||||
enumerator_data_t *data;
|
||||
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
INIT(data,
|
||||
.lock = this->lock,
|
||||
.ike = ike_sa->get_version(ike_sa),
|
||||
);
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->attributes->create_enumerator(this->attributes),
|
||||
(void*)attr_enum_filter, this->lock, (void*)this->lock->unlock);
|
||||
(void*)attr_enum_filter, data, attr_enum_destroy);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
@@ -116,8 +143,6 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
|
||||
host = host_create_from_string(str, 0);
|
||||
if (host)
|
||||
{
|
||||
entry = malloc_thing(attribute_entry_t);
|
||||
|
||||
if (host->get_family(host) == AF_INET6)
|
||||
{
|
||||
switch (type)
|
||||
@@ -132,8 +157,11 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
|
||||
break;
|
||||
}
|
||||
}
|
||||
entry->type = type;
|
||||
entry->value = chunk_clone(host->get_address(host));
|
||||
INIT(entry,
|
||||
.type = type,
|
||||
.value = chunk_clone(host->get_address(host)),
|
||||
.ike = IKE_ANY,
|
||||
);
|
||||
host->destroy(host);
|
||||
DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
|
||||
configuration_attribute_type_names, entry->type, &entry->value);
|
||||
@@ -149,19 +177,20 @@ typedef struct {
|
||||
char *name;
|
||||
configuration_attribute_type_t v4;
|
||||
configuration_attribute_type_t v6;
|
||||
ike_version_t ike;
|
||||
} attribute_type_key_t;
|
||||
|
||||
static attribute_type_key_t keys[] = {
|
||||
{"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS},
|
||||
{"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS},
|
||||
{"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS},
|
||||
{"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP},
|
||||
{"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK},
|
||||
{"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER},
|
||||
{"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET},
|
||||
{"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS},
|
||||
{"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE},
|
||||
{"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN},
|
||||
{"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, IKE_ANY},
|
||||
{"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS, IKE_ANY},
|
||||
{"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS, IKE_ANY},
|
||||
{"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP, IKE_ANY},
|
||||
{"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK, IKE_ANY},
|
||||
{"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, IKE_ANY},
|
||||
{"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET, IKE_ANY},
|
||||
{"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, IKEV2},
|
||||
{"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE, IKEV1},
|
||||
{"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN, IKEV1},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -276,6 +305,7 @@ static void load_entries(private_attr_provider_t *this)
|
||||
INIT(entry,
|
||||
.type = type,
|
||||
.value = data,
|
||||
.ike = mapped ? mapped->ike : IKE_ANY,
|
||||
);
|
||||
DBG2(DBG_CFG, "loaded attribute %N: %#B",
|
||||
configuration_attribute_type_names, entry->type, &entry->value);
|
||||
|
||||
Reference in New Issue
Block a user