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" #include "util-internal.h"
/* Private functions */ /* 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 struct getdns_list *create_default_root_servers();
static getdns_return_t add_ip_str(getdns_dict *); static getdns_return_t add_ip_str(getdns_dict *);
static struct getdns_dict *create_ipaddr_dict_from_rdf(ldns_rdf *); static struct getdns_dict *create_ipaddr_dict_from_rdf(getdns_context_t,
static struct getdns_list *create_from_ldns_list(ldns_rdf **, size_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 getdns_return_t set_os_defaults(getdns_context_t);
static int transaction_id_cmp(const void *, const void *); static int transaction_id_cmp(const void *, const void *);
static void set_ub_string_opt(getdns_context_t, char *, char *); 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 * TODO: Determine from OS
*/ */
static uint16_t * 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[0] = GETDNS_CONTEXT_NAMESPACE_LOCALNAMES;
result[1] = GETDNS_CONTEXT_NAMESPACE_DNS; result[1] = GETDNS_CONTEXT_NAMESPACE_DNS;
return result; return result;
@ -117,11 +119,11 @@ add_ip_str(getdns_dict * ip)
} }
static struct getdns_dict * 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); ldns_rdf_type rt = ldns_rdf_get_type(rdf);
size_t sz = ldns_rdf_size(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 */ /* set type */
if (rt == LDNS_RDF_TYPE_A) { if (rt == LDNS_RDF_TYPE_A) {
getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE, 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 * 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 i = 0;
size_t idx = 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) { for (i = 0; i < count; ++i) {
ldns_rdf *rdf = ldns_list[i]; ldns_rdf *rdf = ldns_list[i];
switch (ldns_rdf_get_type(rdf)) { 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: case LDNS_RDF_TYPE_AAAA:
{ {
getdns_dict *ipaddr = getdns_dict *ipaddr =
create_ipaddr_dict_from_rdf(rdf); create_ipaddr_dict_from_rdf(context, rdf);
getdns_list_add_item(result, &idx); getdns_list_add_item(result, &idx);
getdns_list_set_dict(result, idx, ipaddr); getdns_list_set_dict(result, idx, ipaddr);
getdns_dict_destroy(ipaddr); getdns_dict_destroy(ipaddr);
@ -161,7 +164,7 @@ create_from_ldns_list(ldns_rdf ** ldns_list, size_t count)
{ {
getdns_bindata item; getdns_bindata item;
char *srch = ldns_rdf2str(rdf); char *srch = ldns_rdf2str(rdf);
item.size = strlen(srch); item.size = strlen(srch) + 1;
item.data = (uint8_t *) srch; item.data = (uint8_t *) srch;
getdns_list_add_item(result, &idx); getdns_list_add_item(result, &idx);
getdns_list_set_bindata(result, idx, &item); 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); size_t rdf_list_sz = ldns_resolver_nameserver_count(lr);
if (rdf_list_sz > 0) { if (rdf_list_sz > 0) {
context->upstream_list = 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 = ldns_resolver_searchlist(lr);
rdf_list_sz = ldns_resolver_searchlist_count(lr); rdf_list_sz = ldns_resolver_searchlist_count(lr);
if (rdf_list_sz > 0) { 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 **/ /** cleanup **/
ldns_resolver_deep_free(lr); 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. * Call this to initialize the context that is used in other getdns calls.
*/ */
getdns_return_t 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; getdns_context_t result = NULL;
if (context == NULL) { if (!context || !malloc || !realloc || !free)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
}
/** default init **/ /** default init **/
result = malloc(sizeof(struct getdns_context_t)); result = (*malloc)(sizeof(struct getdns_context_t));
if (!result) { if (!result) {
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
result->update_callback = NULL; result->update_callback = NULL;
result->memory_allocator = malloc; result->malloc = malloc;
result->memory_deallocator = free; result->realloc = realloc;
result->memory_reallocator = realloc; result->free = free;
result->event_base_sync = event_base_new(); result->event_base_sync = event_base_new();
result->unbound_sync = ub_ctx_create_event(result->event_base_sync); 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->outbound_requests = ldns_rbtree_create(transaction_id_cmp);
result->resolution_type = GETDNS_CONTEXT_RECURSING; result->resolution_type = GETDNS_CONTEXT_RECURSING;
result->namespaces = create_default_namespaces(); result->namespaces = create_default_namespaces(result);
result->timeout = 5000; result->timeout = 5000;
result->follow_redirects = GETDNS_CONTEXT_FOLLOW_REDIRECTS; 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; return GETDNS_RETURN_GOOD;
} /* getdns_context_create */ } /* 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 * getdns_context_destroy
* *
@ -304,9 +325,9 @@ getdns_context_destroy(getdns_context_t context)
if (context == NULL) { if (context == NULL) {
return; return;
} }
if (context->namespaces) { if (context->namespaces)
context->memory_deallocator(context->namespaces); GETDNS_FREE(context, context->namespaces);
}
getdns_list_destroy(context->dns_root_servers); getdns_list_destroy(context->dns_root_servers);
getdns_list_destroy(context->suffix); getdns_list_destroy(context->suffix);
getdns_list_destroy(context->dnssec_trust_anchors); getdns_list_destroy(context->dnssec_trust_anchors);
@ -320,7 +341,7 @@ getdns_context_destroy(getdns_context_t context)
ldns_rbtree_free(context->outbound_requests); ldns_rbtree_free(context->outbound_requests);
free(context); GETDNS_FREE(context, context);
return; return;
} /* getdns_context_destroy */ } /* getdns_context_destroy */
@ -416,18 +437,18 @@ getdns_return_t
getdns_context_set_namespaces(getdns_context_t context, getdns_context_set_namespaces(getdns_context_t context,
size_t namespace_count, uint16_t * namespaces) size_t namespace_count, uint16_t * namespaces)
{ {
size_t namespaces_size;
if (namespace_count == 0 || namespaces == NULL) { if (namespace_count == 0 || namespaces == NULL) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} }
/** clean up old namespaces **/ /** clean up old namespaces **/
context->memory_deallocator(context->namespaces); GETDNS_FREE(context, context->namespaces);
/** duplicate **/ /** duplicate **/
namespaces_size = namespace_count * sizeof(uint16_t); context->namespaces = GETDNS_XMALLOC(context, uint16_t,
context->namespaces = context->memory_allocator(namespaces_size); namespace_count);
memcpy(context->namespaces, namespaces, namespaces_size); memcpy(context->namespaces, namespaces,
namespace_count * sizeof(uint16_t));
dispatch_updated(context, GETDNS_CONTEXT_CODE_NAMESPACES); 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_edns_do_bit */
/* /*
* getdns_context_set_memory_allocator * getdns_context_set_memory_functions
* *
*/ */
getdns_return_t getdns_return_t
getdns_context_set_memory_allocator(getdns_context_t context, getdns_context_set_memory_functions(getdns_context_t context,
void (*value) (size_t somesize) void *(*malloc) (size_t),
void *(*realloc) (void *, size_t),
void (*free) (void *)
) )
{ {
UNUSED_PARAM(context); if (!context)
UNUSED_PARAM(value); return GETDNS_RETURN_BAD_CONTEXT;
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_memory_allocator */
/* if (!malloc || !realloc || !free)
* getdns_context_set_memory_deallocator return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
*
*/ context->malloc = malloc;
getdns_return_t context->realloc = realloc;
getdns_context_set_memory_deallocator(getdns_context_t context, context->free = free;
void (*value) (void *)
) dispatch_updated(context, GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS);
{
UNUSED_PARAM(context); return GETDNS_RETURN_GOOD;
UNUSED_PARAM(value); } /* getdns_context_set_memory_functions*/
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_memory_deallocator */
/*
* 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 * getdns_extension_set_libevent_base
@ -864,7 +870,7 @@ getdns_context_cancel_request(getdns_context_t context,
user_pointer = req->user_pointer; user_pointer = req->user_pointer;
/* clean up */ /* clean up */
context->memory_deallocator(node); GETDNS_FREE(context, node);
dns_req_free(req); dns_req_free(req);
/* fire callback */ /* fire callback */
@ -949,7 +955,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
getdns_context_t context = req->context; 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) { if (!node) {
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
@ -957,7 +963,7 @@ getdns_context_track_outbound_request(getdns_dns_req * req)
node->data = req; node->data = req;
if (!ldns_rbtree_insert(context->outbound_requests, node)) { if (!ldns_rbtree_insert(context->outbound_requests, node)) {
/* free the node */ /* free the node */
context->memory_deallocator(node); GETDNS_FREE(context, node);
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
return GETDNS_RETURN_GOOD; 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, ldns_rbnode_t *node = ldns_rbtree_delete(context->outbound_requests,
&(req->trans_id)); &(req->trans_id));
if (node) { if (node) {
context->memory_deallocator(node); GETDNS_FREE(context, node);
} }
return GETDNS_RETURN_GOOD; 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 */ /* getdns_context.c */

View File

@ -62,9 +62,9 @@ struct getdns_context_t
uint8_t edns_do_bit; uint8_t edns_do_bit;
getdns_update_callback update_callback; getdns_update_callback update_callback;
getdns_memory_allocator memory_allocator; getdns_memory_allocator malloc;
getdns_memory_deallocator memory_deallocator; getdns_memory_reallocator realloc;
getdns_memory_reallocator memory_reallocator; getdns_memory_deallocator free;
/* Event loop for sync requests */ /* Event loop for sync requests */
struct event_base *event_base_sync; struct event_base *event_base_sync;
@ -87,6 +87,19 @@ struct getdns_context_t
struct ldns_rbtree_t *outbound_requests; 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 **/ /** internal functions **/
/** /**
* Sets up the unbound contexts with stub or recursive behavior * 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_return_t getdns_context_cancel_request(getdns_context_t context,
getdns_transaction_t transaction_id, int fire_callback); 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_ */ #endif /* _GETDNS_CONTEXT_H_ */

View File

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

View File

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

View File

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

View File

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

View File

@ -340,7 +340,7 @@ getdns_address(getdns_context_t context,
{ {
int cleanup_extensions = 0; int cleanup_extensions = 0;
if (!extensions) { if (!extensions) {
extensions = getdns_dict_create(); extensions = getdns_dict_create_with_context(context);
cleanup_extensions = 1; cleanup_extensions = 1;
} }
getdns_dict_set_int(extensions, 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_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 614
#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT Change related to getdns_context_set_dnssec_allowed_skew #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_FUNCTIONS 615
#define GETDNS_CONTEXT_CODE_MEMORY_ALLOCATOR_TEXT Change related to getdns_context_set_memory_allocator #define GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT Change related to getdns_context_set_memory_functions
#define GETDNS_CONTEXT_CODE_MEMORY_DEALLOCATOR 616 #define GETDNS_CONTEXT_CODE_TIMEOUT 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_TIMEOUT_TEXT Change related to getdns_context_set_timeout #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 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; } getdns_data_type;
typedef struct getdns_bindata 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 * 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 * 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 * 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 srclist pointer to list to copy
* @param dstlist pointer to pointer to list to receive the copy (will be allocated) * @param dstlist pointer to pointer to list to receive the copy (will be allocated)
* @return GETDNS_RETURN_GOOD on success * @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 * @return pointer to an allocated list, NULL if insufficient memory
*/ */
struct getdns_list *getdns_list_create(); 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) * 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_* * 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 * @return pointer to an allocated dictionary, NULL if insufficient memory
*/ */
struct getdns_dict *getdns_dict_create(); 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 * 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, void *userarg,
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn); 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, getdns_return_t getdns_context_create(getdns_context_t * context,
int set_from_os); 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_context_set_edns_do_bit(getdns_context_t context, uint8_t value);
getdns_return_t getdns_return_t
getdns_context_set_memory_allocator(getdns_context_t context, getdns_context_set_memory_functions(getdns_context_t context,
void (*value) (size_t somesize) void *(*malloc) (size_t),
); void *(*realloc) (void *, size_t),
void (*free) (void *)
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 *)
); );
/* Extension - refactor to abstract async evt loop */ /* Extension - refactor to abstract async evt loop */

View File

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

View File

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

View File

@ -39,8 +39,8 @@
#include <event2/event.h> #include <event2/event.h>
/* useful macros */ /* useful macros */
#define gd_malloc(sz) context->memory_allocator(sz) #define gd_malloc(sz) context->malloc(sz)
#define gd_free(ptr) context->memory_deallocator(ptr) #define gd_free(ptr) context->free(ptr)
void void
network_req_free(getdns_network_req * net_req) 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; int cleanup_extensions = 0;
if (!extensions) { if (!extensions) {
extensions = getdns_dict_create(); extensions = getdns_dict_create_with_context(context);
cleanup_extensions = 1; cleanup_extensions = 1;
} }
getdns_dict_set_int(extensions, getdns_dict_set_int(extensions,

View File

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

View File

@ -104,8 +104,7 @@ tst_bindatasetget(void)
new_bindata = new_bindata =
(struct getdns_bindata *) malloc(sizeof(struct getdns_bindata)); (struct getdns_bindata *) malloc(sizeof(struct getdns_bindata));
new_bindata->size = strlen("foobar") + 1; new_bindata->size = strlen("foobar") + 1;
new_bindata->data = (uint8_t *) strdup("foobar"); new_bindata->data = (uint8_t *) "foobar";
new_bindata->data[strlen("foobar")] = '\0';
getdns_list_add_item(list, &index); getdns_list_add_item(list, &index);
getdns_list_set_bindata(list, index, new_bindata); getdns_list_set_bindata(list, index, new_bindata);
@ -403,6 +402,7 @@ tst_create(void)
i, (int) index, retval); i, (int) index, retval);
tstmsg_case_msg(msg); 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()"); tstmsg_case_msg("getdns_list_get_length()");
retval = getdns_list_get_length(NULL, &index); 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); tstmsg_case_msg(msg);
retval = getdns_list_get_length(NULL, NULL); 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_context_set_resolution_type(this_context, GETDNS_CONTEXT_STUB);
getdns_dict *response = NULL; getdns_dict *response = NULL;
uint32_t responseLen = 0;
getdns_return_t ret = getdns_return_t ret =
getdns_address_sync(this_context, "www.google.com", NULL, getdns_address_sync(this_context, "www.google.com", NULL, &response);
&responseLen, &response);
if (ret != GETDNS_RETURN_GOOD || response == NULL) { if (ret != GETDNS_RETURN_GOOD || response == NULL) {
fprintf(stderr, "Address sync returned error.\n"); fprintf(stderr, "Address sync returned error.\n");
@ -70,8 +68,7 @@ main()
getdns_dict_destroy(response); getdns_dict_destroy(response);
ret = ret =
getdns_service_sync(this_context, "www.google.com", NULL, getdns_service_sync(this_context, "www.google.com", NULL, &response);
&responseLen, &response);
if (ret != GETDNS_RETURN_GOOD || response == NULL) { if (ret != GETDNS_RETURN_GOOD || response == NULL) {
fprintf(stderr, "Service sync returned error.\n"); fprintf(stderr, "Service sync returned error.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

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

View File

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