Merge json pointer branch from spec repo

(including examples)
This commit is contained in:
Willem Toorop 2015-10-07 13:15:07 +02:00
parent 5e269b69fa
commit 3373ed5056
13 changed files with 705 additions and 1437 deletions

View File

@ -48,9 +48,9 @@ LDFLAGS=@LDFLAGS@ -L../../src
LDLIBS=../../src/libgetdns.la @LIBS@
OBJS=example-all-functions.lo example-simple-answers.lo example-tree.lo example-synchronous.lo example-reverse.lo synchronous-json-pointer.lo simple-json-pointer.lo tree-json-pointer.lo reverse-json-pointer.lo
OBJS=example-all-functions.lo example-simple-answers.lo example-tree.lo example-synchronous.lo example-reverse.lo
PROGRAMS=example-all-functions example-synchronous example-simple-answers example-tree example-reverse synchronous-json-pointer simple-json-pointer tree-json-pointer reverse-json-pointer
PROGRAMS=example-all-functions example-synchronous example-simple-answers example-tree example-reverse
.SUFFIXES: .c .o .a .lo .h
@ -74,18 +74,6 @@ example-all-functions: example-all-functions.lo
example-synchronous: example-synchronous.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ example-synchronous.lo
synchronous-json-pointer: synchronous-json-pointer.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ synchronous-json-pointer.lo
simple-json-pointer: simple-json-pointer.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBEVENT_LDFLAGS) $(EXTENSION_LIBEVENT_EXT_LIBS) -o $@ simple-json-pointer.lo
tree-json-pointer: tree-json-pointer.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBEVENT_LDFLAGS) $(EXTENSION_LIBEVENT_EXT_LIBS) -o $@ tree-json-pointer.lo
reverse-json-pointer: reverse-json-pointer.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBEVENT_LDFLAGS) $(EXTENSION_LIBEVENT_EXT_LIBS) -o $@ reverse-json-pointer.lo
$(EXTENSION_LIBEVENT_LIB):
@echo "***"
@echo "*** Three examples from the specification need libevent."
@ -172,19 +160,3 @@ example-synchronous.lo example-synchronous.o: $(srcdir)/example-synchronous.c $(
example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h ../../src/config.h \
../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \
$(srcdir)/../../src/getdns/getdns_extra.h
reverse-json-pointer.lo reverse-json-pointer.o: $(srcdir)/reverse-json-pointer.c $(srcdir)/getdns_libevent.h \
../../src/config.h ../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h $(srcdir)/../../src/getdns/getdns_extra.h
simple-concise.lo simple-concise.o: $(srcdir)/simple-concise.c $(srcdir)/getdns_libevent.h ../../src/config.h \
../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \
$(srcdir)/../../src/getdns/getdns_extra.h
simple-json-pointer.lo simple-json-pointer.o: $(srcdir)/simple-json-pointer.c $(srcdir)/getdns_libevent.h \
../../src/config.h ../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h $(srcdir)/../../src/getdns/getdns_extra.h
synchronous-concise.lo synchronous-concise.o: $(srcdir)/synchronous-concise.c $(srcdir)/getdns_core_only.h \
../../src/getdns/getdns.h
synchronous-json-pointer.lo synchronous-json-pointer.o: $(srcdir)/synchronous-json-pointer.c $(srcdir)/getdns_core_only.h \
../../src/getdns/getdns.h
tree-json-pointer.lo tree-json-pointer.o: $(srcdir)/tree-json-pointer.c $(srcdir)/getdns_libevent.h \
../../src/config.h ../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h $(srcdir)/../../src/getdns/getdns_extra.h

View File

@ -1,135 +1,112 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
#define UNUSED_PARAM(x) ((void)(x))
/* Set up the callback function, which will also do the processing of the results */
void this_callbackfn(getdns_context *this_context,
getdns_callback_type_t this_callback_type,
getdns_dict *this_response,
void *this_userarg,
getdns_transaction_t this_transaction_id)
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
getdns_return_t this_ret; /* Holder for all function returns */
UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */
UNUSED_PARAM(this_context); /* Not looking at the context for this example */
UNUSED_PARAM(this_ret); /* Set, but not read */
if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */
{
/* Be sure the search returned something */
uint32_t this_error;
this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error
if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good"
{
fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error);
getdns_dict_destroy(this_response);
return;
}
getdns_list *replies_tree;
this_ret = getdns_dict_get_list(this_response, "replies_tree", &replies_tree); // Ignore any error
size_t num_replies;
this_ret = getdns_list_get_length(replies_tree, &num_replies); // Ignore any error
/* Go through each reply */
for ( size_t reply_count = 0; reply_count < num_replies; ++reply_count)
{
getdns_dict * this_reply;
this_ret = getdns_list_get_dict(replies_tree, reply_count, &this_reply); // Ignore any error
/* Just print the address */
getdns_list* reply_answers;
this_ret = getdns_dict_get_list(this_reply, "answer", &reply_answers); // Ignore any error
size_t num_answers;
this_ret = getdns_list_get_length(reply_answers, &num_answers); // Ignore any error
/* Go through each answer */
for ( size_t answer_count = 0; answer_count < num_answers; ++answer_count)
{
getdns_dict * this_rr;
this_ret = getdns_list_get_dict(reply_answers, answer_count, &this_rr);
/* Get the RDATA type */
uint32_t this_type;
this_ret = getdns_dict_get_int(this_rr, "type", &this_type); // Ignore any error
if (this_type == GETDNS_RRTYPE_PTR)
{
getdns_dict *this_rdata;
this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error
getdns_return_t r; /* Holder for all function returns */
getdns_list *answer;
size_t n_answers, i;
getdns_bindata * this_dname;
this_ret = getdns_dict_get_bindata(this_rdata, "rdata_raw", &this_dname);
char *this_dname_str;
this_ret = getdns_convert_dns_name_to_fqdn(this_dname, &this_dname_str); // Ignore any error
printf("The dname is %s\n", this_dname_str);
free(this_dname_str);
}
}
(void) context; (void) userarg; /* unused parameters */
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_list(response, "/replies_tree/0/answer", &answer)))
fprintf(stderr, "Could not get \"answer\" section from first reply in the reponse");
else if ((r = getdns_list_get_length(answer, &n_answers)))
fprintf(stderr, "Could not get replies_tree\'s length");
else for (i = 0; i < n_answers && r == GETDNS_RETURN_GOOD; i++) {
getdns_dict *rr;
getdns_bindata *dname;
char *dname_str;
if ((r = getdns_list_get_dict(answer, i, &rr)))
fprintf(stderr, "Could not get rr %zu from answer section", i);
else if (getdns_dict_get_bindata(rr, "/rdata/ptrdname", &dname))
continue; /* Not a PTR */
else if ((r = getdns_convert_dns_name_to_fqdn(dname, &dname_str)))
fprintf(stderr, "Could not convert PTR dname to string");
else {
printf("The dname is %s\n", dname_str);
free(dname_str);
}
}
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);
getdns_dict_destroy(this_response);
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
/* Create the DNS context for this call */
getdns_context *this_context = NULL;
getdns_return_t context_create_return = getdns_context_create(&this_context, 1);
if (context_create_return != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Trying to create the context failed: %d", context_create_return);
return(GETDNS_RETURN_GENERIC_ERROR);
}
/* Create an event base and put it in the context using the unknown function name */
struct event_base *this_event_base;
this_event_base = event_base_new();
if (this_event_base == NULL)
{
fprintf(stderr, "Trying to create the event base failed.");
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
(void)getdns_extension_set_libevent_base(this_context, this_event_base);
/* Set up the getdns call */
getdns_dict * this_addr_to_look_up = getdns_dict_create();
// TODO: check the return value above
getdns_bindata this_type = { 4, (void *)"IPv4" };
getdns_return_t this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_type", &this_type);
UNUSED_PARAM(this_ret);
getdns_bindata this_ipv4_addr = { 4, (void *)"\x08\x08\x08\x08" };
this_ret = getdns_dict_set_bindata(this_addr_to_look_up, "address_data", &this_ipv4_addr);
char* this_userarg = "somestring"; // Could add things here to help identify this call
getdns_transaction_t this_transaction_id = 0;
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_bindata address_type = { 4, (void *)"IPv4" };
getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
getdns_dict *address = NULL;
getdns_dict *extensions = NULL;
/* Could add things here to help identify this call */
char *userarg = NULL;
getdns_transaction_t transaction_id;
/* Make the call */
getdns_return_t dns_request_return = getdns_hostname(this_context, this_addr_to_look_up,
NULL, this_userarg, &this_transaction_id, this_callbackfn);
if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
{
char *ip_address_str = getdns_display_ip_address(&this_ipv4_addr);
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if (!(address = getdns_dict_create()))
fprintf(stderr, "Could not create address dict.\n");
else if ((r = getdns_dict_set_bindata(address, "address_type", &address_type)))
fprintf(stderr, "Could not set address_type in address dict.\n");
else if ((r = getdns_dict_set_bindata(address, "address_data", &address_data)))
fprintf(stderr, "Could not set address_data in address dict.\n");
else if ((r = getdns_hostname( context, address, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
fprintf(stderr, "A bad IP address was used: %s. Exiting.\n", ip_address_str);
free(ip_address_str);
getdns_dict_destroy(this_addr_to_look_up);
event_base_free(this_event_base);
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
else
{
/* Call the event loop */
int dispatch_return = event_base_dispatch(this_event_base);
UNUSED_PARAM(dispatch_return);
// TODO: check the return value above
}
/* Clean up */
getdns_dict_destroy(this_addr_to_look_up);
event_base_free(this_event_base);
getdns_context_destroy(this_context);
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,108 +1,109 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
#define UNUSED_PARAM(x) ((void)(x))
/* Set up the callback function, which will also do the processing of the results */
void this_callbackfn(getdns_context *this_context,
getdns_callback_type_t this_callback_type,
getdns_dict *this_response,
void *this_userarg,
getdns_transaction_t this_transaction_id)
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */
UNUSED_PARAM(this_context); /* Not looking at the context for this example */
getdns_return_t this_ret; /* Holder for all function returns */
if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */
{
/* Be sure the search returned something */
uint32_t this_error;
this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error
if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good"
{
fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error);
getdns_dict_destroy(this_response);
return;
}
getdns_list * just_the_addresses_ptr;
this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr);
if (this_ret != GETDNS_RETURN_GOOD) // This check is really not needed, but prevents a compiler error under "pedantic"
{
fprintf(stderr, "Trying to get the answers failed: %d\n", this_ret);
getdns_dict_destroy(this_response);
return;
}
size_t num_addresses;
this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses); // Ignore any error
/* Go through each record */
for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count )
{
getdns_dict * this_address;
this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error
/* Just print the address */
getdns_bindata * this_address_data;
this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error
char *this_address_str = getdns_display_ip_address(this_address_data);
printf("The address is %s\n", this_address_str);
free(this_address_str);
}
getdns_return_t r; /* Holder for all function returns */
uint32_t status;
getdns_bindata *address_data;
char *first = NULL, *second = NULL;
(void) context; /* unused parameter */
printf( "Callback for query \"%s\" with request ID %"PRIu64".\n"
, (char *)userarg, transaction_id );
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.\n", this_transaction_id);
else
fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type);
getdns_dict_destroy(this_response);
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_int(response, "status", &status)))
fprintf(stderr, "Could not get \"status\" from reponse");
else if (status != GETDNS_RESPSTATUS_GOOD)
fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status);
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data)))
fprintf(stderr, "Could not get first address");
else if (!(first = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert first address to string\n");
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data)))
fprintf(stderr, "Could not get second address");
else if (!(second = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert second address to string\n");
if (first) {
printf("The address is %s\n", first);
free(first);
}
if (second) {
printf("The address is %s\n", second);
free(second);
}
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
/* Create the DNS context for this call */
getdns_context *this_context = NULL;
getdns_return_t context_create_return = getdns_context_create(&this_context, 1);
if (context_create_return != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Trying to create the context failed: %d", context_create_return);
return(GETDNS_RETURN_GENERIC_ERROR);
}
/* Create an event base and put it in the context using the unknown function name */
struct event_base *this_event_base;
this_event_base = event_base_new();
if (this_event_base == NULL)
{
fprintf(stderr, "Trying to create the event base failed.\n");
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
(void)getdns_extension_set_libevent_base(this_context, this_event_base);
/* Set up the getdns call */
const char * this_name = "www.example.com";
char* this_userarg = "somestring"; // Could add things here to help identify this call
getdns_transaction_t this_transaction_id = 0;
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_dict *extensions = NULL;
char *query_name = "www.example.com";
/* Could add things here to help identify this call */
char *userarg = query_name;
getdns_transaction_t transaction_id;
/* Make the call */
getdns_return_t dns_request_return = getdns_address(this_context, this_name,
NULL, this_userarg, &this_transaction_id, this_callbackfn);
if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
{
fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name);
event_base_free(this_event_base);
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
else
{
/* Call the event loop */
int dispatch_return = event_base_dispatch(this_event_base);
UNUSED_PARAM(dispatch_return);
// TODO: check the return value above
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if ((r = getdns_address( context, query_name, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else {
printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id);
if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
}
/* Clean up */
event_base_free(this_event_base);
getdns_context_destroy(this_context);
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,81 +1,66 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <assert.h>
#include <getdns_core_only.h>
int main()
{
getdns_return_t this_ret; /* Holder for all function returns */
/* Create the DNS context for this call */
getdns_context *this_context = NULL;
getdns_return_t context_create_return = getdns_context_create(&this_context, 1);
if (context_create_return != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Trying to create the context failed: %d\n", context_create_return);
return(GETDNS_RETURN_GENERIC_ERROR);
}
/* Set up the getdns_sync_request call */
const char * this_name = "www.example.com";
uint8_t this_request_type = GETDNS_RRTYPE_A;
/* Get the A and AAAA records */
getdns_dict * this_extensions = getdns_dict_create();
this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
if (this_ret != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed: %d\n", this_ret);
getdns_dict_destroy(this_extensions);
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
getdns_dict * this_response = NULL;
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
getdns_dict *response = NULL;
getdns_dict *extensions = NULL;
getdns_bindata *address_data;
char *first = NULL, *second = NULL;
/* Make the call */
getdns_return_t dns_request_return = getdns_general_sync(this_context, this_name, this_request_type,
this_extensions, &this_response);
if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
{
fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name);
getdns_dict_destroy(this_response);
getdns_dict_destroy(this_extensions);
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
/* Create the DNS context for this call */
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(extensions = getdns_dict_create()))
fprintf(stderr, "Could not create extensions dict.\n");
else if ((r = getdns_dict_set_int(extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE)))
fprintf(stderr, "Trying to set an extension do both IPv4 and IPv6 failed");
else if ((r = getdns_general_sync(context, "example.com", GETDNS_RRTYPE_A, extensions, &response)))
fprintf(stderr, "Error scheduling synchronous request");
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data)))
fprintf(stderr, "Could not get first address");
else if (!(first = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert first address to string\n");
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data)))
fprintf(stderr, "Could not get second address");
else if (!(second = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert second address to string\n");
if (first) {
printf("The address is %s\n", first);
free(first);
}
else
{
/* Be sure the search returned something */
uint32_t this_error;
this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error
if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good"
{
fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error);
getdns_dict_destroy(this_response);
getdns_dict_destroy(this_extensions);
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
getdns_list * just_the_addresses_ptr;
this_ret = getdns_dict_get_list(this_response, "just_address_answers", &just_the_addresses_ptr); // Ignore any error
size_t num_addresses;
this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses); // Ignore any error
/* Go through each record */
for ( size_t rec_count = 0; rec_count < num_addresses; ++rec_count )
{
getdns_dict * this_address;
this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error
/* Just print the address */
getdns_bindata * this_address_data;
this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error
char *this_address_str = getdns_display_ip_address(this_address_data);
printf("The address is %s\n", this_address_str);
free(this_address_str);
}
if (second) {
printf("The address is %s\n", second);
free(second);
}
/* Clean up */
getdns_dict_destroy(this_response);
getdns_dict_destroy(this_extensions);
getdns_context_destroy(this_context);
if (response)
getdns_dict_destroy(response);
if (extensions)
getdns_dict_destroy(extensions);
if (context)
getdns_context_destroy(context);
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
exit(EXIT_FAILURE);
}
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,151 +1,121 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
#define UNUSED_PARAM(x) ((void)(x))
/* Set up the callback function, which will also do the processing of the results */
void this_callbackfn(getdns_context *this_context,
getdns_callback_type_t this_callback_type,
getdns_dict *this_response,
void *this_userarg,
getdns_transaction_t this_transaction_id)
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
UNUSED_PARAM(this_userarg); /* Not looking at the userarg for this example */
UNUSED_PARAM(this_context); /* Not looking at the context for this example */
getdns_return_t this_ret; /* Holder for all function returns */
if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */
{
/* Be sure the search returned something */
uint32_t this_error;
this_ret = getdns_dict_get_int(this_response, "status", &this_error); // Ignore any error
if (this_error != GETDNS_RESPSTATUS_GOOD) // If the search didn't return "good"
{
fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error);
getdns_dict_destroy(this_response);
return;
}
/* Find all the answers returned */
getdns_list * these_answers;
this_ret = getdns_dict_get_list(this_response, "replies_tree", &these_answers);
if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME)
{
fprintf(stderr, "Weird: the response had no error, but also no replies_tree. Exiting.\n");
getdns_dict_destroy(this_response);
return;
}
size_t num_answers;
this_ret = getdns_list_get_length(these_answers, &num_answers);
/* Go through each answer */
for ( size_t rec_count = 0; rec_count < num_answers; ++rec_count )
{
getdns_dict * this_record;
this_ret = getdns_list_get_dict(these_answers, rec_count, &this_record); // Ignore any error
/* Get the answer section */
getdns_list * this_answer;
this_ret = getdns_dict_get_list(this_record, "answer", &this_answer); // Ignore any error
/* Get each RR in the answer section */
size_t num_rrs;
this_ret = getdns_list_get_length(this_answer, &num_rrs);
for ( size_t rr_count = 0; rr_count < num_rrs; ++rr_count )
{
getdns_dict *this_rr = NULL;
this_ret = getdns_list_get_dict(this_answer, rr_count, &this_rr); // Ignore any error
/* Get the RDATA */
getdns_dict * this_rdata = NULL;
this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error
/* Get the RDATA type */
uint32_t this_type;
this_ret = getdns_dict_get_int(this_rr, "type", &this_type); // Ignore any error
/* If it is type A or AAAA, print the value */
if (this_type == GETDNS_RRTYPE_A)
{
getdns_bindata * this_a_record = NULL;
this_ret = getdns_dict_get_bindata(this_rdata, "ipv4_address", &this_a_record);
if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME)
{
fprintf(stderr, "Weird: the A record at %d in record at %d had no address. Exiting.\n",
(int) rr_count, (int) rec_count);
getdns_dict_destroy(this_response);
return;
}
char *this_address_str = getdns_display_ip_address(this_a_record);
printf("The IPv4 address is %s\n", this_address_str);
free(this_address_str);
}
else if (this_type == GETDNS_RRTYPE_AAAA)
{
getdns_bindata * this_aaaa_record = NULL;
this_ret = getdns_dict_get_bindata(this_rdata, "ipv6_address", &this_aaaa_record);
if (this_ret == GETDNS_RETURN_NO_SUCH_DICT_NAME)
{
fprintf(stderr, "Weird: the AAAA record at %d in record at %d had no address. Exiting.\n",
(int) rr_count, (int) rec_count);
getdns_dict_destroy(this_response);
return;
}
char *this_address_str = getdns_display_ip_address(this_aaaa_record);
printf("The IPv6 address is %s\n", this_address_str);
free(this_address_str);
getdns_return_t r; /* Holder for all function returns */
getdns_list *replies_tree;
size_t n_replies, i;
(void) context; (void) userarg; /* unused parameters */
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree)))
fprintf(stderr, "Could not get \"replies_tree\" from reponse");
else if ((r = getdns_list_get_length(replies_tree, &n_replies)))
fprintf(stderr, "Could not get replies_tree\'s length");
else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) {
getdns_dict *reply;
getdns_list *answer;
size_t n_answers, j;
if ((r = getdns_list_get_dict(replies_tree, i, &reply)))
fprintf(stderr, "Could not get address %zu from just_address_answers", i);
else if ((r = getdns_dict_get_list(reply, "answer", &answer)))
fprintf(stderr, "Could not get \"address_data\" from address");
else if ((r = getdns_list_get_length(answer, &n_answers)))
fprintf(stderr, "Could not get answer section\'s length");
else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) {
getdns_dict *rr;
getdns_bindata *address = NULL;
if ((r = getdns_list_get_dict(answer, j, &rr)))
fprintf(stderr, "Could net get rr %zu from answer section", j);
else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD)
printf("The IPv4 address is ");
else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD)
printf("The IPv6 address is ");
if (address) {
char *address_str;
if (!(address_str = getdns_display_ip_address(address))) {
fprintf(stderr, "Could not convert second address to string");
r = GETDNS_RETURN_MEMORY_ERROR;
break;
}
printf("%s\n", address_str);
free(address_str);
}
}
}
else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
fprintf(stderr, "The callback with ID %"PRIu64" was cancelled. Exiting.\n", this_transaction_id);
else
fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type);
getdns_dict_destroy(this_response);
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
/* Create the DNS context for this call */
getdns_context *this_context = NULL;
getdns_return_t context_create_return = getdns_context_create(&this_context, 1);
if (context_create_return != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Trying to create the context failed: %d\n", context_create_return);
return(GETDNS_RETURN_GENERIC_ERROR);
}
/* Create an event base and put it in the context using the unknown function name */
struct event_base *this_event_base;
this_event_base = event_base_new();
if (this_event_base == NULL)
{
fprintf(stderr, "Trying to create the event base failed.\n");
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
(void)getdns_extension_set_libevent_base(this_context, this_event_base);
/* Set up the getdns call */
const char * this_name = "www.example.com";
char* this_userarg = "somestring"; // Could add things here to help identify this call
getdns_transaction_t this_transaction_id = 0;
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_dict *extensions = NULL;
char *query_name = "www.example.com";
/* Could add things here to help identify this call */
char *userarg = NULL;
getdns_transaction_t transaction_id;
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if ((r = getdns_address( context, query_name, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
/* Make the call */
getdns_return_t dns_request_return = getdns_address(this_context, this_name,
NULL, this_userarg, &this_transaction_id, this_callbackfn);
if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME)
{
fprintf(stderr, "A bad domain name was used: %s. Exiting.\n", this_name);
event_base_free(this_event_base);
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
else
{
/* Call the event loop */
int dispatch_return = event_base_dispatch(this_event_base);
UNUSED_PARAM(dispatch_return);
// TODO: check the return value above
}
/* Clean up */
event_base_free(this_event_base);
getdns_context_destroy(this_context);
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,110 +0,0 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
/* Set up the callback function, which will also do the processing of the results */
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
getdns_return_t r; /* Holder for all function returns */
getdns_list *answer;
size_t n_answers, i;
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_list(response, "/replies_tree/0/answer", &answer)))
fprintf(stderr, "Could not get \"answer\" section from first reply in the reponse");
else if ((r = getdns_list_get_length(answer, &n_answers)))
fprintf(stderr, "Could not get replies_tree\'s length");
else for (i = 0; i < n_answers && r == GETDNS_RETURN_GOOD; i++) {
getdns_dict *rr;
getdns_bindata *dname;
char *dname_str;
if ((r = getdns_list_get_dict(answer, i, &rr)))
fprintf(stderr, "Could not get rr %zu from answer section", i);
else if (getdns_dict_get_bindata(rr, "/rdata/ptrdname", &dname))
continue; /* Not a PTR */
else if ((r = getdns_convert_dns_name_to_fqdn(dname, &dname_str)))
fprintf(stderr, "Could not convert PTR dname to string");
else {
printf("The dname is %s\n", dname_str);
free(dname_str);
}
}
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_bindata address_type = { 4, (void *)"IPv4" };
getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
getdns_dict *address = NULL;
getdns_dict *extensions = NULL;
/* Could add things here to help identify this call */
char *userarg = NULL;
getdns_transaction_t transaction_id;
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if (!(address = getdns_dict_create()))
fprintf(stderr, "Could not create address dict.\n");
else if ((r = getdns_dict_set_bindata(address, "address_type", &address_type)))
fprintf(stderr, "Could not set address_type in address dict.\n");
else if ((r = getdns_dict_set_bindata(address, "address_data", &address_data)))
fprintf(stderr, "Could not set address_data in address dict.\n");
else if ((r = getdns_hostname( context, address, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
/* Clean up */
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,113 +0,0 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
/* Set up the callback function, which will also do the processing of the results */
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
getdns_return_t r; /* Holder for all function returns */
uint32_t status;
getdns_list *just_address_answers;
size_t length, i;
printf( "Callback for query \"%s\" with request ID %"PRIu64".\n"
, (char *)userarg, transaction_id );
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_int(response, "status", &status)))
fprintf(stderr, "Could not get \"status\" from reponse");
else if (status != GETDNS_RESPSTATUS_GOOD)
fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status);
else if ((r = getdns_dict_get_list(response, "just_address_answers", &just_address_answers)))
fprintf(stderr, "Could not get \"just_address_answers\" from reponse");
else if ((r = getdns_list_get_length(just_address_answers, &length)))
fprintf(stderr, "Could not get just_address_answers\' length");
else for (i = 0; i < length && r == GETDNS_RETURN_GOOD; i++) {
getdns_dict *address;
getdns_bindata *address_data;
char *address_str;
if ((r = getdns_list_get_dict(just_address_answers, i, &address)))
fprintf(stderr, "Could not get address %zu from just_address_answers", i);
else if ((r = getdns_dict_get_bindata(address, "address_data", &address_data)))
fprintf(stderr, "Could not get \"address_data\" from address");
else if (!(address_str = getdns_display_ip_address(address_data))) {
fprintf(stderr, "Could not convert address to string");
r = GETDNS_RETURN_MEMORY_ERROR;
}
else {
printf("The address is %s\n", address_str);
free(address_str);
}
}
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_dict *extensions = NULL;
char *query_name = "www.example.com";
/* Could add things here to help identify this call */
char *userarg = query_name;
getdns_transaction_t transaction_id;
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if ((r = getdns_address( context, query_name, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else {
printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id);
if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
}
/* Clean up */
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,107 +0,0 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
/* Set up the callback function, which will also do the processing of the results */
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
getdns_return_t r; /* Holder for all function returns */
uint32_t status;
getdns_bindata *address_data;
char *first = NULL, *second = NULL;
printf( "Callback for query \"%s\" with request ID %"PRIu64".\n"
, (char *)userarg, transaction_id );
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_int(response, "status", &status)))
fprintf(stderr, "Could not get \"status\" from reponse");
else if (status != GETDNS_RESPSTATUS_GOOD)
fprintf(stderr, "The search had no results, and a return value of %"PRIu32".\n", status);
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data)))
fprintf(stderr, "Could not get first address");
else if (!(first = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert first address to string\n");
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data)))
fprintf(stderr, "Could not get second address");
else if (!(second = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert second address to string\n");
if (first) {
printf("The address is %s\n", first);
free(first);
}
if (second) {
printf("The address is %s\n", second);
free(second);
}
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_dict *extensions = NULL;
char *query_name = "www.example.com";
/* Could add things here to help identify this call */
char *userarg = query_name;
getdns_transaction_t transaction_id;
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if ((r = getdns_address( context, query_name, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else {
printf("Request with transaction ID %"PRIu64" scheduled.\n", transaction_id);
if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
}
/* Clean up */
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,65 +0,0 @@
#include <stdio.h>
#include <getdns_core_only.h>
int main()
{
getdns_return_t r;
getdns_context *context = NULL;
getdns_dict *response = NULL;
uint32_t status;
getdns_list *just_address_answers;
size_t length, i;
/* Create the DNS context for this call */
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if ((r = getdns_address_sync(context, "example.com", NULL, &response)))
fprintf(stderr, "Error scheduling synchronous request");
else if ((r = getdns_dict_get_int(response, "status", &status)))
fprintf(stderr, "Could not get \"status\" from reponse");
else if (status != GETDNS_RESPSTATUS_GOOD)
fprintf(stderr, "The search had no results, and a return value of %zu.\n", status);
else if ((r = getdns_dict_get_list(response, "just_address_answers", &just_address_answers)))
fprintf(stderr, "Could not get \"just_address_answers\" from reponse");
else if ((r = getdns_list_get_length(just_address_answers, &length)))
fprintf(stderr, "Could not get just_address_answers\' length");
else for (i = 0; i < length && r == GETDNS_RETURN_GOOD; i++) {
getdns_dict *address;
getdns_bindata *address_data;
char *address_str;
if ((r = getdns_list_get_dict(just_address_answers, i, &address)))
fprintf(stderr, "Could not get address %zu from just_address_answers", i);
else if ((r = getdns_dict_get_bindata(address, "address_data", &address_data)))
fprintf(stderr, "Could not get \"address_data\" from address");
else if (!(address_str = getdns_display_ip_address(address_data))) {
fprintf(stderr, "Could not convert address to string");
r = GETDNS_RETURN_MEMORY_ERROR;
}
else {
printf("The address is %s\n", address_str);
free(address_str);
}
}
/* Clean up */
if (response)
getdns_dict_destroy(response);
if (context)
getdns_context_destroy(context);
if (r) {
fprintf(stderr, ": %d\n", r);
exit(EXIT_FAILURE);
}
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,56 +0,0 @@
#include <stdio.h>
#include <assert.h>
#include <getdns_core_only.h>
int main()
{
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
getdns_dict *response = NULL;
getdns_bindata *address_data;
char *first = NULL, *second = NULL;
/* Create the DNS context for this call */
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if ((r = getdns_address_sync(context, "example.com", NULL, &response)))
fprintf(stderr, "Error scheduling synchronous request");
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/0/address_data", &address_data)))
fprintf(stderr, "Could not get first address");
else if (!(first = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert first address to string\n");
else if ((r = getdns_dict_get_bindata(response, "/just_address_answers/1/address_data", &address_data)))
fprintf(stderr, "Could not get second address");
else if (!(second = getdns_display_ip_address(address_data)))
fprintf(stderr, "Could not convert second address to string\n");
if (first) {
printf("The address is %s\n", first);
free(first);
}
if (second) {
printf("The address is %s\n", second);
free(second);
}
/* Clean up */
if (response)
getdns_dict_destroy(response);
if (context)
getdns_context_destroy(context);
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
exit(EXIT_FAILURE);
}
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

View File

@ -1,119 +0,0 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <getdns_libevent.h>
/* Set up the callback function, which will also do the processing of the results */
void callback(getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id)
{
getdns_return_t r; /* Holder for all function returns */
getdns_list *replies_tree;
size_t length, i;
switch(callback_type) {
case GETDNS_CALLBACK_CANCEL:
printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id);
return;
case GETDNS_CALLBACK_TIMEOUT:
printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id);
return;
case GETDNS_CALLBACK_ERROR:
printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id);
return;
default: break;
}
assert( callback_type == GETDNS_CALLBACK_COMPLETE );
if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree)))
fprintf(stderr, "Could not get \"replies_tree\" from reponse");
else if ((r = getdns_list_get_length(replies_tree, &length)))
fprintf(stderr, "Could not get replies_tree\'s length");
else for (i = 0; i < length && r == GETDNS_RETURN_GOOD; i++) {
getdns_dict *reply;
getdns_list *answer;
size_t n_answers, j;
if ((r = getdns_list_get_dict(replies_tree, i, &reply)))
fprintf(stderr, "Could not get address %zu from just_address_answers", i);
else if ((r = getdns_dict_get_list(reply, "answer", &answer)))
fprintf(stderr, "Could not get \"address_data\" from address");
else if ((r = getdns_list_get_length(answer, &n_answers)))
fprintf(stderr, "Could not get answer section\'s length");
else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) {
getdns_dict *rr;
getdns_bindata *address = NULL;
if ((r = getdns_list_get_dict(answer, j, &rr)))
fprintf(stderr, "Could net get rr %zu from answer section", j);
else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD)
printf("The IPv4 address is ");
else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD)
printf("The IPv6 address is ");
if (address) {
char *address_str;
if (!(address_str = getdns_display_ip_address(address))) {
fprintf(stderr, "Could not convert second address to string");
r = GETDNS_RETURN_MEMORY_ERROR;
break;
}
printf("%s\n", address_str);
free(address_str);
}
}
}
if (r) {
assert( r != GETDNS_RETURN_GOOD );
fprintf(stderr, ": %d\n", r);
}
getdns_dict_destroy(response);
}
int main()
{
getdns_return_t r; /* Holder for all function returns */
getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_dict *extensions = NULL;
char *query_name = "www.example.com";
/* Could add things here to help identify this call */
char *userarg = NULL;
getdns_transaction_t transaction_id;
if ((r = getdns_context_create(&context, 1)))
fprintf(stderr, "Trying to create the context failed");
else if (!(event_base = event_base_new()))
fprintf(stderr, "Trying to create the event base failed.\n");
else if ((r = getdns_extension_set_libevent_base(context, event_base)))
fprintf(stderr, "Setting the event base failed");
else if ((r = getdns_address( context, query_name, extensions
, userarg, &transaction_id, callback)))
fprintf(stderr, "Error scheduling asynchronous request");
else if (event_base_dispatch(event_base) < 0)
fprintf(stderr, "Error dispatching events\n");
/* Clean up */
if (event_base)
event_base_free(event_base);
if (context)
getdns_context_destroy(context);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}

Binary file not shown.

View File

@ -94,7 +94,7 @@ tr.code { font-family: monospace }
<p class=title2>Originally edited by Paul Hoffman</p>
<p class=title2>Currently maintained by the <a
href="mailto:team@getdnsapi.net">getdns team</a></p>
<p class=title2>Document version: "getdns July 2015"</p>
<p class=title2>Document version: "getdns October 2015 - release candidate 1"</p>
<p>This document describes a modern asynchronous DNS API. This new API is intended to be useful to
application developers and operating system distributors as a way of making
@ -558,6 +558,8 @@ The user must not directly destroy these retrieved "child" data structures; inst
they will automatically be destroyed when the containing "parent" data structure is destroyed.
Because of this, retrieved "child" data structures cannot be used any more after the containing "parent" data structure has been destroyed.</p>
<p>When the name parameter to the <code>getdns_dict_get_</code> functions, starts with a '<code>/</code>' (<code>%x2F</code>) character, it is interpreted as a JSON Pointer as described in RFC 6901, and will then be used to dereference the nested data structures to get to the requested data type.</p>
<h2>2.1 Creating Data Structures</h2>
<p>Some of the features of the API require that you create your own data structures to be used in
@ -626,6 +628,8 @@ list. <code>getdns_dict_remove_name()</code> will return
<p>The helper setter functions store copies of the given "child" values.
It is the responsibility of the caller to dispose of the original values.</p>
<p>When the name parameter to the <code>getdns_dict_set_</code> functions, starts with a '<code>/</code>' (<code>%x2F</code>) character, it is interpreted as a JSON Pointer as described in RFC 6901, and will then be used to dereference the nested data structures to set the given value at the specified name or list index.</p>
<h1>3. <a id="Extensions">Extensions</a></h1>
<p>Extensions are dict data structures. The names in the dict are the names of the extensions.
@ -1169,6 +1173,8 @@ typedef struct getdns_list getdns_list;
<p class=descrip>Unable to allocate the memory required.</p>
<p class=define>GETDNS_RETURN_INVALID_PARAMETER</p>
<p class=descrip>A required parameter had an invalid value.</p>
<p class=define>GETDNS_RETURN_NOT_IMPLEMENTED</p>
<p class=descrip>The library did not have the requested API feature implemented.</p>
<h2>5.3 <a id="TypeList">Types of RDATA Returned in the API</a></h2>
@ -1464,111 +1470,112 @@ function.</p>
<p>This is an example of a common call to <code>getdns_address()</code>.</p>
<br><div class="highlight"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;stdint.h&gt;</span>
<span class="cp">#include &lt;stdlib.h&gt;</span>
<span class="cp">#include &lt;string.h&gt;</span>
<br><div class="highlight"><pre><span class="cp">#include &lt;assert.h&gt;</span>
<span class="cp">#include &lt;inttypes.h&gt;</span>
<span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;getdns_libevent.h&gt;</span>
<span class="cp">#define UNUSED_PARAM(x) ((void)(x))</span>
<span class="cm">/* Set up the callback function, which will also do the processing of the results */</span>
<span class="kt">void</span> <span class="nf">this_callbackfn</span><span class="p">(</span><span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span><span class="p">,</span>
<span class="kt">getdns_callback_type_t</span> <span class="n">this_callback_type</span><span class="p">,</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">this_response</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">this_userarg</span><span class="p">,</span>
<span class="kt">getdns_transaction_t</span> <span class="n">this_transaction_id</span><span class="p">)</span>
<span class="kt">void</span> <span class="nf">callback</span><span class="p">(</span><span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span><span class="p">,</span>
<span class="kt">getdns_callback_type_t</span> <span class="n">callback_type</span><span class="p">,</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">response</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">userarg</span><span class="p">,</span>
<span class="kt">getdns_transaction_t</span> <span class="n">transaction_id</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_userarg</span><span class="p">);</span> <span class="cm">/* Not looking at the userarg for this example */</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span> <span class="cm">/* Not looking at the context for this example */</span>
<span class="kt">getdns_return_t</span> <span class="n">this_ret</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_COMPLETE</span><span class="p">)</span> <span class="cm">/* This is a callback with data */</span>
<span class="p">{</span>
<span class="cm">/* Be sure the search returned something */</span>
<span class="kt">uint32_t</span> <span class="n">this_error</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;status&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_error</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_error</span> <span class="o">!=</span> <span class="n">GETDNS_RESPSTATUS_GOOD</span><span class="p">)</span> <span class="c1">// If the search didn&#39;t return &quot;good&quot;</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The search had no results, and a return value of %d. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_error</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">getdns_list</span> <span class="o">*</span> <span class="n">just_the_addresses_ptr</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;just_address_answers&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">just_the_addresses_ptr</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_ret</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span> <span class="c1">// This check is really not needed, but prevents a compiler error under &quot;pedantic&quot;</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to get the answers failed: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_ret</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">size_t</span> <span class="n">num_addresses</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">just_the_addresses_ptr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">num_addresses</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Go through each record */</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">rec_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">rec_count</span> <span class="o">&lt;</span> <span class="n">num_addresses</span><span class="p">;</span> <span class="o">++</span><span class="n">rec_count</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_address</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">just_the_addresses_ptr</span><span class="p">,</span> <span class="n">rec_count</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_address</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Just print the address */</span>
<span class="n">getdns_bindata</span> <span class="o">*</span> <span class="n">this_address_data</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">this_address</span><span class="p">,</span> <span class="s">&quot;address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_address_data</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">this_address_str</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">this_address_data</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_address_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">this_address_str</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="kt">uint32_t</span> <span class="n">status</span><span class="p">;</span>
<span class="n">getdns_bindata</span> <span class="o">*</span><span class="n">address_data</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">first</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">*</span><span class="n">second</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">context</span><span class="p">;</span> <span class="cm">/* unused parameter */</span>
<span class="n">printf</span><span class="p">(</span> <span class="s">&quot;Callback for query </span><span class="se">\&quot;</span><span class="s">%s</span><span class="se">\&quot;</span><span class="s"> with request ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot;.</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="p">,</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">userarg</span><span class="p">,</span> <span class="n">transaction_id</span> <span class="p">);</span>
<span class="k">switch</span><span class="p">(</span><span class="n">callback_type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_CANCEL</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Transaction with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; was cancelled.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_TIMEOUT</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Transaction with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; timed out.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_ERROR</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;An error occurred for transaction ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot;.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">default</span><span class="o">:</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">this_callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_CANCEL</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The callback with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; was cancelled. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_transaction_id</span><span class="p">);</span>
<span class="k">else</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The callback got a callback_type of %d. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_callback_type</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_COMPLETE</span> <span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;status&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">status</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get </span><span class="se">\&quot;</span><span class="s">status</span><span class="se">\&quot;</span><span class="s"> from reponse&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">status</span> <span class="o">!=</span> <span class="n">GETDNS_RESPSTATUS_GOOD</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The search had no results, and a return value of %&quot;</span><span class="n">PRIu32</span><span class="s">&quot;.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">status</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;/just_address_answers/0/address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get first address&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">first</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not convert first address to string</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;/just_address_answers/1/address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get second address&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">second</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not convert second address to string</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">first</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">first</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">second</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">second</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">second</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="p">{</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">r</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span> <span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">response</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="cm">/* Create the DNS context for this call */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">context_create_return</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">this_context</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context_create_return</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed: %d&quot;</span><span class="p">,</span> <span class="n">context_create_return</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Create an event base and put it in the context using the unknown function name */</span>
<span class="k">struct</span> <span class="n">event_base</span> <span class="o">*</span><span class="n">this_event_base</span><span class="p">;</span>
<span class="n">this_event_base</span> <span class="o">=</span> <span class="n">event_base_new</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_event_base</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the event base failed.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">getdns_extension_set_libevent_base</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_event_base</span><span class="p">);</span>
<span class="cm">/* Set up the getdns call */</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">this_name</span> <span class="o">=</span> <span class="s">&quot;www.example.com&quot;</span><span class="p">;</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">this_userarg</span> <span class="o">=</span> <span class="s">&quot;somestring&quot;</span><span class="p">;</span> <span class="c1">// Could add things here to help identify this call</span>
<span class="kt">getdns_transaction_t</span> <span class="n">this_transaction_id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">event_base</span> <span class="o">*</span><span class="n">event_base</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">extensions</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">query_name</span> <span class="o">=</span> <span class="s">&quot;www.example.com&quot;</span><span class="p">;</span>
<span class="cm">/* Could add things here to help identify this call */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">userarg</span> <span class="o">=</span> <span class="n">query_name</span><span class="p">;</span>
<span class="kt">getdns_transaction_t</span> <span class="n">transaction_id</span><span class="p">;</span>
<span class="cm">/* Make the call */</span>
<span class="kt">getdns_return_t</span> <span class="n">dns_request_return</span> <span class="o">=</span> <span class="n">getdns_address</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_name</span><span class="p">,</span>
<span class="nb">NULL</span><span class="p">,</span> <span class="n">this_userarg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_transaction_id</span><span class="p">,</span> <span class="n">this_callbackfn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dns_request_return</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_BAD_DOMAIN_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;A bad domain name was used: %s. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_name</span><span class="p">);</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="cm">/* Call the event loop */</span>
<span class="kt">int</span> <span class="n">dispatch_return</span> <span class="o">=</span> <span class="n">event_base_dispatch</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">dispatch_return</span><span class="p">);</span>
<span class="c1">// TODO: check the return value above</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">context</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">event_base</span> <span class="o">=</span> <span class="n">event_base_new</span><span class="p">()))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the event base failed.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_extension_set_libevent_base</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">event_base</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Setting the event base failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_address</span><span class="p">(</span> <span class="n">context</span><span class="p">,</span> <span class="n">query_name</span><span class="p">,</span> <span class="n">extensions</span>
<span class="p">,</span> <span class="n">userarg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">transaction_id</span><span class="p">,</span> <span class="n">callback</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error scheduling asynchronous request&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Request with transaction ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; scheduled.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">event_base_dispatch</span><span class="p">(</span><span class="n">event_base</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error dispatching events</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Clean up */</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">event_base</span><span class="p">)</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">event_base</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
<span class="cm">/* Assuming we get here, leave gracefully */</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_SUCCESS</span><span class="p">);</span>
<span class="p">}</span>
@ -1582,154 +1589,124 @@ function.</p>
the addresses, so it traverses the replies_tree. In this case, it gets both the addresses and
their TTLs.</p>
<br><div class="highlight"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;stdint.h&gt;</span>
<span class="cp">#include &lt;stdlib.h&gt;</span>
<span class="cp">#include &lt;string.h&gt;</span>
<br><div class="highlight"><pre><span class="cp">#include &lt;assert.h&gt;</span>
<span class="cp">#include &lt;inttypes.h&gt;</span>
<span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;getdns_libevent.h&gt;</span>
<span class="cp">#define UNUSED_PARAM(x) ((void)(x))</span>
<span class="cm">/* Set up the callback function, which will also do the processing of the results */</span>
<span class="kt">void</span> <span class="nf">this_callbackfn</span><span class="p">(</span><span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span><span class="p">,</span>
<span class="kt">getdns_callback_type_t</span> <span class="n">this_callback_type</span><span class="p">,</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">this_response</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">this_userarg</span><span class="p">,</span>
<span class="kt">getdns_transaction_t</span> <span class="n">this_transaction_id</span><span class="p">)</span>
<span class="kt">void</span> <span class="nf">callback</span><span class="p">(</span><span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span><span class="p">,</span>
<span class="kt">getdns_callback_type_t</span> <span class="n">callback_type</span><span class="p">,</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">response</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">userarg</span><span class="p">,</span>
<span class="kt">getdns_transaction_t</span> <span class="n">transaction_id</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_userarg</span><span class="p">);</span> <span class="cm">/* Not looking at the userarg for this example */</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span> <span class="cm">/* Not looking at the context for this example */</span>
<span class="kt">getdns_return_t</span> <span class="n">this_ret</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_COMPLETE</span><span class="p">)</span> <span class="cm">/* This is a callback with data */</span>
<span class="p">{</span>
<span class="cm">/* Be sure the search returned something */</span>
<span class="kt">uint32_t</span> <span class="n">this_error</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;status&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_error</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_error</span> <span class="o">!=</span> <span class="n">GETDNS_RESPSTATUS_GOOD</span><span class="p">)</span> <span class="c1">// If the search didn&#39;t return &quot;good&quot;</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The search had no results, and a return value of %d. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_error</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Find all the answers returned */</span>
<span class="n">getdns_list</span> <span class="o">*</span> <span class="n">these_answers</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;replies_tree&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">these_answers</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_ret</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_NO_SUCH_DICT_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Weird: the response had no error, but also no replies_tree. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">size_t</span> <span class="n">num_answers</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">these_answers</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">num_answers</span><span class="p">);</span>
<span class="cm">/* Go through each answer */</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">rec_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">rec_count</span> <span class="o">&lt;</span> <span class="n">num_answers</span><span class="p">;</span> <span class="o">++</span><span class="n">rec_count</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_record</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">these_answers</span><span class="p">,</span> <span class="n">rec_count</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_record</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Get the answer section */</span>
<span class="n">getdns_list</span> <span class="o">*</span> <span class="n">this_answer</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">this_record</span><span class="p">,</span> <span class="s">&quot;answer&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_answer</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Get each RR in the answer section */</span>
<span class="kt">size_t</span> <span class="n">num_rrs</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">this_answer</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">num_rrs</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">rr_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">rr_count</span> <span class="o">&lt;</span> <span class="n">num_rrs</span><span class="p">;</span> <span class="o">++</span><span class="n">rr_count</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">this_rr</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">this_answer</span><span class="p">,</span> <span class="n">rr_count</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_rr</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Get the RDATA */</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_rdata</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_dict</span><span class="p">(</span><span class="n">this_rr</span><span class="p">,</span> <span class="s">&quot;rdata&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_rdata</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Get the RDATA type */</span>
<span class="kt">uint32_t</span> <span class="n">this_type</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">this_rr</span><span class="p">,</span> <span class="s">&quot;type&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_type</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* If it is type A or AAAA, print the value */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_type</span> <span class="o">==</span> <span class="n">GETDNS_RRTYPE_A</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_bindata</span> <span class="o">*</span> <span class="n">this_a_record</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">this_rdata</span><span class="p">,</span> <span class="s">&quot;ipv4_address&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_a_record</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_ret</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_NO_SUCH_DICT_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Weird: the A record at %d in record at %d had no address. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">rr_count</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">rec_count</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">this_address_str</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">this_a_record</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The IPv4 address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_address_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">this_address_str</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">this_type</span> <span class="o">==</span> <span class="n">GETDNS_RRTYPE_AAAA</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_bindata</span> <span class="o">*</span> <span class="n">this_aaaa_record</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">this_rdata</span><span class="p">,</span> <span class="s">&quot;ipv6_address&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_aaaa_record</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_ret</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_NO_SUCH_DICT_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Weird: the AAAA record at %d in record at %d had no address. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">rr_count</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">rec_count</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">this_address_str</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">this_aaaa_record</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The IPv6 address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_address_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">this_address_str</span><span class="p">);</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">getdns_list</span> <span class="o">*</span><span class="n">replies_tree</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">n_replies</span><span class="p">,</span> <span class="n">i</span><span class="p">;</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">context</span><span class="p">;</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">userarg</span><span class="p">;</span> <span class="cm">/* unused parameters */</span>
<span class="k">switch</span><span class="p">(</span><span class="n">callback_type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_CANCEL</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Transaction with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; was cancelled.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_TIMEOUT</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Transaction with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; timed out.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_ERROR</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;An error occurred for transaction ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot;.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">default</span><span class="o">:</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_COMPLETE</span> <span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;replies_tree&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">replies_tree</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get </span><span class="se">\&quot;</span><span class="s">replies_tree</span><span class="se">\&quot;</span><span class="s"> from reponse&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">replies_tree</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n_replies</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get replies_tree</span><span class="se">\&#39;</span><span class="s">s length&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n_replies</span> <span class="o">&amp;&amp;</span> <span class="n">r</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">reply</span><span class="p">;</span>
<span class="n">getdns_list</span> <span class="o">*</span><span class="n">answer</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">n_answers</span><span class="p">,</span> <span class="n">j</span><span class="p">;</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">replies_tree</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">reply</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get address %zu from just_address_answers&quot;</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">reply</span><span class="p">,</span> <span class="s">&quot;answer&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">answer</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get </span><span class="se">\&quot;</span><span class="s">address_data</span><span class="se">\&quot;</span><span class="s"> from address&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n_answers</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get answer section</span><span class="se">\&#39;</span><span class="s">s length&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">for</span> <span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">n_answers</span> <span class="o">&amp;&amp;</span> <span class="n">r</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">rr</span><span class="p">;</span>
<span class="n">getdns_bindata</span> <span class="o">*</span><span class="n">address</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">rr</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could net get rr %zu from answer section&quot;</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">rr</span><span class="p">,</span> <span class="s">&quot;/rdata/ipv4_address&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address</span><span class="p">)</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The IPv4 address is &quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">rr</span><span class="p">,</span> <span class="s">&quot;/rdata/ipv6_address&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address</span><span class="p">)</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The IPv6 address is &quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">address</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">address_str</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">address_str</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">address</span><span class="p">)))</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not convert second address to string&quot;</span><span class="p">);</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">GETDNS_RETURN_MEMORY_ERROR</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;%s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">address_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">address_str</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">this_callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_CANCEL</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The callback with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; was cancelled. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_transaction_id</span><span class="p">);</span>
<span class="k">else</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The callback got a callback_type of %d. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_callback_type</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="p">{</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">r</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span> <span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">response</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="cm">/* Create the DNS context for this call */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">context_create_return</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">this_context</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context_create_return</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">context_create_return</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Create an event base and put it in the context using the unknown function name */</span>
<span class="k">struct</span> <span class="n">event_base</span> <span class="o">*</span><span class="n">this_event_base</span><span class="p">;</span>
<span class="n">this_event_base</span> <span class="o">=</span> <span class="n">event_base_new</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_event_base</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the event base failed.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">getdns_extension_set_libevent_base</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_event_base</span><span class="p">);</span>
<span class="cm">/* Set up the getdns call */</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">this_name</span> <span class="o">=</span> <span class="s">&quot;www.example.com&quot;</span><span class="p">;</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">this_userarg</span> <span class="o">=</span> <span class="s">&quot;somestring&quot;</span><span class="p">;</span> <span class="c1">// Could add things here to help identify this call</span>
<span class="kt">getdns_transaction_t</span> <span class="n">this_transaction_id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">event_base</span> <span class="o">*</span><span class="n">event_base</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">extensions</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">query_name</span> <span class="o">=</span> <span class="s">&quot;www.example.com&quot;</span><span class="p">;</span>
<span class="cm">/* Could add things here to help identify this call */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">userarg</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_transaction_t</span> <span class="n">transaction_id</span><span class="p">;</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">context</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">event_base</span> <span class="o">=</span> <span class="n">event_base_new</span><span class="p">()))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the event base failed.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_extension_set_libevent_base</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">event_base</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Setting the event base failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_address</span><span class="p">(</span> <span class="n">context</span><span class="p">,</span> <span class="n">query_name</span><span class="p">,</span> <span class="n">extensions</span>
<span class="p">,</span> <span class="n">userarg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">transaction_id</span><span class="p">,</span> <span class="n">callback</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error scheduling asynchronous request&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">event_base_dispatch</span><span class="p">(</span><span class="n">event_base</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error dispatching events</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="cm">/* Make the call */</span>
<span class="kt">getdns_return_t</span> <span class="n">dns_request_return</span> <span class="o">=</span> <span class="n">getdns_address</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_name</span><span class="p">,</span>
<span class="nb">NULL</span><span class="p">,</span> <span class="n">this_userarg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_transaction_id</span><span class="p">,</span> <span class="n">this_callbackfn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dns_request_return</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_BAD_DOMAIN_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;A bad domain name was used: %s. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_name</span><span class="p">);</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="cm">/* Call the event loop */</span>
<span class="kt">int</span> <span class="n">dispatch_return</span> <span class="o">=</span> <span class="n">event_base_dispatch</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">dispatch_return</span><span class="p">);</span>
<span class="c1">// TODO: check the return value above</span>
<span class="p">}</span>
<span class="cm">/* Clean up */</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">event_base</span><span class="p">)</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">event_base</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
<span class="cm">/* Assuming we get here, leave gracefully */</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_SUCCESS</span><span class="p">);</span>
<span class="p">}</span>
@ -1745,20 +1722,17 @@ callback function, add a check for the DNSSEC status. It shows how to add two
extensions to the <code>extensions</code> argument of the call.</p>
<pre>
getdns_dict * this_extensions = getdns_dict_create();
this_ret = getdns_dict_set_int(this_extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
this_ret = getdns_dict_set_int(this_extensions, "dnssec_return_status", GETDNS_EXTENSION_TRUE);
getdns_dict *extensions = getdns_dict_create();
r = getdns_dict_set_int(extensions, "return_both_v4_and_v6", GETDNS_EXTENSION_TRUE);
r = getdns_dict_set_int(extensions, "dnssec_return_status", GETDNS_EXTENSION_TRUE);
. . .
if (this_type == GETDNS_RRTYPE_A)
{
uint32_t this_dnssec_status;
this_ret = getdns_dict_get_int(this_answer, "dnssec_status", &amp;this_dnssec_status);
if (this_dnssec_status != GETDNS_DNSSEC_SECURE)
{
if (rr_type == GETDNS_RRTYPE_A) {
uint32_t dnssec_status;
r = getdns_dict_get_int(answer, "dnssec_status", &amp;dnssec_status);
if (dnssec_status != GETDNS_DNSSEC_SECURE) {
// Log the DNSSEC status somewhere
}
else
{
} else {
// Deal with the record however you were going to
}
}
@ -1775,83 +1749,67 @@ and thus does not use the async code. Note that the processing of the answers is
as it is for the synchronous example, it is just done in <code>main()</code>.</p>
<br><div class="highlight"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;stdint.h&gt;</span>
<span class="cp">#include &lt;stdlib.h&gt;</span>
<span class="cp">#include &lt;string.h&gt;</span>
<span class="cp">#include &lt;inttypes.h&gt;</span>
<span class="cp">#include &lt;assert.h&gt;</span>
<span class="cp">#include &lt;getdns_core_only.h&gt;</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">getdns_return_t</span> <span class="n">this_ret</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="cm">/* Create the DNS context for this call */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">context_create_return</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">this_context</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context_create_return</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">context_create_return</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Set up the getdns_sync_request call */</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">this_name</span> <span class="o">=</span> <span class="s">&quot;www.example.com&quot;</span><span class="p">;</span>
<span class="kt">uint8_t</span> <span class="n">this_request_type</span> <span class="o">=</span> <span class="n">GETDNS_RRTYPE_A</span><span class="p">;</span>
<span class="cm">/* Get the A and AAAA records */</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_extensions</span> <span class="o">=</span> <span class="n">getdns_dict_create</span><span class="p">();</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_set_int</span><span class="p">(</span><span class="n">this_extensions</span><span class="p">,</span> <span class="s">&quot;return_both_v4_and_v6&quot;</span><span class="p">,</span> <span class="n">GETDNS_EXTENSION_TRUE</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_ret</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to set an extension do both IPv4 and IPv6 failed: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_ret</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_extensions</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_response</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">response</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">extensions</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_bindata</span> <span class="o">*</span><span class="n">address_data</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">first</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">*</span><span class="n">second</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="cm">/* Make the call */</span>
<span class="kt">getdns_return_t</span> <span class="n">dns_request_return</span> <span class="o">=</span> <span class="n">getdns_general_sync</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_name</span><span class="p">,</span> <span class="n">this_request_type</span><span class="p">,</span>
<span class="n">this_extensions</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dns_request_return</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_BAD_DOMAIN_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;A bad domain name was used: %s. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_name</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_extensions</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="cm">/* Create the DNS context for this call */</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">context</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">extensions</span> <span class="o">=</span> <span class="n">getdns_dict_create</span><span class="p">()))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not create extensions dict.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_set_int</span><span class="p">(</span><span class="n">extensions</span><span class="p">,</span> <span class="s">&quot;return_both_v4_and_v6&quot;</span><span class="p">,</span> <span class="n">GETDNS_EXTENSION_TRUE</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to set an extension do both IPv4 and IPv6 failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_general_sync</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="s">&quot;example.com&quot;</span><span class="p">,</span> <span class="n">GETDNS_RRTYPE_A</span><span class="p">,</span> <span class="n">extensions</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">response</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error scheduling synchronous request&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;/just_address_answers/0/address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get first address&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">first</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not convert first address to string</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;/just_address_answers/1/address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get second address&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">second</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not convert second address to string</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">first</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">first</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">first</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="cm">/* Be sure the search returned something */</span>
<span class="kt">uint32_t</span> <span class="n">this_error</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;status&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_error</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_error</span> <span class="o">!=</span> <span class="n">GETDNS_RESPSTATUS_GOOD</span><span class="p">)</span> <span class="c1">// If the search didn&#39;t return &quot;good&quot;</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The search had no results, and a return value of %d. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_error</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_extensions</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">getdns_list</span> <span class="o">*</span> <span class="n">just_the_addresses_ptr</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;just_address_answers&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">just_the_addresses_ptr</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="kt">size_t</span> <span class="n">num_addresses</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">just_the_addresses_ptr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">num_addresses</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Go through each record */</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">rec_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">rec_count</span> <span class="o">&lt;</span> <span class="n">num_addresses</span><span class="p">;</span> <span class="o">++</span><span class="n">rec_count</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_address</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">just_the_addresses_ptr</span><span class="p">,</span> <span class="n">rec_count</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_address</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Just print the address */</span>
<span class="n">getdns_bindata</span> <span class="o">*</span> <span class="n">this_address_data</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">this_address</span><span class="p">,</span> <span class="s">&quot;address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_address_data</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">this_address_str</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="n">this_address_data</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_address_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">this_address_str</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">second</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The address is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">second</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">second</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Clean up */</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_extensions</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">response</span><span class="p">)</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">response</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">extensions</span><span class="p">)</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">extensions</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="p">{</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">r</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span> <span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Assuming we get here, leave gracefully */</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_SUCCESS</span><span class="p">);</span>
<span class="p">}</span>
@ -1863,138 +1821,115 @@ as it is for the synchronous example, it is just done in <code>main()</code>.</p
<p>This example shows how to use <code>getdns_hostname()</code> to get names from the DNS reverse tree.</p>
<br><div class="highlight"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;stdint.h&gt;</span>
<span class="cp">#include &lt;stdlib.h&gt;</span>
<span class="cp">#include &lt;string.h&gt;</span>
<br><div class="highlight"><pre><span class="cp">#include &lt;assert.h&gt;</span>
<span class="cp">#include &lt;inttypes.h&gt;</span>
<span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;getdns_libevent.h&gt;</span>
<span class="cp">#define UNUSED_PARAM(x) ((void)(x))</span>
<span class="cm">/* Set up the callback function, which will also do the processing of the results */</span>
<span class="kt">void</span> <span class="nf">this_callbackfn</span><span class="p">(</span><span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span><span class="p">,</span>
<span class="kt">getdns_callback_type_t</span> <span class="n">this_callback_type</span><span class="p">,</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">this_response</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">this_userarg</span><span class="p">,</span>
<span class="kt">getdns_transaction_t</span> <span class="n">this_transaction_id</span><span class="p">)</span>
<span class="kt">void</span> <span class="nf">callback</span><span class="p">(</span><span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span><span class="p">,</span>
<span class="kt">getdns_callback_type_t</span> <span class="n">callback_type</span><span class="p">,</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">response</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">userarg</span><span class="p">,</span>
<span class="kt">getdns_transaction_t</span> <span class="n">transaction_id</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">getdns_return_t</span> <span class="n">this_ret</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_userarg</span><span class="p">);</span> <span class="cm">/* Not looking at the userarg for this example */</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span> <span class="cm">/* Not looking at the context for this example */</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_ret</span><span class="p">);</span> <span class="cm">/* Set, but not read */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_COMPLETE</span><span class="p">)</span> <span class="cm">/* This is a callback with data */</span>
<span class="p">{</span>
<span class="cm">/* Be sure the search returned something */</span>
<span class="kt">uint32_t</span> <span class="n">this_error</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;status&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_error</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_error</span> <span class="o">!=</span> <span class="n">GETDNS_RESPSTATUS_GOOD</span><span class="p">)</span> <span class="c1">// If the search didn&#39;t return &quot;good&quot;</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The search had no results, and a return value of %d. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_error</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">getdns_list</span> <span class="o">*</span><span class="n">replies_tree</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">this_response</span><span class="p">,</span> <span class="s">&quot;replies_tree&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">replies_tree</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="kt">size_t</span> <span class="n">num_replies</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">replies_tree</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">num_replies</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Go through each reply */</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">reply_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">reply_count</span> <span class="o">&lt;</span> <span class="n">num_replies</span><span class="p">;</span> <span class="o">++</span><span class="n">reply_count</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_reply</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">replies_tree</span><span class="p">,</span> <span class="n">reply_count</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_reply</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Just print the address */</span>
<span class="n">getdns_list</span><span class="o">*</span> <span class="n">reply_answers</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">this_reply</span><span class="p">,</span> <span class="s">&quot;answer&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">reply_answers</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="kt">size_t</span> <span class="n">num_answers</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">reply_answers</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">num_answers</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="cm">/* Go through each answer */</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">answer_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">answer_count</span> <span class="o">&lt;</span> <span class="n">num_answers</span><span class="p">;</span> <span class="o">++</span><span class="n">answer_count</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_rr</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">reply_answers</span><span class="p">,</span> <span class="n">answer_count</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_rr</span><span class="p">);</span>
<span class="cm">/* Get the RDATA type */</span>
<span class="kt">uint32_t</span> <span class="n">this_type</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_int</span><span class="p">(</span><span class="n">this_rr</span><span class="p">,</span> <span class="s">&quot;type&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_type</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_type</span> <span class="o">==</span> <span class="n">GETDNS_RRTYPE_PTR</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">this_rdata</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_dict</span><span class="p">(</span><span class="n">this_rr</span><span class="p">,</span> <span class="s">&quot;rdata&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_rdata</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">getdns_list</span> <span class="o">*</span><span class="n">answer</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">n_answers</span><span class="p">,</span> <span class="n">i</span><span class="p">;</span>
<span class="n">getdns_bindata</span> <span class="o">*</span> <span class="n">this_dname</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">this_rdata</span><span class="p">,</span> <span class="s">&quot;rdata_raw&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_dname</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">this_dname_str</span><span class="p">;</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_convert_dns_name_to_fqdn</span><span class="p">(</span><span class="n">this_dname</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_dname_str</span><span class="p">);</span> <span class="c1">// Ignore any error</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The dname is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">this_dname_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">this_dname_str</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">context</span><span class="p">;</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">userarg</span><span class="p">;</span> <span class="cm">/* unused parameters */</span>
<span class="k">switch</span><span class="p">(</span><span class="n">callback_type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_CANCEL</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Transaction with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; was cancelled.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_TIMEOUT</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Transaction with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; timed out.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">GETDNS_CALLBACK_ERROR</span><span class="p">:</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;An error occurred for transaction ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot;.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="k">default</span><span class="o">:</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_COMPLETE</span> <span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_get_list</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s">&quot;/replies_tree/0/answer&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">answer</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get </span><span class="se">\&quot;</span><span class="s">answer</span><span class="se">\&quot;</span><span class="s"> section from first reply in the reponse&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_list_get_length</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">n_answers</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get replies_tree</span><span class="se">\&#39;</span><span class="s">s length&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n_answers</span> <span class="o">&amp;&amp;</span> <span class="n">r</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">rr</span><span class="p">;</span>
<span class="n">getdns_bindata</span> <span class="o">*</span><span class="n">dname</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">dname_str</span><span class="p">;</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_list_get_dict</span><span class="p">(</span><span class="n">answer</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">rr</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not get rr %zu from answer section&quot;</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">getdns_dict_get_bindata</span><span class="p">(</span><span class="n">rr</span><span class="p">,</span> <span class="s">&quot;/rdata/ptrdname&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">dname</span><span class="p">))</span>
<span class="k">continue</span><span class="p">;</span> <span class="cm">/* Not a PTR */</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_convert_dns_name_to_fqdn</span><span class="p">(</span><span class="n">dname</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">dname_str</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not convert PTR dname to string&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;The dname is %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">dname_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">dname_str</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">this_callback_type</span> <span class="o">==</span> <span class="n">GETDNS_CALLBACK_CANCEL</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The callback with ID %&quot;</span><span class="n">PRIu64</span><span class="s">&quot; was cancelled. Exiting.&quot;</span><span class="p">,</span> <span class="n">this_transaction_id</span><span class="p">);</span>
<span class="k">else</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;The callback got a callback_type of %d. Exiting.&quot;</span><span class="p">,</span> <span class="n">this_callback_type</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_response</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="p">{</span>
<span class="n">assert</span><span class="p">(</span> <span class="n">r</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span> <span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">response</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="cm">/* Create the DNS context for this call */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">this_context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">context_create_return</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">this_context</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context_create_return</span> <span class="o">!=</span> <span class="n">GETDNS_RETURN_GOOD</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed: %d&quot;</span><span class="p">,</span> <span class="n">context_create_return</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Create an event base and put it in the context using the unknown function name */</span>
<span class="k">struct</span> <span class="n">event_base</span> <span class="o">*</span><span class="n">this_event_base</span><span class="p">;</span>
<span class="n">this_event_base</span> <span class="o">=</span> <span class="n">event_base_new</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">this_event_base</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the event base failed.&quot;</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">getdns_extension_set_libevent_base</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_event_base</span><span class="p">);</span>
<span class="cm">/* Set up the getdns call */</span>
<span class="n">getdns_dict</span> <span class="o">*</span> <span class="n">this_addr_to_look_up</span> <span class="o">=</span> <span class="n">getdns_dict_create</span><span class="p">();</span>
<span class="c1">// TODO: check the return value above</span>
<span class="n">getdns_bindata</span> <span class="n">this_type</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="s">&quot;IPv4&quot;</span> <span class="p">};</span>
<span class="kt">getdns_return_t</span> <span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_set_bindata</span><span class="p">(</span><span class="n">this_addr_to_look_up</span><span class="p">,</span> <span class="s">&quot;address_type&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_type</span><span class="p">);</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">this_ret</span><span class="p">);</span>
<span class="n">getdns_bindata</span> <span class="n">this_ipv4_addr</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="s">&quot;</span><span class="se">\x08\x08\x08\x08</span><span class="s">&quot;</span> <span class="p">};</span>
<span class="n">this_ret</span> <span class="o">=</span> <span class="n">getdns_dict_set_bindata</span><span class="p">(</span><span class="n">this_addr_to_look_up</span><span class="p">,</span> <span class="s">&quot;address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_ipv4_addr</span><span class="p">);</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">this_userarg</span> <span class="o">=</span> <span class="s">&quot;somestring&quot;</span><span class="p">;</span> <span class="c1">// Could add things here to help identify this call</span>
<span class="kt">getdns_transaction_t</span> <span class="n">this_transaction_id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">getdns_return_t</span> <span class="n">r</span><span class="p">;</span> <span class="cm">/* Holder for all function returns */</span>
<span class="n">getdns_context</span> <span class="o">*</span><span class="n">context</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">event_base</span> <span class="o">*</span><span class="n">event_base</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_bindata</span> <span class="n">address_type</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="s">&quot;IPv4&quot;</span> <span class="p">};</span>
<span class="n">getdns_bindata</span> <span class="n">address_data</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="s">&quot;</span><span class="se">\x08\x08\x08\x08</span><span class="s">&quot;</span> <span class="p">};</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">address</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">getdns_dict</span> <span class="o">*</span><span class="n">extensions</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="cm">/* Could add things here to help identify this call */</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">userarg</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">getdns_transaction_t</span> <span class="n">transaction_id</span><span class="p">;</span>
<span class="cm">/* Make the call */</span>
<span class="kt">getdns_return_t</span> <span class="n">dns_request_return</span> <span class="o">=</span> <span class="n">getdns_hostname</span><span class="p">(</span><span class="n">this_context</span><span class="p">,</span> <span class="n">this_addr_to_look_up</span><span class="p">,</span>
<span class="nb">NULL</span><span class="p">,</span> <span class="n">this_userarg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">this_transaction_id</span><span class="p">,</span> <span class="n">this_callbackfn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dns_request_return</span> <span class="o">==</span> <span class="n">GETDNS_RETURN_BAD_DOMAIN_NAME</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">ip_address_str</span> <span class="o">=</span> <span class="n">getdns_display_ip_address</span><span class="p">(</span><span class="o">&amp;</span><span class="n">this_ipv4_addr</span><span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_context_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">context</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the context failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">event_base</span> <span class="o">=</span> <span class="n">event_base_new</span><span class="p">()))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Trying to create the event base failed.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_extension_set_libevent_base</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">event_base</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Setting the event base failed&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">address</span> <span class="o">=</span> <span class="n">getdns_dict_create</span><span class="p">()))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not create address dict.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_set_bindata</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="s">&quot;address_type&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address_type</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not set address_type in address dict.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_dict_set_bindata</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="s">&quot;address_data&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">address_data</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Could not set address_data in address dict.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="n">r</span> <span class="o">=</span> <span class="n">getdns_hostname</span><span class="p">(</span> <span class="n">context</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">extensions</span>
<span class="p">,</span> <span class="n">userarg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">transaction_id</span><span class="p">,</span> <span class="n">callback</span><span class="p">)))</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error scheduling asynchronous request&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">event_base_dispatch</span><span class="p">(</span><span class="n">event_base</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Error dispatching events</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;A bad IP address was used: %s. Exiting.</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">ip_address_str</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">ip_address_str</span><span class="p">);</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_addr_to_look_up</span><span class="p">);</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">return</span><span class="p">(</span><span class="n">GETDNS_RETURN_GENERIC_ERROR</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="cm">/* Call the event loop */</span>
<span class="kt">int</span> <span class="n">dispatch_return</span> <span class="o">=</span> <span class="n">event_base_dispatch</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">UNUSED_PARAM</span><span class="p">(</span><span class="n">dispatch_return</span><span class="p">);</span>
<span class="c1">// TODO: check the return value above</span>
<span class="p">}</span>
<span class="cm">/* Clean up */</span>
<span class="n">getdns_dict_destroy</span><span class="p">(</span><span class="n">this_addr_to_look_up</span><span class="p">);</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">this_event_base</span><span class="p">);</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">this_context</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">event_base</span><span class="p">)</span>
<span class="n">event_base_free</span><span class="p">(</span><span class="n">event_base</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="n">getdns_context_destroy</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
<span class="cm">/* Assuming we get here, leave gracefully */</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_SUCCESS</span><span class="p">);</span>
<span class="p">}</span>
@ -2209,9 +2144,7 @@ getdns_context_set_dns_transport_list(
<p class=cont>The <code>transports</code> array contains an ordered list of transports that will be used for DNS lookups.
If only one transport value is specified it will be the only transport used.
Should it not be available basic resolution will fail.
Fallback transport options are specified by including multiple values in the list. Currently the TLS and STARTTLS options
perform Strict TLS which requires a hostname to be
specified so that authentication can be performed. This hostname can be specified in the tls_auth_name parameter for an upstream.
Fallback transport options are specified by including multiple values in the list.
The values are <span class=default>
<code>GETDNS_TRANSPORT_UDP</code></span>,
<code>GETDNS_TRANSPORT_TCP</code>,
@ -2493,7 +2426,7 @@ getdns_pretty_print_dict() for debugging.</li>
<h1>9. The Generated Files</h1>
<p>There is <a href="getdns-0.604.tgz">a tarball</a> that includes the .h files,
<p>There is <a href="getdns-0.607.tgz">a tarball</a> that includes the .h files,
the examples, and so on. The examples all make, even though there is no API implementation, based
on a pseudo-implementation in the tarball; see make-examples-PLATFORM.sh. Note that this currently builds fine
on the Macintosh and Ubuntu; help is definitely appreciated on making the build process