From 0af3a4f103919a522d92b53a904232473dbec68f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Sep 2016 11:48:07 +0200 Subject: [PATCH] charon-nm: Handle IPv6 DNS server attributes --- src/charon-nm/nm/nm_handler.c | 91 ++++++++++++++++++++--------------- src/charon-nm/nm/nm_handler.h | 3 +- src/charon-nm/nm/nm_service.c | 4 +- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c index aa7bb5b8c1..3561e7091f 100644 --- a/src/charon-nm/nm/nm_handler.c +++ b/src/charon-nm/nm/nm_handler.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Tobias Brunner * Copyright (C) 2009 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -16,6 +17,7 @@ #include "nm_handler.h" #include +#include typedef struct private_nm_handler_t private_nm_handler_t; @@ -30,38 +32,56 @@ struct private_nm_handler_t { 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, private_nm_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { - linked_list_t *list; + array_t *list; switch (type) { case INTERNAL_IP4_DNS: list = this->dns; break; + case INTERNAL_IP6_DNS: + list = this->dns6; + break; case INTERNAL_IP4_NBNS: list = this->nbns; break; default: return FALSE; } - if (data.len != 4) - { - return FALSE; - } - list->insert_last(list, chunk_clone(data).ptr); + data = chunk_clone(data); + array_insert(list, ARRAY_TAIL, &data); + return TRUE; +} + +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; } @@ -74,7 +94,8 @@ METHOD(enumerator_t, enumerate_nbns, bool, VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_NBNS; *data = chunk_empty; - this->venumerate = (void*)return_false; + /* enumerate IPv6 DNS server as next attribute ... */ + this->venumerate = _enumerate_dns6; return TRUE; } @@ -113,54 +134,44 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, 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*, private_nm_handler_t *this, configuration_attribute_type_t type) { - linked_list_t *list; + array_t *list; switch (type) { case INTERNAL_IP4_DNS: list = this->dns; break; + case INTERNAL_IP6_DNS: + list = this->dns6; + break; case INTERNAL_IP4_NBNS: list = this->nbns; break; default: return enumerator_create_empty(); } - return enumerator_create_filter(list->create_enumerator(list), - filter_chunks, NULL, NULL); + return array_create_enumerator(list); } METHOD(nm_handler_t, reset, void, 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)) + { + chunk_free(&chunk); + } + while (array_remove(this->dns6, ARRAY_TAIL, &chunk)) { - free(data); + chunk_free(&chunk); } - while (this->nbns->remove_last(this->nbns, (void**)&data) == SUCCESS) + while (array_remove(this->nbns, ARRAY_TAIL, &chunk)) { - free(data); + chunk_free(&chunk); } } @@ -168,8 +179,9 @@ METHOD(nm_handler_t, destroy, void, private_nm_handler_t *this) { reset(this); - this->dns->destroy(this->dns); - this->nbns->destroy(this->nbns); + array_destroy(this->dns); + array_destroy(this->dns6); + array_destroy(this->nbns); free(this); } @@ -191,8 +203,9 @@ nm_handler_t *nm_handler_create() .reset = _reset, .destroy = _destroy, }, - .dns = linked_list_create(), - .nbns = linked_list_create(), + .dns = array_create(sizeof(chunk_t), 0), + .dns6 = array_create(sizeof(chunk_t), 0), + .nbns = array_create(sizeof(chunk_t), 0), ); return &this->public; diff --git a/src/charon-nm/nm/nm_handler.h b/src/charon-nm/nm/nm_handler.h index f4103e67e3..91b0d10fe1 100644 --- a/src/charon-nm/nm/nm_handler.h +++ b/src/charon-nm/nm/nm_handler.h @@ -39,10 +39,11 @@ struct nm_handler_t { * Create an enumerator over received attributes of a given kind. * * @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, configuration_attribute_type_t type); + /** * Reset state, flush all received attributes. */ diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index 9ac9761fcb..d86b89f8f4 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -58,14 +58,14 @@ static GVariant* handler_to_variant(nm_handler_t *handler, { GVariantBuilder builder; enumerator_t *enumerator; - chunk_t chunk; + chunk_t *chunk; g_variant_builder_init (&builder, G_VARIANT_TYPE ("au")); enumerator = handler->create_enumerator(handler, type); 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); -- 2.39.2