charon-nm: Handle IPv6 DNS server attributes

This commit is contained in:
Tobias Brunner
2019-03-14 13:42:08 +01:00
parent 0b117dc960
commit 0af3a4f103
3 changed files with 56 additions and 42 deletions
+52 -39
View File
@@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2016 Tobias Brunner
* Copyright (C) 2009 Martin Willi * Copyright (C) 2009 Martin Willi
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@@ -16,6 +17,7 @@
#include "nm_handler.h" #include "nm_handler.h"
#include <daemon.h> #include <daemon.h>
#include <collections/array.h>
typedef struct private_nm_handler_t private_nm_handler_t; typedef struct private_nm_handler_t private_nm_handler_t;
@@ -30,38 +32,56 @@ struct private_nm_handler_t {
nm_handler_t public; nm_handler_t public;
/** /**
* list of received DNS server attributes, pointer to 4 byte data * Received DNS server attributes, chunk_t
*/ */
linked_list_t *dns; array_t *dns;
/** /**
* list of received NBNS server attributes, pointer to 4 byte data * Received IPv6 DNS server attributes, chunk_t
*/ */
linked_list_t *nbns; array_t *dns6;
/**
* Received NBNS server attributes, chunk_t
*/
array_t *nbns;
}; };
METHOD(attribute_handler_t, handle, bool, METHOD(attribute_handler_t, handle, bool,
private_nm_handler_t *this, ike_sa_t *ike_sa, private_nm_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data) configuration_attribute_type_t type, chunk_t data)
{ {
linked_list_t *list; array_t *list;
switch (type) switch (type)
{ {
case INTERNAL_IP4_DNS: case INTERNAL_IP4_DNS:
list = this->dns; list = this->dns;
break; break;
case INTERNAL_IP6_DNS:
list = this->dns6;
break;
case INTERNAL_IP4_NBNS: case INTERNAL_IP4_NBNS:
list = this->nbns; list = this->nbns;
break; break;
default: default:
return FALSE; return FALSE;
} }
if (data.len != 4) data = chunk_clone(data);
{ array_insert(list, ARRAY_TAIL, &data);
return FALSE; return TRUE;
} }
list->insert_last(list, chunk_clone(data).ptr);
METHOD(enumerator_t, enumerate_dns6, bool,
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->venumerate = (void*)return_false;
return TRUE; return TRUE;
} }
@@ -74,7 +94,8 @@ METHOD(enumerator_t, enumerate_nbns, bool,
VA_ARGS_VGET(args, type, data); VA_ARGS_VGET(args, type, data);
*type = INTERNAL_IP4_NBNS; *type = INTERNAL_IP4_NBNS;
*data = chunk_empty; *data = chunk_empty;
this->venumerate = (void*)return_false; /* enumerate IPv6 DNS server as next attribute ... */
this->venumerate = _enumerate_dns6;
return TRUE; return TRUE;
} }
@@ -113,54 +134,44 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
return enumerator_create_empty(); return enumerator_create_empty();
} }
CALLBACK(filter_chunks, bool,
void *null, enumerator_t *orig, va_list args)
{
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*, METHOD(nm_handler_t, create_enumerator, enumerator_t*,
private_nm_handler_t *this, configuration_attribute_type_t type) private_nm_handler_t *this, configuration_attribute_type_t type)
{ {
linked_list_t *list; array_t *list;
switch (type) switch (type)
{ {
case INTERNAL_IP4_DNS: case INTERNAL_IP4_DNS:
list = this->dns; list = this->dns;
break; break;
case INTERNAL_IP6_DNS:
list = this->dns6;
break;
case INTERNAL_IP4_NBNS: case INTERNAL_IP4_NBNS:
list = this->nbns; list = this->nbns;
break; break;
default: default:
return enumerator_create_empty(); return enumerator_create_empty();
} }
return enumerator_create_filter(list->create_enumerator(list), return array_create_enumerator(list);
filter_chunks, NULL, NULL);
} }
METHOD(nm_handler_t, reset, void, METHOD(nm_handler_t, reset, void,
private_nm_handler_t *this) private_nm_handler_t *this)
{ {
void *data; chunk_t chunk;
while (this->dns->remove_last(this->dns, (void**)&data) == SUCCESS) while (array_remove(this->dns, ARRAY_TAIL, &chunk))
{ {
free(data); chunk_free(&chunk);
} }
while (this->nbns->remove_last(this->nbns, (void**)&data) == SUCCESS) while (array_remove(this->dns6, ARRAY_TAIL, &chunk))
{ {
free(data); chunk_free(&chunk);
}
while (array_remove(this->nbns, ARRAY_TAIL, &chunk))
{
chunk_free(&chunk);
} }
} }
@@ -168,8 +179,9 @@ METHOD(nm_handler_t, destroy, void,
private_nm_handler_t *this) private_nm_handler_t *this)
{ {
reset(this); reset(this);
this->dns->destroy(this->dns); array_destroy(this->dns);
this->nbns->destroy(this->nbns); array_destroy(this->dns6);
array_destroy(this->nbns);
free(this); free(this);
} }
@@ -191,8 +203,9 @@ nm_handler_t *nm_handler_create()
.reset = _reset, .reset = _reset,
.destroy = _destroy, .destroy = _destroy,
}, },
.dns = linked_list_create(), .dns = array_create(sizeof(chunk_t), 0),
.nbns = linked_list_create(), .dns6 = array_create(sizeof(chunk_t), 0),
.nbns = array_create(sizeof(chunk_t), 0),
); );
return &this->public; return &this->public;
+2 -1
View File
@@ -39,10 +39,11 @@ struct nm_handler_t {
* Create an enumerator over received attributes of a given kind. * Create an enumerator over received attributes of a given kind.
* *
* @param type type of attributes to enumerate * @param type type of attributes to enumerate
* @return enumerator over attribute data (chunk_t) * @return enumerator over attribute data (chunk_t*)
*/ */
enumerator_t* (*create_enumerator)(nm_handler_t *this, enumerator_t* (*create_enumerator)(nm_handler_t *this,
configuration_attribute_type_t type); configuration_attribute_type_t type);
/** /**
* Reset state, flush all received attributes. * Reset state, flush all received attributes.
*/ */
+2 -2
View File
@@ -58,14 +58,14 @@ static GVariant* handler_to_variant(nm_handler_t *handler,
{ {
GVariantBuilder builder; GVariantBuilder builder;
enumerator_t *enumerator; enumerator_t *enumerator;
chunk_t chunk; chunk_t *chunk;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("au")); g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
enumerator = handler->create_enumerator(handler, type); enumerator = handler->create_enumerator(handler, type);
while (enumerator->enumerate(enumerator, &chunk)) while (enumerator->enumerate(enumerator, &chunk))
{ {
g_variant_builder_add (&builder, "u", *(uint32_t*)chunk.ptr); g_variant_builder_add (&builder, "u", *(uint32_t*)chunk->ptr);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);