From 2d1ad47f075a730a95ef7406aabdb1e567a0913d Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 3 Nov 2013 16:08:28 -0800 Subject: [PATCH 01/10] And another little typedef fix --- src/list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/list.h b/src/list.h index a3c3cd58..2fb1b100 100644 --- a/src/list.h +++ b/src/list.h @@ -61,7 +61,7 @@ struct getdns_list { int numalloc; int numinuse; struct getdns_list_item *items; -} getdns_list; +}; #endif From 2db5fdbe0cc6d272c9f7ab508496c739302201e4 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 12:51:13 -0500 Subject: [PATCH 02/10] Fix some memory leaks --- src/list.c | 9 ++++++++- src/sync.c | 5 +++-- src/test/testmessages.c | 1 + src/test/tests_dict.c | 6 +++++- src/util-internal.c | 8 +++++--- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/list.c b/src/list.c index 5c6ca170..d3865cd9 100644 --- a/src/list.c +++ b/src/list.c @@ -220,8 +220,11 @@ getdns_list_copy(struct getdns_list *srclist, struct getdns_list **dstlist) &((*dstlist)->items[i].data.dict)); } } - else + else { retval = GETDNS_RETURN_GENERIC_ERROR; + getdns_list_destroy(*dstlist); + *dstlist = NULL; + } if(retval != GETDNS_RETURN_GOOD) break; @@ -276,6 +279,10 @@ getdns_list_destroy(struct getdns_list *list) 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); } diff --git a/src/sync.c b/src/sync.c index 3aee6364..cc5b00d9 100644 --- a/src/sync.c +++ b/src/sync.c @@ -146,6 +146,7 @@ void getdns_free_sync_request_memory( struct getdns_dict *response ) -{ UNUSED_PARAM(response); } - +{ + getdns_dict_destroy(response); +} /* getdns_core_sync.c */ diff --git a/src/test/testmessages.c b/src/test/testmessages.c index 0161e9e7..b7377ddb 100644 --- a/src/test/testmessages.c +++ b/src/test/testmessages.c @@ -49,6 +49,7 @@ void tstmsg_prog_end() { printf("TESTPROG %s END\n", testprog); + free(testprog); } /* tstmsg_prog_end */ void diff --git a/src/test/tests_dict.c b/src/test/tests_dict.c index 4129c282..10ff2d2c 100644 --- a/src/test/tests_dict.c +++ b/src/test/tests_dict.c @@ -208,13 +208,15 @@ tst_getnames(void) tstmsg_case_msg("getdns_dict_get_names(NULL, &list)"); getdns_dict_get_names(NULL, &list); + getdns_list_destroy(list); tstmsg_case_msg("getdns_dict_get_names(dict, NULL)"); getdns_dict_get_names(dict, NULL); tstmsg_case_msg("getdns_dict_get_names(dict, &list), empty dictionary"); getdns_dict_get_names(dict, &list); - + getdns_list_destroy(list); + /* legit use case, add items out of order to exercise tree */ /* TODO: add elements of type dict, bindata, list to the dict */ @@ -263,6 +265,7 @@ tst_getnames(void) } getdns_dict_destroy(dict); + getdns_list_destroy(list); tstmsg_case_end(); } /* tst_getnames */ @@ -452,6 +455,7 @@ tst_copy(void) getdns_dict_copy(NULL, NULL); dict1 = getdns_dict_create(); getdns_dict_copy(dict1, &dict2); + getdns_dict_destroy(dict2); getdns_dict_copy(NULL, &dict1); tstmsg_case_msg("dict1 populate"); diff --git a/src/util-internal.c b/src/util-internal.c index ef28fd73..08e862c8 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -396,7 +396,7 @@ static char* get_canonical_name(const char* name) { return NULL; } char* result = convert_rdf_to_str(rdf); - ldns_rdf_free(rdf); + ldns_rdf_deep_free(rdf); return result; } @@ -406,7 +406,7 @@ getdns_dict *create_getdns_response(struct getdns_dns_req* completed_request) { getdns_list* just_addrs = NULL; getdns_list* replies_tree = getdns_list_create(); getdns_network_req *netreq = completed_request->first_req; - + char* canonical_name = NULL; int r = 0; @@ -416,7 +416,9 @@ getdns_dict *create_getdns_response(struct getdns_dns_req* completed_request) { } r |= getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS, GETDNS_RESPSTATUS_GOOD); - r |= getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM, get_canonical_name(completed_request->name)); + canonical_name = get_canonical_name(completed_request->name); + r |= getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM, canonical_name); + free(canonical_name); r |= getdns_dict_set_int(result, GETDNS_STR_KEY_ANSWER_TYPE, GETDNS_NAMETYPE_DNS); while (netreq) { From 3da70546caca8bd2c645348287e98117611d8821 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 12:57:46 -0500 Subject: [PATCH 03/10] Fix synchronous example to destroy the extensions dict --- src/example/example_synchronous.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/example/example_synchronous.c b/src/example/example_synchronous.c index bf845255..a08ef79a 100644 --- a/src/example/example_synchronous.c +++ b/src/example/example_synchronous.c @@ -70,6 +70,8 @@ main() /* Make the call */ getdns_return_t dns_request_return = getdns_general_sync(this_context, this_name, this_request_type, this_extensions, &this_response_length, &this_response); + /* free the extensions */ + getdns_dict_destroy(this_extensions); if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); From bd7740fefa3cb408e95e3188d9d3aade16dea888 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 4 Nov 2013 10:33:27 -0800 Subject: [PATCH 04/10] Let tests_stub_sync print reply dict pretty --- src/test/tests_stub_sync.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/tests_stub_sync.c b/src/test/tests_stub_sync.c index fec2aa5b..48359251 100644 --- a/src/test/tests_stub_sync.c +++ b/src/test/tests_stub_sync.c @@ -33,13 +33,10 @@ #include static void print_response(getdns_dict* response) { - getdns_bindata* bindata = NULL; - getdns_dict_get_bindata(response, "pkt", &bindata); - if (bindata) { - char* data = (char*) bindata->data; - data[bindata->size] = 0; - memcpy(data, bindata->data, bindata->size); - fprintf(stdout, "The packet %s\n", data); + char *dict_str = getdns_pretty_print_dict(response); + if (dict_str) { + fprintf(stdout, "The packet %s\n", dict_str); + free(dict_str); } } From 30d1e11a14e18ac1d42e75825f655febec28cd41 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 4 Nov 2013 10:34:14 -0800 Subject: [PATCH 05/10] Fix some easy to find memory leaks... --- src/context.c | 2 +- src/util-internal.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/context.c b/src/context.c index a1a04ba8..6eccf4c7 100644 --- a/src/context.c +++ b/src/context.c @@ -159,7 +159,7 @@ static getdns_return_t set_os_defaults(getdns_context_t context) { context->suffix = create_from_ldns_list(rdf_list, rdf_list_sz); } /** cleanup **/ - ldns_resolver_free(lr); + ldns_resolver_deep_free(lr); return GETDNS_RETURN_GOOD; } diff --git a/src/util-internal.c b/src/util-internal.c index ef28fd73..7f45892a 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -396,7 +396,7 @@ static char* get_canonical_name(const char* name) { return NULL; } char* result = convert_rdf_to_str(rdf); - ldns_rdf_free(rdf); + ldns_rdf_deep_free(rdf); return result; } @@ -406,6 +406,7 @@ getdns_dict *create_getdns_response(struct getdns_dns_req* completed_request) { getdns_list* just_addrs = NULL; getdns_list* replies_tree = getdns_list_create(); getdns_network_req *netreq = completed_request->first_req; + char *canonical_nm; int r = 0; @@ -416,7 +417,10 @@ getdns_dict *create_getdns_response(struct getdns_dns_req* completed_request) { } r |= getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS, GETDNS_RESPSTATUS_GOOD); - r |= getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM, get_canonical_name(completed_request->name)); + canonical_nm = get_canonical_name(completed_request->name); + r |= getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM, canonical_nm); + + free(canonical_nm); r |= getdns_dict_set_int(result, GETDNS_STR_KEY_ANSWER_TYPE, GETDNS_NAMETYPE_DNS); while (netreq) { From bf57b1e5b97c32f5ad9a4d0345f1f64e6efa03cb Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 13:44:09 -0500 Subject: [PATCH 06/10] Update test messages per efence --- src/test/testmessages.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/testmessages.c b/src/test/testmessages.c index b7377ddb..820884ad 100644 --- a/src/test/testmessages.c +++ b/src/test/testmessages.c @@ -70,7 +70,11 @@ tstmsg_case_end(void) printf("TESTCASE %s:%s END\n", testprog, cases[ncases-1]); ncases--; free(cases[ncases]); - cases = (char **) realloc(cases, sizeof(char *) * ncases); + if (ncases) { + cases = (char **) realloc(cases, sizeof(char *) * ncases); + } else { + cases = NULL; + } } } /* tstmsg_case_end */ From 31e7bf1a8a3cd0cc81b83b68ba0869eed9840272 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 14:43:06 -0500 Subject: [PATCH 07/10] Some guards and make example_all_functions at least run --- src/dict.c | 4 ++++ src/example/example_all_functions.c | 17 +++++++---------- src/general.c | 4 ++++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/dict.c b/src/dict.c index 2d78e5f8..6d7a89ea 100644 --- a/src/dict.c +++ b/src/dict.c @@ -660,6 +660,10 @@ getdns_pretty_print_dict(struct getdns_dict *dict) ldns_buffer *buf; char *ret; + if (!dict) { + return NULL; + } + buf = ldns_buffer_new(100); if (! buf) return NULL; diff --git a/src/example/example_all_functions.c b/src/example/example_all_functions.c index eb81736c..24367269 100644 --- a/src/example/example_all_functions.c +++ b/src/example/example_all_functions.c @@ -89,10 +89,6 @@ retregular = getdns_context_create( boolarg ); -getdns_context_destroy( - contextarg -); - retregular = getdns_cancel_callback( contextarg, txidarg @@ -150,18 +146,19 @@ retregular = getdns_dict_get_bindata(dictarg, charstararg, bindataptrarg); retregular = getdns_dict_get_int(dictarg, charstararg, uint32ptrarg); listarg = getdns_list_create(); -getdns_list_destroy(listarg); retregular = getdns_list_set_dict(listarg, sizetarg, dictarg); retregular = getdns_list_set_list(listarg, sizetarg, listarg); retregular = getdns_list_set_bindata(listarg, sizetarg, bindataarg); retregular = getdns_list_set_int(listarg, sizetarg, uint32arg); dictarg = getdns_dict_create(); -getdns_dict_destroy(dictarg); retregular = getdns_dict_set_dict(dictarg, charstararg, dictarg); retregular = getdns_dict_set_list(dictarg, charstararg, listarg); retregular = getdns_dict_set_bindata(dictarg, charstararg, bindataarg); retregular = getdns_dict_set_int(dictarg, charstararg, uint32arg); +retcharstar = getdns_pretty_print_dict( + dictarg +); retcharstar = getdns_convert_fqdn_to_dns_name( charstararg @@ -185,10 +182,6 @@ retregular = getdns_validate_dnssec( listarg ); -retcharstar = getdns_pretty_print_dict( - dictarg -); - retcharstar = getdns_display_ip_address( bindataarg ); @@ -294,4 +287,8 @@ retregular = getdns_context_set_memory_reallocator( deallocfunctionarg ); +getdns_list_destroy(listarg); +getdns_dict_destroy(dictarg); +getdns_context_destroy(contextarg); + return(0); } /* End of main() */ diff --git a/src/general.c b/src/general.c index 2e59af63..13c8c294 100644 --- a/src/general.c +++ b/src/general.c @@ -201,6 +201,10 @@ getdns_general_ub(struct ub_ctx* unbound, getdns_return_t gr; int r; + if (!name) { + return GETDNS_RETURN_GENERIC_ERROR; + } + gr = getdns_context_prepare_for_resolution(context); if (gr != GETDNS_RETURN_GOOD) { return GETDNS_RETURN_BAD_CONTEXT; From 6f825addd4577e78fe27e2db0b00f4c5b218484e Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 14:59:42 -0500 Subject: [PATCH 08/10] Update README to reflect unbound revision change --- README.md | 10 ++-- unbound.2985.patch | 118 --------------------------------------------- 2 files changed, 5 insertions(+), 123 deletions(-) delete mode 100644 unbound.2985.patch diff --git a/README.md b/README.md index 228bf5fe..1f864b5e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ getdns API {#mainpage} ========== * Date: 2013-11-03 -* GitHub: +* GitHub: getdns is a [modern asynchronous DNS API](http://www.vpnc.org/getdns-api/) intended to make all types of DNS information easily available as described by Paul Hoffman. This implementation is licensed under the New BSD License (BSD-new). @@ -23,19 +23,19 @@ The goals of this implementation of the getdns API are: ** the master branch is always in a production ready state ** the develop branch contains the latest development changes which are merged from develop into master once they are considered production ready * Both synchronous and asynchronous entry points with an early focus on the asynchronous model - + Non-goals (things we will not be doing) include: * implementation of the traditional DNS related routines (gethostbyname, etc.) Releases ======== -Release numbering follows the [Semantic Versioning](http://semver.org/) approach. We are currently in the early stages of building the API so the code should be considered incomplete. +Release numbering follows the [Semantic Versioning](http://semver.org/) approach. We are currently in the early stages of building the API so the code should be considered incomplete. The 0.1.0 release will be issued when the repository is opened to the public, our goal is to meet the following requirements prior to opening the repository: * code compiles cleanly on at least the primary target platforms: RHEL/CentOS 6.3 Linux, FreeBSD 9.2 * examples must compile and be clean -* clearly document supported/unsupported elements of the API +* clearly document supported/unsupported elements of the API Tickets/Bug Reports =================== @@ -50,7 +50,7 @@ External dependencies are linked outside the getdns API build tree (we rely on c * [libevent](http://libevent.org) version 2.0.21 stable * [libldns from NL](https://www.nlnetlabs.nl/projects/ldns/) version 1.6.16 (ldns may require openssl headers and libraries) -* [libunbound from NL](http://www.nlnetlabs.nl/projects/unbound/) svn revision 2985, configure must be run with the --with-libevent option (recommended to also use --with-libunbound-only). The unbound.2985.patch included with getdns must be applied to the source tree prior to building libunbound. +* [libunbound from NL](http://www.nlnetlabs.nl/projects/unbound/) svn revision 3012, configure must be run with the --with-libevent option (recommended to also use --with-libunbound-only). * Doxygen is used to generate documentation, while this is not technically necessary for the build it makes things a lot more pleasant. Assuming that the getdns sources are in a diretory named getdns in your home directory, to build libunbound (note that the svn checkout may take a while): diff --git a/unbound.2985.patch b/unbound.2985.patch deleted file mode 100644 index ed3875c1..00000000 --- a/unbound.2985.patch +++ /dev/null @@ -1,118 +0,0 @@ -Index: Makefile.in -=================================================================== ---- Makefile.in (revision 2985) -+++ Makefile.in (working copy) -@@ -280,7 +280,7 @@ - longtest: tests - if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi - --lib: libunbound.la unbound.h -+lib: libunbound.la unbound.h unbound-event.h - - libunbound.la: $(LIBUNBOUND_OBJ_LINK) - $(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) -lssl $(LIBS) -@@ -348,6 +348,9 @@ - unbound.h: $(srcdir)/libunbound/unbound.h - sed -e 's/@''UNBOUND_VERSION_MAJOR@/$(UNBOUND_VERSION_MAJOR)/' -e 's/@''UNBOUND_VERSION_MINOR@/$(UNBOUND_VERSION_MINOR)/' -e 's/@''UNBOUND_VERSION_MICRO@/$(UNBOUND_VERSION_MICRO)/' < $(srcdir)/libunbound/unbound.h > $@ - -+unbound-event.h: $(srcdir)/libunbound/unbound-event.h -+ sed -e 's/@''UNBOUND_VERSION_MAJOR@/$(UNBOUND_VERSION_MAJOR)/' -e 's/@''UNBOUND_VERSION_MINOR@/$(UNBOUND_VERSION_MINOR)/' -e 's/@''UNBOUND_VERSION_MICRO@/$(UNBOUND_VERSION_MICRO)/' < $(srcdir)/libunbound/unbound-event.h > $@ -+ - unbound-control-setup: $(srcdir)/smallapp/unbound-control-setup.sh - sed -e 's:^DESTDIR=.*$$:DESTDIR=$(UNBOUND_RUN_DIR):' < $(srcdir)/smallapp/unbound-control-setup.sh > $@ - -chmod +x $@ -@@ -496,6 +499,7 @@ - $(INSTALL) -c -m 755 unbound-control-setup $(DESTDIR)$(sbindir)/unbound-control-setup - if test ! -e $(DESTDIR)$(configfile); then $(INSTALL) -d `dirname $(DESTDIR)$(configfile)`; $(INSTALL) -c -m 644 doc/example.conf $(DESTDIR)$(configfile); fi - $(LIBTOOL) --mode=install cp unbound.h $(DESTDIR)$(includedir)/unbound.h -+ $(LIBTOOL) --mode=install cp unbound-event.h $(DESTDIR)$(includedir)/unbound-event.h - $(LIBTOOL) --mode=install cp libunbound.la $(DESTDIR)$(libdir) - $(LIBTOOL) --mode=finish $(DESTDIR)$(libdir) - -Index: libunbound/ubsyms.def -=================================================================== ---- libunbound/ubsyms.def (revision 2985) -+++ libunbound/ubsyms.def (working copy) -@@ -29,3 +29,4 @@ - ub_ctx_data_add - ub_ctx_data_remove - ub_version -+ub_ctx_set_event -Index: libunbound/unbound-event.h -=================================================================== ---- libunbound/unbound-event.h (revision 2985) -+++ libunbound/unbound-event.h (working copy) -@@ -63,9 +63,9 @@ - struct ub_ctx; - struct ub_result; - struct event_base; --struct ldns_buffer; -+struct ldns_struct_buffer; - --typedef void (*ub_event_callback_t)(void*, int, struct ldns_buffer*, int, char*); -+typedef void (*ub_event_callback_t)(void*, int, struct ldns_struct_buffer*, int, char*); - - /** - * Create a resolving and validation context. -@@ -82,6 +82,15 @@ - struct ub_ctx* ub_ctx_create_event(struct event_base* base); - - /** -+ * Set a new event_base on a context created with ub_ctx_create_event. -+ * Any outbound queries will be canceled. -+ * @param ctx the ub_ctx to update. Must have been created with ub_ctx_create_event -+ * @param base the new event_base to attach to the ctx -+ * @return 0 if OK, else error -+ */ -+int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base); -+ -+/** - * Perform resolution and validation of the target name. - * Asynchronous, after a while, the callback will be called with your - * data and the result. Uses the event_base user installed by creating the -Index: libunbound/libunbound.c -=================================================================== ---- libunbound/libunbound.c (revision 2985) -+++ libunbound/libunbound.c (working copy) -@@ -656,15 +656,14 @@ - return r; - } - } -+ lock_basic_unlock(&ctx->cfglock); - if(!ctx->event_worker) { - ctx->event_worker = libworker_create_event(ctx, - ctx->event_base); - if(!ctx->event_worker) { -- lock_basic_unlock(&ctx->cfglock); - return UB_INITFAIL; - } - } -- lock_basic_unlock(&ctx->cfglock); - - /* create new ctx_query and attempt to add to the list */ - q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback, -@@ -1212,3 +1211,24 @@ - { - return PACKAGE_VERSION; - } -+ -+int -+ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) { -+ if (!ctx || !ctx->event_base || !base) { -+ return UB_INITFAIL; -+ } -+ if (ctx->event_base == base) { -+ /* already set */ -+ return UB_NOERROR; -+ } -+ -+ lock_basic_lock(&ctx->cfglock); -+ /* destroy the current worker - safe to pass in NULL */ -+ libworker_delete_event(ctx->event_worker); -+ ctx->event_worker = NULL; -+ ctx->event_base = base; -+ ctx->created_bg = 0; -+ ctx->dothread = 1; -+ lock_basic_unlock(&ctx->cfglock); -+ return UB_NOERROR; -+} From 0c137a876668a7da45c2f508e11f4b9cbcefd04f Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 15:11:40 -0500 Subject: [PATCH 09/10] Update readme unbound build instructions --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 1f864b5e..a6474cfd 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,8 @@ Assuming that the getdns sources are in a diretory named getdns in your home dir ``` # mkdir unbound # cd unbound -# svn checkout -r 2985 http://unbound.nlnetlabs.nl/svn +# svn checkout -r 3012 http://unbound.nlnetlabs.nl/svn # cd svn/trunk -# patch -p0 < ~/getdns/unbound.2985.patch # ./configure --with-libevent --with-libunbound-only # make # make install From 266cdb0063cfae923199b8af6260eb490a24cb65 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Mon, 4 Nov 2013 15:26:52 -0500 Subject: [PATCH 10/10] Cleanup some memory issues in simple answers --- src/example/example_simple_answers.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/example/example_simple_answers.c b/src/example/example_simple_answers.c index 36078fce..8b2bacec 100644 --- a/src/example/example_simple_answers.c +++ b/src/example/example_simple_answers.c @@ -69,14 +69,20 @@ void this_callbackfn(struct getdns_context_t *this_context, for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count ) { struct getdns_bindata * this_address_data; + char* ipAddr = NULL; this_ret = getdns_list_get_bindata(just_the_addresses_ptr, rec_count, &this_address_data); // Ignore any error - printf("The address is %s\n", getdns_display_ip_address(this_address_data)); + ipAddr = getdns_display_ip_address(this_address_data); + printf("The address is %s\n", ipAddr); + free(ipAddr); } } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.", this_transaction_id); else fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + + /* clean up */ + getdns_dict_destroy(this_response); } int @@ -121,6 +127,7 @@ main() } /* Clean up */ getdns_context_destroy(this_context); + event_base_free(this_event_base); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } /* main */