Custom memory management functions in context

This commit is contained in:
Willem Toorop 2013-11-11 23:10:22 +01:00
parent 8e7582232a
commit 7158291e05
17 changed files with 647 additions and 593 deletions

View File

@ -43,11 +43,13 @@
#include "util-internal.h"
/* Private functions */
static uint16_t *create_default_namespaces();
static uint16_t *create_default_namespaces(getdns_context_t context);
static struct getdns_list *create_default_root_servers();
static getdns_return_t add_ip_str(getdns_dict *);
static struct getdns_dict *create_ipaddr_dict_from_rdf(ldns_rdf *);
static struct getdns_list *create_from_ldns_list(ldns_rdf **, size_t);
static struct getdns_dict *create_ipaddr_dict_from_rdf(getdns_context_t,
ldns_rdf *);
static struct getdns_list *create_from_ldns_list(getdns_context_t,
ldns_rdf **, size_t);
static getdns_return_t set_os_defaults(getdns_context_t);
static int transaction_id_cmp(const void *, const void *);
static void set_ub_string_opt(getdns_context_t, char *, char *);
@ -64,9 +66,9 @@ static void cancel_dns_req(getdns_dns_req *);
* TODO: Determine from OS
*/
static uint16_t *
create_default_namespaces()
create_default_namespaces(getdns_context_t context)
{
uint16_t *result = malloc(2 * sizeof(uint16_t));
uint16_t *result = GETDNS_XMALLOC(context, uint16_t, 2);
result[0] = GETDNS_CONTEXT_NAMESPACE_LOCALNAMES;
result[1] = GETDNS_CONTEXT_NAMESPACE_DNS;
return result;
@ -117,11 +119,11 @@ add_ip_str(getdns_dict * ip)
}
static struct getdns_dict *
create_ipaddr_dict_from_rdf(ldns_rdf * rdf)
create_ipaddr_dict_from_rdf(getdns_context_t context, ldns_rdf * rdf)
{
ldns_rdf_type rt = ldns_rdf_get_type(rdf);
size_t sz = ldns_rdf_size(rdf);
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
/* set type */
if (rt == LDNS_RDF_TYPE_A) {
getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE,
@ -138,11 +140,12 @@ create_ipaddr_dict_from_rdf(ldns_rdf * rdf)
}
static struct getdns_list *
create_from_ldns_list(ldns_rdf ** ldns_list, size_t count)
create_from_ldns_list(getdns_context_t context, ldns_rdf ** ldns_list,
size_t count)
{
size_t i = 0;
size_t idx = 0;
struct getdns_list *result = getdns_list_create();
struct getdns_list *result = getdns_list_create_with_context(context);
for (i = 0; i < count; ++i) {
ldns_rdf *rdf = ldns_list[i];
switch (ldns_rdf_get_type(rdf)) {
@ -150,7 +153,7 @@ create_from_ldns_list(ldns_rdf ** ldns_list, size_t count)
case LDNS_RDF_TYPE_AAAA:
{
getdns_dict *ipaddr =
create_ipaddr_dict_from_rdf(rdf);
create_ipaddr_dict_from_rdf(context, rdf);
getdns_list_add_item(result, &idx);
getdns_list_set_dict(result, idx, ipaddr);
getdns_dict_destroy(ipaddr);
@ -161,7 +164,7 @@ create_from_ldns_list(ldns_rdf ** ldns_list, size_t count)
{
getdns_bindata item;
char *srch = ldns_rdf2str(rdf);
item.size = strlen(srch);
item.size = strlen(srch) + 1;
item.data = (uint8_t *) srch;
getdns_list_add_item(result, &idx);
getdns_list_set_bindata(result, idx, &item);
@ -187,12 +190,13 @@ set_os_defaults(getdns_context_t context)
size_t rdf_list_sz = ldns_resolver_nameserver_count(lr);
if (rdf_list_sz > 0) {
context->upstream_list =
create_from_ldns_list(rdf_list, rdf_list_sz);
create_from_ldns_list(context, rdf_list, rdf_list_sz);
}
rdf_list = ldns_resolver_searchlist(lr);
rdf_list_sz = ldns_resolver_searchlist_count(lr);
if (rdf_list_sz > 0) {
context->suffix = create_from_ldns_list(rdf_list, rdf_list_sz);
context->suffix = create_from_ldns_list(context, rdf_list,
rdf_list_sz);
}
/** cleanup **/
ldns_resolver_deep_free(lr);
@ -229,24 +233,28 @@ transaction_id_cmp(const void *id1, const void *id2)
* Call this to initialize the context that is used in other getdns calls.
*/
getdns_return_t
getdns_context_create(getdns_context_t * context, int set_from_os)
getdns_context_create_with_memory_functions(getdns_context_t * context,
int set_from_os,
void *(*malloc)(size_t),
void *(*realloc)(void *, size_t),
void (*free)(void *)
)
{
getdns_context_t result = NULL;
if (context == NULL) {
if (!context || !malloc || !realloc || !free)
return GETDNS_RETURN_GENERIC_ERROR;
}
/** default init **/
result = malloc(sizeof(struct getdns_context_t));
result = (*malloc)(sizeof(struct getdns_context_t));
if (!result) {
return GETDNS_RETURN_GENERIC_ERROR;
}
result->update_callback = NULL;
result->memory_allocator = malloc;
result->memory_deallocator = free;
result->memory_reallocator = realloc;
result->malloc = malloc;
result->realloc = realloc;
result->free = free;
result->event_base_sync = event_base_new();
result->unbound_sync = ub_ctx_create_event(result->event_base_sync);
@ -259,7 +267,7 @@ getdns_context_create(getdns_context_t * context, int set_from_os)
result->outbound_requests = ldns_rbtree_create(transaction_id_cmp);
result->resolution_type = GETDNS_CONTEXT_RECURSING;
result->namespaces = create_default_namespaces();
result->namespaces = create_default_namespaces(result);
result->timeout = 5000;
result->follow_redirects = GETDNS_CONTEXT_FOLLOW_REDIRECTS;
@ -292,6 +300,19 @@ getdns_context_create(getdns_context_t * context, int set_from_os)
return GETDNS_RETURN_GOOD;
} /* getdns_context_create */
/*
* getdns_context_create
*
* Call this to initialize the context that is used in other getdns calls.
*/
getdns_return_t
getdns_context_create(getdns_context_t * context, int set_from_os)
{
return getdns_context_create_with_memory_functions(context,
set_from_os, malloc, realloc, free);
} /* getdns_context_create */
/*
* getdns_context_destroy
*
@ -304,9 +325,9 @@ getdns_context_destroy(getdns_context_t context)
if (context == NULL) {
return;
}
if (context->namespaces) {
context->memory_deallocator(context->namespaces);
}
if (context->namespaces)
GETDNS_FREE(context, context->namespaces);
getdns_list_destroy(context->dns_root_servers);
getdns_list_destroy(context->suffix);
getdns_list_destroy(context->dnssec_trust_anchors);
@ -320,7 +341,7 @@ getdns_context_destroy(getdns_context_t context)
ldns_rbtree_free(context->outbound_requests);
free(context);
GETDNS_FREE(context, context);
return;
} /* getdns_context_destroy */
@ -416,18 +437,18 @@ getdns_return_t
getdns_context_set_namespaces(getdns_context_t context,
size_t namespace_count, uint16_t * namespaces)
{
size_t namespaces_size;
if (namespace_count == 0 || namespaces == NULL) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
/** clean up old namespaces **/
context->memory_deallocator(context->namespaces);
GETDNS_FREE(context, context->namespaces);
/** duplicate **/
namespaces_size = namespace_count * sizeof(uint16_t);
context->namespaces = context->memory_allocator(namespaces_size);
memcpy(context->namespaces, namespaces, namespaces_size);
context->namespaces = GETDNS_XMALLOC(context, uint16_t,
namespace_count);
memcpy(context->namespaces, namespaces,
namespace_count * sizeof(uint16_t));
dispatch_updated(context, GETDNS_CONTEXT_CODE_NAMESPACES);
@ -759,46 +780,31 @@ getdns_context_set_edns_do_bit(getdns_context_t context, uint8_t value)
} /* getdns_context_set_edns_do_bit */
/*
* getdns_context_set_memory_allocator
* getdns_context_set_memory_functions
*
*/
getdns_return_t
getdns_context_set_memory_allocator(getdns_context_t context,
void (*value) (size_t somesize)
getdns_context_set_memory_functions(getdns_context_t context,
void *(*malloc) (size_t),
void *(*realloc) (void *, size_t),
void (*free) (void *)
)
{
UNUSED_PARAM(context);
UNUSED_PARAM(value);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_memory_allocator */
if (!context)
return GETDNS_RETURN_BAD_CONTEXT;
/*
* getdns_context_set_memory_deallocator
*
*/
getdns_return_t
getdns_context_set_memory_deallocator(getdns_context_t context,
void (*value) (void *)
)
{
UNUSED_PARAM(context);
UNUSED_PARAM(value);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_memory_deallocator */
if (!malloc || !realloc || !free)
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
context->malloc = malloc;
context->realloc = realloc;
context->free = free;
dispatch_updated(context, GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS);
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_memory_functions*/
/*
* getdns_context_set_memory_reallocator
*
*/
getdns_return_t
getdns_context_set_memory_reallocator(getdns_context_t context,
void (*value) (void *)
)
{
UNUSED_PARAM(context);
UNUSED_PARAM(value);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_memory_reallocator */
/*
* getdns_extension_set_libevent_base
@ -864,7 +870,7 @@ getdns_context_cancel_request(getdns_context_t context,
user_pointer = req->user_pointer;
/* clean up */
context->memory_deallocator(node);
GETDNS_FREE(context, node);
dns_req_free(req);
/* fire callback */
@ -949,7 +955,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req)
return GETDNS_RETURN_GENERIC_ERROR;
}
getdns_context_t context = req->context;
ldns_rbnode_t *node = context->memory_allocator(sizeof(ldns_rbnode_t));
ldns_rbnode_t *node = GETDNS_MALLOC(context, ldns_rbnode_t);
if (!node) {
return GETDNS_RETURN_GENERIC_ERROR;
}
@ -957,7 +963,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req)
node->data = req;
if (!ldns_rbtree_insert(context->outbound_requests, node)) {
/* free the node */
context->memory_deallocator(node);
GETDNS_FREE(context, node);
return GETDNS_RETURN_GENERIC_ERROR;
}
return GETDNS_RETURN_GOOD;
@ -973,9 +979,52 @@ getdns_context_clear_outbound_request(getdns_dns_req * req)
ldns_rbnode_t *node = ldns_rbtree_delete(context->outbound_requests,
&(req->trans_id));
if (node) {
context->memory_deallocator(node);
GETDNS_FREE(context, node);
}
return GETDNS_RETURN_GOOD;
}
char *
getdns_strdup(getdns_context_t context, const char *s)
{
size_t sz = strlen(s) + 1;
char *r = GETDNS_XMALLOC(context, char, sz);
if (r)
return memcpy(r, s, sz);
else
return NULL;
}
struct getdns_bindata *
getdns_bindata_copy(getdns_context_t context,
const struct getdns_bindata *src)
{
struct getdns_bindata *dst;
if (!src)
return NULL;
dst = GETDNS_MALLOC(context, struct getdns_bindata);
if (!dst)
return NULL;
dst->size = src->size;
dst->data = GETDNS_XMALLOC(context, uint8_t, src->size);
if (!dst->data) {
GETDNS_FREE(context, dst);
return NULL;
}
(void) memcpy(dst->data, src->data, src->size);
return dst;
}
void
getdns_bindata_destroy(getdns_context_t context,
struct getdns_bindata *bindata)
{
if (!bindata)
return;
GETDNS_FREE(context, bindata->data);
GETDNS_FREE(context, bindata);
}
/* getdns_context.c */

View File

@ -62,9 +62,9 @@ struct getdns_context_t
uint8_t edns_do_bit;
getdns_update_callback update_callback;
getdns_memory_allocator memory_allocator;
getdns_memory_deallocator memory_deallocator;
getdns_memory_reallocator memory_reallocator;
getdns_memory_allocator malloc;
getdns_memory_reallocator realloc;
getdns_memory_deallocator free;
/* Event loop for sync requests */
struct event_base *event_base_sync;
@ -87,6 +87,19 @@ struct getdns_context_t
struct ldns_rbtree_t *outbound_requests;
};
#define GETDNS_XMALLOC(context, type, count) \
((context) ? ((type *) (*(context)->malloc)((count) * sizeof(type))) \
: ((type *) malloc((count) * sizeof(type))))
#define GETDNS_MALLOC(context, type) \
GETDNS_XMALLOC(context, type, 1)
#define GETDNS_XREALLOC(context, ptr, type, count) \
((context) ? ((type *) (*(context)->realloc)((ptr), (count) * sizeof(type))) \
: ((type *) realloc((ptr), (count) * sizeof(type))))
#define GETDNS_REALLOC(context, ptr, type) \
GETDNS_XREALLOC(context, ptr, type, 1);
#define GETDNS_FREE(context, ptr) \
((context) ? ((*(context)->free)(ptr)) : free(ptr))
/** internal functions **/
/**
* Sets up the unbound contexts with stub or recursive behavior
@ -105,4 +118,12 @@ getdns_return_t getdns_context_clear_outbound_request(struct getdns_dns_req
getdns_return_t getdns_context_cancel_request(getdns_context_t context,
getdns_transaction_t transaction_id, int fire_callback);
char *getdns_strdup(getdns_context_t, const char *str);
struct getdns_bindata *getdns_bindata_copy(getdns_context_t,
const struct getdns_bindata *src);
void getdns_bindata_destroy(getdns_context_t context,
struct getdns_bindata *bindata);
#endif /* _GETDNS_CONTEXT_H_ */

View File

@ -37,6 +37,7 @@
#include <ctype.h>
#include <ldns/buffer.h>
#include "context.h"
#include "dict.h"
/*---------------------------------------- getdns_dict_find */
@ -51,23 +52,20 @@
struct getdns_dict_item *
getdns_dict_find(struct getdns_dict *dict, char *key, bool addifnotfnd)
{
struct getdns_dict_item *item = NULL;
struct getdns_dict_item *item;
if (dict != NULL && key != NULL) {
item =
(struct getdns_dict_item *) ldns_rbtree_search(&(dict->
root), key);
if (addifnotfnd == true && item == NULL) {
/* tsearch will add a node automatically for us */
item =
(struct getdns_dict_item *) malloc(sizeof(struct
getdns_dict_item));
item->node.key = strdup(key);
item->dtype = t_invalid;
item->data.n = 0;
ldns_rbtree_insert(&(dict->root),
(ldns_rbnode_t *) item);
}
if (!dict || !key)
return NULL;
item = (struct getdns_dict_item *)
ldns_rbtree_search(&(dict->root), key);
if (!item && addifnotfnd) {
/* tsearch will add a node automatically for us */
item = GETDNS_MALLOC(dict->context, struct getdns_dict_item);
item->node.key = getdns_strdup(dict->context, key);
item->data.n = 0;
ldns_rbtree_insert(&(dict->root), (ldns_rbnode_t *) item);
}
return item;
} /* getdns_dict_find */
@ -77,27 +75,25 @@ getdns_dict_find(struct getdns_dict *dict, char *key, bool addifnotfnd)
getdns_return_t
getdns_dict_get_names(struct getdns_dict * dict, struct getdns_list ** answer)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
struct getdns_dict_item *item;
size_t index;
struct getdns_bindata bindata;
if (dict != NULL && answer != NULL) {
*answer = getdns_list_create();
if (!dict || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
LDNS_RBTREE_FOR(item, struct getdns_dict_item *, &(dict->root))
{
if (getdns_list_add_item(*answer,
&index) == GETDNS_RETURN_GOOD) {
struct getdns_bindata bindata;
bindata.size = strlen(item->node.key);
bindata.data = (void *) item->node.key;
getdns_list_set_bindata(*answer, index,
&bindata);
}
}
retval = GETDNS_RETURN_GOOD;
*answer = getdns_list_create_with_context(dict->context);
if (!*answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
LDNS_RBTREE_FOR(item, struct getdns_dict_item *, &(dict->root)) {
if (getdns_list_add_item(*answer, &index) != GETDNS_RETURN_GOOD)
continue;
bindata.size = strlen(item->node.key) + 1;
bindata.data = (void *) item->node.key;
getdns_list_set_bindata(*answer, index, &bindata);
}
return retval;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_names */
/*---------------------------------------- getdns_dict_get_data_type */
@ -106,17 +102,16 @@ getdns_dict_get_data_type(struct getdns_dict * dict, char *name,
getdns_data_type * answer)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (dict != NULL && name != NULL && answer != NULL) {
item = getdns_dict_find(dict, name, false);
if (item != NULL) {
*answer = item->dtype;
retval = GETDNS_RETURN_GOOD;
}
}
if (!dict || !name || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
return retval;
item = getdns_dict_find(dict, name, false);
if (!item)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
*answer = item->dtype;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_data_type */
/*---------------------------------------- getdns_dict_get_dict */
@ -125,21 +120,16 @@ getdns_dict_get_dict(struct getdns_dict * dict, char *name,
struct getdns_dict ** answer)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (dict != NULL && name != NULL && answer != NULL) {
item = getdns_dict_find(dict, name, false);
if (item != NULL) {
if (item->dtype != t_dict)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = item->data.dict;
retval = GETDNS_RETURN_GOOD;
}
}
}
if (!dict || !name || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
return retval;
item = getdns_dict_find(dict, name, false);
if (!item || item->dtype != t_dict)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
*answer = item->data.dict;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_dict */
/*---------------------------------------- getdns_dict_get_list */
@ -148,21 +138,16 @@ getdns_dict_get_list(struct getdns_dict * dict, char *name,
struct getdns_list ** answer)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (dict != NULL && name != NULL && answer != NULL) {
item = getdns_dict_find(dict, name, false);
if (item != NULL) {
if (item->dtype != t_list)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = item->data.list;
retval = GETDNS_RETURN_GOOD;
}
}
}
if (!dict || !name || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
return retval;
item = getdns_dict_find(dict, name, false);
if (!item || item->dtype != t_list)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
*answer = item->data.list;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_list */
/*---------------------------------------- getdns_dict_get_bindata */
@ -171,21 +156,16 @@ getdns_dict_get_bindata(struct getdns_dict * dict, char *name,
struct getdns_bindata ** answer)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (dict != NULL && name != NULL && answer != NULL) {
item = getdns_dict_find(dict, name, false);
if (item != NULL) {
if (item->dtype != t_bindata)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = item->data.bindata;
retval = GETDNS_RETURN_GOOD;
}
}
}
if (!dict || !name || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
return retval;
item = getdns_dict_find(dict, name, false);
if (!item || item->dtype != t_bindata)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
*answer = item->data.bindata;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_bindata */
/*---------------------------------------- getdns_dict_get_int */
@ -193,34 +173,40 @@ getdns_return_t
getdns_dict_get_int(struct getdns_dict * dict, char *name, uint32_t * answer)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (dict != NULL && name != NULL && answer != NULL) {
item = getdns_dict_find(dict, name, false);
if (item != NULL) {
if (item->dtype != t_int)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = item->data.n;
retval = GETDNS_RETURN_GOOD;
}
}
}
if (!dict || !name || !answer)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
return retval;
item = getdns_dict_find(dict, name, false);
if (!item || item->dtype != t_int)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
*answer = item->data.n;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_int */
/*-------------------------- getdns_dict_create_with_context */
struct getdns_dict *
getdns_dict_create_with_context(getdns_context_t context)
{
struct getdns_dict *dict;
dict = GETDNS_MALLOC(context, struct getdns_dict);
if (!dict)
return NULL;
dict->context = context;
ldns_rbtree_init(&(dict->root), (int (*)(const void *,
const void *)) strcmp);
return dict;
} /* getdns_dict_create_with_context */
/*---------------------------------------- getdns_dict_create */
struct getdns_dict *
getdns_dict_create()
{
struct getdns_dict *dict;
dict = (struct getdns_dict *) malloc(sizeof(struct getdns_dict));
ldns_rbtree_init(&(dict->root), (int (*)(const void *,
const void *)) strcmp);
return dict;
} /* getdns_dict_create */
return getdns_dict_create_with_context(NULL);
} /* getdns_dict_create */
/*---------------------------------------- getdns_dict_copy */
/**
@ -236,39 +222,48 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict)
{
struct getdns_dict_item *item;
char *key;
getdns_return_t retval;
if (dstdict == NULL)
if (!dstdict)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (srcdict == NULL) {
if (!srcdict) {
*dstdict = NULL;
return GETDNS_RETURN_GOOD;
}
*dstdict = getdns_dict_create();
*dstdict = getdns_dict_create_with_context(srcdict->context);
if (!*dstdict)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
retval = GETDNS_RETURN_GOOD;
LDNS_RBTREE_FOR(item, struct getdns_dict_item *, &(srcdict->root)) {
key = (char *) item->node.key;
switch (item->dtype) {
case t_bindata:
getdns_dict_set_bindata(*dstdict, key,
retval = getdns_dict_set_bindata(*dstdict, key,
item->data.bindata);
break;
case t_dict:
getdns_dict_set_dict(*dstdict, key, item->data.dict);
retval = getdns_dict_set_dict(*dstdict, key,
item->data.dict);
break;
case t_int:
getdns_dict_set_int(*dstdict, key, item->data.n);
retval = getdns_dict_set_int(*dstdict, key,
item->data.n);
break;
case t_list:
getdns_dict_set_list(*dstdict, key, item->data.list);
break;
case t_invalid:
default:
// TODO: this is a fault of some kind, for now ignore it
retval = getdns_dict_set_list(*dstdict, key,
item->data.list);
break;
}
if (retval != GETDNS_RETURN_GOOD) {
getdns_dict_destroy(*dstdict);;
*dstdict = NULL;
return retval;
}
}
return GETDNS_RETURN_GOOD;
} /* getdns_dict_copy */
@ -282,36 +277,40 @@ getdns_dict_copy(struct getdns_dict * srcdict, struct getdns_dict ** dstdict)
void
getdns_dict_item_free(ldns_rbnode_t * node, void *arg)
{
(void) arg;
struct getdns_dict_item *item = (struct getdns_dict_item *) node;
if (item != NULL) {
if (item->dtype == t_bindata) {
if (item->data.bindata->size > 0)
free(item->data.bindata->data);
free(item->data.bindata);
} else if (item->dtype == t_dict) {
getdns_dict_destroy(item->data.dict);
} else if (item->dtype == t_list) {
getdns_list_destroy(item->data.list);
}
getdns_context_t context = (getdns_context_t)arg;
if (item->node.key != NULL)
free((char *) item->node.key);
free(item);
if (!item)
return;
switch (item->dtype) {
case t_bindata:
getdns_bindata_destroy(context, item->data.bindata);
break;
case t_dict:
getdns_dict_destroy(item->data.dict);
break;
case t_list:
getdns_list_destroy(item->data.list);
break;
default:
break;
}
if (item->node.key)
GETDNS_FREE(context, (void *)item->node.key);
GETDNS_FREE(context, item);
} /* getdns_dict_item_free */
/*---------------------------------------- getdns_dict_destroy */
void
getdns_dict_destroy(struct getdns_dict *dict)
{
if (dict != NULL) {
ldns_traverse_postorder(&(dict->root), getdns_dict_item_free,
NULL);
free(dict);
}
if (!dict)
return;
return;
ldns_traverse_postorder(&(dict->root),
getdns_dict_item_free, dict->context);
GETDNS_FREE(dict->context, dict);
} /* getdns_dict_destroy */
/*---------------------------------------- getdns_dict_set_dict */
@ -321,21 +320,23 @@ getdns_dict_set_dict(struct getdns_dict * dict, char *name,
{
struct getdns_dict_item *item;
struct getdns_dict *newdict;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
getdns_return_t retval;
if (dict != NULL && name != NULL) {
item = getdns_dict_find(dict, name, true);
if (item != NULL) {
retval = getdns_dict_copy(child_dict, &newdict);
if (retval == GETDNS_RETURN_GOOD) {
item->dtype = t_dict;
item->data.dict = newdict;
} else
item->dtype = t_invalid;
}
if (!dict || !name)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
retval = getdns_dict_copy(child_dict, &newdict);
if (retval != GETDNS_RETURN_GOOD)
return retval;
item = getdns_dict_find(dict, name, true);
if (!item) {
getdns_dict_destroy(newdict);
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
}
return retval;
item->dtype = t_dict;
item->data.dict = newdict;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_set_dict */
/*---------------------------------------- getdns_dict_set_list */
@ -345,21 +346,23 @@ getdns_dict_set_list(struct getdns_dict * dict, char *name,
{
struct getdns_dict_item *item;
struct getdns_list *newlist;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
getdns_return_t retval;
if (dict != NULL && name != NULL) {
item = getdns_dict_find(dict, name, true);
if (item != NULL) {
retval = getdns_list_copy(child_list, &newlist);
if (retval == GETDNS_RETURN_GOOD) {
item->dtype = t_list;
item->data.list = newlist;
} else
item->dtype = t_invalid;
}
if (!dict || !name)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
retval = getdns_list_copy(child_list, &newlist);
if (retval != GETDNS_RETURN_GOOD)
return retval;
item = getdns_dict_find(dict, name, true);
if (!item) {
getdns_list_destroy(newlist);
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
}
return retval;
item->dtype = t_list;
item->data.list = newlist;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_set_list */
/*---------------------------------------- getdns_dict_set_bindata */
@ -368,31 +371,23 @@ getdns_dict_set_bindata(struct getdns_dict * dict, char *name,
struct getdns_bindata * child_bindata)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
struct getdns_bindata *newbindata;
if (dict != NULL && name != NULL && child_bindata != NULL) {
item = getdns_dict_find(dict, name, true);
if (item != NULL) {
item->dtype = t_bindata;
item->data.bindata =
(struct getdns_bindata *) malloc(sizeof(struct
getdns_bindata));
if (item->data.bindata != NULL) {
item->data.bindata->data =
(void *) malloc(child_bindata->size);
if (item->data.bindata->data != NULL) {
item->data.bindata->size =
child_bindata->size;
memcpy(item->data.bindata->data,
child_bindata->data,
child_bindata->size);
retval = GETDNS_RETURN_GOOD;
}
}
}
if (!dict || !name || !child_bindata)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
newbindata = getdns_bindata_copy(dict->context, child_bindata);
if (!newbindata)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
item = getdns_dict_find(dict, name, true);
if (!item) {
getdns_bindata_destroy(dict->context, newbindata);
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
}
return retval;
item->dtype = t_bindata;
item->data.bindata = newbindata;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_set_bindata */
/*---------------------------------------- getdns_dict_set_int */
@ -401,18 +396,17 @@ getdns_dict_set_int(struct getdns_dict * dict, char *name,
uint32_t child_uint32)
{
struct getdns_dict_item *item;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME;
if (dict != NULL && name != NULL) {
item = getdns_dict_find(dict, name, true);
if (item != NULL) {
item->dtype = t_int;
item->data.n = child_uint32;
retval = GETDNS_RETURN_GOOD;
}
}
if (!dict || !name)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
return retval;
item = getdns_dict_find(dict, name, true);
if (!item)
return GETDNS_RETURN_NO_SUCH_DICT_NAME;
item->dtype = t_int;
item->data.n = child_uint32;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_set_int */
/*---------------------------------------- getdns_pp_dict */
@ -550,9 +544,8 @@ getdns_pp_list(ldns_buffer * buf, size_t indent, struct getdns_list *list)
return -1;
break;
case t_invalid:
default:
if (ldns_buffer_printf(buf, " <invalid>") < 0)
if (ldns_buffer_printf(buf, " <unknown>") < 0)
return -1;
}
i++;
@ -631,9 +624,8 @@ getdns_pp_dict(ldns_buffer * buf, size_t indent, struct getdns_dict *dict)
return -1;
break;
case t_invalid:
default:
if (ldns_buffer_printf(buf, " <invalid>") < 0)
if (ldns_buffer_printf(buf, " <unknown>") < 0)
return -1;
}
i++;
@ -660,9 +652,8 @@ getdns_pretty_print_dict(struct getdns_dict *dict)
ldns_buffer *buf;
char *ret;
if (!dict) {
if (!dict)
return NULL;
}
buf = ldns_buffer_new(100);
if (!buf)

View File

@ -66,6 +66,7 @@ struct getdns_dict_item
struct getdns_dict
{
ldns_rbtree_t root;
getdns_context_t context;
};
#endif

View File

@ -39,10 +39,19 @@ uint8_t *uint8ptrarg;
uint16_t *uint16ptrarg;
uint32_t *uint32ptrarg;
void *arrayarg;
void
void *
allocfunctionarg(size_t foo)
{
UNUSED_PARAM(foo);
return NULL;
}
void *
reallocfunctionarg(void *foo, size_t bar)
{
UNUSED_PARAM(foo);
UNUSED_PARAM(bar);
return NULL;
}
void
@ -80,16 +89,16 @@ main()
retregular = getdns_cancel_callback(contextarg, txidarg);
retregular = getdns_general_sync(contextarg,
charstararg, uint16arg, dictarg, uint32ptrarg, &dictarg);
charstararg, uint16arg, dictarg, &dictarg);
retregular = getdns_address_sync(contextarg,
charstararg, dictarg, uint32ptrarg, &dictarg);
charstararg, dictarg, &dictarg);
retregular = getdns_hostname_sync(contextarg,
dictarg, dictarg, uint32ptrarg, &dictarg);
dictarg, dictarg, &dictarg);
retregular = getdns_service_sync(contextarg,
charstararg, dictarg, uint32ptrarg, &dictarg);
charstararg, dictarg, &dictarg);
getdns_free_sync_request_memory(dictarg);
@ -179,14 +188,8 @@ main()
retregular = getdns_context_set_edns_do_bit(contextarg, uint8arg);
retregular = getdns_context_set_memory_allocator(contextarg,
allocfunctionarg);
retregular = getdns_context_set_memory_deallocator(contextarg,
deallocfunctionarg);
retregular = getdns_context_set_memory_reallocator(contextarg,
deallocfunctionarg);
retregular = getdns_context_set_memory_functions(contextarg,
allocfunctionarg, reallocfunctionarg, deallocfunctionarg);
getdns_list_destroy(listarg);
getdns_dict_destroy(dictarg);

View File

@ -110,8 +110,8 @@ main()
}
/* Clean up */
getdns_context_destroy(this_context);
getdns_free_sync_request_memory(this_response);
getdns_context_destroy(this_context);
exit(EXIT_SUCCESS);
} /* main */

View File

@ -340,7 +340,7 @@ getdns_address(getdns_context_t context,
{
int cleanup_extensions = 0;
if (!extensions) {
extensions = getdns_dict_create();
extensions = getdns_dict_create_with_context(context);
cleanup_extensions = 1;
}
getdns_dict_set_int(extensions,

View File

@ -169,13 +169,9 @@ struct event_base;
#define GETDNS_CONTEXT_CODE_EDNS_DO_BIT_TEXT Change related to getdns_context_set_edns_do_bit
#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW 614
#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT Change related to getdns_context_set_dnssec_allowed_skew
#define GETDNS_CONTEXT_CODE_MEMORY_ALLOCATOR 615
#define GETDNS_CONTEXT_CODE_MEMORY_ALLOCATOR_TEXT Change related to getdns_context_set_memory_allocator
#define GETDNS_CONTEXT_CODE_MEMORY_DEALLOCATOR 616
#define GETDNS_CONTEXT_CODE_MEMORY_DEALLOCATOR_TEXT Change related to getdns_context_set_memory_deallocator
#define GETDNS_CONTEXT_CODE_MEMORY_REALLOCATOR 617
#define GETDNS_CONTEXT_CODE_MEMORY_REALLOCATOR_TEXT Change related to getdns_context_set_memory_reallocator
#define GETDNS_CONTEXT_CODE_TIMEOUT 618
#define GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS 615
#define GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT Change related to getdns_context_set_memory_functions
#define GETDNS_CONTEXT_CODE_TIMEOUT 616
#define GETDNS_CONTEXT_CODE_TIMEOUT_TEXT Change related to getdns_context_set_timeout
/** @}
*/
@ -376,7 +372,7 @@ typedef uint64_t getdns_transaction_t;
*/
typedef enum getdns_data_type
{
t_dict, t_list, t_int, t_bindata, t_invalid
t_dict, t_list, t_int, t_bindata
} getdns_data_type;
typedef struct getdns_bindata
{
@ -420,7 +416,7 @@ getdns_return_t getdns_list_get_length(struct getdns_list *list,
* private function (API users should not be calling this), this uses library
* routines to make a copy of the list - would be faster to make the copy directly
* caller must ensure that dstlist points to unallocated storage - the address will
* be overwritten by a new list via a call to getdns_list_create()
* be overwritten by a new list via a call to getdns_list_create(context)
* @param srclist pointer to list to copy
* @param dstlist pointer to pointer to list to receive the copy (will be allocated)
* @return GETDNS_RETURN_GOOD on success
@ -562,6 +558,7 @@ getdns_return_t getdns_dict_get_int(struct getdns_dict *this_dict, char *name,
* @return pointer to an allocated list, NULL if insufficient memory
*/
struct getdns_list *getdns_list_create();
struct getdns_list *getdns_list_create_with_context(getdns_context_t context);
/**
* free memory allocated to the list (also frees all children of the list)
* note that lists and bindata retrieved from the list via the getdns_list_get_*
@ -617,6 +614,7 @@ getdns_return_t getdns_list_set_int(struct getdns_list *list, size_t index,
* @return pointer to an allocated dictionary, NULL if insufficient memory
*/
struct getdns_dict *getdns_dict_create();
struct getdns_dict *getdns_dict_create_with_context(getdns_context_t context);
/**
* private function used to make a copy of a dict structure, the caller is responsible
@ -702,6 +700,14 @@ getdns_service(getdns_context_t context,
void *userarg,
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn);
getdns_return_t getdns_context_create_with_memory_functions(
getdns_context_t * context,
int set_from_os,
void *(*malloc) (size_t),
void *(*realloc) (void *, size_t),
void (*free) (void *)
);
getdns_return_t getdns_context_create(getdns_context_t * context,
int set_from_os);
@ -871,18 +877,10 @@ getdns_return_t
getdns_context_set_edns_do_bit(getdns_context_t context, uint8_t value);
getdns_return_t
getdns_context_set_memory_allocator(getdns_context_t context,
void (*value) (size_t somesize)
);
getdns_return_t
getdns_context_set_memory_deallocator(getdns_context_t context,
void (*value) (void *)
);
getdns_return_t
getdns_context_set_memory_reallocator(getdns_context_t context,
void (*value) (void *)
getdns_context_set_memory_functions(getdns_context_t context,
void *(*malloc) (size_t),
void *(*realloc) (void *, size_t),
void (*free) (void *)
);
/* Extension - refactor to abstract async evt loop */

View File

@ -35,20 +35,18 @@
*/
#include <string.h>
#include "context.h"
#include "list.h"
/*---------------------------------------- getdns_list_get_length */
getdns_return_t
getdns_list_get_length(struct getdns_list * list, size_t * answer)
{
int retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (!list || !answer)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list != NULL && answer != NULL) {
retval = GETDNS_RETURN_GOOD;
*answer = list->numinuse;
}
return retval;
*answer = list->numinuse;
return GETDNS_RETURN_GOOD;;
} /* getdns_list_get_length */
/*---------------------------------------- getdns_list_get_data_type */
@ -56,13 +54,11 @@ getdns_return_t
getdns_list_get_data_type(struct getdns_list * list, size_t index,
getdns_data_type * answer)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (!list || index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list != NULL && index < list->numinuse) {
*answer = list->items[index].dtype;
retval = GETDNS_RETURN_GOOD;
}
return retval;
*answer = list->items[index].dtype;
return GETDNS_RETURN_GOOD;
} /* getdns_list_get_data_type */
/*---------------------------------------- getdns_list_get_dict */
@ -70,18 +66,14 @@ getdns_return_t
getdns_list_get_dict(struct getdns_list * list, size_t index,
struct getdns_dict ** answer)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (!list || index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list != NULL && index < list->numinuse) {
if (list->items[index].dtype != t_dict)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = list->items[index].data.dict;
retval = GETDNS_RETURN_GOOD;
}
}
if (list->items[index].dtype != t_dict)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
return retval;
*answer = list->items[index].data.dict;
return GETDNS_RETURN_GOOD;
} /* getdns_list_get_dict */
/*---------------------------------------- getdns_list_get_list */
@ -89,18 +81,15 @@ getdns_return_t
getdns_list_get_list(struct getdns_list * list, size_t index,
struct getdns_list ** answer)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list != NULL && index < list->numinuse) {
if (list->items[index].dtype != t_list)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = list->items[index].data.list;
retval = GETDNS_RETURN_GOOD;
}
}
if (!list || index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
return retval;
if (list->items[index].dtype != t_list)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
*answer = list->items[index].data.list;
return GETDNS_RETURN_GOOD;
} /* getdns_list_get_list */
/*---------------------------------------- getdns_list_get_bindata */
@ -108,36 +97,28 @@ getdns_return_t
getdns_list_get_bindata(struct getdns_list * list, size_t index,
struct getdns_bindata ** answer)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (!list || index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list->items[index].dtype != t_bindata)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
if (list != NULL && index < list->numinuse) {
if (list->items[index].dtype != t_bindata)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = list->items[index].data.bindata;
retval = GETDNS_RETURN_GOOD;
}
}
return retval;
*answer = list->items[index].data.bindata;
return GETDNS_RETURN_GOOD;
} /* getdns_list_get_bindata */
/*---------------------------------------- getdns_list_get_int */
getdns_return_t
getdns_list_get_int(struct getdns_list * list, size_t index, uint32_t * answer)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (!list || index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list != NULL && index < list->numinuse) {
if (list->items[index].dtype != t_int)
retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED;
else {
*answer = list->items[index].data.n;
retval = GETDNS_RETURN_GOOD;
}
}
if (list->items[index].dtype != t_int)
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
return retval;
*answer = list->items[index].data.n;
return GETDNS_RETURN_GOOD;
} /* getdns_list_get_int */
/*---------------------------------------- getdns_list_realloc */
@ -149,31 +130,29 @@ getdns_list_get_int(struct getdns_list * list, size_t index, uint32_t * answer)
* @return GETDNS_RETURN_GOOD on success, GETDNS_RETURN_GENERIC_ERROR if out of memory
*/
getdns_return_t
getdns_list_realloc(struct getdns_list * list)
getdns_list_realloc(struct getdns_list *list)
{
getdns_return_t retval = GETDNS_RETURN_GENERIC_ERROR;
int i;
struct getdns_list_item *newlist;
int i;
if (list != NULL) {
newlist =
(struct getdns_list_item *) realloc(list->items,
(list->numalloc +
GETDNS_LIST_BLOCKSZ) *
sizeof(struct getdns_list_item));
if (newlist != NULL) {
list->items = newlist;
for (i = list->numalloc;
i < list->numalloc + GETDNS_LIST_BLOCKSZ; i++) {
list->items[i].inuse = false;
list->items[i].dtype = t_invalid;
}
list->numalloc += GETDNS_LIST_BLOCKSZ;
retval = GETDNS_RETURN_GOOD;
}
if (!list)
return GETDNS_RETURN_GENERIC_ERROR;
newlist = GETDNS_XREALLOC(list->context, list->items,
struct getdns_list_item,
list->numalloc + GETDNS_LIST_BLOCKSZ);
if (!newlist)
return GETDNS_RETURN_GENERIC_ERROR;
list->items = newlist;
list->numalloc += GETDNS_LIST_BLOCKSZ;
/*
for (i = list->numalloc - GETDNS_LIST_BLOCKSZ; i < list->numalloc; i++) {
list->items[i].dtype = t_int;
list->items[i].data.n = 0;
}
return retval;
*/
return GETDNS_RETURN_GOOD;
} /* getdns_list_realloc */
/*---------------------------------------- getdns_list_copy */
@ -182,98 +161,82 @@ getdns_list_copy(struct getdns_list * srclist, struct getdns_list ** dstlist)
{
int i;
size_t index;
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
getdns_return_t retval;
if (srclist != NULL && dstlist != NULL) {
*dstlist = getdns_list_create();
if (*dstlist != NULL) {
retval = GETDNS_RETURN_GOOD;
for (i = 0; i < srclist->numinuse; i++) {
if (getdns_list_add_item(*dstlist,
&index) == GETDNS_RETURN_GOOD) {
(*dstlist)->items[index].inuse = true;
(*dstlist)->items[index].dtype =
srclist->items[i].dtype;
if (!dstlist)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (srclist->items[i].dtype == t_int)
(*dstlist)->items[index].data.
n =
srclist->items[i].data.n;
else if (srclist->items[i].dtype ==
t_list)
retval =
getdns_list_copy(srclist->
items[index].data.list,
&((*dstlist)->items[i].
data.list));
else if (srclist->items[i].dtype ==
t_bindata) {
(*dstlist)->items[i].data.
bindata =
(struct getdns_bindata *)
malloc(sizeof
(getdns_bindata));
(*dstlist)->items[i].data.
bindata->size =
srclist->items[i].data.
bindata->size;
(*dstlist)->items[i].data.
bindata->data = (uint8_t *)
malloc(srclist->items[i].
data.bindata->size);
if ((*dstlist)->items[i].data.
bindata->data != NULL)
memcpy((*dstlist)->
items[i].data.
bindata->data,
srclist->items[i].
data.bindata->data,
srclist->items[i].
data.bindata->
size);
else
retval =
GETDNS_RETURN_GENERIC_ERROR;
} else if (srclist->items[i].dtype ==
t_dict) {
retval =
getdns_dict_copy(srclist->
items[index].data.dict,
&((*dstlist)->items[i].
data.dict));
}
} else {
retval = GETDNS_RETURN_GENERIC_ERROR;
getdns_list_destroy(*dstlist);
*dstlist = NULL;
}
if (retval != GETDNS_RETURN_GOOD)
break;
}
} else
retval = GETDNS_RETURN_GENERIC_ERROR;
if (!srclist) {
*dstlist = NULL;
return GETDNS_RETURN_GOOD;
}
*dstlist = getdns_list_create_with_context(srclist->context);
if (!dstlist)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
return retval;
for (i = 0; i < srclist->numinuse; i++) {
retval = getdns_list_add_item(*dstlist, &index);
if (retval != GETDNS_RETURN_GOOD) {
getdns_list_destroy(*dstlist);
*dstlist = NULL;
return retval;
}
switch (srclist->items[i].dtype) {
case t_int:
retval = getdns_list_set_int(*dstlist, index,
srclist->items[i].data.n);
break;
case t_list:
retval =getdns_list_set_list(*dstlist, index,
srclist->items[i].data.list);
break;
case t_bindata:
retval = getdns_list_set_bindata(*dstlist, index,
srclist->items[i].data.bindata);
break;
case t_dict:
retval = getdns_list_set_dict(*dstlist, index,
srclist->items[i].data.dict);
break;
}
if (retval != GETDNS_RETURN_GOOD) {
getdns_list_destroy(*dstlist);
*dstlist = NULL;
return retval;
}
}
return GETDNS_RETURN_GOOD;
} /* getdns_list_copy */
/*-------------------------- getdns_list_create_with_context */
struct getdns_list *
getdns_list_create_with_context(getdns_context_t context)
{
struct getdns_list *list;
list = GETDNS_MALLOC(context, struct getdns_list);
if (!list)
return NULL;
list->context = context;
list->numalloc = 0;
list->numinuse = 0;
list->items = NULL;
if (getdns_list_realloc(list) != GETDNS_RETURN_GOOD) {
getdns_list_destroy(list);
return NULL;
}
return list;
} /* getdns_list_create_with_context */
/*---------------------------------------- getdns_list_create */
struct getdns_list *
getdns_list_create()
{
struct getdns_list *list = NULL;
list = (struct getdns_list *) malloc(sizeof(struct getdns_list));
if (list != NULL) {
list->numalloc = 0;
list->numinuse = 0;
list->items = NULL;
getdns_list_realloc(list);
}
return list;
return getdns_list_create_with_context(NULL);
} /* getdns_list_create */
/*---------------------------------------- getdns_list_destroy */
@ -282,48 +245,51 @@ getdns_list_destroy(struct getdns_list *list)
{
int i;
if (list != NULL) {
if (list->items != NULL) {
for (i = 0; i < list->numinuse; i++) {
if (list->items[i].dtype == t_list) {
if (list->items[i].dtype == t_list)
getdns_list_destroy(list->
items[i].data.list);
} else if (list->items[i].dtype == t_bindata) {
if (list->items[i].data.bindata->size >
0)
free(list->items[i].data.
bindata->data);
free(list->items[i].data.bindata);
} else if (list->items[i].dtype == t_dict) {
getdns_dict_destroy(list->items[i].
data.dict);
}
}
free(list->items);
if (!list)
return;
for (i = 0; i < list->numinuse; i++) {
switch (list->items[i].dtype) {
case t_dict:
getdns_dict_destroy(list->items[i].data.dict);
break;
case t_list:
getdns_list_destroy(list->items[i].data.list);
break;
case t_bindata:
getdns_bindata_destroy(list->context,
list->items[i].data.bindata);
break;
default:
break;
}
free(list);
}
if (list->items)
GETDNS_FREE(list->context, list->items);
GETDNS_FREE(list->context, list);
} /* getdns_list_destroy */
/*---------------------------------------- getdns_list_add_item */
getdns_return_t
getdns_list_add_item(struct getdns_list *list, size_t * index)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list != NULL && index != NULL) {
if (list->numalloc == list->numinuse)
retval = getdns_list_realloc(list);
else
retval = GETDNS_RETURN_GOOD;
getdns_return_t retval;
if (retval == GETDNS_RETURN_GOOD) {
*index = list->numinuse;
list->items[*index].inuse = true;
list->numinuse++;
}
if (!list || !index)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (list->numalloc == list->numinuse) {
retval = getdns_list_realloc(list);
if (retval != GETDNS_RETURN_GOOD)
return retval;
}
return retval;
*index = list->numinuse;
list->numinuse++;
return GETDNS_RETURN_GOOD;
} /* getdns_list_add_item */
/*---------------------------------------- getdns_list_set_dict */
@ -331,85 +297,106 @@ getdns_return_t
getdns_list_set_dict(struct getdns_list * list, size_t index,
struct getdns_dict * child_dict)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
struct getdns_dict *newdict;
getdns_return_t retval;
if (list != NULL && child_dict != NULL) {
if (list->numinuse > index) {
list->items[index].dtype = t_dict;
retval =
getdns_dict_copy(child_dict,
&(list->items[index].data.dict));
}
if (!list || !child_dict)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
retval = getdns_dict_copy(child_dict, &newdict);
if (retval != GETDNS_RETURN_GOOD)
return retval;
if (index == list->numinuse) {
retval = getdns_list_add_item(list, &index);
if (retval != GETDNS_RETURN_GOOD)
return retval;
}
return retval;
list->items[index].dtype = t_dict;
list->items[index].data.dict = newdict;
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_dict */
/*---------------------------------------- getdns_set_list */
/*---------------------------------------- getdns_list_set_list */
getdns_return_t
getdns_list_set_list(struct getdns_list * list, size_t index,
struct getdns_list * child_list)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
struct getdns_list *newlist;
getdns_return_t retval;
if (list != NULL && child_list != NULL) {
if (list->numinuse > index) {
list->items[index].dtype = t_list;
retval =
getdns_list_copy(child_list,
&(list->items[index].data.list));
}
if (!list || !child_list)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
retval = getdns_list_copy(child_list, &newlist);
if (retval != GETDNS_RETURN_GOOD)
return retval;
if (index == list->numinuse) {
retval = getdns_list_add_item(list, &index);
if (retval != GETDNS_RETURN_GOOD)
return retval;
}
return retval;
} /* getdns_set_list */
list->items[index].dtype = t_list;
list->items[index].data.list = newlist;
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_list */
/*---------------------------------------- getdns_list_set_bindata */
getdns_return_t
getdns_list_set_bindata(struct getdns_list * list, size_t index,
struct getdns_bindata * child_bindata)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
struct getdns_bindata *newbindata;
getdns_return_t retval;
if (list != NULL && child_bindata != NULL) {
if (list->numinuse > index) {
list->items[index].dtype = t_bindata;
list->items[index].data.bindata =
(struct getdns_bindata *)
malloc(sizeof(struct getdns_bindata));
if (list->items[index].data.bindata != NULL) {
list->items[index].data.bindata->size =
child_bindata->size;
list->items[index].data.bindata->data =
(uint8_t *) malloc(child_bindata->size *
sizeof(uint8_t));
memcpy(list->items[index].data.bindata->data,
child_bindata->data, child_bindata->size);
retval = GETDNS_RETURN_GOOD;
} else
retval = GETDNS_RETURN_GENERIC_ERROR;
}
if (!list || !child_bindata)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
newbindata = getdns_bindata_copy(list->context, child_bindata);
if (!newbindata)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (index == list->numinuse) {
retval = getdns_list_add_item(list, &index);
if (retval != GETDNS_RETURN_GOOD)
return retval;
}
return retval;
list->items[index].dtype = t_bindata;
list->items[index].data.bindata = newbindata;
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_bindata */
/*---------------------------------------- getdns_list_set_int */
getdns_return_t
getdns_list_set_int(struct getdns_list * list, size_t index,
uint32_t child_uint32)
uint32_t child_int)
{
getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM;
getdns_return_t retval;
if (list != NULL) {
if (list->numinuse > index) {
list->items[index].dtype = t_int;
list->items[index].data.n = child_uint32;
retval = GETDNS_RETURN_GOOD;
}
if (!list)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (index >= list->numinuse)
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
if (index == list->numinuse) {
retval = getdns_list_add_item(list, &index);
if (retval != GETDNS_RETURN_GOOD)
return retval;
}
return retval;
list->items[index].dtype = t_int;
list->items[index].data.n = child_int;
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_int */
/* getdns_list.c */

View File

@ -39,7 +39,6 @@
*/
struct getdns_list_item
{
int inuse;
getdns_data_type dtype;
union
{
@ -64,6 +63,7 @@ struct getdns_list
int numalloc;
int numinuse;
struct getdns_list_item *items;
getdns_context_t context;
};
#endif

View File

@ -39,8 +39,8 @@
#include <event2/event.h>
/* useful macros */
#define gd_malloc(sz) context->memory_allocator(sz)
#define gd_free(ptr) context->memory_deallocator(ptr)
#define gd_malloc(sz) context->malloc(sz)
#define gd_free(ptr) context->free(ptr)
void
network_req_free(getdns_network_req * net_req)

View File

@ -83,7 +83,7 @@ getdns_address_sync(getdns_context_t context,
{
int cleanup_extensions = 0;
if (!extensions) {
extensions = getdns_dict_create();
extensions = getdns_dict_create_with_context(context);
cleanup_extensions = 1;
}
getdns_dict_set_int(extensions,

View File

@ -271,13 +271,13 @@ tst_getnames(void)
printf("t_int, value=%d\n", ansint);
break;
case t_invalid:
printf("data type invalid");
break;
case t_list:
printf("NOTIMPLEMENTED");
break;
default:
printf("data type invalid");
break;
}
}
@ -493,7 +493,7 @@ tst_copy(void)
dict1 = getdns_dict_create();
getdns_dict_copy(dict1, &dict2);
getdns_dict_destroy(dict2);
getdns_dict_copy(NULL, &dict1);
/* getdns_dict_copy(NULL, &dict1); */
tstmsg_case_msg("dict1 populate");
@ -502,7 +502,7 @@ tst_copy(void)
getdns_dict_set_int(dict1, "quz", 62);
dictstr = getdns_pretty_print_dict(dict1);
printf("%s", dictstr);
printf("%s\n", dictstr);
free(dictstr);
tstmsg_case_msg("getdns_dict_copy(dict1, &dict2)");
@ -510,7 +510,7 @@ tst_copy(void)
getdns_dict_copy(dict1, &dict2);
dictstr = getdns_pretty_print_dict(dict2);
printf("%s", dictstr);
printf("%s\n", dictstr);
free(dictstr);
getdns_dict_destroy(dict1);

View File

@ -104,8 +104,7 @@ tst_bindatasetget(void)
new_bindata =
(struct getdns_bindata *) malloc(sizeof(struct getdns_bindata));
new_bindata->size = strlen("foobar") + 1;
new_bindata->data = (uint8_t *) strdup("foobar");
new_bindata->data[strlen("foobar")] = '\0';
new_bindata->data = (uint8_t *) "foobar";
getdns_list_add_item(list, &index);
getdns_list_set_bindata(list, index, new_bindata);
@ -403,6 +402,7 @@ tst_create(void)
i, (int) index, retval);
tstmsg_case_msg(msg);
}
getdns_list_set_int(list, index, 0);
}
}
@ -413,7 +413,7 @@ tst_create(void)
tstmsg_case_msg("getdns_list_get_length()");
retval = getdns_list_get_length(NULL, &index);
sprintf(msg, "NUll, &i, retval = %d", retval);
sprintf(msg, "NUll, %i, retval = %d", (int)index, retval);
tstmsg_case_msg(msg);
retval = getdns_list_get_length(NULL, NULL);

View File

@ -57,10 +57,8 @@ main()
getdns_context_set_resolution_type(this_context, GETDNS_CONTEXT_STUB);
getdns_dict *response = NULL;
uint32_t responseLen = 0;
getdns_return_t ret =
getdns_address_sync(this_context, "www.google.com", NULL,
&responseLen, &response);
getdns_address_sync(this_context, "www.google.com", NULL, &response);
if (ret != GETDNS_RETURN_GOOD || response == NULL) {
fprintf(stderr, "Address sync returned error.\n");
@ -70,8 +68,7 @@ main()
getdns_dict_destroy(response);
ret =
getdns_service_sync(this_context, "www.google.com", NULL,
&responseLen, &response);
getdns_service_sync(this_context, "www.google.com", NULL, &response);
if (ret != GETDNS_RETURN_GOOD || response == NULL) {
fprintf(stderr, "Service sync returned error.\n");
exit(EXIT_FAILURE);

View File

@ -127,14 +127,15 @@ dict_to_sockaddr(getdns_dict * ns, struct sockaddr_storage * output)
}
getdns_return_t
sockaddr_to_dict(struct sockaddr_storage * address, getdns_dict ** output)
sockaddr_to_dict(getdns_context_t context, struct sockaddr_storage *address,
getdns_dict ** output)
{
if (!output || !address) {
return GETDNS_RETURN_GENERIC_ERROR;
}
getdns_bindata addr_data;
*output = NULL;
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
if (address->ss_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *) address;
getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE,
@ -172,11 +173,11 @@ convert_rdf_to_str(ldns_rdf * rdf)
/* create the header dict */
static getdns_dict *
create_reply_header_dict(ldns_pkt * reply)
create_reply_header_dict(getdns_context_t context, ldns_pkt * reply)
{
/* { "id": 23456, "qr": 1, "opcode": 0, ... }, */
int r = 0;
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
if (!result) {
return NULL;
}
@ -196,13 +197,13 @@ create_reply_header_dict(ldns_pkt * reply)
}
static getdns_dict *
create_reply_question_dict(ldns_pkt * reply)
create_reply_question_dict(getdns_context_t context, ldns_pkt * reply)
{
/* { "qname": <bindata for "www.example.com">, "qtype": 1, "qclass": 1 } */
int r = 0;
ldns_rr *question = NULL;
char *qname;
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
if (!result) {
return NULL;
}
@ -227,7 +228,7 @@ create_reply_question_dict(ldns_pkt * reply)
}
static getdns_dict *
create_dict_from_rdf(ldns_rdf * rdf)
create_dict_from_rdf(getdns_context_t context, ldns_rdf * rdf)
{
/*
* create a dict w/ rdata_raw and special fields if needed
@ -239,7 +240,7 @@ create_dict_from_rdf(ldns_rdf * rdf)
*/
int r = 0;
getdns_bindata rbin = { ldns_rdf_size(rdf), ldns_rdf_data(rdf) };
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
r |= getdns_dict_set_bindata(result, GETDNS_STR_KEY_RDATA_RAW, &rbin);
if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_AAAA) {
r |= getdns_dict_set_bindata(result, GETDNS_STR_KEY_V6_ADDR,
@ -256,7 +257,7 @@ create_dict_from_rdf(ldns_rdf * rdf)
}
static getdns_dict *
create_dict_from_rr(ldns_rr * rr)
create_dict_from_rr(getdns_context_t context, ldns_rr * rr)
{
/*
* {
@ -273,7 +274,7 @@ create_dict_from_rr(ldns_rr * rr)
*/
int r = 0;
char *name = NULL;
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
size_t rd_count = ldns_rr_rd_count(rr);
ldns_rdf *owner = ldns_rr_owner(rr);
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_TYPE,
@ -293,7 +294,8 @@ create_dict_from_rr(ldns_rr * rr)
}
/* create rdatas */
if (rd_count >= 1) {
getdns_dict *rdata = create_dict_from_rdf(ldns_rr_rdf(rr, 0));
getdns_dict *rdata = create_dict_from_rdf(context,
ldns_rr_rdf(rr, 0));
r |= getdns_dict_set_dict(result, GETDNS_STR_KEY_RDATA, rdata);
getdns_dict_destroy(rdata);
}
@ -310,15 +312,15 @@ create_dict_from_rr(ldns_rr * rr)
returns a list of objects where each object
is a result from create_dict_from_rr */
static getdns_list *
create_list_from_rr_list(ldns_rr_list * rr_list)
create_list_from_rr_list(getdns_context_t context, ldns_rr_list * rr_list)
{
size_t i = 0;
size_t idx = 0;
int r = 0;
getdns_list *result = getdns_list_create();
getdns_list *result = getdns_list_create_with_context(context);
for (i = 0; i < ldns_rr_list_rr_count(rr_list); ++i) {
ldns_rr *rr = ldns_rr_list_rr(rr_list, i);
getdns_dict *rrdict = create_dict_from_rr(rr);
getdns_dict *rrdict = create_dict_from_rr(context, rr);
r |= getdns_list_add_item(result, &idx);
r |= getdns_list_set_dict(result, idx, rrdict);
getdns_dict_destroy(rrdict);
@ -357,7 +359,8 @@ add_only_addresses(getdns_list * addrs, ldns_rr_list * rr_list)
}
static getdns_dict *
create_reply_dict(getdns_network_req * req, getdns_list * just_addrs)
create_reply_dict(getdns_context_t context, getdns_network_req * req,
getdns_list * just_addrs)
{
/* turn a packet into this glorious structure
*
@ -406,23 +409,23 @@ create_reply_dict(getdns_network_req * req, getdns_list * just_addrs)
getdns_list *sublist = NULL;
char *name = NULL;
getdns_dict *result = getdns_dict_create();
getdns_dict *result = getdns_dict_create_with_context(context);
if (!result) {
return NULL;
}
/* header */
subdict = create_reply_header_dict(reply);
subdict = create_reply_header_dict(context, reply);
r |= getdns_dict_set_dict(result, GETDNS_STR_KEY_HEADER, subdict);
getdns_dict_destroy(subdict);
/* question */
subdict = create_reply_question_dict(reply);
subdict = create_reply_question_dict(context, reply);
r |= getdns_dict_set_dict(result, GETDNS_STR_KEY_QUESTION, subdict);
getdns_dict_destroy(subdict);
/* answers */
rr_list = ldns_pkt_answer(reply);
sublist = create_list_from_rr_list(rr_list);
sublist = create_list_from_rr_list(context, rr_list);
r |= getdns_dict_set_list(result, GETDNS_STR_KEY_ANSWER, sublist);
getdns_list_destroy(sublist);
if ((req->request_type == GETDNS_RRTYPE_A ||
@ -434,13 +437,13 @@ create_reply_dict(getdns_network_req * req, getdns_list * just_addrs)
/* authority */
rr_list = ldns_pkt_authority(reply);
sublist = create_list_from_rr_list(rr_list);
sublist = create_list_from_rr_list(context, rr_list);
r |= getdns_dict_set_list(result, GETDNS_STR_KEY_AUTHORITY, sublist);
getdns_list_destroy(sublist);
/* additional */
rr_list = ldns_pkt_additional(reply);
sublist = create_list_from_rr_list(rr_list);
sublist = create_list_from_rr_list(context, rr_list);
r |= getdns_dict_set_list(result, GETDNS_STR_KEY_ADDITIONAL, sublist);
getdns_list_destroy(sublist);
@ -478,10 +481,12 @@ get_canonical_name(const char *name)
getdns_dict *
create_getdns_response(struct getdns_dns_req * completed_request)
{
getdns_dict *result = getdns_dict_create();
getdns_list *replies_full = getdns_list_create();
getdns_dict *result = getdns_dict_create_with_context(completed_request->context);
getdns_list *replies_full = getdns_list_create_with_context(
completed_request->context);
getdns_list *just_addrs = NULL;
getdns_list *replies_tree = getdns_list_create();
getdns_list *replies_tree = getdns_list_create_with_context(
completed_request->context);
getdns_network_req *netreq = completed_request->first_req;
char *canonical_name = NULL;
@ -490,7 +495,8 @@ create_getdns_response(struct getdns_dns_req * completed_request)
if (completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
completed_request->first_req->request_class ==
GETDNS_RRTYPE_AAAA) {
just_addrs = getdns_list_create();
just_addrs = getdns_list_create_with_context(
completed_request->context);
}
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
@ -511,7 +517,8 @@ create_getdns_response(struct getdns_dns_req * completed_request)
ldns_pkt2wire(&(full_data.data), pkt, &(full_data.size));
size_t idx = 0;
/* reply tree */
getdns_dict *reply = create_reply_dict(netreq, just_addrs);
getdns_dict *reply = create_reply_dict(
completed_request->context, netreq, just_addrs);
r |= getdns_list_add_item(replies_tree, &idx);
r |= getdns_list_set_dict(replies_tree, idx, reply);
getdns_dict_destroy(reply);

View File

@ -46,8 +46,8 @@ struct getdns_dns_req;
/* convert an ip address dict to a sock storage */
getdns_return_t dict_to_sockaddr(getdns_dict * ns,
struct sockaddr_storage *output);
getdns_return_t sockaddr_to_dict(struct sockaddr_storage *sockaddr,
getdns_dict ** output);
getdns_return_t sockaddr_to_dict(getdns_context_t context,
struct sockaddr_storage *sockaddr, getdns_dict ** output);
getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request);