Merge branch 'variadic-enumerators'
This adds several changes to enumerator_t and linked_list_t to improve portability. In particular to Apple's ARM64 iOS platform, whose calling convention for variadic and regular functions are different. This means that assigning a non-variadic function to a variadic function pointer, as we did with our enumerator_t::enumerate() implementations and several callbacks, will result in crashes as the called function will access the arguments differently than the caller provided them. To avoid this issue the enumerator_t interface is now fully variadic. A new mandatory method is added, venumerate(), that takes a va_list with the arguments provided while enumerating. enumerate() is replaced with a generic implementation that prepares a va_list and calls the enumerator's venumerate() implementation. As this allows passing the arguments of one enumerator to another it avoids the five pointer hack used by enumerator_create_nested() and enumerator_create_cleaner(). To simplify the implementation of venumerate() a helper macro is provided that assigns values from a given va_list to local variables. The signature of the callback passed to enumerator_create_filter() has also changed significantly. It's now required to enumerate over the original enumerator in the callback as this avoids the previous in/out pointer hack. The arguments to the outer enumerator are provided in a va_list. Similar changes to avoid such five pointer hacks affect the signatures of the callbacks for linked_list_t's invoke_function() and find_first() methods. For the latter the return type also changed from status_t to bool, which is important as SUCCESS is defined as 0, so checks for == SUCCESS will now fail.
This commit is contained in:
commit
b668bf3f9e
|
@ -120,48 +120,49 @@ typedef struct {
|
|||
identification_t *id;
|
||||
} cert_data_t;
|
||||
|
||||
/**
|
||||
* Destroy CA certificate enumerator data
|
||||
*/
|
||||
static void cert_data_destroy(cert_data_t *data)
|
||||
CALLBACK(cert_data_destroy, void,
|
||||
cert_data_t *data)
|
||||
{
|
||||
data->this->lock->unlock(data->this->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function for certificates enumerator
|
||||
*/
|
||||
static bool cert_filter(cert_data_t *data, certificate_t **in,
|
||||
certificate_t **out)
|
||||
CALLBACK(cert_filter, bool,
|
||||
cert_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
certificate_t *cert = *in;
|
||||
certificate_t *cert, **out;
|
||||
public_key_t *public;
|
||||
|
||||
public = cert->get_public_key(cert);
|
||||
if (!public)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (data->key != KEY_ANY && public->get_type(public) != data->key)
|
||||
{
|
||||
public->destroy(public);
|
||||
return FALSE;
|
||||
}
|
||||
if (data->id && data->id->get_type(data->id) == ID_KEY_ID &&
|
||||
public->has_fingerprint(public, data->id->get_encoding(data->id)))
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &cert))
|
||||
{
|
||||
public = cert->get_public_key(cert);
|
||||
if (!public)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (data->key != KEY_ANY && public->get_type(public) != data->key)
|
||||
{
|
||||
public->destroy(public);
|
||||
continue;
|
||||
}
|
||||
if (data->id && data->id->get_type(data->id) == ID_KEY_ID &&
|
||||
public->has_fingerprint(public, data->id->get_encoding(data->id)))
|
||||
{
|
||||
public->destroy(public);
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
public->destroy(public);
|
||||
if (data->id && !cert->has_subject(cert, data->id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
public->destroy(public);
|
||||
if (data->id && !cert->has_subject(cert, data->id))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,7 +182,7 @@ static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this,
|
|||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->certs->create_enumerator(this->certs),
|
||||
(void*)cert_filter, data, (void*)cert_data_destroy);
|
||||
cert_filter, data, cert_data_destroy);
|
||||
}
|
||||
|
||||
METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
||||
|
@ -235,9 +236,13 @@ typedef struct {
|
|||
} shared_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, shared_enumerate, bool,
|
||||
shared_enumerator_t *this, shared_key_t **key, id_match_t *me,
|
||||
id_match_t *other)
|
||||
shared_enumerator_t *this, va_list args)
|
||||
{
|
||||
shared_key_t **key;
|
||||
id_match_t *me, *other;
|
||||
|
||||
VA_ARGS_VGET(args, key, me, other);
|
||||
|
||||
if (this->done)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -307,7 +312,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_shared_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _shared_enumerate,
|
||||
.destroy = _shared_destroy,
|
||||
},
|
||||
.this = this,
|
||||
|
|
|
@ -65,29 +65,33 @@ METHOD(attribute_handler_t, handle, bool,
|
|||
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)
|
||||
METHOD(enumerator_t, enumerate_nbns, bool,
|
||||
enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
*type = INTERNAL_IP4_NBNS;
|
||||
*data = chunk_empty;
|
||||
/* done */
|
||||
this->enumerate = (void*)return_false;
|
||||
this->venumerate = (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)
|
||||
METHOD(enumerator_t, enumerate_dns, bool,
|
||||
enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
*data = chunk_empty;
|
||||
/* enumerate WINS server as next attribute ... */
|
||||
this->enumerate = (void*)enumerate_nbns;
|
||||
this->venumerate = _enumerate_nbns;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -100,7 +104,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
/* enumerate DNS attribute first ... */
|
||||
.enumerate = (void*)enumerate_dns,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_dns,
|
||||
.destroy = (void*)free,
|
||||
);
|
||||
return enumerator;
|
||||
|
@ -108,13 +113,20 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
|||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* convert plain byte ptrs to handy chunk during enumeration
|
||||
*/
|
||||
static bool filter_chunks(void* null, char **in, chunk_t *out)
|
||||
CALLBACK(filter_chunks, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = chunk_create(*in, 4);
|
||||
return TRUE;
|
||||
chunk_t *out;
|
||||
char *ptr;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &ptr))
|
||||
{
|
||||
*out = chunk_create(ptr, 4);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(nm_handler_t, create_enumerator, enumerator_t*,
|
||||
|
@ -134,7 +146,7 @@ METHOD(nm_handler_t, create_enumerator, enumerator_t*,
|
|||
return enumerator_create_empty();
|
||||
}
|
||||
return enumerator_create_filter(list->create_enumerator(list),
|
||||
(void*)filter_chunks, NULL, NULL);
|
||||
filter_chunks, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(nm_handler_t, reset, void,
|
||||
|
|
|
@ -101,61 +101,63 @@ static void sad_entry_destroy(sad_entry_t *entry)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a list entry with given src, dst, (remote) spi and proto values.
|
||||
*/
|
||||
static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
|
||||
const host_t * const dst, const uint32_t * const spi,
|
||||
const uint8_t * const proto)
|
||||
CALLBACK(sad_entry_match, bool,
|
||||
sad_entry_t * const entry, va_list args)
|
||||
{
|
||||
const host_t *src, *dst;
|
||||
const uint32_t *spi;
|
||||
const uint8_t *proto;
|
||||
|
||||
VA_ARGS_VGET(args, src, dst, spi, proto);
|
||||
|
||||
if (entry->src == NULL || entry->dst == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return src->ip_equals(entry->src, (host_t *)src) &&
|
||||
dst->ip_equals(entry->dst, (host_t *)dst) &&
|
||||
entry->spi_rem == *spi && entry->proto == *proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a list entry with given reqid, spi and proto values.
|
||||
*/
|
||||
static bool sad_entry_match_dst(sad_entry_t * const entry,
|
||||
const uint32_t * const reqid,
|
||||
const uint32_t * const spi,
|
||||
const uint8_t * const proto)
|
||||
CALLBACK(sad_entry_match_dst, bool,
|
||||
sad_entry_t * const entry, va_list args)
|
||||
{
|
||||
const uint32_t *reqid, *spi;
|
||||
const uint8_t *proto;
|
||||
|
||||
VA_ARGS_VGET(args, reqid, spi, proto);
|
||||
return entry->reqid == *reqid &&
|
||||
entry->spi_rem == *spi &&
|
||||
entry->proto == *proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a list entry with given esa id.
|
||||
*/
|
||||
static bool sad_entry_match_esa_id(sad_entry_t * const entry,
|
||||
const esa_id_type * const esa_id)
|
||||
CALLBACK(sad_entry_match_esa_id, bool,
|
||||
sad_entry_t * const entry, va_list args)
|
||||
{
|
||||
const esa_id_type *esa_id;
|
||||
|
||||
VA_ARGS_VGET(args, esa_id);
|
||||
return entry->esa_id == *esa_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a list entry with given reqid and different esa id.
|
||||
*/
|
||||
static bool sad_entry_match_other_esa(sad_entry_t * const entry,
|
||||
const esa_id_type * const esa_id,
|
||||
const uint32_t * const reqid)
|
||||
CALLBACK(sad_entry_match_other_esa, bool,
|
||||
sad_entry_t * const entry, va_list args)
|
||||
{
|
||||
const esa_id_type *esa_id;
|
||||
const uint32_t *reqid;
|
||||
|
||||
VA_ARGS_VGET(args, esa_id, reqid);
|
||||
return entry->reqid == *reqid &&
|
||||
entry->esa_id != *esa_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two SAD entries for equality.
|
||||
*/
|
||||
static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
|
||||
CALLBACK(sad_entry_equal, bool,
|
||||
sad_entry_t * const left, va_list args)
|
||||
{
|
||||
sad_entry_t *right;
|
||||
|
||||
VA_ARGS_VGET(args, right);
|
||||
|
||||
if (left->src == NULL || left->dst == NULL || right->src == NULL ||
|
||||
right->dst == NULL)
|
||||
{
|
||||
|
@ -175,8 +177,8 @@ METHOD(tkm_kernel_sad_t, insert, bool,
|
|||
const uint32_t reqid, const host_t * const src, const host_t * const dst,
|
||||
const uint32_t spi_loc, const uint32_t spi_rem, const uint8_t proto)
|
||||
{
|
||||
status_t result;
|
||||
sad_entry_t *new_entry;
|
||||
bool found;
|
||||
|
||||
INIT(new_entry,
|
||||
.esa_id = esa_id,
|
||||
|
@ -189,10 +191,9 @@ METHOD(tkm_kernel_sad_t, insert, bool,
|
|||
);
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
result = this->data->find_first(this->data,
|
||||
(linked_list_match_t)sad_entry_equal, NULL,
|
||||
found = this->data->find_first(this->data, sad_entry_equal, NULL,
|
||||
new_entry);
|
||||
if (result == NOT_FOUND)
|
||||
if (!found)
|
||||
{
|
||||
DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, "
|
||||
"dst: %H, spi_loc: %x, spi_rem: %x,proto: %u)", esa_id, reqid, src,
|
||||
|
@ -207,7 +208,7 @@ METHOD(tkm_kernel_sad_t, insert, bool,
|
|||
free(new_entry);
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
return result == NOT_FOUND;
|
||||
return !found;
|
||||
}
|
||||
|
||||
METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
|
||||
|
@ -218,11 +219,10 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
|
|||
sad_entry_t *entry = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
const status_t res = this->data->find_first(this->data,
|
||||
(linked_list_match_t)sad_entry_match,
|
||||
(void**)&entry, src, dst, &spi,
|
||||
&proto);
|
||||
if (res == SUCCESS && entry)
|
||||
const bool res = this->data->find_first(this->data, sad_entry_match,
|
||||
(void**)&entry, src, dst, &spi,
|
||||
&proto);
|
||||
if (res && entry)
|
||||
{
|
||||
id = entry->esa_id;
|
||||
DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, "
|
||||
|
@ -243,13 +243,12 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type,
|
|||
esa_id_type id = 0;
|
||||
sad_entry_t *entry = NULL;
|
||||
uint32_t reqid;
|
||||
status_t res;
|
||||
bool res;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
res = this->data->find_first(this->data,
|
||||
(linked_list_match_t)sad_entry_match_esa_id,
|
||||
res = this->data->find_first(this->data, sad_entry_match_esa_id,
|
||||
(void**)&entry, &esa_id);
|
||||
if (res == SUCCESS && entry)
|
||||
if (res && entry)
|
||||
{
|
||||
reqid = entry->reqid;
|
||||
}
|
||||
|
@ -260,10 +259,9 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type,
|
|||
return id;
|
||||
}
|
||||
|
||||
res = this->data->find_first(this->data,
|
||||
(linked_list_match_t)sad_entry_match_other_esa,
|
||||
res = this->data->find_first(this->data, sad_entry_match_other_esa,
|
||||
(void**)&entry, &esa_id, &reqid);
|
||||
if (res == SUCCESS && entry)
|
||||
if (res && entry)
|
||||
{
|
||||
id = entry->esa_id;
|
||||
DBG3(DBG_KNL, "returning ESA id %llu of other SAD entry with reqid %u",
|
||||
|
@ -281,10 +279,9 @@ METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
|
|||
sad_entry_t *entry = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
const status_t res = this->data->find_first(this->data,
|
||||
(linked_list_match_t)sad_entry_match_dst,
|
||||
(void**)&entry, &reqid, &spi, &proto);
|
||||
if (res == SUCCESS && entry)
|
||||
const bool res = this->data->find_first(this->data, sad_entry_match_dst,
|
||||
(void**)&entry, &reqid, &spi, &proto);
|
||||
if (res && entry)
|
||||
{
|
||||
dst = entry->dst;
|
||||
DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u,"
|
||||
|
|
|
@ -36,13 +36,20 @@ struct private_config_t {
|
|||
linked_list_t *configs;
|
||||
};
|
||||
|
||||
/**
|
||||
* filter function for ike configs
|
||||
*/
|
||||
static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
|
||||
CALLBACK(ike_filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = (*in)->get_ike_cfg(*in);
|
||||
return TRUE;
|
||||
peer_cfg_t *cfg;
|
||||
ike_cfg_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &cfg))
|
||||
{
|
||||
*out = cfg->get_ike_cfg(cfg);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
||||
|
@ -51,7 +58,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
|||
|
||||
return enumerator_create_filter(
|
||||
this->configs->create_enumerator(this->configs),
|
||||
(void*)ike_filter, NULL, NULL);
|
||||
ike_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
||||
|
|
|
@ -92,11 +92,12 @@ static void overlay_destroy(overlay_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* compare two overlays by path
|
||||
*/
|
||||
static bool overlay_equals(overlay_t *this, overlay_t *other)
|
||||
CALLBACK(overlay_equals, bool,
|
||||
overlay_t *this, va_list args)
|
||||
{
|
||||
overlay_t *other;
|
||||
|
||||
VA_ARGS_VGET(args, other);
|
||||
return streq(this->path, other->path);
|
||||
}
|
||||
|
||||
|
@ -108,8 +109,8 @@ static bool overlay_remove(private_cowfs_t *this, char *path)
|
|||
{
|
||||
overlay_t over, *current;
|
||||
over.path = path;
|
||||
if (this->overlays->find_first(this->overlays,
|
||||
(linked_list_match_t)overlay_equals, (void**)¤t, &over) != SUCCESS)
|
||||
if (!this->overlays->find_first(this->overlays, overlay_equals,
|
||||
(void**)¤t, &over))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -267,10 +267,12 @@ typedef struct {
|
|||
} template_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, template_enumerate, bool,
|
||||
template_enumerator_t *this, char **template)
|
||||
template_enumerator_t *this, va_list args)
|
||||
{
|
||||
struct stat st;
|
||||
char *rel;
|
||||
char *rel, **template;
|
||||
|
||||
VA_ARGS_VGET(args, template);
|
||||
|
||||
while (this->inner->enumerate(this->inner, &rel, NULL, &st))
|
||||
{
|
||||
|
@ -296,7 +298,8 @@ METHOD(dumm_t, create_template_enumerator, enumerator_t*,
|
|||
template_enumerator_t *enumerator;
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_template_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _template_enumerate,
|
||||
.destroy = (void*)_template_enumerator_destroy,
|
||||
},
|
||||
.inner = enumerator_create_directory(TEMPLATE_DIR),
|
||||
|
|
|
@ -73,20 +73,28 @@ METHOD(attribute_handler_t, release, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_dns6, bool,
|
||||
enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data)
|
||||
enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
*data = chunk_empty;
|
||||
this->enumerate = (void*)return_false;
|
||||
this->venumerate = (void*)return_false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_dns4, bool,
|
||||
enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data)
|
||||
enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
*data = chunk_empty;
|
||||
this->enumerate = (void*)_enumerate_dns6;
|
||||
this->venumerate = _enumerate_dns6;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -96,7 +104,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
|||
enumerator_t *enumerator;
|
||||
|
||||
INIT(enumerator,
|
||||
.enumerate = (void*)_enumerate_dns4,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_dns4,
|
||||
.destroy = (void*)free,
|
||||
);
|
||||
return enumerator;
|
||||
|
|
|
@ -215,7 +215,7 @@ failed:
|
|||
/**
|
||||
* Bypass a single socket
|
||||
*/
|
||||
static bool bypass_single_socket(intptr_t fd, private_charonservice_t *this)
|
||||
static bool bypass_single_socket(private_charonservice_t *this, int fd)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
|
@ -242,16 +242,24 @@ failed:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
CALLBACK(bypass_single_socket_cb, void,
|
||||
intptr_t fd, va_list args)
|
||||
{
|
||||
private_charonservice_t *this;
|
||||
|
||||
VA_ARGS_VGET(args, this);
|
||||
bypass_single_socket(this, fd);
|
||||
}
|
||||
|
||||
METHOD(charonservice_t, bypass_socket, bool,
|
||||
private_charonservice_t *this, int fd, int family)
|
||||
{
|
||||
if (fd >= 0)
|
||||
{
|
||||
this->sockets->insert_last(this->sockets, (void*)(intptr_t)fd);
|
||||
return bypass_single_socket((intptr_t)fd, this);
|
||||
return bypass_single_socket(this, fd);
|
||||
}
|
||||
this->sockets->invoke_function(this->sockets, (void*)bypass_single_socket,
|
||||
this);
|
||||
this->sockets->invoke_function(this->sockets, bypass_single_socket_cb, this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,15 @@ METHOD(kernel_net_t, get_source_addr, host_t*,
|
|||
return host_create_from_sockaddr((sockaddr_t*)&addr);
|
||||
}
|
||||
|
||||
CALLBACK(vip_equals, bool,
|
||||
host_t *vip, va_list args)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
VA_ARGS_VGET(args, host);
|
||||
return host->ip_equals(host, vip);
|
||||
}
|
||||
|
||||
METHOD(kernel_net_t, get_source_addr_old, host_t*,
|
||||
private_android_net_t *this, host_t *dest, host_t *src)
|
||||
{
|
||||
|
@ -179,8 +188,7 @@ METHOD(kernel_net_t, get_source_addr_old, host_t*,
|
|||
if (host)
|
||||
{
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->vips->find_first(this->vips, (void*)host->ip_equals,
|
||||
NULL, host) == SUCCESS)
|
||||
if (this->vips->find_first(this->vips, vip_equals, NULL, host))
|
||||
{
|
||||
host->destroy(host);
|
||||
host = NULL;
|
||||
|
@ -236,8 +244,8 @@ METHOD(kernel_net_t, del_ip, status_t,
|
|||
host_t *vip;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->vips->find_first(this->vips, (void*)virtual_ip->ip_equals,
|
||||
(void**)&vip, virtual_ip) == SUCCESS)
|
||||
if (this->vips->find_first(this->vips, vip_equals, (void**)&vip,
|
||||
virtual_ip))
|
||||
{
|
||||
this->vips->remove(this->vips, vip, NULL);
|
||||
vip->destroy(vip);
|
||||
|
|
|
@ -237,14 +237,14 @@ typedef struct {
|
|||
linked_list_t *vips;
|
||||
} initiator_enumerator_t;
|
||||
|
||||
/**
|
||||
* Enumerator implementation for initiator attributes
|
||||
*/
|
||||
static bool initiator_enumerate(initiator_enumerator_t *this,
|
||||
attribute_handler_t **handler,
|
||||
configuration_attribute_type_t *type,
|
||||
chunk_t *value)
|
||||
METHOD(enumerator_t, initiator_enumerate, bool,
|
||||
initiator_enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
attribute_handler_t **handler;
|
||||
chunk_t *value;
|
||||
|
||||
VA_ARGS_VGET(args, handler, type, value);
|
||||
/* enumerate inner attributes using outer handler enumerator */
|
||||
while (!this->inner || !this->inner->enumerate(this->inner, type, value))
|
||||
{
|
||||
|
@ -261,10 +261,8 @@ static bool initiator_enumerate(initiator_enumerator_t *this,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup function of initiator attribute enumerator
|
||||
*/
|
||||
static void initiator_destroy(initiator_enumerator_t *this)
|
||||
METHOD(enumerator_t, initiator_destroy, void,
|
||||
initiator_enumerator_t *this)
|
||||
{
|
||||
this->this->lock->unlock(this->this->lock);
|
||||
this->outer->destroy(this->outer);
|
||||
|
@ -281,8 +279,9 @@ METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)initiator_enumerate,
|
||||
.destroy = (void*)initiator_destroy,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _initiator_enumerate,
|
||||
.destroy = _initiator_destroy,
|
||||
},
|
||||
.this = this,
|
||||
.ike_sa = ike_sa,
|
||||
|
|
|
@ -512,10 +512,15 @@ typedef struct {
|
|||
} lease_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, lease_enumerate, bool,
|
||||
lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online)
|
||||
lease_enumerator_t *this, va_list args)
|
||||
{
|
||||
u_int *offset;
|
||||
identification_t **id;
|
||||
unique_lease_t *lease;
|
||||
host_t **addr;
|
||||
u_int *offset;
|
||||
bool *online;
|
||||
|
||||
VA_ARGS_VGET(args, id, addr, online);
|
||||
|
||||
DESTROY_IF(this->addr);
|
||||
this->addr = NULL;
|
||||
|
@ -570,7 +575,8 @@ METHOD(mem_pool_t, create_lease_enumerator, enumerator_t*,
|
|||
this->mutex->lock(this->mutex);
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_lease_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _lease_enumerate,
|
||||
.destroy = _lease_enumerator_destroy,
|
||||
},
|
||||
.pool = this,
|
||||
|
|
|
@ -207,20 +207,20 @@ static inline void register_logger(private_bus_t *this, debug_t group,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the log level of the first registered logger that implements log or
|
||||
* vlog (or both).
|
||||
*/
|
||||
static bool find_max_levels(log_entry_t *entry, debug_t *group, level_t *level,
|
||||
level_t *vlevel)
|
||||
CALLBACK(find_max_levels, bool,
|
||||
log_entry_t *entry, va_list args)
|
||||
{
|
||||
level_t *level, *vlevel;
|
||||
debug_t group;
|
||||
|
||||
VA_ARGS_VGET(args, group, level, vlevel);
|
||||
if (entry->logger->log && *level == LEVEL_SILENT)
|
||||
{
|
||||
*level = entry->levels[*group];
|
||||
*level = entry->levels[group];
|
||||
}
|
||||
if (entry->logger->vlog && *vlevel == LEVEL_SILENT)
|
||||
{
|
||||
*vlevel = entry->levels[*group];
|
||||
*vlevel = entry->levels[group];
|
||||
}
|
||||
return *level > LEVEL_SILENT && *vlevel > LEVEL_SILENT;
|
||||
}
|
||||
|
@ -258,8 +258,8 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger)
|
|||
|
||||
loggers = this->loggers[group];
|
||||
loggers->remove(loggers, found, NULL);
|
||||
loggers->find_first(loggers, (linked_list_match_t)find_max_levels,
|
||||
NULL, &group, &level, &vlevel);
|
||||
loggers->find_first(loggers, find_max_levels, NULL, group,
|
||||
&level, &vlevel);
|
||||
set_level(&this->max_level[group], level);
|
||||
set_level(&this->max_vlevel[group], vlevel);
|
||||
}
|
||||
|
@ -330,11 +330,12 @@ typedef struct {
|
|||
va_list args;
|
||||
} log_data_t;
|
||||
|
||||
/**
|
||||
* logger->log() invocation as a invoke_function callback
|
||||
*/
|
||||
static void log_cb(log_entry_t *entry, log_data_t *data)
|
||||
CALLBACK(log_cb, void,
|
||||
log_entry_t *entry, va_list args)
|
||||
{
|
||||
log_data_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, data);
|
||||
if (entry->logger->log && entry->levels[data->group] >= data->level)
|
||||
{
|
||||
entry->logger->log(entry->logger, data->group, data->level,
|
||||
|
@ -342,11 +343,12 @@ static void log_cb(log_entry_t *entry, log_data_t *data)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* logger->vlog() invocation as a invoke_function callback
|
||||
*/
|
||||
static void vlog_cb(log_entry_t *entry, log_data_t *data)
|
||||
CALLBACK(vlog_cb, void,
|
||||
log_entry_t *entry, va_list args)
|
||||
{
|
||||
log_data_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, data);
|
||||
if (entry->logger->vlog && entry->levels[data->group] >= data->level)
|
||||
{
|
||||
va_list copy;
|
||||
|
@ -405,8 +407,7 @@ METHOD(bus_t, vlog, void,
|
|||
}
|
||||
if (len > 0)
|
||||
{
|
||||
loggers->invoke_function(loggers, (linked_list_invoke_t)log_cb,
|
||||
&data);
|
||||
loggers->invoke_function(loggers, log_cb, &data);
|
||||
}
|
||||
if (data.message != buf)
|
||||
{
|
||||
|
@ -422,7 +423,7 @@ METHOD(bus_t, vlog, void,
|
|||
data.message = format;
|
||||
|
||||
va_copy(data.args, args);
|
||||
loggers->invoke_function(loggers, (linked_list_invoke_t)vlog_cb, &data);
|
||||
loggers->invoke_function(loggers, vlog_cb, &data);
|
||||
va_end(data.args);
|
||||
}
|
||||
|
||||
|
|
|
@ -265,20 +265,24 @@ static void peer_enum_destroy(peer_data_t *data)
|
|||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert enumerator value from match_entry to config
|
||||
*/
|
||||
static bool peer_enum_filter(linked_list_t *configs,
|
||||
match_entry_t **in, peer_cfg_t **out)
|
||||
CALLBACK(peer_enum_filter, bool,
|
||||
linked_list_t *configs, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = (*in)->cfg;
|
||||
return TRUE;
|
||||
match_entry_t *entry;
|
||||
peer_cfg_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*out = entry->cfg;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up temporary config list
|
||||
*/
|
||||
static void peer_enum_filter_destroy(linked_list_t *configs)
|
||||
CALLBACK(peer_enum_filter_destroy, void,
|
||||
linked_list_t *configs)
|
||||
{
|
||||
match_entry_t *entry;
|
||||
|
||||
|
@ -379,8 +383,8 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
helper->destroy(helper);
|
||||
|
||||
return enumerator_create_filter(configs->create_enumerator(configs),
|
||||
(void*)peer_enum_filter, configs,
|
||||
(void*)peer_enum_filter_destroy);
|
||||
peer_enum_filter, configs,
|
||||
peer_enum_filter_destroy);
|
||||
}
|
||||
|
||||
METHOD(backend_manager_t, get_peer_cfg_by_name, peer_cfg_t*,
|
||||
|
|
|
@ -165,8 +165,12 @@ METHOD(child_cfg_t, add_proposal, void,
|
|||
}
|
||||
}
|
||||
|
||||
static bool match_proposal(proposal_t *item, proposal_t *proposal)
|
||||
CALLBACK(match_proposal, bool,
|
||||
proposal_t *item, va_list args)
|
||||
{
|
||||
proposal_t *proposal;
|
||||
|
||||
VA_ARGS_VGET(args, proposal);
|
||||
return item->equals(item, proposal);
|
||||
}
|
||||
|
||||
|
@ -185,8 +189,7 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*,
|
|||
{
|
||||
current->strip_dh(current, MODP_NONE);
|
||||
}
|
||||
if (proposals->find_first(proposals, (linked_list_match_t)match_proposal,
|
||||
NULL, current) == SUCCESS)
|
||||
if (proposals->find_first(proposals, match_proposal, NULL, current))
|
||||
{
|
||||
current->destroy(current);
|
||||
continue;
|
||||
|
|
|
@ -209,9 +209,12 @@ typedef struct {
|
|||
} child_cfgs_replace_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, child_cfgs_replace_enumerate, bool,
|
||||
child_cfgs_replace_enumerator_t *this, child_cfg_t **chd, bool *added)
|
||||
child_cfgs_replace_enumerator_t *this, va_list args)
|
||||
{
|
||||
child_cfg_t *child_cfg;
|
||||
child_cfg_t *child_cfg, **chd;
|
||||
bool *added;
|
||||
|
||||
VA_ARGS_VGET(args, chd, added);
|
||||
|
||||
if (!this->wrapped)
|
||||
{
|
||||
|
@ -303,8 +306,9 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_child_cfgs_replace_enumerate,
|
||||
.destroy = (void*)_child_cfgs_replace_enumerator_destroy,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _child_cfgs_replace_enumerate,
|
||||
.destroy = _child_cfgs_replace_enumerator_destroy,
|
||||
},
|
||||
.removed = removed,
|
||||
.added = added,
|
||||
|
@ -336,8 +340,11 @@ METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, child_cfg_enumerate, bool,
|
||||
child_cfg_enumerator_t *this, child_cfg_t **chd)
|
||||
child_cfg_enumerator_t *this, va_list args)
|
||||
{
|
||||
child_cfg_t **chd;
|
||||
|
||||
VA_ARGS_VGET(args, chd);
|
||||
return this->wrapped->enumerate(this->wrapped, chd);
|
||||
}
|
||||
|
||||
|
@ -348,8 +355,9 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_child_cfg_enumerate,
|
||||
.destroy = (void*)_child_cfg_enumerator_destroy,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _child_cfg_enumerate,
|
||||
.destroy = _child_cfg_enumerator_destroy,
|
||||
},
|
||||
.mutex = this->mutex,
|
||||
.wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
|
||||
|
|
|
@ -94,27 +94,31 @@ METHOD(proposal_t, add_algorithm, void,
|
|||
array_insert(this->transforms, ARRAY_TAIL, &entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter function for peer configs
|
||||
*/
|
||||
static bool alg_filter(uintptr_t type, entry_t **in, uint16_t *alg,
|
||||
void **unused, uint16_t *key_size)
|
||||
CALLBACK(alg_filter, bool,
|
||||
uintptr_t type, enumerator_t *orig, va_list args)
|
||||
{
|
||||
entry_t *entry = *in;
|
||||
entry_t *entry;
|
||||
uint16_t *alg, *key_size;
|
||||
|
||||
if (entry->type != type)
|
||||
VA_ARGS_VGET(args, alg, key_size);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
return FALSE;
|
||||
if (entry->type != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (alg)
|
||||
{
|
||||
*alg = entry->alg;
|
||||
}
|
||||
if (key_size)
|
||||
{
|
||||
*key_size = entry->key_size;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (alg)
|
||||
{
|
||||
*alg = entry->alg;
|
||||
}
|
||||
if (key_size)
|
||||
{
|
||||
*key_size = entry->key_size;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(proposal_t, create_enumerator, enumerator_t*,
|
||||
|
@ -122,7 +126,7 @@ METHOD(proposal_t, create_enumerator, enumerator_t*,
|
|||
{
|
||||
return enumerator_create_filter(
|
||||
array_create_enumerator(this->transforms),
|
||||
(void*)alg_filter, (void*)(uintptr_t)type, NULL);
|
||||
alg_filter, (void*)(uintptr_t)type, NULL);
|
||||
}
|
||||
|
||||
METHOD(proposal_t, get_algorithm, bool,
|
||||
|
|
|
@ -282,13 +282,14 @@ static void logger_entry_unregister_destroy(logger_entry_t *this)
|
|||
logger_entry_destroy(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a logger entry by target and whether it is a file or syslog logger
|
||||
*/
|
||||
static bool logger_entry_match(logger_entry_t *this, char *target,
|
||||
logger_type_t *type)
|
||||
CALLBACK(logger_entry_match, bool,
|
||||
logger_entry_t *this, va_list args)
|
||||
{
|
||||
return this->type == *type && streq(this->target, target);
|
||||
logger_type_t type;
|
||||
char *target;
|
||||
|
||||
VA_ARGS_VGET(args, target, type);
|
||||
return this->type == type && streq(this->target, target);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -350,8 +351,8 @@ static logger_entry_t *get_logger_entry(char *target, logger_type_t type,
|
|||
{
|
||||
logger_entry_t *entry;
|
||||
|
||||
if (existing->find_first(existing, (void*)logger_entry_match,
|
||||
(void**)&entry, target, &type) != SUCCESS)
|
||||
if (!existing->find_first(existing, logger_entry_match, (void**)&entry,
|
||||
target, type))
|
||||
{
|
||||
INIT(entry,
|
||||
.target = strdup(target),
|
||||
|
|
|
@ -190,8 +190,12 @@ struct keyid_enumerator_t {
|
|||
};
|
||||
|
||||
METHOD(enumerator_t, keyid_enumerate, bool,
|
||||
keyid_enumerator_t *this, chunk_t *chunk)
|
||||
keyid_enumerator_t *this, va_list args)
|
||||
{
|
||||
chunk_t *chunk;
|
||||
|
||||
VA_ARGS_VGET(args, chunk);
|
||||
|
||||
if (this->pos == NULL)
|
||||
{
|
||||
this->pos = this->full.ptr;
|
||||
|
@ -224,7 +228,8 @@ METHOD(certreq_payload_t, create_keyid_enumerator, enumerator_t*,
|
|||
}
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_keyid_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _keyid_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.full = this->data,
|
||||
|
|
|
@ -306,8 +306,12 @@ typedef struct {
|
|||
} spi_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, spis_enumerate, bool,
|
||||
spi_enumerator_t *this, uint32_t *spi)
|
||||
spi_enumerator_t *this, va_list args)
|
||||
{
|
||||
uint32_t *spi;
|
||||
|
||||
VA_ARGS_VGET(args, spi);
|
||||
|
||||
if (this->spis.len >= sizeof(*spi))
|
||||
{
|
||||
memcpy(spi, this->spis.ptr, sizeof(*spi));
|
||||
|
@ -328,7 +332,8 @@ METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*,
|
|||
}
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_spis_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _spis_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.spis = this->spis,
|
||||
|
|
|
@ -270,8 +270,12 @@ typedef struct {
|
|||
} type_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, enumerate_types, bool,
|
||||
type_enumerator_t *this, eap_type_t *type, uint32_t *vendor)
|
||||
type_enumerator_t *this, va_list args)
|
||||
{
|
||||
eap_type_t *type;
|
||||
uint32_t *vendor;
|
||||
|
||||
VA_ARGS_VGET(args, type, vendor);
|
||||
this->offset = extract_type(this->payload, this->offset, type, vendor);
|
||||
return this->offset;
|
||||
}
|
||||
|
@ -289,7 +293,8 @@ METHOD(eap_payload_t, get_types, enumerator_t*,
|
|||
{
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_enumerate_types,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_types,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.payload = this,
|
||||
|
|
|
@ -632,21 +632,18 @@ METHOD(kernel_interface_t, enable_udp_decap, bool,
|
|||
METHOD(kernel_interface_t, is_interface_usable, bool,
|
||||
private_kernel_interface_t *this, const char *iface)
|
||||
{
|
||||
status_t expected;
|
||||
|
||||
if (!this->ifaces_filter)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS;
|
||||
return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq,
|
||||
NULL, iface) == expected;
|
||||
return this->ifaces_filter->find_first(this->ifaces_filter,
|
||||
linked_list_match_str, NULL, iface) != this->ifaces_exclude;
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, all_interfaces_usable, bool,
|
||||
private_kernel_interface_t *this)
|
||||
{
|
||||
return this->ifaces_filter == NULL;
|
||||
return !this->ifaces_filter;
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, get_address_by_ts, status_t,
|
||||
|
|
|
@ -182,12 +182,15 @@ METHOD(attribute_handler_t, release, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_dns, bool,
|
||||
enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data)
|
||||
enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
*data = chunk_empty;
|
||||
/* stop enumeration */
|
||||
this->enumerate = (void*)return_false;
|
||||
this->venumerate = return_false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -198,7 +201,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
|||
enumerator_t *enumerator;
|
||||
|
||||
INIT(enumerator,
|
||||
.enumerate = (void*)_enumerate_dns,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_dns,
|
||||
.destroy = (void*)free,
|
||||
);
|
||||
return enumerator;
|
||||
|
|
|
@ -75,17 +75,23 @@ typedef struct {
|
|||
ike_version_t ike;
|
||||
} enumerator_data_t;
|
||||
|
||||
/**
|
||||
* convert enumerator value from attribute_entry
|
||||
*/
|
||||
static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in,
|
||||
configuration_attribute_type_t *type, void* none, chunk_t *value)
|
||||
CALLBACK(attr_enum_filter, bool,
|
||||
enumerator_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike)
|
||||
configuration_attribute_type_t *type;
|
||||
attribute_entry_t *entry;
|
||||
chunk_t *value;
|
||||
|
||||
VA_ARGS_VGET(args, type, value);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*type = (*in)->type;
|
||||
*value = (*in)->value;
|
||||
return TRUE;
|
||||
if (entry->ike == IKE_ANY || entry->ike == data->ike)
|
||||
{
|
||||
*type = entry->type;
|
||||
*value = entry->value;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -112,7 +118,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
|||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->attributes->create_enumerator(this->attributes),
|
||||
(void*)attr_enum_filter, data, attr_enum_destroy);
|
||||
attr_enum_filter, data, attr_enum_destroy);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
|
|
@ -110,15 +110,12 @@ static bool policy_equals(bypass_policy_t *a, bypass_policy_t *b)
|
|||
*/
|
||||
static bool consider_interface(private_bypass_lan_listener_t *this, char *iface)
|
||||
{
|
||||
status_t expected;
|
||||
|
||||
if (!iface || !this->ifaces_filter)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS;
|
||||
return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq,
|
||||
NULL, iface) == expected;
|
||||
return this->ifaces_filter->find_first(this->ifaces_filter,
|
||||
linked_list_match_str, NULL, iface) != this->ifaces_exclude;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -151,8 +151,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
|||
identification_t *id;
|
||||
host_t *vip;
|
||||
|
||||
if (pools->find_first(pools, (linked_list_match_t)streq,
|
||||
NULL, "dhcp") != SUCCESS)
|
||||
if (!pools->find_first(pools, linked_list_match_str, NULL, "dhcp"))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -382,8 +382,7 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*,
|
|||
while (try <= DHCP_TRIES && discover(this, transaction))
|
||||
{
|
||||
if (!this->condvar->timed_wait(this->condvar, this->mutex, 1000 * try) &&
|
||||
this->request->find_first(this->request, NULL,
|
||||
(void**)&transaction) == SUCCESS)
|
||||
this->request->find_first(this->request, NULL, (void**)&transaction))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -114,16 +114,22 @@ METHOD(dhcp_transaction_t, add_attribute, void,
|
|||
this->attributes->insert_last(this->attributes, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to map entries to type/data
|
||||
*/
|
||||
static bool attribute_filter(void *null, attribute_entry_t **entry,
|
||||
configuration_attribute_type_t *type,
|
||||
void **dummy, chunk_t *data)
|
||||
CALLBACK(attribute_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*type = (*entry)->type;
|
||||
*data = (*entry)->data;
|
||||
return TRUE;
|
||||
configuration_attribute_type_t *type;
|
||||
attribute_entry_t *entry;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*type = entry->type;
|
||||
*data = entry->data;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*,
|
||||
|
@ -131,7 +137,7 @@ METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*,
|
|||
{
|
||||
return enumerator_create_filter(
|
||||
this->attributes->create_enumerator(this->attributes),
|
||||
(void*)attribute_filter, NULL, NULL);
|
||||
attribute_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,12 +75,15 @@ typedef struct {
|
|||
} cert_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, cert_enumerator_enumerate, bool,
|
||||
cert_enumerator_t *this, certificate_t **cert)
|
||||
cert_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t **cert;
|
||||
dnscert_t *cur_crt;
|
||||
rr_t *cur_rr;
|
||||
chunk_t certificate;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
|
||||
/* Get the next supported CERT using the inner enumerator. */
|
||||
while (this->inner->enumerate(this->inner, &cur_rr))
|
||||
{
|
||||
|
@ -175,7 +178,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_cert_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _cert_enumerator_enumerate,
|
||||
.destroy = _cert_enumerator_destroy,
|
||||
},
|
||||
.inner = response->get_rr_set(response)->create_rr_enumerator(
|
||||
|
|
|
@ -69,6 +69,15 @@ static bool entry_matches(eap_vendor_type_t *item, eap_vendor_type_t *other)
|
|||
return item->type == other->type && item->vendor == other->vendor;
|
||||
}
|
||||
|
||||
CALLBACK(entry_matches_cb, bool,
|
||||
eap_vendor_type_t *item, va_list args)
|
||||
{
|
||||
eap_vendor_type_t *other;
|
||||
|
||||
VA_ARGS_VGET(args, other);
|
||||
return entry_matches(item, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given EAP method
|
||||
*/
|
||||
|
@ -121,8 +130,7 @@ static void select_method(private_eap_dynamic_t *this)
|
|||
{
|
||||
if (inner)
|
||||
{
|
||||
if (inner->find_first(inner, (void*)entry_matches,
|
||||
NULL, entry) != SUCCESS)
|
||||
if (!inner->find_first(inner, entry_matches_cb, NULL, entry))
|
||||
{
|
||||
if (entry->vendor)
|
||||
{
|
||||
|
|
|
@ -404,11 +404,13 @@ typedef struct {
|
|||
attr_t *current;
|
||||
} attribute_enumerator_t;
|
||||
|
||||
|
||||
METHOD(enumerator_t, attribute_enumerate, bool,
|
||||
attribute_enumerator_t *this, configuration_attribute_type_t *type,
|
||||
chunk_t *data)
|
||||
attribute_enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
if (this->current)
|
||||
{
|
||||
destroy_attr(this->current);
|
||||
|
@ -446,7 +448,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_attribute_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _attribute_enumerate,
|
||||
.destroy = _attribute_destroy,
|
||||
},
|
||||
.list = linked_list_create(),
|
||||
|
|
|
@ -79,10 +79,8 @@ typedef struct {
|
|||
private_eap_sim_file_triplets_t *this;
|
||||
} triplet_enumerator_t;
|
||||
|
||||
/**
|
||||
* destroy a triplet enumerator
|
||||
*/
|
||||
static void enumerator_destroy(triplet_enumerator_t *e)
|
||||
METHOD(enumerator_t, enumerator_destroy, void,
|
||||
triplet_enumerator_t *e)
|
||||
{
|
||||
if (e->current)
|
||||
{
|
||||
|
@ -97,13 +95,14 @@ static void enumerator_destroy(triplet_enumerator_t *e)
|
|||
free(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerate through triplets
|
||||
*/
|
||||
static bool enumerator_enumerate(triplet_enumerator_t *e, identification_t **imsi,
|
||||
char **rand, char **sres, char **kc)
|
||||
METHOD(enumerator_t, enumerator_enumerate, bool,
|
||||
triplet_enumerator_t *e, va_list args)
|
||||
{
|
||||
identification_t **imsi;
|
||||
triplet_t *triplet;
|
||||
char **rand, **sres, **kc;
|
||||
|
||||
VA_ARGS_VGET(args, imsi, rand, sres, kc);
|
||||
|
||||
if (e->inner->enumerate(e->inner, &triplet))
|
||||
{
|
||||
|
@ -124,12 +123,15 @@ METHOD(eap_sim_file_triplets_t, create_enumerator, enumerator_t*,
|
|||
triplet_enumerator_t *enumerator = malloc_thing(triplet_enumerator_t);
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator->public.enumerate = (void*)enumerator_enumerate;
|
||||
enumerator->public.destroy = (void*)enumerator_destroy;
|
||||
enumerator->inner = this->triplets->create_enumerator(this->triplets);
|
||||
enumerator->current = NULL;
|
||||
enumerator->this = this;
|
||||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerator_enumerate,
|
||||
.destroy = _enumerator_destroy,
|
||||
},
|
||||
.inner = this->triplets->create_enumerator(this->triplets),
|
||||
.this = this,
|
||||
);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -613,17 +613,23 @@ METHOD(listener_t, ike_update, bool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to map entries to ts/mark
|
||||
*/
|
||||
static bool ts_filter(entry_t *entry, traffic_selector_t **ts,
|
||||
traffic_selector_t **out, void *dummy, uint32_t *mark,
|
||||
void *dummy2, bool *reinject)
|
||||
CALLBACK(ts_filter, bool,
|
||||
entry_t *entry, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = *ts;
|
||||
*mark = entry->mark;
|
||||
*reinject = entry->reinject;
|
||||
return TRUE;
|
||||
traffic_selector_t *ts, **out;
|
||||
uint32_t *mark;
|
||||
bool *reinject;
|
||||
|
||||
VA_ARGS_VGET(args, out, mark, reinject);
|
||||
|
||||
if (orig->enumerate(orig, &ts))
|
||||
{
|
||||
*out = ts;
|
||||
*mark = entry->mark;
|
||||
*reinject = entry->reinject;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -632,7 +638,7 @@ static bool ts_filter(entry_t *entry, traffic_selector_t **ts,
|
|||
static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock)
|
||||
{
|
||||
return enumerator_create_filter(array_create_enumerator(entry->lts),
|
||||
(void*)ts_filter, entry, NULL);
|
||||
ts_filter, entry, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -641,7 +647,7 @@ static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock)
|
|||
static enumerator_t* create_inner_remote(entry_t *entry, rwlock_t *lock)
|
||||
{
|
||||
return enumerator_create_filter(array_create_enumerator(entry->rts),
|
||||
(void*)ts_filter, entry, NULL);
|
||||
ts_filter, entry, NULL);
|
||||
}
|
||||
|
||||
METHOD(forecast_listener_t, create_enumerator, enumerator_t*,
|
||||
|
|
|
@ -331,10 +331,12 @@ typedef struct {
|
|||
} attribute_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, attribute_enumerate, bool,
|
||||
attribute_enumerator_t *this, ha_message_attribute_t *attr_out,
|
||||
ha_message_value_t *value)
|
||||
attribute_enumerator_t *this, va_list args)
|
||||
{
|
||||
ha_message_attribute_t attr;
|
||||
ha_message_attribute_t attr, *attr_out;
|
||||
ha_message_value_t *value;
|
||||
|
||||
VA_ARGS_VGET(args, attr_out, value);
|
||||
|
||||
if (this->cleanup)
|
||||
{
|
||||
|
@ -602,7 +604,8 @@ METHOD(ha_message_t, create_attribute_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_attribute_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _attribute_enumerate,
|
||||
.destroy = _enum_destroy,
|
||||
},
|
||||
.buf = chunk_skip(this->buf, 2),
|
||||
|
|
|
@ -111,8 +111,12 @@ typedef struct {
|
|||
} shared_enum_t;
|
||||
|
||||
METHOD(enumerator_t, shared_enumerate, bool,
|
||||
shared_enum_t *this, shared_key_t **key, id_match_t *me, id_match_t *other)
|
||||
shared_enum_t *this, va_list args)
|
||||
{
|
||||
shared_key_t **key;
|
||||
id_match_t *me, *other;
|
||||
|
||||
VA_ARGS_VGET(args, key, me, other);
|
||||
if (this->key)
|
||||
{
|
||||
if (me)
|
||||
|
@ -151,7 +155,8 @@ METHOD(ha_creds_t, create_shared_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_shared_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _shared_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.key = this->key,
|
||||
|
|
|
@ -62,13 +62,16 @@ typedef struct {
|
|||
} cert_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, cert_enumerator_enumerate, bool,
|
||||
cert_enumerator_t *this, certificate_t **cert)
|
||||
cert_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t **cert;
|
||||
ipseckey_t *cur_ipseckey;
|
||||
public_key_t *public;
|
||||
rr_t *cur_rr;
|
||||
chunk_t key;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
|
||||
/* Get the next supported IPSECKEY using the inner enumerator. */
|
||||
while (this->inner->enumerate(this->inner, &cur_rr))
|
||||
{
|
||||
|
@ -211,7 +214,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_cert_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _cert_enumerator_enumerate,
|
||||
.destroy = _cert_enumerator_destroy,
|
||||
},
|
||||
.inner = rrset->create_rr_enumerator(rrset),
|
||||
|
|
|
@ -466,9 +466,12 @@ typedef struct {
|
|||
} addr_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, addr_enumerate, bool,
|
||||
addr_enumerator_t *this, host_t **host)
|
||||
addr_enumerator_t *this, va_list args)
|
||||
{
|
||||
iface_t *entry;
|
||||
host_t **host;
|
||||
|
||||
VA_ARGS_VGET(args, host);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
|
@ -523,7 +526,8 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_addr_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _addr_enumerate,
|
||||
.destroy = _addr_destroy,
|
||||
},
|
||||
.which = which,
|
||||
|
|
|
@ -84,12 +84,12 @@ static void exclude_route_destroy(exclude_route_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an exclude route entry by destination address
|
||||
*/
|
||||
static bool exclude_route_match(exclude_route_t *current,
|
||||
host_t *dst)
|
||||
CALLBACK(exclude_route_match, bool,
|
||||
exclude_route_t *current, va_list args)
|
||||
{
|
||||
host_t *dst;
|
||||
|
||||
VA_ARGS_VGET(args, dst);
|
||||
return dst->ip_equals(dst, current->dst);
|
||||
}
|
||||
|
||||
|
@ -204,12 +204,12 @@ static void policy_entry_destroy(policy_entry_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two policy_entry_t objects
|
||||
*/
|
||||
static inline bool policy_entry_equals(policy_entry_t *a,
|
||||
policy_entry_t *b)
|
||||
CALLBACK(policy_entry_equals, bool,
|
||||
policy_entry_t *a, va_list args)
|
||||
{
|
||||
policy_entry_t *b;
|
||||
|
||||
VA_ARGS_VGET(args, b);
|
||||
return a->direction == b->direction &&
|
||||
a->src.proto == b->src.proto &&
|
||||
a->dst.proto == b->dst.proto &&
|
||||
|
@ -297,9 +297,8 @@ static void add_exclude_route(private_kernel_libipsec_ipsec_t *this,
|
|||
exclude_route_t *exclude;
|
||||
host_t *gtw;
|
||||
|
||||
if (this->excludes->find_first(this->excludes,
|
||||
(linked_list_match_t)exclude_route_match,
|
||||
(void**)&exclude, dst) == SUCCESS)
|
||||
if (this->excludes->find_first(this->excludes, exclude_route_match,
|
||||
(void**)&exclude, dst))
|
||||
{
|
||||
route->exclude = exclude;
|
||||
exclude->refs++;
|
||||
|
@ -524,9 +523,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir);
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies,
|
||||
(linked_list_match_t)policy_entry_equals,
|
||||
(void**)&found, policy) == SUCCESS)
|
||||
if (this->policies->find_first(this->policies, policy_entry_equals,
|
||||
(void**)&found, policy))
|
||||
{
|
||||
policy_entry_destroy(policy);
|
||||
policy = found;
|
||||
|
@ -567,9 +565,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir);
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies,
|
||||
(linked_list_match_t)policy_entry_equals,
|
||||
(void**)&found, policy) != SUCCESS)
|
||||
if (!this->policies->find_first(this->policies, policy_entry_equals,
|
||||
(void**)&found, policy))
|
||||
{
|
||||
policy_entry_destroy(policy);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
|
|
@ -542,10 +542,10 @@ static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
|
|||
/**
|
||||
* Destroy a policy_sa(_in)_t object
|
||||
*/
|
||||
static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
|
||||
static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t dir,
|
||||
private_kernel_netlink_ipsec_t *this)
|
||||
{
|
||||
if (*dir == POLICY_OUT)
|
||||
if (dir == POLICY_OUT)
|
||||
{
|
||||
policy_sa_out_t *out = (policy_sa_out_t*)policy;
|
||||
out->src_ts->destroy(out->src_ts);
|
||||
|
@ -555,6 +555,16 @@ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
|
|||
free(policy);
|
||||
}
|
||||
|
||||
CALLBACK(policy_sa_destroy_cb, void,
|
||||
policy_sa_t *policy, va_list args)
|
||||
{
|
||||
private_kernel_netlink_ipsec_t *this;
|
||||
policy_dir_t dir;
|
||||
|
||||
VA_ARGS_VGET(args, dir, this);
|
||||
policy_sa_destroy(policy, dir, this);
|
||||
}
|
||||
|
||||
typedef struct policy_entry_t policy_entry_t;
|
||||
|
||||
/**
|
||||
|
@ -599,9 +609,8 @@ static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this,
|
|||
}
|
||||
if (policy->used_by)
|
||||
{
|
||||
policy->used_by->invoke_function(policy->used_by,
|
||||
(linked_list_invoke_t)policy_sa_destroy,
|
||||
&policy->direction, this);
|
||||
policy->used_by->invoke_function(policy->used_by, policy_sa_destroy_cb,
|
||||
policy->direction, this);
|
||||
policy->used_by->destroy(policy->used_by);
|
||||
}
|
||||
free(policy);
|
||||
|
@ -2768,7 +2777,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
ipsec_sa_equals(mapping->sa, &assigned_sa))
|
||||
{
|
||||
current->used_by->remove_at(current->used_by, enumerator);
|
||||
policy_sa_destroy(mapping, &id->dir, this);
|
||||
policy_sa_destroy(mapping, id->dir, this);
|
||||
break;
|
||||
}
|
||||
if (is_installed)
|
||||
|
|
|
@ -163,19 +163,21 @@ static void iface_entry_destroy(iface_entry_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* find an interface entry by index
|
||||
*/
|
||||
static bool iface_entry_by_index(iface_entry_t *this, int *ifindex)
|
||||
CALLBACK(iface_entry_by_index, bool,
|
||||
iface_entry_t *this, va_list args)
|
||||
{
|
||||
return this->ifindex == *ifindex;
|
||||
int ifindex;
|
||||
|
||||
VA_ARGS_VGET(args, ifindex);
|
||||
return this->ifindex == ifindex;
|
||||
}
|
||||
|
||||
/**
|
||||
* find an interface entry by name
|
||||
*/
|
||||
static bool iface_entry_by_name(iface_entry_t *this, char *ifname)
|
||||
CALLBACK(iface_entry_by_name, bool,
|
||||
iface_entry_t *this, va_list args)
|
||||
{
|
||||
char *ifname;
|
||||
|
||||
VA_ARGS_VGET(args, ifname);
|
||||
return streq(this->ifname, ifname);
|
||||
}
|
||||
|
||||
|
@ -1112,8 +1114,8 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this,
|
|||
{
|
||||
iface_entry_t *iface;
|
||||
|
||||
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index,
|
||||
(void**)&iface, &index) == SUCCESS)
|
||||
if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
|
||||
(void**)&iface, index))
|
||||
{
|
||||
return iface_entry_up_and_usable(iface);
|
||||
}
|
||||
|
@ -1125,9 +1127,13 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this,
|
|||
*
|
||||
* this->lock must be locked when calling this function
|
||||
*/
|
||||
static void addr_entry_unregister(addr_entry_t *addr, iface_entry_t *iface,
|
||||
private_kernel_netlink_net_t *this)
|
||||
CALLBACK(addr_entry_unregister, void,
|
||||
addr_entry_t *addr, va_list args)
|
||||
{
|
||||
private_kernel_netlink_net_t *this;
|
||||
iface_entry_t *iface;
|
||||
|
||||
VA_ARGS_VGET(args, iface, this);
|
||||
if (addr->refcount)
|
||||
{
|
||||
addr_map_entry_remove(this->vips, addr, iface);
|
||||
|
@ -1171,9 +1177,8 @@ static void process_link(private_kernel_netlink_net_t *this,
|
|||
{
|
||||
case RTM_NEWLINK:
|
||||
{
|
||||
if (this->ifaces->find_first(this->ifaces,
|
||||
(void*)iface_entry_by_index, (void**)&entry,
|
||||
&msg->ifi_index) != SUCCESS)
|
||||
if (!this->ifaces->find_first(this->ifaces, iface_entry_by_index,
|
||||
(void**)&entry, msg->ifi_index))
|
||||
{
|
||||
INIT(entry,
|
||||
.ifindex = msg->ifi_index,
|
||||
|
@ -1217,7 +1222,7 @@ static void process_link(private_kernel_netlink_net_t *this,
|
|||
* another interface? */
|
||||
this->ifaces->remove_at(this->ifaces, enumerator);
|
||||
current->addrs->invoke_function(current->addrs,
|
||||
(void*)addr_entry_unregister, current, this);
|
||||
addr_entry_unregister, current, this);
|
||||
iface_entry_destroy(current);
|
||||
break;
|
||||
}
|
||||
|
@ -1288,8 +1293,8 @@ static void process_addr(private_kernel_netlink_net_t *this,
|
|||
}
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index,
|
||||
(void**)&iface, &msg->ifa_index) == SUCCESS)
|
||||
if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
|
||||
(void**)&iface, msg->ifa_index))
|
||||
{
|
||||
addr_map_entry_t *entry, lookup = {
|
||||
.ip = host,
|
||||
|
@ -1518,35 +1523,39 @@ typedef struct {
|
|||
kernel_address_type_t which;
|
||||
} address_enumerator_t;
|
||||
|
||||
/**
|
||||
* cleanup function for address enumerator
|
||||
*/
|
||||
static void address_enumerator_destroy(address_enumerator_t *data)
|
||||
CALLBACK(address_enumerator_destroy, void,
|
||||
address_enumerator_t *data)
|
||||
{
|
||||
data->this->lock->unlock(data->this->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter for addresses
|
||||
*/
|
||||
static bool filter_addresses(address_enumerator_t *data,
|
||||
addr_entry_t** in, host_t** out)
|
||||
CALLBACK(filter_addresses, bool,
|
||||
address_enumerator_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->refcount)
|
||||
{ /* skip virtual interfaces added by us */
|
||||
return FALSE;
|
||||
addr_entry_t *addr;
|
||||
host_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &addr))
|
||||
{
|
||||
if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->refcount)
|
||||
{ /* skip virtual interfaces added by us */
|
||||
continue;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_REGULAR) && !addr->refcount)
|
||||
{ /* address is regular, but not requested */
|
||||
continue;
|
||||
}
|
||||
if (addr->scope >= RT_SCOPE_LINK)
|
||||
{ /* skip addresses with a unusable scope */
|
||||
continue;
|
||||
}
|
||||
*out = addr->ip;
|
||||
return TRUE;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->refcount)
|
||||
{ /* address is regular, but not requested */
|
||||
return FALSE;
|
||||
}
|
||||
if ((*in)->scope >= RT_SCOPE_LINK)
|
||||
{ /* skip addresses with a unusable scope */
|
||||
return FALSE;
|
||||
}
|
||||
*out = (*in)->ip;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1556,30 +1565,35 @@ static enumerator_t *create_iface_enumerator(iface_entry_t *iface,
|
|||
address_enumerator_t *data)
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
iface->addrs->create_enumerator(iface->addrs),
|
||||
(void*)filter_addresses, data, NULL);
|
||||
iface->addrs->create_enumerator(iface->addrs),
|
||||
filter_addresses, data, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter for interfaces
|
||||
*/
|
||||
static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in,
|
||||
iface_entry_t** out)
|
||||
CALLBACK(filter_interfaces, bool,
|
||||
address_enumerator_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable)
|
||||
{ /* skip interfaces excluded by config */
|
||||
return FALSE;
|
||||
iface_entry_t *iface, **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &iface))
|
||||
{
|
||||
if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable)
|
||||
{ /* skip interfaces excluded by config */
|
||||
continue;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK))
|
||||
{ /* ignore loopback devices */
|
||||
continue;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP))
|
||||
{ /* skip interfaces not up */
|
||||
continue;
|
||||
}
|
||||
*out = iface;
|
||||
return TRUE;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK))
|
||||
{ /* ignore loopback devices */
|
||||
return FALSE;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP))
|
||||
{ /* skip interfaces not up */
|
||||
return FALSE;
|
||||
}
|
||||
*out = *in;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
||||
|
@ -1596,9 +1610,9 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
|||
return enumerator_create_nested(
|
||||
enumerator_create_filter(
|
||||
this->ifaces->create_enumerator(this->ifaces),
|
||||
(void*)filter_interfaces, data, NULL),
|
||||
filter_interfaces, data, NULL),
|
||||
(void*)create_iface_enumerator, data,
|
||||
(void*)address_enumerator_destroy);
|
||||
address_enumerator_destroy);
|
||||
}
|
||||
|
||||
METHOD(kernel_net_t, get_interface_name, bool,
|
||||
|
@ -1661,8 +1675,8 @@ static int get_interface_index(private_kernel_netlink_net_t *this, char* name)
|
|||
DBG2(DBG_KNL, "getting iface index for %s", name);
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name,
|
||||
(void**)&iface, name) == SUCCESS)
|
||||
if (this->ifaces->find_first(this->ifaces, iface_entry_by_name,
|
||||
(void**)&iface, name))
|
||||
{
|
||||
ifindex = iface->ifindex;
|
||||
}
|
||||
|
@ -1687,8 +1701,8 @@ static char *get_interface_name_by_index(private_kernel_netlink_net_t *this,
|
|||
DBG2(DBG_KNL, "getting iface name for index %d", index);
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index,
|
||||
(void**)&iface, &index) == SUCCESS)
|
||||
if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
|
||||
(void**)&iface, index))
|
||||
{
|
||||
name = strdup(iface->ifname);
|
||||
}
|
||||
|
@ -1928,7 +1942,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
|
|||
|
||||
table = (uintptr_t)route->table;
|
||||
if (this->rt_exclude->find_first(this->rt_exclude, NULL,
|
||||
(void**)&table) == SUCCESS)
|
||||
(void**)&table))
|
||||
{ /* route is from an excluded routing table */
|
||||
continue;
|
||||
}
|
||||
|
@ -2165,8 +2179,14 @@ METHOD(enumerator_t, destroy_subnet_enumerator, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_subnets, bool,
|
||||
subnet_enumerator_t *this, host_t **net, uint8_t *mask, char **ifname)
|
||||
subnet_enumerator_t *this, va_list args)
|
||||
{
|
||||
host_t **net;
|
||||
uint8_t *mask;
|
||||
char **ifname;
|
||||
|
||||
VA_ARGS_VGET(args, net, mask, ifname);
|
||||
|
||||
if (!this->current)
|
||||
{
|
||||
this->current = this->msg;
|
||||
|
@ -2270,7 +2290,8 @@ METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_enumerate_subnets,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_subnets,
|
||||
.destroy = _destroy_subnet_enumerator,
|
||||
},
|
||||
.private = this,
|
||||
|
@ -2380,11 +2401,11 @@ METHOD(kernel_net_t, add_ip, status_t,
|
|||
}
|
||||
/* try to find the target interface, either by config or via src ip */
|
||||
if (!this->install_virtual_ip_on ||
|
||||
this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name,
|
||||
(void**)&iface, this->install_virtual_ip_on) != SUCCESS)
|
||||
!this->ifaces->find_first(this->ifaces, iface_entry_by_name,
|
||||
(void**)&iface, this->install_virtual_ip_on))
|
||||
{
|
||||
if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name,
|
||||
(void**)&iface, iface_name) != SUCCESS)
|
||||
if (!this->ifaces->find_first(this->ifaces, iface_entry_by_name,
|
||||
(void**)&iface, iface_name))
|
||||
{ /* if we don't find the requested interface we just use the first */
|
||||
this->ifaces->get_first(this->ifaces, (void**)&iface);
|
||||
}
|
||||
|
|
|
@ -464,10 +464,10 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this,
|
|||
/**
|
||||
* Destroy a policy_sa(_in)_t object
|
||||
*/
|
||||
static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
|
||||
static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t dir,
|
||||
private_kernel_pfkey_ipsec_t *this)
|
||||
{
|
||||
if (*dir == POLICY_OUT)
|
||||
if (dir == POLICY_OUT)
|
||||
{
|
||||
policy_sa_out_t *out = (policy_sa_out_t*)policy;
|
||||
out->src_ts->destroy(out->src_ts);
|
||||
|
@ -477,6 +477,16 @@ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
|
|||
free(policy);
|
||||
}
|
||||
|
||||
CALLBACK(policy_sa_destroy_cb, void,
|
||||
policy_sa_t *policy, va_list args)
|
||||
{
|
||||
private_kernel_pfkey_ipsec_t *this;
|
||||
policy_dir_t dir;
|
||||
|
||||
VA_ARGS_VGET(args, dir, this);
|
||||
policy_sa_destroy(policy, dir, this);
|
||||
}
|
||||
|
||||
typedef struct policy_entry_t policy_entry_t;
|
||||
|
||||
/**
|
||||
|
@ -557,9 +567,8 @@ static void policy_entry_destroy(policy_entry_t *policy,
|
|||
}
|
||||
if (policy->used_by)
|
||||
{
|
||||
policy->used_by->invoke_function(policy->used_by,
|
||||
(linked_list_invoke_t)policy_sa_destroy,
|
||||
&policy->direction, this);
|
||||
policy->used_by->invoke_function(policy->used_by, policy_sa_destroy_cb,
|
||||
policy->direction, this);
|
||||
policy->used_by->destroy(policy->used_by);
|
||||
}
|
||||
DESTROY_IF(policy->src.net);
|
||||
|
@ -567,12 +576,21 @@ static void policy_entry_destroy(policy_entry_t *policy,
|
|||
free(policy);
|
||||
}
|
||||
|
||||
/**
|
||||
* compares two policy_entry_t
|
||||
*/
|
||||
static inline bool policy_entry_equals(policy_entry_t *current,
|
||||
policy_entry_t *policy)
|
||||
CALLBACK(policy_entry_destroy_cb, void,
|
||||
policy_entry_t *policy, va_list args)
|
||||
{
|
||||
private_kernel_pfkey_ipsec_t *this;
|
||||
|
||||
VA_ARGS_VGET(args, this);
|
||||
policy_entry_destroy(policy, this);
|
||||
}
|
||||
|
||||
CALLBACK(policy_entry_equals, bool,
|
||||
policy_entry_t *current, va_list args)
|
||||
{
|
||||
policy_entry_t *policy;
|
||||
|
||||
VA_ARGS_VGET(args, policy);
|
||||
return current->direction == policy->direction &&
|
||||
current->src.proto == policy->src.proto &&
|
||||
current->dst.proto == policy->dst.proto &&
|
||||
|
@ -582,13 +600,13 @@ static inline bool policy_entry_equals(policy_entry_t *current,
|
|||
current->dst.net->equals(current->dst.net, policy->dst.net);
|
||||
}
|
||||
|
||||
/**
|
||||
* compare the given kernel index with that of a policy
|
||||
*/
|
||||
static inline bool policy_entry_match_byindex(policy_entry_t *current,
|
||||
uint32_t *index)
|
||||
CALLBACK(policy_entry_match_byindex, bool,
|
||||
policy_entry_t *current, va_list args)
|
||||
{
|
||||
return current->index == *index;
|
||||
uint32_t index;
|
||||
|
||||
VA_ARGS_VGET(args, index);
|
||||
return current->index == index;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1261,9 +1279,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this,
|
|||
|
||||
index = response.x_policy->sadb_x_policy_id;
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies,
|
||||
(linked_list_match_t)policy_entry_match_byindex,
|
||||
(void**)&policy, &index) == SUCCESS &&
|
||||
if (this->policies->find_first(this->policies, policy_entry_match_byindex,
|
||||
(void**)&policy, index) &&
|
||||
policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS)
|
||||
{
|
||||
reqid = sa->sa->cfg.reqid;
|
||||
|
@ -2554,8 +2571,7 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
|
|||
|
||||
/* we try to find the policy again and update the kernel index */
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies, NULL,
|
||||
(void**)&policy) != SUCCESS)
|
||||
if (!this->policies->find_first(this->policies, NULL, (void**)&policy))
|
||||
{
|
||||
DBG2(DBG_KNL, "unable to update index, the policy is already gone, "
|
||||
"ignoring");
|
||||
|
@ -2606,9 +2622,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
|
||||
/* find a matching policy */
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies,
|
||||
(linked_list_match_t)policy_entry_equals,
|
||||
(void**)&found, policy) == SUCCESS)
|
||||
if (this->policies->find_first(this->policies, policy_entry_equals,
|
||||
(void**)&found, policy))
|
||||
{ /* use existing policy */
|
||||
DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
|
||||
"refcount", id->src_ts, id->dst_ts, policy_dir_names, id->dir);
|
||||
|
@ -2701,9 +2716,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
|||
|
||||
/* find a matching policy */
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies,
|
||||
(linked_list_match_t)policy_entry_equals,
|
||||
(void**)&found, policy) != SUCCESS)
|
||||
if (!this->policies->find_first(this->policies, policy_entry_equals,
|
||||
(void**)&found, policy))
|
||||
{
|
||||
DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found",
|
||||
id->src_ts, id->dst_ts, policy_dir_names, id->dir);
|
||||
|
@ -2814,9 +2828,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
|
||||
/* find a matching policy */
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->policies->find_first(this->policies,
|
||||
(linked_list_match_t)policy_entry_equals,
|
||||
(void**)&found, policy) != SUCCESS)
|
||||
if (!this->policies->find_first(this->policies, policy_entry_equals,
|
||||
(void**)&found, policy))
|
||||
{
|
||||
DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found",
|
||||
id->src_ts, id->dst_ts, policy_dir_names, id->dir);
|
||||
|
@ -2860,7 +2873,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
if (policy->used_by->get_count(policy->used_by) > 0)
|
||||
{ /* policy is used by more SAs, keep in kernel */
|
||||
DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
|
||||
policy_sa_destroy(mapping, &id->dir, this);
|
||||
policy_sa_destroy(mapping, id->dir, this);
|
||||
|
||||
if (!is_installed)
|
||||
{ /* no need to update as the policy was not installed for this SA */
|
||||
|
@ -2915,7 +2928,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
}
|
||||
|
||||
this->policies->remove(this->policies, found, NULL);
|
||||
policy_sa_destroy(mapping, &id->dir, this);
|
||||
policy_sa_destroy(mapping, id->dir, this);
|
||||
policy_entry_destroy(policy, this);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
|
@ -3088,8 +3101,7 @@ METHOD(kernel_ipsec_t, destroy, void,
|
|||
lib->watcher->remove(lib->watcher, this->socket_events);
|
||||
close(this->socket_events);
|
||||
}
|
||||
this->policies->invoke_function(this->policies,
|
||||
(linked_list_invoke_t)policy_entry_destroy,
|
||||
this->policies->invoke_function(this->policies, policy_entry_destroy_cb,
|
||||
this);
|
||||
this->policies->destroy(this->policies);
|
||||
this->excludes->destroy(this->excludes);
|
||||
|
|
|
@ -601,9 +601,12 @@ typedef struct {
|
|||
} rt_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, rt_enumerate, bool,
|
||||
rt_enumerator_t *this, int *xtype, struct sockaddr **addr)
|
||||
rt_enumerator_t *this, va_list args)
|
||||
{
|
||||
int i, type;
|
||||
struct sockaddr **addr;
|
||||
int i, type, *xtype;
|
||||
|
||||
VA_ARGS_VGET(args, xtype, addr);
|
||||
|
||||
if (this->remaining < sizeof(this->addr->sa_len) ||
|
||||
this->remaining < this->addr->sa_len)
|
||||
|
@ -637,7 +640,8 @@ static enumerator_t *create_rt_enumerator(int types, int remaining,
|
|||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = (void*)_rt_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _rt_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.types = types,
|
||||
|
@ -1050,41 +1054,45 @@ typedef struct {
|
|||
kernel_address_type_t which;
|
||||
} address_enumerator_t;
|
||||
|
||||
/**
|
||||
* cleanup function for address enumerator
|
||||
*/
|
||||
static void address_enumerator_destroy(address_enumerator_t *data)
|
||||
CALLBACK(address_enumerator_destroy, void,
|
||||
address_enumerator_t *data)
|
||||
{
|
||||
data->this->lock->unlock(data->this->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter for addresses
|
||||
*/
|
||||
static bool filter_addresses(address_enumerator_t *data,
|
||||
addr_entry_t** in, host_t** out)
|
||||
CALLBACK(filter_addresses, bool,
|
||||
address_enumerator_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
host_t *ip;
|
||||
if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->virtual)
|
||||
{ /* skip virtual interfaces added by us */
|
||||
return FALSE;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->virtual)
|
||||
{ /* address is regular, but not requested */
|
||||
return FALSE;
|
||||
}
|
||||
ip = (*in)->ip;
|
||||
if (ip->get_family(ip) == AF_INET6)
|
||||
addr_entry_t *addr;
|
||||
host_t *ip, **out;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &addr))
|
||||
{
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip);
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
{ /* skip addresses with a unusable scope */
|
||||
return FALSE;
|
||||
if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->virtual)
|
||||
{ /* skip virtual interfaces added by us */
|
||||
continue;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_REGULAR) && !addr->virtual)
|
||||
{ /* address is regular, but not requested */
|
||||
continue;
|
||||
}
|
||||
ip = addr->ip;
|
||||
if (ip->get_family(ip) == AF_INET6)
|
||||
{
|
||||
sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip);
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
{ /* skip addresses with a unusable scope */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*out = ip;
|
||||
return TRUE;
|
||||
}
|
||||
*out = ip;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1094,29 +1102,34 @@ static enumerator_t *create_iface_enumerator(iface_entry_t *iface,
|
|||
address_enumerator_t *data)
|
||||
{
|
||||
return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs),
|
||||
(void*)filter_addresses, data, NULL);
|
||||
filter_addresses, data, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter for interfaces
|
||||
*/
|
||||
static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in,
|
||||
iface_entry_t** out)
|
||||
CALLBACK(filter_interfaces, bool,
|
||||
address_enumerator_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable)
|
||||
{ /* skip interfaces excluded by config */
|
||||
return FALSE;
|
||||
iface_entry_t *iface, **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &iface))
|
||||
{
|
||||
if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable)
|
||||
{ /* skip interfaces excluded by config */
|
||||
continue;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK))
|
||||
{ /* ignore loopback devices */
|
||||
continue;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP))
|
||||
{ /* skip interfaces not up */
|
||||
continue;
|
||||
}
|
||||
*out = iface;
|
||||
return TRUE;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK))
|
||||
{ /* ignore loopback devices */
|
||||
return FALSE;
|
||||
}
|
||||
if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP))
|
||||
{ /* skip interfaces not up */
|
||||
return FALSE;
|
||||
}
|
||||
*out = *in;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
||||
|
@ -1133,9 +1146,9 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
|||
return enumerator_create_nested(
|
||||
enumerator_create_filter(
|
||||
this->ifaces->create_enumerator(this->ifaces),
|
||||
(void*)filter_interfaces, data, NULL),
|
||||
filter_interfaces, data, NULL),
|
||||
(void*)create_iface_enumerator, data,
|
||||
(void*)address_enumerator_destroy);
|
||||
address_enumerator_destroy);
|
||||
}
|
||||
|
||||
METHOD(kernel_net_t, get_features, kernel_feature_t,
|
||||
|
@ -1789,13 +1802,18 @@ METHOD(enumerator_t, destroy_subnet_enumerator, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_subnets, bool,
|
||||
subnet_enumerator_t *this, host_t **net, uint8_t *mask, char **ifname)
|
||||
subnet_enumerator_t *this, va_list args)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t **net;
|
||||
struct rt_msghdr *rtm;
|
||||
struct sockaddr *addr;
|
||||
uint8_t *mask;
|
||||
char **ifname;
|
||||
int type;
|
||||
|
||||
VA_ARGS_VGET(args, net, mask, ifname);
|
||||
|
||||
if (!this->current)
|
||||
{
|
||||
this->current = this->buf;
|
||||
|
@ -1888,7 +1906,8 @@ METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_enumerate_subnets,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_subnets,
|
||||
.destroy = _destroy_subnet_enumerator,
|
||||
},
|
||||
.buf = buf,
|
||||
|
|
|
@ -395,22 +395,28 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function for shared keys, returning ID matches
|
||||
*/
|
||||
static bool shared_filter(void *null, shared_key_t **in, shared_key_t **out,
|
||||
void **un1, id_match_t *me, void **un2, id_match_t *other)
|
||||
CALLBACK(shared_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = *in;
|
||||
if (me)
|
||||
shared_key_t *key, **out;
|
||||
id_match_t *me, *other;
|
||||
|
||||
VA_ARGS_VGET(args, out, me, other);
|
||||
|
||||
if (orig->enumerate(orig, &key))
|
||||
{
|
||||
*me = ID_MATCH_ANY;
|
||||
*out = key;
|
||||
if (me)
|
||||
{
|
||||
*me = ID_MATCH_ANY;
|
||||
}
|
||||
if (other)
|
||||
{
|
||||
*other = ID_MATCH_ANY;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (other)
|
||||
{
|
||||
*other = ID_MATCH_ANY;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
||||
|
@ -431,7 +437,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
|||
return NULL;
|
||||
}
|
||||
return enumerator_create_filter(enumerator_create_single(shared, NULL),
|
||||
(void*)shared_filter, NULL, NULL);
|
||||
shared_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(load_tester_creds_t, destroy, void,
|
||||
|
|
|
@ -223,10 +223,11 @@ typedef struct {
|
|||
} peer_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
peer_enumerator_t *this, peer_cfg_t **cfg)
|
||||
peer_enumerator_t *this, va_list args)
|
||||
{
|
||||
char *name, *local_net, *remote_net;
|
||||
chunk_t me, other;
|
||||
peer_cfg_t **cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
auth_cfg_t *auth;
|
||||
peer_cfg_create_t peer = {
|
||||
|
@ -249,6 +250,8 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
|||
.mode = MODE_TUNNEL,
|
||||
};
|
||||
|
||||
VA_ARGS_VGET(args, cfg);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
if (!this->inner->enumerate(this->inner, &name, &me, &other,
|
||||
&local_net, &remote_net))
|
||||
|
@ -295,7 +298,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_peer_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _peer_enumerator_enumerate,
|
||||
.destroy = _peer_enumerator_destroy,
|
||||
},
|
||||
.ike = this->ike,
|
||||
|
|
|
@ -50,10 +50,13 @@ typedef struct {
|
|||
} private_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, private_enumerator_enumerate, bool,
|
||||
private_enumerator_t *this, private_key_t **key)
|
||||
private_enumerator_t *this, va_list args)
|
||||
{
|
||||
private_key_t **key;
|
||||
chunk_t chunk;
|
||||
|
||||
VA_ARGS_VGET(args, key);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
while (this->inner->enumerate(this->inner, &chunk))
|
||||
{
|
||||
|
@ -92,7 +95,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_private_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _private_enumerator_enumerate,
|
||||
.destroy = _private_enumerator_destroy,
|
||||
},
|
||||
);
|
||||
|
@ -123,11 +127,14 @@ typedef struct {
|
|||
} cert_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, cert_enumerator_enumerate, bool,
|
||||
cert_enumerator_t *this, certificate_t **cert)
|
||||
cert_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t **cert;
|
||||
public_key_t *public;
|
||||
chunk_t chunk;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
while (this->inner->enumerate(this->inner, &chunk))
|
||||
{
|
||||
|
@ -180,7 +187,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_cert_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _cert_enumerator_enumerate,
|
||||
.destroy = _cert_enumerator_destroy,
|
||||
},
|
||||
.type = key,
|
||||
|
|
|
@ -52,12 +52,14 @@ typedef struct {
|
|||
} cert_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, cert_enumerator_enumerate, bool,
|
||||
cert_enumerator_t *this, certificate_t **cert)
|
||||
cert_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t *trusted;
|
||||
certificate_t *trusted, **cert;
|
||||
public_key_t *public;
|
||||
chunk_t chunk;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
while (this->inner->enumerate(this->inner, &chunk))
|
||||
{
|
||||
|
@ -110,7 +112,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_cert_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _cert_enumerator_enumerate,
|
||||
.destroy = _cert_enumerator_destroy,
|
||||
},
|
||||
.type = key,
|
||||
|
|
|
@ -218,12 +218,15 @@ METHOD(attribute_handler_t, release, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_dns, bool,
|
||||
enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data)
|
||||
enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
*data = chunk_empty;
|
||||
/* stop enumeration */
|
||||
this->enumerate = (void*)return_false;
|
||||
this->venumerate = (void*)return_false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -234,7 +237,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
|||
enumerator_t *enumerator;
|
||||
|
||||
INIT(enumerator,
|
||||
.enumerate = (void*)_enumerate_dns,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_dns,
|
||||
.destroy = (void*)free,
|
||||
);
|
||||
return enumerator;
|
||||
|
|
|
@ -83,9 +83,12 @@ typedef struct {
|
|||
} attr_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, enumerate_attrs, bool,
|
||||
attr_enumerator_t *this, configuration_attribute_type_t *type,
|
||||
chunk_t *data)
|
||||
attr_enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
if (this->request_ipv4)
|
||||
{
|
||||
*type = P_CSCF_IP4_ADDRESS;
|
||||
|
@ -103,12 +106,13 @@ METHOD(enumerator_t, enumerate_attrs, bool,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given host has a matching address family
|
||||
*/
|
||||
static bool is_family(host_t *host, int *family)
|
||||
CALLBACK(is_family, bool,
|
||||
host_t *host, va_list args)
|
||||
{
|
||||
return host->get_family(host) == *family;
|
||||
int family;
|
||||
|
||||
VA_ARGS_VGET(args, family);
|
||||
return host->get_family(host) == family;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +120,7 @@ static bool is_family(host_t *host, int *family)
|
|||
*/
|
||||
static bool has_host_family(linked_list_t *list, int family)
|
||||
{
|
||||
return list->find_first(list, (void*)is_family, NULL, &family) == SUCCESS;
|
||||
return list->find_first(list, is_family, NULL, family);
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
||||
|
@ -132,7 +136,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_enumerate_attrs,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_attrs,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
);
|
||||
|
|
|
@ -391,10 +391,13 @@ typedef struct {
|
|||
bool v6;
|
||||
} attribute_enumerator_t;
|
||||
|
||||
static bool attribute_enumerate(attribute_enumerator_t *this,
|
||||
configuration_attribute_type_t *type,
|
||||
chunk_t *data)
|
||||
METHOD(enumerator_t, attribute_enumerate, bool,
|
||||
attribute_enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
if (this->v4)
|
||||
{
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
|
@ -443,7 +446,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)attribute_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _attribute_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.v4 = has_host_family(vips, AF_INET),
|
||||
|
|
|
@ -504,11 +504,12 @@ typedef struct {
|
|||
ike_cfg_t *current;
|
||||
} ike_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of ike_enumerator_t.public.enumerate
|
||||
*/
|
||||
static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
|
||||
METHOD(enumerator_t, ike_enumerator_enumerate, bool,
|
||||
ike_enumerator_t *this, va_list args)
|
||||
{
|
||||
ike_cfg_t **cfg;
|
||||
|
||||
VA_ARGS_VGET(args, cfg);
|
||||
DESTROY_IF(this->current);
|
||||
this->current = build_ike_cfg(this->this, this->inner, this->me, this->other);
|
||||
if (this->current)
|
||||
|
@ -519,10 +520,8 @@ static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_enumerator_t.public.destroy
|
||||
*/
|
||||
static void ike_enumerator_destroy(ike_enumerator_t *this)
|
||||
METHOD(enumerator_t, ike_enumerator_destroy, void,
|
||||
ike_enumerator_t *this)
|
||||
{
|
||||
DESTROY_IF(this->current);
|
||||
this->inner->destroy(this->inner);
|
||||
|
@ -532,19 +531,22 @@ static void ike_enumerator_destroy(ike_enumerator_t *this)
|
|||
METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
||||
private_sql_config_t *this, host_t *me, host_t *other)
|
||||
{
|
||||
ike_enumerator_t *e = malloc_thing(ike_enumerator_t);
|
||||
|
||||
e->this = this;
|
||||
e->me = me;
|
||||
e->other = other;
|
||||
e->current = NULL;
|
||||
e->public.enumerate = (void*)ike_enumerator_enumerate;
|
||||
e->public.destroy = (void*)ike_enumerator_destroy;
|
||||
ike_enumerator_t *e;
|
||||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _ike_enumerator_enumerate,
|
||||
.destroy = _ike_enumerator_destroy,
|
||||
},
|
||||
.this = this,
|
||||
.me = me,
|
||||
.other = other,
|
||||
);
|
||||
e->inner = this->db->query(this->db,
|
||||
"SELECT id, certreq, force_encap, local, remote "
|
||||
"FROM ike_configs",
|
||||
DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
|
||||
"SELECT id, certreq, force_encap, local, remote "
|
||||
"FROM ike_configs",
|
||||
DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
|
||||
if (!e->inner)
|
||||
{
|
||||
free(e);
|
||||
|
@ -569,11 +571,12 @@ typedef struct {
|
|||
peer_cfg_t *current;
|
||||
} peer_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of peer_enumerator_t.public.enumerate
|
||||
*/
|
||||
static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
|
||||
METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
peer_enumerator_t *this, va_list args)
|
||||
{
|
||||
peer_cfg_t **cfg;
|
||||
|
||||
VA_ARGS_VGET(args, cfg);
|
||||
DESTROY_IF(this->current);
|
||||
this->current = build_peer_cfg(this->this, this->inner, this->me, this->other);
|
||||
if (this->current)
|
||||
|
@ -584,10 +587,8 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of peer_enumerator_t.public.destroy
|
||||
*/
|
||||
static void peer_enumerator_destroy(peer_enumerator_t *this)
|
||||
METHOD(enumerator_t, peer_enumerator_destroy, void,
|
||||
peer_enumerator_t *this)
|
||||
{
|
||||
DESTROY_IF(this->current);
|
||||
this->inner->destroy(this->inner);
|
||||
|
@ -599,12 +600,16 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
{
|
||||
peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
|
||||
|
||||
e->this = this;
|
||||
e->me = me;
|
||||
e->other = other;
|
||||
e->current = NULL;
|
||||
e->public.enumerate = (void*)peer_enumerator_enumerate;
|
||||
e->public.destroy = (void*)peer_enumerator_destroy;
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _peer_enumerator_enumerate,
|
||||
.destroy = _peer_enumerator_destroy,
|
||||
},
|
||||
.this = this,
|
||||
.me = me,
|
||||
.other = other,
|
||||
);
|
||||
|
||||
/* TODO: only get configs whose IDs match exactly or contain wildcards */
|
||||
e->inner = this->db->query(this->db,
|
||||
|
|
|
@ -52,11 +52,14 @@ typedef struct {
|
|||
} private_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, private_enumerator_enumerate, bool,
|
||||
private_enumerator_t *this, private_key_t **key)
|
||||
private_enumerator_t *this, va_list args)
|
||||
{
|
||||
private_key_t **key;
|
||||
chunk_t blob;
|
||||
int type;
|
||||
|
||||
VA_ARGS_VGET(args, key);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
while (this->inner->enumerate(this->inner, &type, &blob))
|
||||
{
|
||||
|
@ -88,7 +91,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_private_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _private_enumerator_enumerate,
|
||||
.destroy = _private_enumerator_destroy,
|
||||
},
|
||||
);
|
||||
|
@ -132,11 +136,14 @@ typedef struct {
|
|||
} cert_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, cert_enumerator_enumerate, bool,
|
||||
cert_enumerator_t *this, certificate_t **cert)
|
||||
cert_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t **cert;
|
||||
chunk_t blob;
|
||||
int type;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
while (this->inner->enumerate(this->inner, &type, &blob))
|
||||
{
|
||||
|
@ -169,7 +176,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_cert_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _cert_enumerator_enumerate,
|
||||
.destroy = _cert_enumerator_destroy,
|
||||
},
|
||||
);
|
||||
|
@ -221,12 +229,15 @@ typedef struct {
|
|||
} shared_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, shared_enumerator_enumerate, bool,
|
||||
shared_enumerator_t *this, shared_key_t **shared,
|
||||
id_match_t *me, id_match_t *other)
|
||||
shared_enumerator_t *this, va_list args)
|
||||
{
|
||||
shared_key_t **shared;
|
||||
id_match_t *me, *other;
|
||||
chunk_t blob;
|
||||
int type;
|
||||
|
||||
VA_ARGS_VGET(args, shared, me, other);
|
||||
|
||||
DESTROY_IF(this->current);
|
||||
while (this->inner->enumerate(this->inner, &type, &blob))
|
||||
{
|
||||
|
@ -265,7 +276,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_shared_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _shared_enumerator_enumerate,
|
||||
.destroy = _shared_enumerator_destroy,
|
||||
},
|
||||
.me = me,
|
||||
|
@ -340,9 +352,11 @@ typedef enum {
|
|||
} cdp_type_t;
|
||||
|
||||
METHOD(enumerator_t, cdp_enumerator_enumerate, bool,
|
||||
cdp_enumerator_t *this, char **uri)
|
||||
cdp_enumerator_t *this, va_list args)
|
||||
{
|
||||
char *text;
|
||||
char *text, **uri;
|
||||
|
||||
VA_ARGS_VGET(args, uri);
|
||||
|
||||
free(this->current);
|
||||
while (this->inner->enumerate(this->inner, &text))
|
||||
|
@ -384,7 +398,8 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
|
|||
}
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_cdp_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _cdp_enumerator_enumerate,
|
||||
.destroy = _cdp_enumerator_destroy,
|
||||
},
|
||||
);
|
||||
|
|
|
@ -178,28 +178,32 @@ METHOD(attribute_provider_t, release_address, bool,
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to convert host to DNS configuration attributes
|
||||
*/
|
||||
static bool attr_filter(void *lock, host_t **in,
|
||||
configuration_attribute_type_t *type,
|
||||
void *dummy, chunk_t *data)
|
||||
CALLBACK(attr_filter, bool,
|
||||
void *lock, enumerator_t *orig, va_list args)
|
||||
{
|
||||
host_t *host = *in;
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
host_t *host;
|
||||
|
||||
switch (host->get_family(host))
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
|
||||
while (orig->enumerate(orig, &host))
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
switch (host->get_family(host))
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
*data = host->get_address(host);
|
||||
return TRUE;
|
||||
}
|
||||
*data = host->get_address(host);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
|
@ -223,7 +227,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
|||
enumerator->destroy(enumerator);
|
||||
return enumerator_create_filter(
|
||||
attr->dns->create_enumerator(attr->dns),
|
||||
(void*)attr_filter, this->lock,
|
||||
attr_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
}
|
||||
|
@ -338,24 +342,28 @@ METHOD(stroke_attribute_t, del_dns, void,
|
|||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pool enumerator filter function, converts pool_t to name, size, ...
|
||||
*/
|
||||
static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name,
|
||||
void *d1, u_int *size, void *d2, u_int *online,
|
||||
void *d3, u_int *offline)
|
||||
CALLBACK(pool_filter, bool,
|
||||
void *lock, enumerator_t *orig, va_list args)
|
||||
{
|
||||
mem_pool_t *pool = *poolp;
|
||||
mem_pool_t *pool;
|
||||
const char **name;
|
||||
u_int *size, *online, *offline;
|
||||
|
||||
if (pool->get_size(pool) == 0)
|
||||
VA_ARGS_VGET(args, name, size, online, offline);
|
||||
|
||||
while (orig->enumerate(orig, &pool))
|
||||
{
|
||||
return FALSE;
|
||||
if (pool->get_size(pool) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*name = pool->get_name(pool);
|
||||
*size = pool->get_size(pool);
|
||||
*online = pool->get_online(pool);
|
||||
*offline = pool->get_offline(pool);
|
||||
return TRUE;
|
||||
}
|
||||
*name = pool->get_name(pool);
|
||||
*size = pool->get_size(pool);
|
||||
*online = pool->get_online(pool);
|
||||
*offline = pool->get_offline(pool);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*,
|
||||
|
@ -363,7 +371,7 @@ METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*,
|
|||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->pools->create_enumerator(this->pools),
|
||||
(void*)pool_filter,
|
||||
pool_filter,
|
||||
this->lock, (void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
|
|
|
@ -171,26 +171,30 @@ typedef struct {
|
|||
identification_t *id;
|
||||
} cert_data_t;
|
||||
|
||||
/**
|
||||
* destroy cert_data
|
||||
*/
|
||||
static void cert_data_destroy(cert_data_t *data)
|
||||
CALLBACK(cert_data_destroy, void,
|
||||
cert_data_t *data)
|
||||
{
|
||||
data->this->lock->unlock(data->this->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter function for certs enumerator
|
||||
*/
|
||||
static bool certs_filter(cert_data_t *data, ca_cert_t **in,
|
||||
certificate_t **out)
|
||||
CALLBACK(certs_filter, bool,
|
||||
cert_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
ca_cert_t *cacert;
|
||||
public_key_t *public;
|
||||
certificate_t *cert = (*in)->cert;
|
||||
certificate_t **out;
|
||||
|
||||
if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &cacert))
|
||||
{
|
||||
certificate_t *cert = cacert->cert;
|
||||
|
||||
if (data->cert != CERT_ANY && data->cert != cert->get_type(cert))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
public = cert->get_public_key(cert);
|
||||
if (public)
|
||||
{
|
||||
|
@ -208,9 +212,9 @@ static bool certs_filter(cert_data_t *data, ca_cert_t **in,
|
|||
}
|
||||
else if (data->key != KEY_ANY)
|
||||
{
|
||||
return FALSE;
|
||||
continue;
|
||||
}
|
||||
if (data->id == NULL || cert->has_subject(cert, data->id))
|
||||
if (!data->id || cert->has_subject(cert, data->id))
|
||||
{
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
|
@ -235,8 +239,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->certs->create_enumerator(this->certs);
|
||||
return enumerator_create_filter(enumerator, (void*)certs_filter, data,
|
||||
(void*)cert_data_destroy);
|
||||
return enumerator_create_filter(enumerator, certs_filter, data,
|
||||
cert_data_destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -354,11 +358,12 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
|
|||
data, (void*)cdp_data_destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the given certificate to the ca_cert_t items in the list
|
||||
*/
|
||||
static bool match_cert(ca_cert_t *item, certificate_t *cert)
|
||||
CALLBACK(match_cert, bool,
|
||||
ca_cert_t *item, va_list args)
|
||||
{
|
||||
certificate_t *cert;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
return cert->equals(cert, item->cert);
|
||||
}
|
||||
|
||||
|
@ -405,8 +410,7 @@ static certificate_t *add_cert_internal(private_stroke_ca_t *this,
|
|||
{
|
||||
ca_cert_t *found;
|
||||
|
||||
if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert,
|
||||
(void**)&found, cert) == SUCCESS)
|
||||
if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert))
|
||||
{
|
||||
cert->destroy(cert);
|
||||
cert = found->cert->get_ref(found->cert);
|
||||
|
@ -511,8 +515,7 @@ METHOD(stroke_ca_t, get_cert_ref, certificate_t*,
|
|||
ca_cert_t *found;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert,
|
||||
(void**)&found, cert) == SUCCESS)
|
||||
if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert))
|
||||
{
|
||||
cert->destroy(cert);
|
||||
cert = found->cert->get_ref(found->cert);
|
||||
|
|
|
@ -68,13 +68,20 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
(void*)this->mutex->unlock, this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter function for ike configs
|
||||
*/
|
||||
static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
|
||||
CALLBACK(ike_filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = (*in)->get_ike_cfg(*in);
|
||||
return TRUE;
|
||||
peer_cfg_t *cfg;
|
||||
ike_cfg_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &cfg))
|
||||
{
|
||||
*out = cfg->get_ike_cfg(cfg);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
||||
|
@ -82,7 +89,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
|||
{
|
||||
this->mutex->lock(this->mutex);
|
||||
return enumerator_create_filter(this->list->create_enumerator(this->list),
|
||||
(void*)ike_filter, this->mutex,
|
||||
ike_filter, this->mutex,
|
||||
(void*)this->mutex->unlock);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,35 +62,39 @@ static void attributes_destroy(attributes_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to convert host to DNS configuration attributes
|
||||
*/
|
||||
static bool attr_filter(void *lock, host_t **in,
|
||||
configuration_attribute_type_t *type,
|
||||
void *dummy, chunk_t *data)
|
||||
CALLBACK(attr_filter, bool,
|
||||
void *lock, enumerator_t *orig, va_list args)
|
||||
{
|
||||
host_t *host = *in;
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
host_t *host;
|
||||
|
||||
switch (host->get_family(host))
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
|
||||
while (orig->enumerate(orig, &host))
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
switch (host->get_family(host))
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (host->is_anyaddr(host))
|
||||
{
|
||||
*data = chunk_empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = host->get_address(host);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (host->is_anyaddr(host))
|
||||
{
|
||||
*data = chunk_empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = host->get_address(host);
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
||||
|
@ -114,7 +118,7 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
|||
enumerator->destroy(enumerator);
|
||||
return enumerator_create_filter(
|
||||
attr->dns->create_enumerator(attr->dns),
|
||||
(void*)attr_filter, this->lock,
|
||||
attr_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -958,8 +958,7 @@ static void list_plugins(FILE *out)
|
|||
{
|
||||
case FEATURE_PROVIDE:
|
||||
fp = &features[i];
|
||||
loaded = list->find_first(list, NULL,
|
||||
(void**)&fp) == SUCCESS;
|
||||
loaded = list->find_first(list, NULL, (void**)&fp);
|
||||
fprintf(out, " %s%s\n",
|
||||
str, loaded ? "" : " (not loaded)");
|
||||
break;
|
||||
|
|
|
@ -118,11 +118,12 @@ static u_int create_rekey(char *string)
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
peer_enumerator_t *this, peer_cfg_t **cfg)
|
||||
peer_enumerator_t *this, va_list args)
|
||||
{
|
||||
char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey;
|
||||
char *local_id, *local_addr, *local_net;
|
||||
char *remote_id, *remote_addr, *remote_net;
|
||||
peer_cfg_t **cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
ike_cfg_t *ike_cfg;
|
||||
auth_cfg_t *auth;
|
||||
|
@ -145,6 +146,8 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
|||
.mode = MODE_TUNNEL,
|
||||
};
|
||||
|
||||
VA_ARGS_VGET(args, cfg);
|
||||
|
||||
/* defaults */
|
||||
name = "unnamed";
|
||||
local_id = NULL;
|
||||
|
@ -212,7 +215,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_peer_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _peer_enumerator_enumerate,
|
||||
.destroy = _peer_enumerator_destroy,
|
||||
},
|
||||
.inner = this->parser->create_section_enumerator(this->parser,
|
||||
|
@ -241,10 +245,13 @@ typedef struct {
|
|||
} ike_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, ike_enumerator_enumerate, bool,
|
||||
ike_enumerator_t *this, ike_cfg_t **cfg)
|
||||
ike_enumerator_t *this, va_list args)
|
||||
{
|
||||
ike_cfg_t **cfg;
|
||||
char *local_addr, *remote_addr, *ike_proposal;
|
||||
|
||||
VA_ARGS_VGET(args, cfg);
|
||||
|
||||
/* defaults */
|
||||
local_addr = "0.0.0.0";
|
||||
remote_addr = "0.0.0.0";
|
||||
|
@ -282,7 +289,8 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_ike_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _ike_enumerator_enumerate,
|
||||
.destroy = _ike_enumerator_destroy,
|
||||
},
|
||||
.inner = this->parser->create_section_enumerator(this->parser,
|
||||
|
|
|
@ -52,12 +52,15 @@ typedef struct {
|
|||
} shared_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, shared_enumerator_enumerate, bool,
|
||||
shared_enumerator_t *this, shared_key_t **key, id_match_t *me,
|
||||
id_match_t *other)
|
||||
shared_enumerator_t *this, va_list args)
|
||||
{
|
||||
shared_key_t **key;
|
||||
id_match_t *me, *other;
|
||||
char *local_id, *remote_id, *psk;
|
||||
identification_t *local, *remote;
|
||||
|
||||
VA_ARGS_VGET(args, key, me, other);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* defaults */
|
||||
|
@ -126,7 +129,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_shared_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _shared_enumerator_enumerate,
|
||||
.destroy = _shared_enumerator_destroy,
|
||||
},
|
||||
.me = me,
|
||||
|
|
|
@ -58,11 +58,10 @@ typedef struct {
|
|||
} section_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, section_enumerator_enumerate, bool,
|
||||
section_enumerator_t *this, ...)
|
||||
section_enumerator_t *this, va_list args)
|
||||
{
|
||||
struct uci_element *element;
|
||||
char **value;
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
if (&this->current->list == this->list)
|
||||
|
@ -70,8 +69,6 @@ METHOD(enumerator_t, section_enumerator_enumerate, bool,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
va_start(args, this);
|
||||
|
||||
value = va_arg(args, char**);
|
||||
if (value)
|
||||
{
|
||||
|
@ -96,7 +93,6 @@ METHOD(enumerator_t, section_enumerator_enumerate, bool,
|
|||
*value = uci_to_option(element)->value;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
this->current = list_to_element(this->current->list.next);
|
||||
return TRUE;
|
||||
|
@ -124,7 +120,13 @@ METHOD(uci_parser_t, create_section_enumerator, enumerator_t*,
|
|||
i++;
|
||||
}
|
||||
va_end(args);
|
||||
e = malloc(sizeof(section_enumerator_t) + sizeof(char*) * i);
|
||||
INIT_EXTRA(e, sizeof(char*) * i,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _section_enumerator_enumerate,
|
||||
.destroy = _section_enumerator_destroy,
|
||||
},
|
||||
);
|
||||
i = 0;
|
||||
va_start(args, this);
|
||||
do
|
||||
|
@ -134,9 +136,6 @@ METHOD(uci_parser_t, create_section_enumerator, enumerator_t*,
|
|||
while (e->keywords[i++]);
|
||||
va_end(args);
|
||||
|
||||
e->public.enumerate = (void*)_section_enumerator_enumerate;
|
||||
e->public.destroy = _section_enumerator_destroy;
|
||||
|
||||
/* load uci context */
|
||||
e->ctx = uci_alloc_context();
|
||||
if (uci_load(e->ctx, this->package, &e->package) != UCI_OK)
|
||||
|
|
|
@ -368,9 +368,12 @@ typedef struct {
|
|||
} attribute_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, enumerate_attributes, bool,
|
||||
attribute_enumerator_t *this, configuration_attribute_type_t *type,
|
||||
chunk_t *data)
|
||||
attribute_enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
if (this->i < countof(attributes))
|
||||
{
|
||||
*type = attributes[this->i++];
|
||||
|
@ -393,7 +396,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
|||
}
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_enumerate_attributes,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_attributes,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
);
|
||||
|
@ -407,24 +411,27 @@ typedef struct {
|
|||
ike_sa_id_t *id;
|
||||
} include_filter_t;
|
||||
|
||||
/**
|
||||
* Include enumerator filter function
|
||||
*/
|
||||
static bool include_filter(include_filter_t *data,
|
||||
entry_t **entry, traffic_selector_t **ts)
|
||||
CALLBACK(include_filter, bool,
|
||||
include_filter_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (data->id->equals(data->id, (*entry)->id))
|
||||
entry_t *entry;
|
||||
traffic_selector_t **ts;
|
||||
|
||||
VA_ARGS_VGET(args, ts);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*ts = (*entry)->ts;
|
||||
return TRUE;
|
||||
if (data->id->equals(data->id, entry->id))
|
||||
{
|
||||
*ts = entry->ts;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy include filter data, unlock mutex
|
||||
*/
|
||||
static void destroy_filter(include_filter_t *data)
|
||||
CALLBACK(destroy_filter, void,
|
||||
include_filter_t *data)
|
||||
{
|
||||
data->mutex->unlock(data->mutex);
|
||||
free(data);
|
||||
|
@ -442,7 +449,7 @@ METHOD(unity_handler_t, create_include_enumerator, enumerator_t*,
|
|||
data->mutex->lock(data->mutex);
|
||||
return enumerator_create_filter(
|
||||
this->include->create_enumerator(this->include),
|
||||
(void*)include_filter, data, (void*)destroy_filter);
|
||||
include_filter, data, destroy_filter);
|
||||
}
|
||||
|
||||
METHOD(unity_handler_t, destroy, void,
|
||||
|
|
|
@ -77,12 +77,15 @@ static void append_ts(bio_writer_t *writer, traffic_selector_t *ts)
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, attribute_enumerate, bool,
|
||||
attribute_enumerator_t *this, configuration_attribute_type_t *type,
|
||||
chunk_t *attr)
|
||||
attribute_enumerator_t *this, va_list args)
|
||||
{
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *attr;
|
||||
traffic_selector_t *ts;
|
||||
bio_writer_t *writer;
|
||||
|
||||
VA_ARGS_VGET(args, type, attr);
|
||||
|
||||
if (this->list->get_count(this->list) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -183,7 +186,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
|||
|
||||
INIT(attr_enum,
|
||||
.public = {
|
||||
.enumerate = (void*)_attribute_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _attribute_enumerate,
|
||||
.destroy = _attribute_destroy,
|
||||
},
|
||||
.list = list,
|
||||
|
|
|
@ -122,9 +122,14 @@ typedef struct {
|
|||
endecode_test_t *next;
|
||||
} endecode_enum_t;
|
||||
|
||||
static bool endecode_enumerate(endecode_enum_t *this, vici_type_t *type,
|
||||
char **name, chunk_t *data)
|
||||
METHOD(enumerator_t, endecode_enumerate, bool,
|
||||
endecode_enum_t *this, va_list args)
|
||||
{
|
||||
vici_type_t *type;
|
||||
chunk_t *data;
|
||||
char **name;
|
||||
|
||||
VA_ARGS_VGET(args, type, name, data);
|
||||
if (this->next)
|
||||
{
|
||||
*type = this->next->type;
|
||||
|
@ -149,7 +154,8 @@ static enumerator_t *endecode_create_enumerator(endecode_test_t *test)
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)endecode_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _endecode_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.next = test,
|
||||
|
|
|
@ -184,16 +184,22 @@ METHOD(attribute_provider_t, release_address, bool,
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter mapping attribute_t to enumerated type/value arguments
|
||||
*/
|
||||
static bool attr_filter(void *data, attribute_t **attr,
|
||||
configuration_attribute_type_t *type,
|
||||
void *in, chunk_t *value)
|
||||
CALLBACK(attr_filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*type = (*attr)->type;
|
||||
*value = (*attr)->value;
|
||||
return TRUE;
|
||||
attribute_t *attr;
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *value;
|
||||
|
||||
VA_ARGS_VGET(args, type, value);
|
||||
|
||||
if (orig->enumerate(orig, &attr))
|
||||
{
|
||||
*type = attr->type;
|
||||
*value = attr->value;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,7 +209,7 @@ CALLBACK(create_nested, enumerator_t*,
|
|||
pool_t *pool, void *this)
|
||||
{
|
||||
return enumerator_create_filter(array_create_enumerator(pool->attrs),
|
||||
(void*)attr_filter, NULL, NULL);
|
||||
attr_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -141,13 +141,20 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
(void*)this->lock->unlock, this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerator filter function for ike configs
|
||||
*/
|
||||
static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
|
||||
CALLBACK(ike_filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = (*in)->get_ike_cfg(*in);
|
||||
return TRUE;
|
||||
peer_cfg_t *cfg;
|
||||
ike_cfg_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &cfg))
|
||||
{
|
||||
*out = cfg->get_ike_cfg(cfg);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
||||
|
@ -155,7 +162,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
|||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->conns->create_enumerator(this->conns),
|
||||
(void*)ike_filter, this->lock,
|
||||
ike_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
|
|
|
@ -135,11 +135,16 @@ typedef struct {
|
|||
} parse_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, parse_enumerate, bool,
|
||||
parse_enumerator_t *this, vici_type_t *out, char **name, chunk_t *value)
|
||||
parse_enumerator_t *this, va_list args)
|
||||
{
|
||||
vici_type_t *out;
|
||||
chunk_t *value;
|
||||
char **name;
|
||||
uint8_t type;
|
||||
chunk_t data;
|
||||
|
||||
VA_ARGS_VGET(args, out, name, value);
|
||||
|
||||
if (!this->reader->remaining(this->reader) ||
|
||||
!this->reader->read_uint8(this->reader, &type))
|
||||
{
|
||||
|
@ -218,7 +223,8 @@ METHOD(vici_message_t, create_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_parse_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _parse_enumerate,
|
||||
.destroy = _parse_destroy,
|
||||
},
|
||||
.reader = bio_reader_create(this->encoding),
|
||||
|
|
|
@ -119,14 +119,19 @@ METHOD(whitelist_listener_t, remove_, void,
|
|||
DESTROY_IF(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerator filter, from hashtable (key, value) to single identity
|
||||
*/
|
||||
static bool whitelist_filter(rwlock_t *lock, identification_t **key,
|
||||
identification_t **id, identification_t **value)
|
||||
CALLBACK(whitelist_filter, bool,
|
||||
rwlock_t *lock, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*id = *value;
|
||||
return TRUE;
|
||||
identification_t *key, *value, **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &key, &value))
|
||||
{
|
||||
*out = value;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(whitelist_listener_t, create_enumerator, enumerator_t*,
|
||||
|
@ -134,7 +139,7 @@ METHOD(whitelist_listener_t, create_enumerator, enumerator_t*,
|
|||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->ids->create_enumerator(this->ids),
|
||||
(void*)whitelist_filter, this->lock,
|
||||
whitelist_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
|
|
|
@ -435,10 +435,11 @@ struct policy_enumerator_t {
|
|||
};
|
||||
|
||||
METHOD(enumerator_t, policy_enumerate, bool,
|
||||
policy_enumerator_t *this, traffic_selector_t **my_out,
|
||||
traffic_selector_t **other_out)
|
||||
policy_enumerator_t *this, va_list args)
|
||||
{
|
||||
traffic_selector_t *other_ts;
|
||||
traffic_selector_t *other_ts, **my_out, **other_out;
|
||||
|
||||
VA_ARGS_VGET(args, my_out, other_out);
|
||||
|
||||
while (this->ts || this->mine->enumerate(this->mine, &this->ts))
|
||||
{
|
||||
|
@ -487,7 +488,8 @@ METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_policy_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _policy_enumerate,
|
||||
.destroy = _policy_destroy,
|
||||
},
|
||||
.mine = array_create_enumerator(this->my_ts),
|
||||
|
@ -1402,13 +1404,13 @@ METHOD(child_sa_t, get_rekey_spi, uint32_t,
|
|||
return this->rekey_spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to reinstall a virtual IP
|
||||
*/
|
||||
static void reinstall_vip(host_t *vip, host_t *me)
|
||||
CALLBACK(reinstall_vip, void,
|
||||
host_t *vip, va_list args)
|
||||
{
|
||||
host_t *me;
|
||||
char *iface;
|
||||
|
||||
VA_ARGS_VGET(args, me);
|
||||
if (charon->kernel->get_interface(charon->kernel, me, &iface))
|
||||
{
|
||||
charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
|
||||
|
@ -1530,7 +1532,7 @@ METHOD(child_sa_t, update, status_t,
|
|||
|
||||
/* we reinstall the virtual IP to handle interface roaming
|
||||
* correctly */
|
||||
vips->invoke_function(vips, (void*)reinstall_vip, me);
|
||||
vips->invoke_function(vips, reinstall_vip, me);
|
||||
|
||||
/* reinstall updated policies */
|
||||
install_policies_internal(this, me, other, my_ts, other_ts,
|
||||
|
|
|
@ -105,31 +105,38 @@ METHOD(eap_manager_t, remove_method, void,
|
|||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter the registered methods
|
||||
*/
|
||||
static bool filter_methods(uintptr_t role, eap_entry_t **entry,
|
||||
eap_type_t *type, void *in, uint32_t *vendor)
|
||||
CALLBACK(filter_methods, bool,
|
||||
uintptr_t role, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if ((*entry)->role != (eap_role_t)role)
|
||||
eap_entry_t *entry;
|
||||
eap_type_t *type;
|
||||
uint32_t *vendor;
|
||||
|
||||
VA_ARGS_VGET(args, type, vendor);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
return FALSE;
|
||||
if (entry->role != (eap_role_t)role)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry->vendor == 0 &&
|
||||
(entry->type < 4 || entry->type == EAP_EXPANDED ||
|
||||
entry->type > EAP_EXPERIMENTAL))
|
||||
{ /* filter invalid types */
|
||||
continue;
|
||||
}
|
||||
if (type)
|
||||
{
|
||||
*type = entry->type;
|
||||
}
|
||||
if (vendor)
|
||||
{
|
||||
*vendor = entry->vendor;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if ((*entry)->vendor == 0 &&
|
||||
((*entry)->type < 4 || (*entry)->type == EAP_EXPANDED ||
|
||||
(*entry)->type > EAP_EXPERIMENTAL))
|
||||
{ /* filter invalid types */
|
||||
return FALSE;
|
||||
}
|
||||
if (type)
|
||||
{
|
||||
*type = (*entry)->type;
|
||||
}
|
||||
if (vendor)
|
||||
{
|
||||
*vendor = (*entry)->vendor;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(eap_manager_t, create_enumerator, enumerator_t*,
|
||||
|
@ -139,7 +146,7 @@ METHOD(eap_manager_t, create_enumerator, enumerator_t*,
|
|||
return enumerator_create_cleaner(
|
||||
enumerator_create_filter(
|
||||
this->methods->create_enumerator(this->methods),
|
||||
(void*)filter_methods, (void*)(uintptr_t)role, NULL),
|
||||
filter_methods, (void*)(uintptr_t)role, NULL),
|
||||
(void*)this->lock->unlock, this->lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -1200,12 +1200,20 @@ METHOD(ike_sa_t, generate_message, status_t,
|
|||
return status;
|
||||
}
|
||||
|
||||
static bool filter_fragments(private_ike_sa_t *this, packet_t **fragment,
|
||||
packet_t **packet)
|
||||
CALLBACK(filter_fragments, bool,
|
||||
private_ike_sa_t *this, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*packet = (*fragment)->clone(*fragment);
|
||||
set_dscp(this, *packet);
|
||||
return TRUE;
|
||||
packet_t *fragment, **packet;
|
||||
|
||||
VA_ARGS_VGET(args, packet);
|
||||
|
||||
if (orig->enumerate(orig, &fragment))
|
||||
{
|
||||
*packet = fragment->clone(fragment);
|
||||
set_dscp(this, *packet);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, generate_message_fragmented, status_t,
|
||||
|
@ -1265,7 +1273,7 @@ METHOD(ike_sa_t, generate_message_fragmented, status_t,
|
|||
{
|
||||
charon->bus->message(charon->bus, message, FALSE, FALSE);
|
||||
}
|
||||
*packets = enumerator_create_filter(fragments, (void*)filter_fragments,
|
||||
*packets = enumerator_create_filter(fragments, filter_fragments,
|
||||
this, NULL);
|
||||
}
|
||||
return status;
|
||||
|
@ -1699,8 +1707,11 @@ typedef struct {
|
|||
} child_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, child_enumerate, bool,
|
||||
child_enumerator_t *this, child_sa_t **child_sa)
|
||||
child_enumerator_t *this, va_list args)
|
||||
{
|
||||
child_sa_t **child_sa;
|
||||
|
||||
VA_ARGS_VGET(args, child_sa);
|
||||
if (this->inner->enumerate(this->inner, &this->current))
|
||||
{
|
||||
*child_sa = this->current;
|
||||
|
@ -1723,7 +1734,8 @@ METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_child_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _child_enumerate,
|
||||
.destroy = _child_enumerator_destroy,
|
||||
},
|
||||
.inner = array_create_enumerator(this->child_sas),
|
||||
|
@ -2619,24 +2631,31 @@ METHOD(ike_sa_t, add_configuration_attribute, void,
|
|||
array_insert(this->attributes, ARRAY_TAIL, &entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerator filter for attributes
|
||||
*/
|
||||
static bool filter_attribute(void *null, attribute_entry_t **in,
|
||||
configuration_attribute_type_t *type, void *in2,
|
||||
chunk_t *data, void *in3, bool *handled)
|
||||
CALLBACK(filter_attribute, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*type = (*in)->type;
|
||||
*data = (*in)->data;
|
||||
*handled = (*in)->handler != NULL;
|
||||
return TRUE;
|
||||
attribute_entry_t *entry;
|
||||
configuration_attribute_type_t *type;
|
||||
chunk_t *data;
|
||||
bool *handled;
|
||||
|
||||
VA_ARGS_VGET(args, type, data, handled);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*type = entry->type;
|
||||
*data = entry->data;
|
||||
*handled = entry->handler != NULL;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_ike_sa_t *this)
|
||||
{
|
||||
return enumerator_create_filter(array_create_enumerator(this->attributes),
|
||||
(void*)filter_attribute, NULL, NULL);
|
||||
filter_attribute, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, create_task_enumerator, enumerator_t*,
|
||||
|
|
|
@ -151,8 +151,10 @@ static entry_t *entry_create()
|
|||
/**
|
||||
* Function that matches entry_t objects by ike_sa_id_t.
|
||||
*/
|
||||
static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id)
|
||||
static bool entry_match_by_id(entry_t *entry, void *arg)
|
||||
{
|
||||
ike_sa_id_t *id = arg;
|
||||
|
||||
if (id->equals(id, entry->ike_sa_id))
|
||||
{
|
||||
return TRUE;
|
||||
|
@ -172,7 +174,7 @@ static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id)
|
|||
/**
|
||||
* Function that matches entry_t objects by ike_sa_t pointers.
|
||||
*/
|
||||
static bool entry_match_by_sa(entry_t *entry, ike_sa_t *ike_sa)
|
||||
static bool entry_match_by_sa(entry_t *entry, void *ike_sa)
|
||||
{
|
||||
return entry->ike_sa == ike_sa;
|
||||
}
|
||||
|
@ -513,8 +515,13 @@ struct private_enumerator_t {
|
|||
};
|
||||
|
||||
METHOD(enumerator_t, enumerate, bool,
|
||||
private_enumerator_t *this, entry_t **entry, u_int *segment)
|
||||
private_enumerator_t *this, va_list args)
|
||||
{
|
||||
entry_t **entry;
|
||||
u_int *segment;
|
||||
|
||||
VA_ARGS_VGET(args, entry, segment);
|
||||
|
||||
if (this->entry)
|
||||
{
|
||||
this->entry->condvar->signal(this->entry->condvar);
|
||||
|
@ -572,7 +579,8 @@ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this)
|
|||
|
||||
INIT(enumerator,
|
||||
.enumerator = {
|
||||
.enumerate = (void*)_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate,
|
||||
.destroy = _enumerator_destroy,
|
||||
},
|
||||
.manager = this,
|
||||
|
@ -671,7 +679,7 @@ static void remove_entry_at(private_enumerator_t *this)
|
|||
*/
|
||||
static status_t get_entry_by_match_function(private_ike_sa_manager_t *this,
|
||||
ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment,
|
||||
linked_list_match_t match, void *param)
|
||||
bool (*match)(entry_t*,void*), void *param)
|
||||
{
|
||||
table_item_t *item;
|
||||
u_int row, seg;
|
||||
|
@ -704,7 +712,7 @@ static status_t get_entry_by_id(private_ike_sa_manager_t *this,
|
|||
ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment)
|
||||
{
|
||||
return get_entry_by_match_function(this, ike_sa_id, entry, segment,
|
||||
(linked_list_match_t)entry_match_by_id, ike_sa_id);
|
||||
entry_match_by_id, ike_sa_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -715,7 +723,7 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this,
|
|||
ike_sa_id_t *ike_sa_id, ike_sa_t *ike_sa, entry_t **entry, u_int *segment)
|
||||
{
|
||||
return get_entry_by_match_function(this, ike_sa_id, entry, segment,
|
||||
(linked_list_match_t)entry_match_by_sa, ike_sa);
|
||||
entry_match_by_sa, ike_sa);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -852,6 +860,15 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
|
|||
lock->unlock(lock);
|
||||
}
|
||||
|
||||
CALLBACK(id_matches, bool,
|
||||
ike_sa_id_t *a, va_list args)
|
||||
{
|
||||
ike_sa_id_t *b;
|
||||
|
||||
VA_ARGS_VGET(args, b);
|
||||
return a->equals(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put an SA between two peers into the hash table.
|
||||
*/
|
||||
|
@ -880,8 +897,7 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
|||
entry->other_id, family))
|
||||
{
|
||||
if (connected_peers->sas->find_first(connected_peers->sas,
|
||||
(linked_list_match_t)entry->ike_sa_id->equals,
|
||||
NULL, entry->ike_sa_id) == SUCCESS)
|
||||
id_matches, NULL, entry->ike_sa_id))
|
||||
{
|
||||
lock->unlock(lock);
|
||||
return;
|
||||
|
@ -1556,42 +1572,52 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
|
|||
return ike_sa;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator filter function, waiting variant
|
||||
*/
|
||||
static bool enumerator_filter_wait(private_ike_sa_manager_t *this,
|
||||
entry_t **in, ike_sa_t **out, u_int *segment)
|
||||
CALLBACK(enumerator_filter_wait, bool,
|
||||
private_ike_sa_manager_t *this, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (wait_for_entry(this, *in, *segment))
|
||||
entry_t *entry;
|
||||
u_int segment;
|
||||
ike_sa_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &entry, &segment))
|
||||
{
|
||||
*out = (*in)->ike_sa;
|
||||
charon->bus->set_sa(charon->bus, *out);
|
||||
return TRUE;
|
||||
if (wait_for_entry(this, entry, segment))
|
||||
{
|
||||
*out = entry->ike_sa;
|
||||
charon->bus->set_sa(charon->bus, *out);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator filter function, skipping variant
|
||||
*/
|
||||
static bool enumerator_filter_skip(private_ike_sa_manager_t *this,
|
||||
entry_t **in, ike_sa_t **out, u_int *segment)
|
||||
CALLBACK(enumerator_filter_skip, bool,
|
||||
private_ike_sa_manager_t *this, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (!(*in)->driveout_new_threads &&
|
||||
!(*in)->driveout_waiting_threads &&
|
||||
!(*in)->checked_out)
|
||||
entry_t *entry;
|
||||
u_int segment;
|
||||
ike_sa_t **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &entry, &segment))
|
||||
{
|
||||
*out = (*in)->ike_sa;
|
||||
charon->bus->set_sa(charon->bus, *out);
|
||||
return TRUE;
|
||||
if (!entry->driveout_new_threads &&
|
||||
!entry->driveout_waiting_threads &&
|
||||
!entry->checked_out)
|
||||
{
|
||||
*out = entry->ike_sa;
|
||||
charon->bus->set_sa(charon->bus, *out);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset threads SA after enumeration
|
||||
*/
|
||||
static void reset_sa(void *data)
|
||||
CALLBACK(reset_sa, void,
|
||||
void *data)
|
||||
{
|
||||
charon->bus->set_sa(charon->bus, NULL);
|
||||
}
|
||||
|
|
|
@ -450,22 +450,21 @@ static initiate_data_t *initiate_data_create(check_list_t *checklist,
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an initiated connection by the peers' ids
|
||||
*/
|
||||
static bool match_initiated_by_ids(initiated_t *current, identification_t *id,
|
||||
identification_t *peer_id)
|
||||
CALLBACK(match_initiated_by_ids, bool,
|
||||
initiated_t *current, va_list args)
|
||||
{
|
||||
identification_t *id, *peer_id;
|
||||
|
||||
VA_ARGS_VGET(args, id, peer_id);
|
||||
return id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id);
|
||||
}
|
||||
|
||||
static status_t get_initiated_by_ids(private_connect_manager_t *this,
|
||||
identification_t *id,
|
||||
identification_t *peer_id,
|
||||
initiated_t **initiated)
|
||||
static bool get_initiated_by_ids(private_connect_manager_t *this,
|
||||
identification_t *id,
|
||||
identification_t *peer_id,
|
||||
initiated_t **initiated)
|
||||
{
|
||||
return this->initiated->find_first(this->initiated,
|
||||
(linked_list_match_t)match_initiated_by_ids,
|
||||
return this->initiated->find_first(this->initiated, match_initiated_by_ids,
|
||||
(void**)initiated, id, peer_id);
|
||||
}
|
||||
|
||||
|
@ -490,21 +489,20 @@ static void remove_initiated(private_connect_manager_t *this,
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the checklist with a specific connect ID
|
||||
*/
|
||||
static bool match_checklist_by_id(check_list_t *current, chunk_t *connect_id)
|
||||
CALLBACK(match_checklist_by_id, bool,
|
||||
check_list_t *current, va_list args)
|
||||
{
|
||||
return chunk_equals(*connect_id, current->connect_id);
|
||||
chunk_t connect_id;
|
||||
|
||||
VA_ARGS_VGET(args, connect_id);
|
||||
return chunk_equals(connect_id, current->connect_id);
|
||||
}
|
||||
|
||||
static status_t get_checklist_by_id(private_connect_manager_t *this,
|
||||
chunk_t connect_id,
|
||||
check_list_t **check_list)
|
||||
static bool get_checklist_by_id(private_connect_manager_t *this,
|
||||
chunk_t connect_id, check_list_t **check_list)
|
||||
{
|
||||
return this->checklists->find_first(this->checklists,
|
||||
(linked_list_match_t)match_checklist_by_id,
|
||||
(void**)check_list, &connect_id);
|
||||
return this->checklists->find_first(this->checklists, match_checklist_by_id,
|
||||
(void**)check_list, connect_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -528,19 +526,19 @@ static void remove_checklist(private_connect_manager_t *this,
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a list of endpoint_notify_t contains a certain host_t
|
||||
*/
|
||||
static bool match_endpoint_by_host(endpoint_notify_t *current, host_t *host)
|
||||
CALLBACK(match_endpoint_by_host, bool,
|
||||
endpoint_notify_t *current, va_list args)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
VA_ARGS_VGET(args, host);
|
||||
return host->equals(host, current->get_host(current));
|
||||
}
|
||||
|
||||
static status_t endpoints_contain(linked_list_t *endpoints, host_t *host,
|
||||
static bool endpoints_contain(linked_list_t *endpoints, host_t *host,
|
||||
endpoint_notify_t **endpoint)
|
||||
{
|
||||
return endpoints->find_first(endpoints,
|
||||
(linked_list_match_t)match_endpoint_by_host,
|
||||
return endpoints->find_first(endpoints, match_endpoint_by_host,
|
||||
(void**)endpoint, host);
|
||||
}
|
||||
|
||||
|
@ -560,39 +558,44 @@ static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair)
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a list of endpoint_pair_t for a pair with specific host_ts
|
||||
*/
|
||||
static bool match_pair_by_hosts(endpoint_pair_t *current, host_t *local,
|
||||
host_t *remote)
|
||||
CALLBACK(match_pair_by_hosts, bool,
|
||||
endpoint_pair_t *current, va_list args)
|
||||
{
|
||||
return local->equals(local, current->local) && remote->equals(remote, current->remote);
|
||||
host_t *local, *remote;
|
||||
|
||||
VA_ARGS_VGET(args, local, remote);
|
||||
return local->equals(local, current->local) &&
|
||||
remote->equals(remote, current->remote);
|
||||
}
|
||||
|
||||
static status_t get_pair_by_hosts(linked_list_t *pairs, host_t *local,
|
||||
host_t *remote, endpoint_pair_t **pair)
|
||||
static bool get_pair_by_hosts(linked_list_t *pairs, host_t *local,
|
||||
host_t *remote, endpoint_pair_t **pair)
|
||||
{
|
||||
return pairs->find_first(pairs, (linked_list_match_t)match_pair_by_hosts,
|
||||
(void**)pair, local, remote);
|
||||
return pairs->find_first(pairs, match_pair_by_hosts, (void**)pair, local,
|
||||
remote);
|
||||
}
|
||||
|
||||
static bool match_pair_by_id(endpoint_pair_t *current, uint32_t *id)
|
||||
CALLBACK(match_pair_by_id, bool,
|
||||
endpoint_pair_t *current, va_list args)
|
||||
{
|
||||
return current->id == *id;
|
||||
uint32_t id;
|
||||
|
||||
VA_ARGS_VGET(args, id);
|
||||
return current->id == id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a pair with a specific id
|
||||
*/
|
||||
static status_t get_pair_by_id(check_list_t *checklist, uint32_t id,
|
||||
endpoint_pair_t **pair)
|
||||
static bool get_pair_by_id(check_list_t *checklist, uint32_t id,
|
||||
endpoint_pair_t **pair)
|
||||
{
|
||||
return checklist->pairs->find_first(checklist->pairs,
|
||||
(linked_list_match_t)match_pair_by_id,
|
||||
(void**)pair, &id);
|
||||
return checklist->pairs->find_first(checklist->pairs, match_pair_by_id,
|
||||
(void**)pair, id);
|
||||
}
|
||||
|
||||
static bool match_succeeded_pair(endpoint_pair_t *current)
|
||||
CALLBACK(match_succeeded_pair, bool,
|
||||
endpoint_pair_t *current, va_list args)
|
||||
{
|
||||
return current->state == CHECK_SUCCEEDED;
|
||||
}
|
||||
|
@ -600,15 +603,14 @@ static bool match_succeeded_pair(endpoint_pair_t *current)
|
|||
/**
|
||||
* Returns the best pair of state CHECK_SUCCEEDED from a checklist.
|
||||
*/
|
||||
static status_t get_best_valid_pair(check_list_t *checklist,
|
||||
endpoint_pair_t **pair)
|
||||
static bool get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair)
|
||||
{
|
||||
return checklist->pairs->find_first(checklist->pairs,
|
||||
(linked_list_match_t)match_succeeded_pair,
|
||||
(void**)pair);
|
||||
return checklist->pairs->find_first(checklist->pairs, match_succeeded_pair,
|
||||
(void**)pair);
|
||||
}
|
||||
|
||||
static bool match_waiting_pair(endpoint_pair_t *current)
|
||||
CALLBACK(match_waiting_pair, bool,
|
||||
endpoint_pair_t *current, va_list args)
|
||||
{
|
||||
return current->state == CHECK_WAITING;
|
||||
}
|
||||
|
@ -865,7 +867,7 @@ static job_requeue_t initiator_finish(callback_data_t *data)
|
|||
this->mutex->lock(this->mutex);
|
||||
|
||||
check_list_t *checklist;
|
||||
if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS)
|
||||
if (!get_checklist_by_id(this, data->connect_id, &checklist))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' not found, can't finish "
|
||||
"connectivity checks", &data->connect_id);
|
||||
|
@ -953,7 +955,7 @@ static job_requeue_t retransmit(callback_data_t *data)
|
|||
this->mutex->lock(this->mutex);
|
||||
|
||||
check_list_t *checklist;
|
||||
if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS)
|
||||
if (!get_checklist_by_id(this, data->connect_id, &checklist))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' not found, can't retransmit "
|
||||
"connectivity check", &data->connect_id);
|
||||
|
@ -962,7 +964,7 @@ static job_requeue_t retransmit(callback_data_t *data)
|
|||
}
|
||||
|
||||
endpoint_pair_t *pair;
|
||||
if (get_pair_by_id(checklist, data->mid, &pair) != SUCCESS)
|
||||
if (!get_pair_by_id(checklist, data->mid, &pair))
|
||||
{
|
||||
DBG1(DBG_IKE, "pair with id '%d' not found, can't retransmit "
|
||||
"connectivity check", data->mid);
|
||||
|
@ -1108,7 +1110,7 @@ static job_requeue_t sender(callback_data_t *data)
|
|||
this->mutex->lock(this->mutex);
|
||||
|
||||
check_list_t *checklist;
|
||||
if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS)
|
||||
if (!get_checklist_by_id(this, data->connect_id, &checklist))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' not found, can't send "
|
||||
"connectivity check", &data->connect_id);
|
||||
|
@ -1124,9 +1126,8 @@ static job_requeue_t sender(callback_data_t *data)
|
|||
{
|
||||
DBG1(DBG_IKE, "no triggered check queued, sending an ordinary check");
|
||||
|
||||
if (checklist->pairs->find_first(checklist->pairs,
|
||||
(linked_list_match_t)match_waiting_pair,
|
||||
(void**)&pair) != SUCCESS)
|
||||
if (!checklist->pairs->find_first(checklist->pairs, match_waiting_pair,
|
||||
(void**)&pair))
|
||||
{
|
||||
this->mutex->unlock(this->mutex);
|
||||
DBG1(DBG_IKE, "no pairs in waiting state, aborting");
|
||||
|
@ -1182,7 +1183,7 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
|
|||
initiated_t *initiated = data->initiated;
|
||||
|
||||
endpoint_pair_t *pair;
|
||||
if (get_best_valid_pair(checklist, &pair) == SUCCESS)
|
||||
if (get_best_valid_pair(checklist, &pair))
|
||||
{
|
||||
ike_sa_id_t *waiting_sa;
|
||||
enumerator_t *enumerator = initiated->mediated->create_enumerator(
|
||||
|
@ -1219,7 +1220,7 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
|
|||
{
|
||||
initiated_t *initiated;
|
||||
if (get_initiated_by_ids(this, checklist->initiator.id,
|
||||
checklist->responder.id, &initiated) == SUCCESS)
|
||||
checklist->responder.id, &initiated))
|
||||
{
|
||||
callback_job_t *job;
|
||||
|
||||
|
@ -1247,7 +1248,7 @@ static void process_response(private_connect_manager_t *this, check_t *check,
|
|||
check_list_t *checklist)
|
||||
{
|
||||
endpoint_pair_t *pair;
|
||||
if (get_pair_by_id(checklist, check->mid, &pair) == SUCCESS)
|
||||
if (get_pair_by_id(checklist, check->mid, &pair))
|
||||
{
|
||||
if (pair->local->equals(pair->local, check->dst) &&
|
||||
pair->remote->equals(pair->remote, check->src))
|
||||
|
@ -1261,9 +1262,9 @@ static void process_response(private_connect_manager_t *this, check_t *check,
|
|||
checklist->initiator.endpoints : checklist->responder.endpoints;
|
||||
|
||||
endpoint_notify_t *local_endpoint;
|
||||
if (endpoints_contain(local_endpoints,
|
||||
check->endpoint->get_host(check->endpoint),
|
||||
&local_endpoint) != SUCCESS)
|
||||
if (!endpoints_contain(local_endpoints,
|
||||
check->endpoint->get_host(check->endpoint),
|
||||
&local_endpoint))
|
||||
{
|
||||
local_endpoint = endpoint_notify_create_from_host(PEER_REFLEXIVE,
|
||||
check->endpoint->get_host(check->endpoint), pair->local);
|
||||
|
@ -1302,15 +1303,14 @@ static void process_request(private_connect_manager_t *this, check_t *check,
|
|||
peer_reflexive->set_priority(peer_reflexive,
|
||||
check->endpoint->get_priority(check->endpoint));
|
||||
|
||||
if (endpoints_contain(remote_endpoints, check->src, &remote_endpoint) != SUCCESS)
|
||||
if (!endpoints_contain(remote_endpoints, check->src, &remote_endpoint))
|
||||
{
|
||||
remote_endpoint = peer_reflexive->clone(peer_reflexive);
|
||||
remote_endpoints->insert_last(remote_endpoints, remote_endpoint);
|
||||
}
|
||||
|
||||
endpoint_pair_t *pair;
|
||||
if (get_pair_by_hosts(checklist->pairs, check->dst, check->src,
|
||||
&pair) == SUCCESS)
|
||||
if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, &pair))
|
||||
{
|
||||
switch(pair->state)
|
||||
{
|
||||
|
@ -1389,7 +1389,7 @@ METHOD(connect_manager_t, process_check, void,
|
|||
this->mutex->lock(this->mutex);
|
||||
|
||||
check_list_t *checklist;
|
||||
if (get_checklist_by_id(this, check->connect_id, &checklist) != SUCCESS)
|
||||
if (!get_checklist_by_id(this, check->connect_id, &checklist))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' not found",
|
||||
&check->connect_id);
|
||||
|
@ -1423,6 +1423,15 @@ METHOD(connect_manager_t, process_check, void,
|
|||
check_destroy(check);
|
||||
}
|
||||
|
||||
CALLBACK(id_matches, bool,
|
||||
ike_sa_id_t *a, va_list args)
|
||||
{
|
||||
ike_sa_id_t *b;
|
||||
|
||||
VA_ARGS_VGET(args, b);
|
||||
return a->equals(a, b);
|
||||
}
|
||||
|
||||
METHOD(connect_manager_t, check_and_register, bool,
|
||||
private_connect_manager_t *this, identification_t *id,
|
||||
identification_t *peer_id, ike_sa_id_t *mediated_sa)
|
||||
|
@ -1432,7 +1441,7 @@ METHOD(connect_manager_t, check_and_register, bool,
|
|||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS)
|
||||
if (!get_initiated_by_ids(this, id, peer_id, &initiated))
|
||||
{
|
||||
DBG2(DBG_IKE, "registered waiting mediated connection with '%Y'",
|
||||
peer_id);
|
||||
|
@ -1441,9 +1450,8 @@ METHOD(connect_manager_t, check_and_register, bool,
|
|||
already_there = FALSE;
|
||||
}
|
||||
|
||||
if (initiated->mediated->find_first(initiated->mediated,
|
||||
(linked_list_match_t)mediated_sa->equals,
|
||||
NULL, mediated_sa) != SUCCESS)
|
||||
if (!initiated->mediated->find_first(initiated->mediated, id_matches,
|
||||
NULL, mediated_sa))
|
||||
{
|
||||
initiated->mediated->insert_last(initiated->mediated,
|
||||
mediated_sa->clone(mediated_sa));
|
||||
|
@ -1462,7 +1470,7 @@ METHOD(connect_manager_t, check_and_initiate, void,
|
|||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS)
|
||||
if (!get_initiated_by_ids(this, id, peer_id, &initiated))
|
||||
{
|
||||
DBG2(DBG_IKE, "no waiting mediated connections with '%Y'", peer_id);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
@ -1492,7 +1500,7 @@ METHOD(connect_manager_t, set_initiator_data, status_t,
|
|||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (get_checklist_by_id(this, connect_id, NULL) == SUCCESS)
|
||||
if (get_checklist_by_id(this, connect_id, NULL))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' already exists, aborting",
|
||||
&connect_id);
|
||||
|
@ -1517,7 +1525,7 @@ METHOD(connect_manager_t, set_responder_data, status_t,
|
|||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS)
|
||||
if (!get_checklist_by_id(this, connect_id, &checklist))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' not found",
|
||||
&connect_id);
|
||||
|
@ -1547,7 +1555,7 @@ METHOD(connect_manager_t, stop_checks, status_t,
|
|||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS)
|
||||
if (!get_checklist_by_id(this, connect_id, &checklist))
|
||||
{
|
||||
DBG1(DBG_IKE, "checklist with id '%#B' not found",
|
||||
&connect_id);
|
||||
|
|
|
@ -2079,13 +2079,20 @@ METHOD(task_manager_t, reset, void,
|
|||
this->reset = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter queued tasks
|
||||
*/
|
||||
static bool filter_queued(void *unused, queued_task_t **queued, task_t **task)
|
||||
CALLBACK(filter_queued, bool,
|
||||
void *unused, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*task = (*queued)->task;
|
||||
return TRUE;
|
||||
queued_task_t *queued;
|
||||
task_t **task;
|
||||
|
||||
VA_ARGS_VGET(args, task);
|
||||
|
||||
if (orig->enumerate(orig, &queued))
|
||||
{
|
||||
*task = queued->task;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
|
||||
|
@ -2100,7 +2107,7 @@ METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
|
|||
case TASK_QUEUE_QUEUED:
|
||||
return enumerator_create_filter(
|
||||
array_create_enumerator(this->queued_tasks),
|
||||
(void*)filter_queued, NULL, NULL);
|
||||
filter_queued, NULL, NULL);
|
||||
default:
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
|
|
@ -81,11 +81,12 @@ typedef struct {
|
|||
bool check_delete_action;
|
||||
} entry_t;
|
||||
|
||||
/**
|
||||
* Check if the given entry is for the same CHILD_SA
|
||||
*/
|
||||
static bool match_child(entry_t *entry, child_sa_t *child_sa)
|
||||
CALLBACK(match_child, bool,
|
||||
entry_t *entry, va_list args)
|
||||
{
|
||||
child_sa_t *child_sa;
|
||||
|
||||
VA_ARGS_VGET(args, child_sa);
|
||||
return entry->child_sa == child_sa;
|
||||
}
|
||||
|
||||
|
@ -252,8 +253,8 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
|
|||
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x",
|
||||
protocol_id_names, protocol, ntohl(spi));
|
||||
|
||||
if (this->child_sas->find_first(this->child_sas,
|
||||
(void*)match_child, NULL, child_sa) == SUCCESS)
|
||||
if (this->child_sas->find_first(this->child_sas, match_child,
|
||||
NULL, child_sa))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -381,14 +381,24 @@ METHOD(shunt_manager_t, uninstall, bool,
|
|||
}
|
||||
|
||||
CALLBACK(filter_entries, bool,
|
||||
void *unused, entry_t **entry, char **ns, void **in, child_cfg_t **cfg)
|
||||
void *unused, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (ns)
|
||||
entry_t *entry;
|
||||
child_cfg_t **cfg;
|
||||
char **ns;
|
||||
|
||||
VA_ARGS_VGET(args, ns, cfg);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*ns = (*entry)->ns;
|
||||
if (ns)
|
||||
{
|
||||
*ns = entry->ns;
|
||||
}
|
||||
*cfg = entry->cfg;
|
||||
return TRUE;
|
||||
}
|
||||
*cfg = (*entry)->cfg;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
|
||||
|
@ -397,7 +407,7 @@ METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
|
|||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->shunts->create_enumerator(this->shunts),
|
||||
(void*)filter_entries, this->lock,
|
||||
filter_entries, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
|
|
|
@ -140,19 +140,21 @@ static void destroy_acquire(acquire_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* match an acquire entry by reqid
|
||||
*/
|
||||
static bool acquire_by_reqid(acquire_t *this, uint32_t *reqid)
|
||||
CALLBACK(acquire_by_reqid, bool,
|
||||
acquire_t *this, va_list args)
|
||||
{
|
||||
return this->reqid == *reqid;
|
||||
uint32_t reqid;
|
||||
|
||||
VA_ARGS_VGET(args, reqid);
|
||||
return this->reqid == reqid;
|
||||
}
|
||||
|
||||
/**
|
||||
* match an acquire entry by destination address
|
||||
*/
|
||||
static bool acquire_by_dst(acquire_t *this, host_t *dst)
|
||||
CALLBACK(acquire_by_dst, bool,
|
||||
acquire_t *this, va_list args)
|
||||
{
|
||||
host_t *dst;
|
||||
|
||||
VA_ARGS_VGET(args, dst);
|
||||
return this->dst && this->dst->ip_equals(this->dst, dst);
|
||||
}
|
||||
|
||||
|
@ -335,25 +337,32 @@ METHOD(trap_manager_t, uninstall, bool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert enumerated entries to peer_cfg, child_sa
|
||||
*/
|
||||
static bool trap_filter(rwlock_t *lock, entry_t **entry, peer_cfg_t **peer_cfg,
|
||||
void *none, child_sa_t **child_sa)
|
||||
CALLBACK(trap_filter, bool,
|
||||
rwlock_t *lock, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (!(*entry)->child_sa)
|
||||
{ /* skip entries that are currently being installed */
|
||||
return FALSE;
|
||||
}
|
||||
if (peer_cfg)
|
||||
entry_t *entry;
|
||||
peer_cfg_t **peer_cfg;
|
||||
child_sa_t **child_sa;
|
||||
|
||||
VA_ARGS_VGET(args, peer_cfg, child_sa);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*peer_cfg = (*entry)->peer_cfg;
|
||||
if (!entry->child_sa)
|
||||
{ /* skip entries that are currently being installed */
|
||||
continue;
|
||||
}
|
||||
if (peer_cfg)
|
||||
{
|
||||
*peer_cfg = entry->peer_cfg;
|
||||
}
|
||||
if (child_sa)
|
||||
{
|
||||
*child_sa = entry->child_sa;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (child_sa)
|
||||
{
|
||||
*child_sa = (*entry)->child_sa;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(trap_manager_t, create_enumerator, enumerator_t*,
|
||||
|
@ -361,7 +370,7 @@ METHOD(trap_manager_t, create_enumerator, enumerator_t*,
|
|||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->traps->create_enumerator(this->traps),
|
||||
(void*)trap_filter, this->lock,
|
||||
trap_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
|
@ -432,8 +441,8 @@ METHOD(trap_manager_t, acquire, void,
|
|||
uint8_t mask;
|
||||
|
||||
dst->to_subnet(dst, &host, &mask);
|
||||
if (this->acquires->find_first(this->acquires, (void*)acquire_by_dst,
|
||||
(void**)&acquire, host) == SUCCESS)
|
||||
if (this->acquires->find_first(this->acquires, acquire_by_dst,
|
||||
(void**)&acquire, host))
|
||||
{
|
||||
host->destroy(host);
|
||||
ignore = TRUE;
|
||||
|
@ -449,8 +458,8 @@ METHOD(trap_manager_t, acquire, void,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (this->acquires->find_first(this->acquires, (void*)acquire_by_reqid,
|
||||
(void**)&acquire, &reqid) == SUCCESS)
|
||||
if (this->acquires->find_first(this->acquires, acquire_by_reqid,
|
||||
(void**)&acquire, reqid))
|
||||
{
|
||||
ignore = TRUE;
|
||||
}
|
||||
|
|
|
@ -269,19 +269,27 @@ kernel_ipsec_t *mock_ipsec_create()
|
|||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter SAs
|
||||
*/
|
||||
static bool filter_sas(void *data, entry_t **entry, ike_sa_t **ike_sa,
|
||||
void *unused, uint32_t *spi)
|
||||
|
||||
CALLBACK(filter_sas, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if ((*entry)->alloc)
|
||||
entry_t *entry;
|
||||
ike_sa_t **ike_sa;
|
||||
uint32_t *spi;
|
||||
|
||||
VA_ARGS_VGET(args, ike_sa, spi);
|
||||
|
||||
while (orig->enumerate(orig, &entry, NULL))
|
||||
{
|
||||
return FALSE;
|
||||
if (entry->alloc)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*ike_sa = entry->ike_sa;
|
||||
*spi = entry->spi;
|
||||
return TRUE;
|
||||
}
|
||||
*ike_sa = (*entry)->ike_sa;
|
||||
*spi = (*entry)->spi;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -291,5 +299,5 @@ enumerator_t *mock_ipsec_create_sa_enumerator()
|
|||
{
|
||||
return enumerator_create_filter(
|
||||
instance->sas->create_enumerator(instance->sas),
|
||||
(void*)filter_sas, NULL, NULL);
|
||||
filter_sas, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
|||
u_char *pos;
|
||||
|
||||
if (this->offset == 0)
|
||||
{
|
||||
{
|
||||
if (this->length < IETF_INSTALLED_PACKAGES_MIN_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF,
|
||||
|
@ -291,15 +291,21 @@ METHOD(ietf_attr_installed_packages_t, add, void,
|
|||
this->packages->insert_last(this->packages, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate package filter entries
|
||||
*/
|
||||
static bool package_filter(void *null, package_entry_t **entry, chunk_t *name,
|
||||
void *i2, chunk_t *version)
|
||||
CALLBACK(package_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*name = (*entry)->name;
|
||||
*version = (*entry)->version;
|
||||
return TRUE;
|
||||
package_entry_t *entry;
|
||||
chunk_t *name, *version;
|
||||
|
||||
VA_ARGS_VGET(args, name, version);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*name = entry->name;
|
||||
*version = entry->version;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*,
|
||||
|
@ -307,7 +313,7 @@ METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*,
|
|||
{
|
||||
return enumerator_create_filter(
|
||||
this->packages->create_enumerator(this->packages),
|
||||
(void*)package_filter, NULL, NULL);
|
||||
package_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(ietf_attr_installed_packages_t, get_count, uint16_t,
|
||||
|
|
|
@ -213,24 +213,31 @@ METHOD(ietf_attr_port_filter_t, add_port, void,
|
|||
this->ports->insert_last(this->ports, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate port filter entries
|
||||
*/
|
||||
static bool port_filter(void *null, port_entry_t **entry,
|
||||
bool *blocked, void *i2, uint8_t *protocol, void *i3,
|
||||
uint16_t *port)
|
||||
CALLBACK(port_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*blocked = (*entry)->blocked;
|
||||
*protocol = (*entry)->protocol;
|
||||
*port = (*entry)->port;
|
||||
return TRUE;
|
||||
port_entry_t *entry;
|
||||
uint16_t *port;
|
||||
uint8_t *protocol;
|
||||
bool *blocked;
|
||||
|
||||
VA_ARGS_VGET(args, blocked, protocol, port);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*blocked = entry->blocked;
|
||||
*protocol = entry->protocol;
|
||||
*port = entry->port;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*,
|
||||
private_ietf_attr_port_filter_t *this)
|
||||
{
|
||||
return enumerator_create_filter(this->ports->create_enumerator(this->ports),
|
||||
(void*)port_filter, NULL, NULL);
|
||||
port_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -283,23 +283,20 @@ typedef struct {
|
|||
|
||||
} package_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of package_enumerator.destroy.
|
||||
*/
|
||||
static void package_enumerator_destroy(package_enumerator_t *this)
|
||||
METHOD(enumerator_t, package_enumerator_destroy, void,
|
||||
package_enumerator_t *this)
|
||||
{
|
||||
pclose(this->file);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of package_enumerator.enumerate
|
||||
*/
|
||||
static bool package_enumerator_enumerate(package_enumerator_t *this, ...)
|
||||
METHOD(enumerator_t, package_enumerator_enumerate, bool,
|
||||
package_enumerator_t *this, va_list args)
|
||||
{
|
||||
chunk_t *name, *version;
|
||||
u_char *pos;
|
||||
va_list args;
|
||||
|
||||
VA_ARGS_VGET(args, name, version);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
|
@ -319,23 +316,16 @@ static bool package_enumerator_enumerate(package_enumerator_t *this, ...)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
va_start(args, this);
|
||||
|
||||
name = va_arg(args, chunk_t*);
|
||||
name->ptr = pos;
|
||||
pos = strchr(pos, '\t');
|
||||
if (!pos)
|
||||
{
|
||||
va_end(args);
|
||||
return FALSE;
|
||||
}
|
||||
name->len = pos++ - name->ptr;
|
||||
|
||||
version = va_arg(args, chunk_t*);
|
||||
version->ptr = pos;
|
||||
version->len = strlen(pos) - 1;
|
||||
|
||||
va_end(args);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -362,12 +352,14 @@ METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a package enumerator instance */
|
||||
enumerator = malloc_thing(package_enumerator_t);
|
||||
enumerator->public.enumerate = (void*)package_enumerator_enumerate;
|
||||
enumerator->public.destroy = (void*)package_enumerator_destroy;
|
||||
enumerator->file = file;
|
||||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _package_enumerator_enumerate,
|
||||
.destroy = _package_enumerator_destroy,
|
||||
},
|
||||
.file = file,
|
||||
);
|
||||
return (enumerator_t*)enumerator;
|
||||
}
|
||||
|
||||
|
|
|
@ -626,22 +626,13 @@ typedef struct {
|
|||
|
||||
} language_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of language_enumerator.destroy.
|
||||
*/
|
||||
static void language_enumerator_destroy(language_enumerator_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of language_enumerator.enumerate
|
||||
*/
|
||||
static bool language_enumerator_enumerate(language_enumerator_t *this, ...)
|
||||
METHOD(enumerator_t, language_enumerator_enumerate, bool,
|
||||
language_enumerator_t *this, va_list args)
|
||||
{
|
||||
char *pos, *cur_lang, **lang;
|
||||
TNC_UInt32 len;
|
||||
va_list args;
|
||||
|
||||
VA_ARGS_VGET(args, lang);
|
||||
|
||||
if (!this->lang_len)
|
||||
{
|
||||
|
@ -676,11 +667,7 @@ static bool language_enumerator_enumerate(language_enumerator_t *this, ...)
|
|||
}
|
||||
cur_lang[len] = '\0';
|
||||
|
||||
va_start(args, this);
|
||||
lang = va_arg(args, char**);
|
||||
*lang = cur_lang;
|
||||
va_end(args);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -689,10 +676,13 @@ METHOD(imv_agent_t, create_language_enumerator, enumerator_t*,
|
|||
{
|
||||
language_enumerator_t *e;
|
||||
|
||||
/* Create a language enumerator instance */
|
||||
e = malloc_thing(language_enumerator_t);
|
||||
e->public.enumerate = (void*)language_enumerator_enumerate;
|
||||
e->public.destroy = (void*)language_enumerator_destroy;
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _language_enumerator_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
);
|
||||
|
||||
if (!this->get_attribute ||
|
||||
!this->get_attribute(this->id, state->get_connection_id(state),
|
||||
|
|
|
@ -262,22 +262,29 @@ METHOD(ita_attr_settings_t, add, void,
|
|||
this->list->insert_last(this->list, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate name/value pairs
|
||||
*/
|
||||
static bool entry_filter(void *null, entry_t **entry, char **name,
|
||||
void *i2, chunk_t *value)
|
||||
CALLBACK(entry_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*name = (*entry)->name;
|
||||
*value = (*entry)->value;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
chunk_t *value;
|
||||
char **name;
|
||||
|
||||
VA_ARGS_VGET(args, name, value);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*name = entry->name;
|
||||
*value = entry->value;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ita_attr_settings_t, create_enumerator, enumerator_t*,
|
||||
private_ita_attr_settings_t *this)
|
||||
{
|
||||
return enumerator_create_filter(this->list->create_enumerator(this->list),
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -418,24 +418,24 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate file measurement entries
|
||||
*/
|
||||
static bool entry_filter(void *null, func_comp_t **entry, uint8_t *flags,
|
||||
void *i2, uint32_t *depth,
|
||||
void *i3, pts_comp_func_name_t **comp_name)
|
||||
CALLBACK(entry_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
pts_component_t *comp;
|
||||
pts_comp_func_name_t *name;
|
||||
func_comp_t *entry;
|
||||
pts_comp_func_name_t **comp_name;
|
||||
uint32_t *depth;
|
||||
uint8_t *flags;
|
||||
|
||||
comp = (*entry)->comp;
|
||||
name = (*entry)->name;
|
||||
VA_ARGS_VGET(args, flags, depth, comp_name);
|
||||
|
||||
*flags = comp->get_evidence_flags(comp);
|
||||
*depth = comp->get_depth(comp);
|
||||
*comp_name = name;
|
||||
|
||||
return TRUE;
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*flags = entry->comp->get_evidence_flags(entry->comp);
|
||||
*depth = entry->comp->get_depth(entry->comp);
|
||||
*comp_name = entry->name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*,
|
||||
|
@ -443,7 +443,7 @@ METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*,
|
|||
{
|
||||
return enumerator_create_filter(
|
||||
this->components->create_enumerator(this->components),
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(imv_attestation_state_t, get_component, pts_component_t*,
|
||||
|
|
|
@ -94,22 +94,29 @@ METHOD(pts_file_meas_t, add, void,
|
|||
this->list->insert_last(this->list, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate file measurement entries
|
||||
*/
|
||||
static bool entry_filter(void *null, entry_t **entry, char **filename,
|
||||
void *i2, chunk_t *measurement)
|
||||
CALLBACK(entry_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*filename = (*entry)->filename;
|
||||
*measurement = (*entry)->measurement;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
chunk_t *measurement;
|
||||
char **filename;
|
||||
|
||||
VA_ARGS_VGET(args, filename, measurement);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*filename = entry->filename;
|
||||
*measurement = entry->measurement;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, create_enumerator, enumerator_t*,
|
||||
private_pts_file_meas_t *this)
|
||||
{
|
||||
return enumerator_create_filter(this->list->create_enumerator(this->list),
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, check, bool,
|
||||
|
|
|
@ -111,17 +111,12 @@ typedef struct {
|
|||
private_pts_pcr_t *pcrs;
|
||||
} pcr_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator.enumerate
|
||||
*/
|
||||
static bool pcr_enumerator_enumerate(pcr_enumerator_t *this, ...)
|
||||
METHOD(enumerator_t, pcr_enumerator_enumerate, bool,
|
||||
pcr_enumerator_t *this, va_list args)
|
||||
{
|
||||
uint32_t *pcr, i, f;
|
||||
va_list args;
|
||||
uint32_t i, f, *pcr;
|
||||
|
||||
va_start(args, this);
|
||||
pcr = va_arg(args, uint32_t*);
|
||||
va_end(args);
|
||||
VA_ARGS_VGET(args, pcr);
|
||||
|
||||
while (this->pcr <= this->pcrs->pcr_max)
|
||||
{
|
||||
|
@ -148,7 +143,8 @@ METHOD(pts_pcr_t, create_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)pcr_enumerator_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _pcr_enumerator_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.pcrs = this,
|
||||
|
|
|
@ -115,18 +115,24 @@ struct entry_t {
|
|||
pts_comp_func_name_t *name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumerate functional component entries
|
||||
*/
|
||||
static bool entry_filter(void *null, entry_t **entry, uint8_t *flags,
|
||||
void *i2, uint32_t *depth, void *i3,
|
||||
pts_comp_func_name_t **name)
|
||||
CALLBACK(entry_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*flags = (*entry)->flags;
|
||||
*depth = (*entry)->depth;
|
||||
*name = (*entry)->name;
|
||||
entry_t *entry;
|
||||
pts_comp_func_name_t **name;
|
||||
uint32_t *depth;
|
||||
uint8_t *flags;
|
||||
|
||||
return TRUE;
|
||||
VA_ARGS_VGET(args, flags, depth, name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*flags = entry->flags;
|
||||
*depth = entry->depth;
|
||||
*name = entry->name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,7 +324,7 @@ METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*,
|
|||
private_tcg_pts_attr_req_func_comp_evid_t *this)
|
||||
{
|
||||
return enumerator_create_filter(this->list->create_enumerator(this->list),
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -224,42 +224,60 @@ static void flush_entries(private_ipsec_sa_mgr_t *this)
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/*
|
||||
* Different match functions to find SAs in the linked list
|
||||
*/
|
||||
static bool match_entry_by_ptr(ipsec_sa_entry_t *item, ipsec_sa_entry_t *entry)
|
||||
CALLBACK(match_entry_by_sa_ptr, bool,
|
||||
ipsec_sa_entry_t *item, va_list args)
|
||||
{
|
||||
return item == entry;
|
||||
}
|
||||
ipsec_sa_t *sa;
|
||||
|
||||
static bool match_entry_by_sa_ptr(ipsec_sa_entry_t *item, ipsec_sa_t *sa)
|
||||
{
|
||||
VA_ARGS_VGET(args, sa);
|
||||
return item->sa == sa;
|
||||
}
|
||||
|
||||
static bool match_entry_by_spi_inbound(ipsec_sa_entry_t *item, uint32_t *spi,
|
||||
bool *inbound)
|
||||
CALLBACK(match_entry_by_spi_inbound, bool,
|
||||
ipsec_sa_entry_t *item, va_list args)
|
||||
{
|
||||
return item->sa->get_spi(item->sa) == *spi &&
|
||||
item->sa->is_inbound(item->sa) == *inbound;
|
||||
uint32_t spi;
|
||||
int inbound;
|
||||
|
||||
VA_ARGS_VGET(args, spi, inbound);
|
||||
return item->sa->get_spi(item->sa) == spi &&
|
||||
item->sa->is_inbound(item->sa) == inbound;
|
||||
}
|
||||
|
||||
static bool match_entry_by_spi_src_dst(ipsec_sa_entry_t *item, uint32_t *spi,
|
||||
static bool match_entry_by_spi_src_dst(ipsec_sa_entry_t *item, uint32_t spi,
|
||||
host_t *src, host_t *dst)
|
||||
{
|
||||
return item->sa->match_by_spi_src_dst(item->sa, *spi, src, dst);
|
||||
return item->sa->match_by_spi_src_dst(item->sa, spi, src, dst);
|
||||
}
|
||||
|
||||
static bool match_entry_by_reqid_inbound(ipsec_sa_entry_t *item,
|
||||
uint32_t *reqid, bool *inbound)
|
||||
CALLBACK(match_entry_by_spi_src_dst_cb, bool,
|
||||
ipsec_sa_entry_t *item, va_list args)
|
||||
{
|
||||
return item->sa->match_by_reqid(item->sa, *reqid, *inbound);
|
||||
host_t *src, *dst;
|
||||
uint32_t spi;
|
||||
|
||||
VA_ARGS_VGET(args, spi, src, dst);
|
||||
return match_entry_by_spi_src_dst(item, spi, src, dst);
|
||||
}
|
||||
|
||||
static bool match_entry_by_spi_dst(ipsec_sa_entry_t *item, uint32_t *spi,
|
||||
host_t *dst)
|
||||
CALLBACK(match_entry_by_reqid_inbound, bool,
|
||||
ipsec_sa_entry_t *item, va_list args)
|
||||
{
|
||||
return item->sa->match_by_spi_dst(item->sa, *spi, dst);
|
||||
uint32_t reqid;
|
||||
int inbound;
|
||||
|
||||
VA_ARGS_VGET(args, reqid, inbound);
|
||||
return item->sa->match_by_reqid(item->sa, reqid, inbound);
|
||||
}
|
||||
|
||||
CALLBACK(match_entry_by_spi_dst, bool,
|
||||
ipsec_sa_entry_t *item, va_list args)
|
||||
{
|
||||
host_t *dst;
|
||||
uint32_t spi;
|
||||
|
||||
VA_ARGS_VGET(args, spi, dst);
|
||||
return item->sa->match_by_spi_dst(item->sa, spi, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,8 +314,7 @@ static job_requeue_t sa_expired(ipsec_sa_expired_t *expired)
|
|||
private_ipsec_sa_mgr_t *this = expired->manager;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_ptr,
|
||||
NULL, expired->entry) == SUCCESS)
|
||||
if (this->sas->find_first(this->sas, NULL, (void**)&expired->entry))
|
||||
{
|
||||
uint32_t hard_offset;
|
||||
|
||||
|
@ -383,8 +400,8 @@ static bool allocate_spi(private_ipsec_sa_mgr_t *this, uint32_t spi)
|
|||
uint32_t *spi_alloc;
|
||||
|
||||
if (this->allocated_spis->get(this->allocated_spis, &spi) ||
|
||||
this->sas->find_first(this->sas, (void*)match_entry_by_spi_inbound,
|
||||
NULL, &spi, TRUE) == SUCCESS)
|
||||
this->sas->find_first(this->sas, match_entry_by_spi_inbound,
|
||||
NULL, spi, TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -484,8 +501,8 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
|
|||
free(spi_alloc);
|
||||
}
|
||||
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst,
|
||||
NULL, &spi, src, dst) == SUCCESS)
|
||||
if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, NULL,
|
||||
spi, src, dst))
|
||||
{
|
||||
this->mutex->unlock(this->mutex);
|
||||
DBG1(DBG_ESP, "failed to install SAD entry: already installed");
|
||||
|
@ -519,8 +536,8 @@ METHOD(ipsec_sa_mgr_t, update_sa, status_t,
|
|||
}
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst,
|
||||
(void**)&entry, &spi, src, dst) == SUCCESS &&
|
||||
if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb,
|
||||
(void**)&entry, spi, src, dst) &&
|
||||
wait_for_entry(this, entry))
|
||||
{
|
||||
entry->sa->set_source(entry->sa, new_src);
|
||||
|
@ -547,8 +564,8 @@ METHOD(ipsec_sa_mgr_t, query_sa, status_t,
|
|||
ipsec_sa_entry_t *entry = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst,
|
||||
(void**)&entry, &spi, src, dst) == SUCCESS &&
|
||||
if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb,
|
||||
(void**)&entry, spi, src, dst) &&
|
||||
wait_for_entry(this, entry))
|
||||
{
|
||||
entry->sa->get_usestats(entry->sa, bytes, packets, time);
|
||||
|
@ -572,7 +589,7 @@ METHOD(ipsec_sa_mgr_t, del_sa, status_t,
|
|||
enumerator = this->sas->create_enumerator(this->sas);
|
||||
while (enumerator->enumerate(enumerator, (void**)¤t))
|
||||
{
|
||||
if (match_entry_by_spi_src_dst(current, &spi, src, dst))
|
||||
if (match_entry_by_spi_src_dst(current, spi, src, dst))
|
||||
{
|
||||
if (wait_remove_entry(this, current))
|
||||
{
|
||||
|
@ -602,8 +619,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_reqid, ipsec_sa_t*,
|
|||
ipsec_sa_t *sa = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_reqid_inbound,
|
||||
(void**)&entry, &reqid, &inbound) == SUCCESS &&
|
||||
if (this->sas->find_first(this->sas, match_entry_by_reqid_inbound,
|
||||
(void**)&entry, reqid, inbound) &&
|
||||
wait_for_entry(this, entry))
|
||||
{
|
||||
sa = entry->sa;
|
||||
|
@ -619,8 +636,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_spi, ipsec_sa_t*,
|
|||
ipsec_sa_t *sa = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_dst,
|
||||
(void**)&entry, &spi, dst) == SUCCESS &&
|
||||
if (this->sas->find_first(this->sas, match_entry_by_spi_dst,
|
||||
(void**)&entry, spi, dst) &&
|
||||
wait_for_entry(this, entry))
|
||||
{
|
||||
sa = entry->sa;
|
||||
|
@ -635,8 +652,8 @@ METHOD(ipsec_sa_mgr_t, checkin, void,
|
|||
ipsec_sa_entry_t *entry;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_sa_ptr,
|
||||
(void**)&entry, sa) == SUCCESS)
|
||||
if (this->sas->find_first(this->sas, match_entry_by_sa_ptr,
|
||||
(void**)&entry, sa))
|
||||
{
|
||||
if (entry->locked)
|
||||
{
|
||||
|
|
|
@ -59,8 +59,11 @@ typedef struct {
|
|||
} mech_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, mech_enumerate, bool,
|
||||
mech_enumerator_t *this, char **name)
|
||||
mech_enumerator_t *this, va_list args)
|
||||
{
|
||||
char **name;
|
||||
|
||||
VA_ARGS_VGET(args, name);
|
||||
while (this->i < countof(mechs))
|
||||
{
|
||||
if (mechs[this->i].server == this->server)
|
||||
|
@ -83,7 +86,8 @@ enumerator_t* sasl_mechanism_create_enumerator(bool server)
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_mech_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _mech_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.server = server,
|
||||
|
|
|
@ -244,8 +244,12 @@ typedef struct {
|
|||
} attribute_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, attribute_enumerate, bool,
|
||||
attribute_enumerator_t *this, int *type, chunk_t *data)
|
||||
attribute_enumerator_t *this, va_list args)
|
||||
{
|
||||
chunk_t *data;
|
||||
int *type;
|
||||
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
if (this->left == 0)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -275,7 +279,8 @@ METHOD(radius_message_t, create_enumerator, enumerator_t*,
|
|||
}
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_attribute_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _attribute_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.next = (rattr_t*)this->msg->attributes,
|
||||
|
@ -299,12 +304,14 @@ typedef struct {
|
|||
} vendor_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, vendor_enumerate, bool,
|
||||
vendor_enumerator_t *this, int *vendor, int *type, chunk_t *data)
|
||||
vendor_enumerator_t *this, va_list args)
|
||||
{
|
||||
chunk_t inner_data;
|
||||
int inner_type;
|
||||
chunk_t inner_data, *data;
|
||||
int inner_type, *vendor, *type;
|
||||
uint8_t type8, len;
|
||||
|
||||
VA_ARGS_VGET(args, vendor, type, data);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (this->reader)
|
||||
|
@ -354,7 +361,8 @@ METHOD(radius_message_t, create_vendor_enumerator, enumerator_t*,
|
|||
|
||||
INIT(e,
|
||||
.public = {
|
||||
.enumerate = (void*)_vendor_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _vendor_enumerate,
|
||||
.destroy = _vendor_destroy,
|
||||
},
|
||||
.inner = create_enumerator(this),
|
||||
|
|
|
@ -222,17 +222,22 @@ METHOD(simaka_message_t, get_type, eap_type_t,
|
|||
return this->hdr->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert attr_t to type and data enumeration
|
||||
*/
|
||||
static bool attr_enum_filter(void *null, attr_t **in, simaka_attribute_t *type,
|
||||
void *dummy, chunk_t *data)
|
||||
CALLBACK(attr_enum_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
attr_t *attr = *in;
|
||||
attr_t *attr;
|
||||
simaka_attribute_t *type;
|
||||
chunk_t *data;
|
||||
|
||||
*type = attr->type;
|
||||
*data = chunk_create(attr->data, attr->len);
|
||||
return TRUE;
|
||||
VA_ARGS_VGET(args, type, data);
|
||||
|
||||
if (orig->enumerate(orig, &attr))
|
||||
{
|
||||
*type = attr->type;
|
||||
*data = chunk_create(attr->data, attr->len);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*,
|
||||
|
@ -240,7 +245,7 @@ METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*,
|
|||
{
|
||||
return enumerator_create_filter(
|
||||
this->attributes->create_enumerator(this->attributes),
|
||||
(void*)attr_enum_filter, NULL, NULL);
|
||||
attr_enum_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(simaka_message_t, add_attribute, void,
|
||||
|
|
|
@ -214,9 +214,11 @@ typedef struct {
|
|||
} array_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, enumerate, bool,
|
||||
array_enumerator_t *this, void **out)
|
||||
array_enumerator_t *this, va_list args)
|
||||
{
|
||||
void *pos;
|
||||
void *pos, **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (this->idx >= this->array->count)
|
||||
{
|
||||
|
@ -250,7 +252,8 @@ enumerator_t* array_create_enumerator(array_t *array)
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.array = array,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2013 Tobias Brunner
|
||||
* Copyright (C) 2008-2017 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -31,22 +31,43 @@
|
|||
|
||||
#include <utils/debug.h>
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_empty().enumerate
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
static bool enumerate_empty(enumerator_t *enumerator, ...)
|
||||
bool enumerator_enumerate_default(enumerator_t *enumerator, ...)
|
||||
{
|
||||
va_list args;
|
||||
bool result;
|
||||
|
||||
if (!enumerator->venumerate)
|
||||
{
|
||||
DBG1(DBG_LIB, "!!! ENUMERATE DEFAULT: venumerate() missing !!!");
|
||||
return FALSE;
|
||||
}
|
||||
va_start(args, enumerator);
|
||||
result = enumerator->venumerate(enumerator, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_empty, bool,
|
||||
enumerator_t *enumerator, va_list args)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t* enumerator_create_empty()
|
||||
{
|
||||
enumerator_t *this = malloc_thing(enumerator_t);
|
||||
this->enumerate = enumerate_empty;
|
||||
this->destroy = (void*)free;
|
||||
enumerator_t *this;
|
||||
|
||||
INIT(this,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_empty,
|
||||
.destroy = (void*)free,
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -64,32 +85,31 @@ typedef struct {
|
|||
char *full_end;
|
||||
} dir_enum_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_directory().destroy
|
||||
*/
|
||||
static void destroy_dir_enum(dir_enum_t *this)
|
||||
METHOD(enumerator_t, destroy_dir_enum, void,
|
||||
dir_enum_t *this)
|
||||
{
|
||||
closedir(this->dir);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_directory().enumerate
|
||||
*/
|
||||
static bool enumerate_dir_enum(dir_enum_t *this, char **relative,
|
||||
char **absolute, struct stat *st)
|
||||
METHOD(enumerator_t, enumerate_dir_enum, bool,
|
||||
dir_enum_t *this, va_list args)
|
||||
{
|
||||
struct dirent *entry = readdir(this->dir);
|
||||
struct stat *st;
|
||||
size_t remaining;
|
||||
char **relative, **absolute;
|
||||
int len;
|
||||
|
||||
VA_ARGS_VGET(args, relative, absolute, st);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (streq(entry->d_name, ".") || streq(entry->d_name, ".."))
|
||||
{
|
||||
return enumerate_dir_enum(this, relative, absolute, st);
|
||||
return this->public.enumerate(&this->public, relative, absolute, st);
|
||||
}
|
||||
if (relative)
|
||||
{
|
||||
|
@ -122,15 +142,21 @@ static bool enumerate_dir_enum(dir_enum_t *this, char **relative,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t* enumerator_create_directory(const char *path)
|
||||
{
|
||||
dir_enum_t *this;
|
||||
int len;
|
||||
dir_enum_t *this = malloc_thing(dir_enum_t);
|
||||
this->public.enumerate = (void*)enumerate_dir_enum;
|
||||
this->public.destroy = (void*)destroy_dir_enum;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_dir_enum,
|
||||
.destroy = _destroy_dir_enum,
|
||||
},
|
||||
);
|
||||
|
||||
if (*path == '\0')
|
||||
{
|
||||
|
@ -152,9 +178,10 @@ enumerator_t* enumerator_create_directory(const char *path)
|
|||
this->full_end = &this->full[len];
|
||||
|
||||
this->dir = opendir(path);
|
||||
if (this->dir == NULL)
|
||||
if (!this->dir)
|
||||
{
|
||||
DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, strerror(errno));
|
||||
DBG1(DBG_LIB, "opening directory '%s' failed: %s", path,
|
||||
strerror(errno));
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -177,21 +204,21 @@ typedef struct {
|
|||
char full[PATH_MAX];
|
||||
} glob_enum_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_glob().destroy
|
||||
*/
|
||||
static void destroy_glob_enum(glob_enum_t *this)
|
||||
METHOD(enumerator_t, destroy_glob_enum, void,
|
||||
glob_enum_t *this)
|
||||
{
|
||||
globfree(&this->glob);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_glob().enumerate
|
||||
*/
|
||||
static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st)
|
||||
METHOD(enumerator_t, enumerate_glob_enum, bool,
|
||||
glob_enum_t *this, va_list args)
|
||||
{
|
||||
struct stat *st;
|
||||
char *match;
|
||||
char **file;
|
||||
|
||||
VA_ARGS_VGET(args, file, st);
|
||||
|
||||
if (this->pos >= this->glob.gl_pathc)
|
||||
{
|
||||
|
@ -202,20 +229,17 @@ static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st)
|
|||
{
|
||||
*file = match;
|
||||
}
|
||||
if (st)
|
||||
if (st && stat(match, st))
|
||||
{
|
||||
if (stat(match, st))
|
||||
{
|
||||
DBG1(DBG_LIB, "stat() on '%s' failed: %s", match,
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_LIB, "stat() on '%s' failed: %s", match,
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t* enumerator_create_glob(const char *pattern)
|
||||
{
|
||||
|
@ -229,8 +253,9 @@ enumerator_t* enumerator_create_glob(const char *pattern)
|
|||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = (void*)enumerate_glob_enum,
|
||||
.destroy = (void*)destroy_glob_enum,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_glob_enum,
|
||||
.destroy = _destroy_glob_enum,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -272,24 +297,22 @@ typedef struct {
|
|||
const char *trim;
|
||||
} token_enum_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_token().destroy
|
||||
*/
|
||||
static void destroy_token_enum(token_enum_t *this)
|
||||
METHOD(enumerator_t, destroy_token_enum, void,
|
||||
token_enum_t *this)
|
||||
{
|
||||
free(this->string);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_token().enumerate
|
||||
*/
|
||||
static bool enumerate_token_enum(token_enum_t *this, char **token)
|
||||
METHOD(enumerator_t, enumerate_token_enum, bool,
|
||||
token_enum_t *this, va_list args)
|
||||
{
|
||||
const char *sep, *trim;
|
||||
char *pos = NULL, *tmp;
|
||||
char *pos = NULL, *tmp, **token;
|
||||
bool last = FALSE;
|
||||
|
||||
VA_ARGS_VGET(args, token);
|
||||
|
||||
/* trim leading characters/separators */
|
||||
while (*this->pos)
|
||||
{
|
||||
|
@ -390,52 +413,48 @@ static bool enumerate_token_enum(token_enum_t *this, char **token)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t* enumerator_create_token(const char *string, const char *sep,
|
||||
const char *trim)
|
||||
{
|
||||
token_enum_t *enumerator = malloc_thing(token_enum_t);
|
||||
token_enum_t *this;
|
||||
|
||||
enumerator->public.enumerate = (void*)enumerate_token_enum;
|
||||
enumerator->public.destroy = (void*)destroy_token_enum;
|
||||
enumerator->string = strdup(string);
|
||||
enumerator->pos = enumerator->string;
|
||||
enumerator->sep = sep;
|
||||
enumerator->trim = trim;
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_token_enum,
|
||||
.destroy = _destroy_token_enum,
|
||||
},
|
||||
.string = strdup(string),
|
||||
.sep = sep,
|
||||
.trim = trim,
|
||||
);
|
||||
this->pos = this->string;
|
||||
|
||||
return &enumerator->public;
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator for nested enumerations
|
||||
* Enumerator for nested enumerations
|
||||
*/
|
||||
typedef struct {
|
||||
/* implements enumerator_t */
|
||||
enumerator_t public;
|
||||
/* outer enumerator */
|
||||
enumerator_t *outer;
|
||||
/* inner enumerator */
|
||||
enumerator_t *inner;
|
||||
/* constructor for inner enumerator */
|
||||
enumerator_t *(*create_inner)(void *outer, void *data);
|
||||
/* data to pass to constructor above */
|
||||
void *data;
|
||||
/* destructor for data */
|
||||
void (*destroy_data)(void *data);
|
||||
void (*destructor)(void *data);
|
||||
} nested_enumerator_t;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_nested().enumerate()
|
||||
*/
|
||||
static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2,
|
||||
void *v3, void *v4, void *v5)
|
||||
METHOD(enumerator_t, enumerate_nested, bool,
|
||||
nested_enumerator_t *this, va_list args)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
while (this->inner == NULL)
|
||||
while (!this->inner)
|
||||
{
|
||||
void *outer;
|
||||
|
||||
|
@ -444,8 +463,13 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2,
|
|||
return FALSE;
|
||||
}
|
||||
this->inner = this->create_inner(outer, this->data);
|
||||
if (this->inner && !this->inner->venumerate)
|
||||
{
|
||||
DBG1(DBG_LIB, "!!! ENUMERATE NESTED: venumerate() missing !!!");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5))
|
||||
if (this->inner->venumerate(this->inner, args))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -454,103 +478,100 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_nested().destroy()
|
||||
**/
|
||||
static void destroy_nested(nested_enumerator_t *this)
|
||||
METHOD(enumerator_t, destroy_nested, void,
|
||||
nested_enumerator_t *this)
|
||||
{
|
||||
if (this->destroy_data)
|
||||
if (this->destructor)
|
||||
{
|
||||
this->destroy_data(this->data);
|
||||
this->destructor(this->data);
|
||||
}
|
||||
DESTROY_IF(this->inner);
|
||||
this->outer->destroy(this->outer);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t *enumerator_create_nested(enumerator_t *outer,
|
||||
enumerator_t *(inner_constructor)(void *outer, void *data),
|
||||
void *data, void (*destroy_data)(void *data))
|
||||
void *data, void (*destructor)(void *data))
|
||||
{
|
||||
nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t);
|
||||
nested_enumerator_t *this;
|
||||
|
||||
enumerator->public.enumerate = (void*)enumerate_nested;
|
||||
enumerator->public.destroy = (void*)destroy_nested;
|
||||
enumerator->outer = outer;
|
||||
enumerator->inner = NULL;
|
||||
enumerator->create_inner = (void*)inner_constructor;
|
||||
enumerator->data = data;
|
||||
enumerator->destroy_data = destroy_data;
|
||||
|
||||
return &enumerator->public;
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_nested,
|
||||
.destroy = _destroy_nested,
|
||||
},
|
||||
.outer = outer,
|
||||
.create_inner = inner_constructor,
|
||||
.data = data,
|
||||
.destructor = destructor,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator for filtered enumerator
|
||||
* Enumerator for filtered enumerator
|
||||
*/
|
||||
typedef struct {
|
||||
enumerator_t public;
|
||||
enumerator_t *unfiltered;
|
||||
enumerator_t *orig;
|
||||
void *data;
|
||||
bool (*filter)(void *data, ...);
|
||||
bool (*filter)(void*,enumerator_t*,va_list);
|
||||
void (*destructor)(void *data);
|
||||
} filter_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_filter().destroy
|
||||
*/
|
||||
static void destroy_filter(filter_enumerator_t *this)
|
||||
METHOD(enumerator_t, destroy_filter, void,
|
||||
filter_enumerator_t *this)
|
||||
{
|
||||
if (this->destructor)
|
||||
{
|
||||
this->destructor(this->data);
|
||||
}
|
||||
this->unfiltered->destroy(this->unfiltered);
|
||||
this->orig->destroy(this->orig);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_filter().enumerate
|
||||
*/
|
||||
static bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2,
|
||||
void *o3, void *o4, void *o5)
|
||||
METHOD(enumerator_t, enumerate_filter, bool,
|
||||
filter_enumerator_t *this, va_list args)
|
||||
{
|
||||
void *i1, *i2, *i3, *i4, *i5;
|
||||
bool result = FALSE;
|
||||
|
||||
while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5))
|
||||
if (this->filter(this->data, this->orig, args))
|
||||
{
|
||||
if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
result = TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* see header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
|
||||
bool (*filter)(void *data, ...),
|
||||
void *data, void (*destructor)(void *data))
|
||||
enumerator_t *enumerator_create_filter(enumerator_t *orig,
|
||||
bool (*filter)(void *data, enumerator_t *orig, va_list args),
|
||||
void *data, void (*destructor)(void *data))
|
||||
{
|
||||
filter_enumerator_t *this = malloc_thing(filter_enumerator_t);
|
||||
|
||||
this->public.enumerate = (void*)enumerate_filter;
|
||||
this->public.destroy = (void*)destroy_filter;
|
||||
this->unfiltered = unfiltered;
|
||||
this->filter = filter;
|
||||
this->data = data;
|
||||
this->destructor = destructor;
|
||||
filter_enumerator_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_filter,
|
||||
.destroy = _destroy_filter,
|
||||
},
|
||||
.orig = orig,
|
||||
.filter = filter,
|
||||
.data = data,
|
||||
.destructor = destructor,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator for cleaner enumerator
|
||||
* Enumerator for cleaner enumerator
|
||||
*/
|
||||
typedef struct {
|
||||
enumerator_t public;
|
||||
|
@ -559,44 +580,48 @@ typedef struct {
|
|||
void *data;
|
||||
} cleaner_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_cleanup().destroy
|
||||
*/
|
||||
static void destroy_cleaner(cleaner_enumerator_t *this)
|
||||
METHOD(enumerator_t, destroy_cleaner, void,
|
||||
cleaner_enumerator_t *this)
|
||||
{
|
||||
this->cleanup(this->data);
|
||||
this->wrapped->destroy(this->wrapped);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_cleaner().enumerate
|
||||
*/
|
||||
static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2,
|
||||
void *v3, void *v4, void *v5)
|
||||
METHOD(enumerator_t, enumerate_cleaner, bool,
|
||||
cleaner_enumerator_t *this, va_list args)
|
||||
{
|
||||
return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5);
|
||||
if (!this->wrapped->venumerate)
|
||||
{
|
||||
DBG1(DBG_LIB, "!!! CLEANER ENUMERATOR: venumerate() missing !!!");
|
||||
return FALSE;
|
||||
}
|
||||
return this->wrapped->venumerate(this->wrapped, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* see header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
|
||||
void (*cleanup)(void *data), void *data)
|
||||
{
|
||||
cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t);
|
||||
|
||||
this->public.enumerate = (void*)enumerate_cleaner;
|
||||
this->public.destroy = (void*)destroy_cleaner;
|
||||
this->wrapped = wrapped;
|
||||
this->cleanup = cleanup;
|
||||
this->data = data;
|
||||
cleaner_enumerator_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_cleaner,
|
||||
.destroy = _destroy_cleaner,
|
||||
},
|
||||
.wrapped = wrapped,
|
||||
.cleanup = cleanup,
|
||||
.data = data,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator for single enumerator
|
||||
* Enumerator for single enumerator
|
||||
*/
|
||||
typedef struct {
|
||||
enumerator_t public;
|
||||
|
@ -605,10 +630,8 @@ typedef struct {
|
|||
bool done;
|
||||
} single_enumerator_t;
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_single().destroy
|
||||
*/
|
||||
static void destroy_single(single_enumerator_t *this)
|
||||
METHOD(enumerator_t, destroy_single, void,
|
||||
single_enumerator_t *this)
|
||||
{
|
||||
if (this->cleanup)
|
||||
{
|
||||
|
@ -617,11 +640,12 @@ static void destroy_single(single_enumerator_t *this)
|
|||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of enumerator_create_single().enumerate
|
||||
*/
|
||||
static bool enumerate_single(single_enumerator_t *this, void **item)
|
||||
METHOD(enumerator_t, enumerate_single, bool,
|
||||
single_enumerator_t *this, va_list args)
|
||||
{
|
||||
void **item;
|
||||
|
||||
VA_ARGS_VGET(args, item);
|
||||
if (this->done)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -631,19 +655,21 @@ static bool enumerate_single(single_enumerator_t *this, void **item)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* see header
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item))
|
||||
{
|
||||
single_enumerator_t *this = malloc_thing(single_enumerator_t);
|
||||
|
||||
this->public.enumerate = (void*)enumerate_single;
|
||||
this->public.destroy = (void*)destroy_single;
|
||||
this->item = item;
|
||||
this->cleanup = cleanup;
|
||||
this->done = FALSE;
|
||||
single_enumerator_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate_single,
|
||||
.destroy = _destroy_single,
|
||||
},
|
||||
.item = item,
|
||||
.cleanup = cleanup,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2013-2017 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -34,8 +34,11 @@ struct enumerator_t {
|
|||
/**
|
||||
* Enumerate collection.
|
||||
*
|
||||
* The enumerate function takes a variable argument list containing
|
||||
* pointers where the enumerated values get written.
|
||||
* The enumerate() method takes a variable number of pointer arguments
|
||||
* where the enumerated values get written to.
|
||||
*
|
||||
* @note Just assigning the generic enumerator_enumerate_default() function
|
||||
* that calls the enumerator's venumerate() method is usually enough.
|
||||
*
|
||||
* @param ... variable list of enumerated items, implementation dependent
|
||||
* @return TRUE if pointers returned
|
||||
|
@ -43,11 +46,33 @@ struct enumerator_t {
|
|||
bool (*enumerate)(enumerator_t *this, ...);
|
||||
|
||||
/**
|
||||
* Destroy a enumerator instance.
|
||||
* Enumerate collection.
|
||||
*
|
||||
* The venumerate() method takes a variable argument list containing
|
||||
* pointers where the enumerated values get written to.
|
||||
*
|
||||
* To simplify the implementation the VA_ARGS_VGET() macro may be used.
|
||||
*
|
||||
* @param args variable list of enumerated items, implementation dependent
|
||||
* @return TRUE if pointers returned
|
||||
*/
|
||||
bool (*venumerate)(enumerator_t *this, va_list args);
|
||||
|
||||
/**
|
||||
* Destroy an enumerator_t instance.
|
||||
*/
|
||||
void (*destroy)(enumerator_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic implementation of enumerator_t::enumerate() that simply calls
|
||||
* the enumerator's venumerate() method.
|
||||
*
|
||||
* @param enumerator the enumerator
|
||||
* @param ... arguments passed to enumerate()
|
||||
*/
|
||||
bool enumerator_enumerate_default(enumerator_t *enumerator, ...);
|
||||
|
||||
/**
|
||||
* Create an enumerator which enumerates over nothing
|
||||
*
|
||||
|
@ -147,38 +172,41 @@ enumerator_t* enumerator_create_token(const char *string, const char *sep,
|
|||
/**
|
||||
* Creates an enumerator which enumerates over enumerated enumerators :-).
|
||||
*
|
||||
* The variable argument list of enumeration values is limit to 5.
|
||||
* The outer enumerator is expected to return objects that, when passed to
|
||||
* inner_contructor, will create a new enumerator that will be enumerated until
|
||||
* completion (to this enumerator will the pointer arguments that are passed to
|
||||
* this enumerator be forwarded) at which point a new element from the outer
|
||||
* enumerator is requested to create a new inner enumerator.
|
||||
*
|
||||
* @param outer outer enumerator
|
||||
* @param inner_constructor constructor to inner enumerator
|
||||
* @param inner_constructor constructor to create inner enumerator
|
||||
* @param data data to pass to each inner_constructor call
|
||||
* @param destroy_data destructor to pass to data
|
||||
* @param destructor destructor function to clean up data after use
|
||||
* @return the nested enumerator
|
||||
*/
|
||||
enumerator_t *enumerator_create_nested(enumerator_t *outer,
|
||||
enumerator_t *(*inner_constructor)(void *outer, void *data),
|
||||
void *data, void (*destroy_data)(void *data));
|
||||
void *data, void (*destructor)(void *data));
|
||||
|
||||
/**
|
||||
* Creates an enumerator which filters output of another enumerator.
|
||||
* Creates an enumerator which filters/maps output of another enumerator.
|
||||
*
|
||||
* The filter function receives the user supplied "data" followed by a
|
||||
* unfiltered enumeration item, followed by an output pointer where to write
|
||||
* the filtered data. Then the next input/output pair follows.
|
||||
* It returns TRUE to deliver the
|
||||
* values to the caller of enumerate(), FALSE to filter this enumeration.
|
||||
* The filter function receives the user supplied "data" followed by the
|
||||
* original enumerator, followed by the arguments passed to the outer
|
||||
* enumerator. It returns TRUE to deliver the values assigned to these
|
||||
* arguments to the caller of enumerate() and FALSE to end the enumeration.
|
||||
* Filtering items is simple as the filter function may just skip enumerated
|
||||
* items from the original enumerator.
|
||||
*
|
||||
* The variable argument list of enumeration values is limit to 5.
|
||||
*
|
||||
* @param unfiltered unfiltered enumerator to wrap, gets destroyed
|
||||
* @param orig original enumerator to wrap, gets destroyed
|
||||
* @param filter filter function
|
||||
* @param data user data to supply to filter
|
||||
* @param destructor destructor function to clean up data after use
|
||||
* @return the filtered enumerator
|
||||
*/
|
||||
enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
|
||||
bool (*filter)(void *data, ...),
|
||||
void *data, void (*destructor)(void *data));
|
||||
enumerator_t *enumerator_create_filter(enumerator_t *orig,
|
||||
bool (*filter)(void *data, enumerator_t *orig, va_list args),
|
||||
void *data, void (*destructor)(void *data));
|
||||
|
||||
/**
|
||||
* Create an enumerator wrapper which does a cleanup on destroy.
|
||||
|
|
|
@ -379,8 +379,13 @@ METHOD(hashtable_t, get_count, u_int,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate, bool,
|
||||
private_enumerator_t *this, const void **key, void **value)
|
||||
private_enumerator_t *this, va_list args)
|
||||
{
|
||||
const void **key;
|
||||
void **value;
|
||||
|
||||
VA_ARGS_VGET(args, key, value);
|
||||
|
||||
while (this->count && this->row < this->table->capacity)
|
||||
{
|
||||
this->prev = this->current;
|
||||
|
@ -417,7 +422,8 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.enumerator = {
|
||||
.enumerate = (void*)_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.table = this,
|
||||
|
|
|
@ -47,6 +47,17 @@ struct element_t {
|
|||
element_t *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool linked_list_match_str(void *item, va_list args)
|
||||
{
|
||||
char *a = item, *b;
|
||||
|
||||
VA_ARGS_VGET(args, b);
|
||||
return streq(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty linked list object.
|
||||
*/
|
||||
|
@ -119,8 +130,12 @@ struct private_enumerator_t {
|
|||
};
|
||||
|
||||
METHOD(enumerator_t, enumerate, bool,
|
||||
private_enumerator_t *this, void **item)
|
||||
private_enumerator_t *this, va_list args)
|
||||
{
|
||||
void **item;
|
||||
|
||||
VA_ARGS_VGET(args, item);
|
||||
|
||||
if (this->finished)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -152,7 +167,8 @@ METHOD(linked_list_t, create_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.enumerator = {
|
||||
.enumerate = (void*)_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.list = this,
|
||||
|
@ -366,52 +382,68 @@ METHOD(linked_list_t, remove_at, void,
|
|||
}
|
||||
}
|
||||
|
||||
METHOD(linked_list_t, find_first, status_t,
|
||||
private_linked_list_t *this, linked_list_match_t match,
|
||||
void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
|
||||
METHOD(linked_list_t, find_first, bool,
|
||||
private_linked_list_t *this, linked_list_match_t match, void **item, ...)
|
||||
{
|
||||
element_t *current = this->first;
|
||||
va_list args;
|
||||
bool matched = FALSE;
|
||||
|
||||
if (!match && !item)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (current)
|
||||
{
|
||||
if ((match && match(current->value, d1, d2, d3, d4, d5)) ||
|
||||
(!match && item && current->value == *item))
|
||||
if (match)
|
||||
{
|
||||
va_start(args, item);
|
||||
matched = match(current->value, args);
|
||||
va_end(args);
|
||||
}
|
||||
else
|
||||
{
|
||||
matched = current->value == *item;
|
||||
}
|
||||
if (matched)
|
||||
{
|
||||
if (item != NULL)
|
||||
{
|
||||
*item = current->value;
|
||||
}
|
||||
return SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return NOT_FOUND;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(linked_list_t, invoke_offset, void,
|
||||
private_linked_list_t *this, size_t offset,
|
||||
void *d1, void *d2, void *d3, void *d4, void *d5)
|
||||
private_linked_list_t *this, size_t offset)
|
||||
{
|
||||
element_t *current = this->first;
|
||||
linked_list_invoke_t *method;
|
||||
void (**method)(void*);
|
||||
|
||||
while (current)
|
||||
{
|
||||
method = current->value + offset;
|
||||
(*method)(current->value, d1, d2, d3, d4, d5);
|
||||
(*method)(current->value);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(linked_list_t, invoke_function, void,
|
||||
private_linked_list_t *this, linked_list_invoke_t fn,
|
||||
void *d1, void *d2, void *d3, void *d4, void *d5)
|
||||
private_linked_list_t *this, linked_list_invoke_t fn, ...)
|
||||
{
|
||||
element_t *current = this->first;
|
||||
va_list args;
|
||||
|
||||
while (current)
|
||||
{
|
||||
fn(current->value, d1, d2, d3, d4, d5);
|
||||
va_start(args, fn);
|
||||
fn(current->value, args);
|
||||
va_end(args);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
@ -542,7 +574,7 @@ linked_list_t *linked_list_create()
|
|||
.reset_enumerator = (void*)_reset_enumerator,
|
||||
.get_first = _get_first,
|
||||
.get_last = _get_last,
|
||||
.find_first = (void*)_find_first,
|
||||
.find_first = _find_first,
|
||||
.insert_first = _insert_first,
|
||||
.insert_last = _insert_last,
|
||||
.insert_before = (void*)_insert_before,
|
||||
|
@ -550,8 +582,8 @@ linked_list_t *linked_list_create()
|
|||
.remove_last = _remove_last,
|
||||
.remove = _remove_,
|
||||
.remove_at = (void*)_remove_at,
|
||||
.invoke_offset = (void*)_invoke_offset,
|
||||
.invoke_function = (void*)_invoke_function,
|
||||
.invoke_offset = _invoke_offset,
|
||||
.invoke_function = _invoke_function,
|
||||
.clone_offset = _clone_offset,
|
||||
.equals_offset = _equals_offset,
|
||||
.equals_function = _equals_function,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2015 Tobias Brunner
|
||||
* Copyright (C) 2007-2017 Tobias Brunner
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
|
@ -28,23 +28,30 @@ typedef struct linked_list_t linked_list_t;
|
|||
#include <collections/enumerator.h>
|
||||
|
||||
/**
|
||||
* Method to match elements in a linked list (used in find_* functions)
|
||||
* Function to match elements in a linked list
|
||||
*
|
||||
* @param item current list item
|
||||
* @param ... user supplied data (only pointers, at most 5)
|
||||
* @return
|
||||
* - TRUE, if the item matched
|
||||
* - FALSE, otherwise
|
||||
* @param args user supplied data
|
||||
* @return TRUE, if the item matched, FALSE otherwise
|
||||
*/
|
||||
typedef bool (*linked_list_match_t)(void *item, ...);
|
||||
typedef bool (*linked_list_match_t)(void *item, va_list args);
|
||||
|
||||
/**
|
||||
* Method to be invoked on elements in a linked list (used in invoke_* functions)
|
||||
* Helper function to match a string in a linked list of strings
|
||||
*
|
||||
* @param item list item (char*)
|
||||
* @param args user supplied data (char*)
|
||||
* @return
|
||||
*/
|
||||
bool linked_list_match_str(void *item, va_list args);
|
||||
|
||||
/**
|
||||
* Function to be invoked on elements in a linked list
|
||||
*
|
||||
* @param item current list item
|
||||
* @param ... user supplied data (only pointers, at most 5)
|
||||
* @param args user supplied data
|
||||
*/
|
||||
typedef void (*linked_list_invoke_t)(void *item, ...);
|
||||
typedef void (*linked_list_invoke_t)(void *item, va_list args);
|
||||
|
||||
/**
|
||||
* Class implementing a double linked list.
|
||||
|
@ -167,21 +174,20 @@ struct linked_list_t {
|
|||
*
|
||||
* The first object passed to the match function is the current list item,
|
||||
* followed by the user supplied data.
|
||||
* If the supplied function returns TRUE this function returns SUCCESS, and
|
||||
* the current object is returned in the third parameter, otherwise,
|
||||
* If the supplied function returns TRUE so does this function, and the
|
||||
* current object is returned in the third parameter (if given), otherwise,
|
||||
* the next item is checked.
|
||||
*
|
||||
* If match is NULL, *item and the current object are compared.
|
||||
*
|
||||
* @warning Only use pointers as user supplied data.
|
||||
*
|
||||
* @param match comparison function to call on each object, or NULL
|
||||
* @param item the list item, if found
|
||||
* @param ... user data to supply to match function (limited to 5 arguments)
|
||||
* @return SUCCESS if found, NOT_FOUND otherwise
|
||||
* @param item the list item, if found, or NULL
|
||||
* @param ... user data to supply to match function
|
||||
* @return TRUE if found, FALSE otherwise (or if neither match,
|
||||
* nor item is supplied)
|
||||
*/
|
||||
status_t (*find_first) (linked_list_t *this, linked_list_match_t match,
|
||||
void **item, ...);
|
||||
bool (*find_first)(linked_list_t *this, linked_list_match_t match,
|
||||
void **item, ...);
|
||||
|
||||
/**
|
||||
* Invoke a method on all of the contained objects.
|
||||
|
@ -192,22 +198,18 @@ struct linked_list_t {
|
|||
* which can be evalutated at compile time using the offsetof
|
||||
* macro, e.g.: list->invoke(list, offsetof(object_t, method));
|
||||
*
|
||||
* @warning Only use pointers as user supplied data.
|
||||
*
|
||||
* @param offset offset of the method to invoke on objects
|
||||
* @param ... user data to supply to called function (limited to 5 arguments)
|
||||
*/
|
||||
void (*invoke_offset) (linked_list_t *this, size_t offset, ...);
|
||||
void (*invoke_offset)(linked_list_t *this, size_t offset);
|
||||
|
||||
/**
|
||||
* Invoke a function on all of the contained objects.
|
||||
*
|
||||
* @warning Only use pointers as user supplied data.
|
||||
*
|
||||
* @param function offset of the method to invoke on objects
|
||||
* @param ... user data to supply to called function (limited to 5 arguments)
|
||||
* @param function function to call for each object
|
||||
* @param ... user data to supply to called function
|
||||
*/
|
||||
void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...);
|
||||
void (*invoke_function)(linked_list_t *this, linked_list_invoke_t function,
|
||||
...);
|
||||
|
||||
/**
|
||||
* Clones a list and its objects using the objects' clone method.
|
||||
|
|
|
@ -146,12 +146,14 @@ typedef struct {
|
|||
bool enumerated[AUTH_RULE_MAX];
|
||||
} entry_enumerator_t;
|
||||
|
||||
/**
|
||||
* enumerate function for item_enumerator_t
|
||||
*/
|
||||
static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
|
||||
METHOD(enumerator_t, enumerate, bool,
|
||||
entry_enumerator_t *this, va_list args)
|
||||
{
|
||||
auth_rule_t *type;
|
||||
entry_t *entry;
|
||||
void **value;
|
||||
|
||||
VA_ARGS_VGET(args, type, value);
|
||||
|
||||
while (this->inner->enumerate(this->inner, &entry))
|
||||
{
|
||||
|
@ -174,10 +176,8 @@ static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy function for item_enumerator_t
|
||||
*/
|
||||
static void entry_enumerator_destroy(entry_enumerator_t *this)
|
||||
METHOD(enumerator_t, entry_enumerator_destroy, void,
|
||||
entry_enumerator_t *this)
|
||||
{
|
||||
this->inner->destroy(this->inner);
|
||||
free(this);
|
||||
|
@ -190,8 +190,9 @@ METHOD(auth_cfg_t, create_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)enumerate,
|
||||
.destroy = (void*)entry_enumerator_destroy,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate,
|
||||
.destroy = _entry_enumerator_destroy,
|
||||
},
|
||||
.inner = array_create_enumerator(this->entries),
|
||||
);
|
||||
|
|
|
@ -163,17 +163,23 @@ METHOD(credential_factory_t, create, void*,
|
|||
return construct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function for builder enumerator
|
||||
*/
|
||||
static bool builder_filter(void *null, entry_t **entry, credential_type_t *type,
|
||||
void *dummy1, int *subtype)
|
||||
CALLBACK(builder_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if ((*entry)->final)
|
||||
entry_t *entry;
|
||||
credential_type_t *type;
|
||||
int *subtype;
|
||||
|
||||
VA_ARGS_VGET(args, type, subtype);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*type = (*entry)->type;
|
||||
*subtype = (*entry)->subtype;
|
||||
return TRUE;
|
||||
if (entry->final)
|
||||
{
|
||||
*type = entry->type;
|
||||
*subtype = entry->subtype;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -184,7 +190,7 @@ METHOD(credential_factory_t, create_builder_enumerator, enumerator_t*,
|
|||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->constructors->create_enumerator(this->constructors),
|
||||
(void*)builder_filter, this->lock, (void*)this->lock->unlock);
|
||||
builder_filter, this->lock, (void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
METHOD(credential_factory_t, destroy, void,
|
||||
|
|
|
@ -155,8 +155,12 @@ METHOD(credential_manager_t, call_hook, void,
|
|||
}
|
||||
|
||||
METHOD(enumerator_t, sets_enumerate, bool,
|
||||
sets_enumerator_t *this, credential_set_t **set)
|
||||
sets_enumerator_t *this, va_list args)
|
||||
{
|
||||
credential_set_t **set;
|
||||
|
||||
VA_ARGS_VGET(args, set);
|
||||
|
||||
if (this->exclusive)
|
||||
{
|
||||
if (this->exclusive->enumerate(this->exclusive, set))
|
||||
|
@ -202,7 +206,8 @@ static enumerator_t *create_sets_enumerator(private_credential_manager_t *this)
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_sets_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _sets_enumerate,
|
||||
.destroy = _sets_destroy,
|
||||
},
|
||||
);
|
||||
|
@ -807,11 +812,12 @@ static bool verify_trust_chain(private_credential_manager_t *this,
|
|||
return trusted;
|
||||
}
|
||||
|
||||
/**
|
||||
* List find match function for certificates
|
||||
*/
|
||||
static bool cert_equals(certificate_t *a, certificate_t *b)
|
||||
CALLBACK(cert_equals, bool,
|
||||
certificate_t *a, va_list args)
|
||||
{
|
||||
certificate_t *b;
|
||||
|
||||
VA_ARGS_VGET(args, b);
|
||||
return a->equals(a, b);
|
||||
}
|
||||
|
||||
|
@ -840,9 +846,12 @@ typedef struct {
|
|||
} trusted_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, trusted_enumerate, bool,
|
||||
trusted_enumerator_t *this, certificate_t **cert, auth_cfg_t **auth)
|
||||
trusted_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t *current;
|
||||
certificate_t *current, **cert;
|
||||
auth_cfg_t **auth;
|
||||
|
||||
VA_ARGS_VGET(args, cert, auth);
|
||||
|
||||
DESTROY_IF(this->auth);
|
||||
this->auth = auth_cfg_create();
|
||||
|
@ -888,8 +897,7 @@ METHOD(enumerator_t, trusted_enumerate, bool,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (this->failed->find_first(this->failed, (void*)cert_equals,
|
||||
NULL, current) == SUCCESS)
|
||||
if (this->failed->find_first(this->failed, cert_equals, NULL, current))
|
||||
{ /* check each candidate only once */
|
||||
continue;
|
||||
}
|
||||
|
@ -931,7 +939,8 @@ METHOD(credential_manager_t, create_trusted_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_trusted_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _trusted_enumerate,
|
||||
.destroy = _trusted_destroy,
|
||||
},
|
||||
.this = this,
|
||||
|
@ -960,9 +969,13 @@ typedef struct {
|
|||
} public_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, public_enumerate, bool,
|
||||
public_enumerator_t *this, public_key_t **key, auth_cfg_t **auth)
|
||||
public_enumerator_t *this, va_list args)
|
||||
{
|
||||
certificate_t *cert;
|
||||
public_key_t **key;
|
||||
auth_cfg_t **auth;
|
||||
|
||||
VA_ARGS_VGET(args, key, auth);
|
||||
|
||||
while (this->inner->enumerate(this->inner, &cert, auth))
|
||||
{
|
||||
|
@ -1001,7 +1014,8 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_public_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _public_enumerate,
|
||||
.destroy = _public_destroy,
|
||||
},
|
||||
.inner = create_trusted_enumerator(this, type, id, online),
|
||||
|
|
|
@ -272,8 +272,12 @@ typedef struct {
|
|||
} private_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, signature_schemes_enumerate, bool,
|
||||
private_enumerator_t *this, signature_scheme_t *scheme)
|
||||
private_enumerator_t *this, va_list args)
|
||||
{
|
||||
signature_scheme_t *scheme;
|
||||
|
||||
VA_ARGS_VGET(args, scheme);
|
||||
|
||||
while (++this->index < countof(scheme_map))
|
||||
{
|
||||
if (this->type == scheme_map[this->index].type &&
|
||||
|
@ -296,7 +300,8 @@ enumerator_t *signature_schemes_for_key(key_type_t type, int size)
|
|||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.enumerate = (void*)_signature_schemes_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _signature_schemes_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.index = -1,
|
||||
|
|
|
@ -112,15 +112,15 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerate function for wrapper_enumerator_t
|
||||
*/
|
||||
static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
|
||||
METHOD(enumerator_t, enumerate, bool,
|
||||
wrapper_enumerator_t *this, va_list args)
|
||||
{
|
||||
auth_rule_t rule;
|
||||
certificate_t *current;
|
||||
certificate_t *current, **cert;
|
||||
public_key_t *public;
|
||||
|
||||
VA_ARGS_VGET(args, cert);
|
||||
|
||||
while (this->inner->enumerate(this->inner, &rule, ¤t))
|
||||
{
|
||||
if (rule == AUTH_HELPER_IM_HASH_URL ||
|
||||
|
@ -164,10 +164,8 @@ static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy function for wrapper_enumerator_t
|
||||
*/
|
||||
static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
|
||||
METHOD(enumerator_t, wrapper_enumerator_destroy, void,
|
||||
wrapper_enumerator_t *this)
|
||||
{
|
||||
this->inner->destroy(this->inner);
|
||||
free(this);
|
||||
|
@ -183,14 +181,18 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*,
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
enumerator = malloc_thing(wrapper_enumerator_t);
|
||||
enumerator->auth = this->auth;
|
||||
enumerator->cert = cert;
|
||||
enumerator->key = key;
|
||||
enumerator->id = id;
|
||||
enumerator->inner = this->auth->create_enumerator(this->auth);
|
||||
enumerator->public.enumerate = (void*)enumerate;
|
||||
enumerator->public.destroy = (void*)wrapper_enumerator_destroy;
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _enumerate,
|
||||
.destroy = _wrapper_enumerator_destroy,
|
||||
},
|
||||
.auth = this->auth,
|
||||
.cert = cert,
|
||||
.key = key,
|
||||
.id = id,
|
||||
.inner = this->auth->create_enumerator(this->auth),
|
||||
);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,9 +60,12 @@ typedef struct {
|
|||
} shared_enumerator_t;
|
||||
|
||||
METHOD(enumerator_t, shared_enumerate, bool,
|
||||
shared_enumerator_t *this, shared_key_t **out,
|
||||
id_match_t *match_me, id_match_t *match_other)
|
||||
shared_enumerator_t *this, va_list args)
|
||||
{
|
||||
shared_key_t **out;
|
||||
id_match_t *match_me, *match_other;
|
||||
|
||||
VA_ARGS_VGET(args, out, match_me, match_other);
|
||||
DESTROY_IF(this->current);
|
||||
this->current = this->this->cb.shared(this->this->data, this->type,
|
||||
this->me, this->other, match_me, match_other);
|
||||
|
@ -89,7 +92,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
|||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_shared_enumerate,
|
||||
.enumerate = enumerator_enumerate_default,
|
||||
.venumerate = _shared_enumerate,
|
||||
.destroy = _shared_destroy,
|
||||
},
|
||||
.this = this,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue