From 51f0299137cd568e61dc5c4ba2d4b49748c867b1 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 11 Dec 2013 23:41:21 +0100 Subject: [PATCH] Fix example-reverse (and reverse_address) From the example it is clear that network format addresses are expected for getdns_hostname* --- src/example/example-reverse.c | 65 ++++++++++++++++++++++++----------- src/hostname.c | 16 +++++---- src/sync.c | 14 +++++--- src/test/tests_stub_async.c | 6 +++- src/util-internal.c | 20 ++++++----- src/util-internal.h | 2 +- 6 files changed, 82 insertions(+), 41 deletions(-) diff --git a/src/example/example-reverse.c b/src/example/example-reverse.c index c55424f8..4389dc42 100644 --- a/src/example/example-reverse.c +++ b/src/example/example-reverse.c @@ -20,37 +20,57 @@ void this_callbackfn(struct getdns_context *this_context, if (this_callback_type == GETDNS_CALLBACK_COMPLETE) /* This is a callback with data */ { /* Be sure the search returned something */ - uint32_t * this_error = NULL; - 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" + 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.", *this_error); + fprintf(stderr, "The search had no results, and a return value of %d. Exiting.\n", this_error); + getdns_dict_destroy(this_response); return; } - struct 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" + struct 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) { - fprintf(stderr, "Trying to get the answers failed: %d", this_ret); - return; - } - size_t * num_addresses_ptr = NULL; - this_ret = getdns_list_get_length(just_the_addresses_ptr, num_addresses_ptr); // Ignore any error - /* Go through each record */ - for ( size_t rec_count = 0; rec_count <= *num_addresses_ptr; ++rec_count ) - { - struct getdns_dict * this_address; - this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error + struct getdns_dict * this_reply; + this_ret = getdns_list_get_dict(replies_tree, reply_count, &this_reply); // Ignore any error /* Just print the address */ - struct getdns_bindata * this_address_data; - this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data); // Ignore any error - printf("The address is %s", getdns_display_ip_address(this_address_data)); + struct 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) + { + struct 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) + { + struct getdns_dict *this_rdata; + this_ret = getdns_dict_get_dict(this_rr, "rdata", &this_rdata); // Ignore any error + + struct getdns_bindata * this_dname; + this_ret = getdns_dict_get_bindata(this_rdata, "rdata_raw", &this_dname); + char *this_dname_str = getdns_convert_dns_name_to_fqdn(this_dname->data); + printf("The dname is %s\n", this_dname_str); + free(this_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); } int main() @@ -69,6 +89,7 @@ int main() 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); @@ -92,6 +113,9 @@ int main() 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 @@ -103,6 +127,7 @@ int main() } /* Clean up */ getdns_dict_destroy(this_addr_to_look_up); + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); diff --git a/src/hostname.c b/src/hostname.c index 66326fd5..960d583f 100644 --- a/src/hostname.c +++ b/src/hostname.c @@ -64,18 +64,22 @@ getdns_hostname(struct getdns_context *context, &address_type)) != GETDNS_RETURN_GOOD) return retval; if ((strncmp(GETDNS_STR_IPV4, (char *) address_type->data, - strlen(GETDNS_STR_IPV4)) == 0) + ( strlen(GETDNS_STR_IPV4) < address_type->size + ? strlen(GETDNS_STR_IPV4) : address_type->size )) == 0 + && address_data->size == 4) || (strncmp(GETDNS_STR_IPV6, (char *) address_type->data, - strlen(GETDNS_STR_IPV6)) == 0)) + ( strlen(GETDNS_STR_IPV6) < address_type->size + ? strlen(GETDNS_STR_IPV6) : address_type->size )) == 0 + && address_data->size == 16)) req_type = GETDNS_RRTYPE_PTR; else return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - if ((name = reverse_address((char *) address_data->data)) == 0) + if ((name = reverse_address(address_data)) == NULL) return GETDNS_RETURN_GENERIC_ERROR; - return getdns_general(context, name, req_type, extensions, + retval = getdns_general(context, name, req_type, extensions, userarg, transaction_id, callback); - - return GETDNS_RETURN_GOOD; + free(name); + return retval; } /* getdns_hostname */ /* getdns_hostname.c */ diff --git a/src/sync.c b/src/sync.c index 327c45c8..3600da70 100644 --- a/src/sync.c +++ b/src/sync.c @@ -126,16 +126,22 @@ getdns_hostname_sync(struct getdns_context *context, &address_type)) != GETDNS_RETURN_GOOD) return retval; if ((strncmp(GETDNS_STR_IPV4, (char *) address_type->data, - strlen(GETDNS_STR_IPV4)) == 0) + ( strlen(GETDNS_STR_IPV4) < address_type->size + ? strlen(GETDNS_STR_IPV4) : address_type->size )) == 0 + && address_data->size == 4) || (strncmp(GETDNS_STR_IPV6, (char *) address_type->data, - strlen(GETDNS_STR_IPV6)) == 0)) + ( strlen(GETDNS_STR_IPV6) < address_type->size + ? strlen(GETDNS_STR_IPV6) : address_type->size )) == 0 + && address_data->size == 16)) req_type = GETDNS_RRTYPE_PTR; else return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - if ((name = reverse_address((char *) address_data)) == 0) + if ((name = reverse_address(address_data)) == NULL) return GETDNS_RETURN_GENERIC_ERROR; - return getdns_general_sync(context, name, req_type, extensions, + retval = getdns_general_sync(context, name, req_type, extensions, response); + free(name); + return retval; } getdns_return_t diff --git a/src/test/tests_stub_async.c b/src/test/tests_stub_async.c index 613444c3..b9274b46 100644 --- a/src/test/tests_stub_async.c +++ b/src/test/tests_stub_async.c @@ -48,7 +48,6 @@ this_callbackfn(struct getdns_context *this_context, if (this_callback_type == GETDNS_CALLBACK_COMPLETE) { /* This is a callback with data */ char *res = getdns_pretty_print_dict(this_response); fprintf(stdout, "%s\n", res); - getdns_dict_destroy(this_response); free(res); } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) @@ -59,6 +58,7 @@ this_callbackfn(struct getdns_context *this_context, fprintf(stderr, "The callback got a callback_type of %d. Exiting.", this_callback_type); + getdns_dict_destroy(this_response); } int @@ -81,6 +81,7 @@ main(int argc, char** argv) 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, @@ -97,6 +98,8 @@ main(int argc, char** argv) if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) { fprintf(stderr, "A bad domain name was used: %s. Exiting.", this_name); + event_base_free(this_event_base); + getdns_context_destroy(this_context); return (GETDNS_RETURN_GENERIC_ERROR); } // dns_request_return = getdns_service(this_context, this_name, NULL, this_userarg, &this_transaction_id, @@ -112,6 +115,7 @@ main(int argc, char** argv) // TODO: check the return value above } /* Clean up */ + event_base_free(this_event_base); getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); diff --git a/src/util-internal.c b/src/util-internal.c index 24992604..2cce9d2f 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -583,26 +583,28 @@ create_getdns_response(struct getdns_dns_req * completed_request) /** * reverse an IP address for PTR lookup - * @param addr_str dotted notation of IP address to reverse + * @param address_data IP address to reverse * @return NULL on allocation failure * @return reversed string on success, caller must free storage via call to free() */ char * -reverse_address(char *addr_str) +reverse_address(struct getdns_bindata *address_data) { ldns_rdf *addr_rdf; ldns_rdf *rev_rdf; char *rev_str; - addr_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, addr_str); - if (!addr_rdf) { - addr_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, addr_str); - if (!addr_rdf) - return NULL; - } + if (address_data->size == 4) + addr_rdf = ldns_rdf_new(LDNS_RDF_TYPE_A, 4, address_data->data); + else if (address_data->size == 16) + addr_rdf = ldns_rdf_new(LDNS_RDF_TYPE_AAAA, 16, address_data->data); + else + return NULL; + if (!addr_rdf) + return NULL; rev_rdf = ldns_rdf_address_reverse(addr_rdf); - ldns_rdf_deep_free(addr_rdf); + ldns_rdf_free(addr_rdf); if (!rev_rdf) return NULL; diff --git a/src/util-internal.h b/src/util-internal.h index 94d2b5d3..04398957 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -94,7 +94,7 @@ getdns_return_t getdns_dict_util_set_string(struct getdns_dict * dict, char *nam /* get a string from a dict. result is valid as long as dict is valid */ getdns_return_t getdns_dict_util_get_string(struct getdns_dict * dict, char *name, char **result); -char *reverse_address(char *addr_str); +char *reverse_address(struct getdns_bindata *address_data); /** * detect unrecognized extension strings or invalid extension formats