Merge develop in. Add local timer

This commit is contained in:
Neel Goyal 2014-02-03 17:23:31 -05:00
commit 8b64c521a8
14 changed files with 1160 additions and 120 deletions

View File

@ -50,8 +50,8 @@ External dependencies are linked outside the getdns API build tree (we rely on c
* [libevent](http://libevent.org) version 2.0.21 stable
Sometimes called libevent2
* [libldns from NL](https://www.nlnetlabs.nl/projects/ldns/) version 1.6.16 (ldns may require openssl headers and libraries)
* [libunbound from NL](http://www.nlnetlabs.nl/projects/unbound/) svn revision 3012, configure must be run with the --with-libevent option (recommended to also use --with-libunbound-only).
* [libldns from NL](https://www.nlnetlabs.nl/projects/ldns/) version 1.6.17 (ldns requires openssl headers and libraries)
* [libunbound from NL](http://www.nlnetlabs.nl/projects/unbound/) svn revision 3069, configure must be run with the --with-libevent and the --enable-event-api option (recommended to also use --with-libunbound-only).
* [libexpat](http://expat.sourceforge.net/) for libunbound.
* [libidn from the FSF](http://www.gnu.org/software/libidn/) version 1.
* Doxygen is used to generate documentation, while this is not technically necessary for the build it makes things a lot more pleasant.

Binary file not shown.

BIN
spec/getdns-0.380.tgz Normal file

Binary file not shown.

View File

@ -1,4 +1,4 @@
/* Created at 2014-01-22-10-48-59*/
/* Created at 2014-02-03-16-52-47*/
#ifndef GETDNS_H
#define GETDNS_H

View File

@ -645,7 +645,7 @@ getdns_dict_destroy(this_extensions);
<li><code>dnssec_return_only_secure</code></li>
<li><code>dnssec_return_supporting_responses</code></li>
<li><code>dnssec_return_validation_chain</code></li>
<li><code>return_both_v4_and_v6</code></li>
@ -692,15 +692,81 @@ are determined to be secure, the error code at the top level of the response obj
<code>GETDNS_RESPSTATUS_NO_SECURE_ANSWERS</code>.</p>
<p>Applications that want to do their own validation will want to have the DNSSEC-related records
for a particular response. Use the <code>dnssec_return_supporting_responses</code> extension. The
for a particular response. Use the <code>dnssec_return_validation_chain</code> extension. The
extension's value (an int) is set to <code>GETDNS_EXTENSION_TRUE</code> to cause a set
of additional DNSSEC-related records needed for validation to be returned in the response object.
This set comes as <code>additional_dnssec</code> (a list) at the top level of the response object.
This list includes any trust anchors needed for the validation. Thus, a reply might look like:</p>
This set comes as <code>validation_chain</code> (a list) at the top level of the response object.
This list includes all resource record dicts for all the resource records (DS, DNSKEY and their RRSIGs) that are needed to perform the validation from the root up. Thus, a reply might look like:</p>
<pre>
{ # This is the response object
"additional_dnssec": [ &lt;bindata of the first DNSSEC record&gt;, &lt;bindata of the second DNSSEC record&gt; ... ],
"validation_chain":
[ { "name": <bindata for .>,
"type": GETDNS_RRTYPE_DNSKEY,
"rdata": { "flags": 256, . . . },
. . .
},
{ "name": <bindata for .>,
"type": GETDNS_RRTYPE_DNSKEY,
"rdata": { "flags": 257, . . . },
. . .
},
{ "name": <bindata for .>,
"type": GETDNS_RRTYPE_RRSIG,
"rdata": { "signers_name": <bindata for .>,
"type_covered": GETDNS_RRTYPE_DNSKEY,
. . .
},
},
{ "name": <bindata for com.>,
"type": GETDNS_RRTYPE_DS,
. . .
},
{ "name": <bindata for com.>,
"type": GETDNS_RRTYPE_RRSIG
"rdata": { "signers_name": <bindata for .>,
"type_covered": GETDNS_RRTYPE_DS,
. . .
},
. . .
},
{ "name": <bindata for com.>,
"type": GETDNS_RRTYPE_DNSKEY
"rdata": { "flags": 256, . . . },
. . .
},
{ "name": <bindata for com.>,
"type": GETDNS_RRTYPE_DNSKEY
"rdata": { "flags": 257, . . . },
. . .
},
{ "name": <bindata for com.>,
"type": GETDNS_RRTYPE_RRSIG
"rdata": { "signers_name": <bindata for com.>,
"type_covered": GETDNS_RRTYPE_DNSKEY,
. . .
},
. . .
},
{ "name": <bindata for example.com.>,
"type": GETDNS_RRTYPE_DS,
. . .
},
{ "name": <bindata for example.com.>,
"type": GETDNS_RRTYPE_RRSIG
"rdata": { "signers_name": <bindata for com.>,
"type_covered": GETDNS_RRTYPE_DS,
. . .
},
. . .
},
{ "name": <bindata for example.com.>,
"type": GETDNS_RRTYPE_DNSKEY
"rdata": { "flags": 257, ... },
. . .
},
. . .
]
"replies_tree":
[
. . .
@ -708,7 +774,7 @@ This list includes any trust anchors needed for the validation. Thus, a reply mi
<p>If a request is using a context in which stub resolution is set, and that request also has
any of the <code>dnssec_return_status</code>, <code>dnssec_return_only_secure</code>, or
<code>dnssec_return_supporting_responses</code> extensions specified, the API will not perform
<code>dnssec_return_validation_chain</code> extensions specified, the API will not perform
the request and will instead return an error of <code>GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED</code>.</p>
<h2>3.2 Returning Both IPv4 and IPv6 Responses</h2>
@ -2210,7 +2276,7 @@ The response dicts inherit the custom memory management functions and the value
<h1>9. The Generated Files</h1>
<p>There is <a href="getdns-0.379.tgz">a tarball</a> that includes the .h files,
<p>There is <a href="getdns-0.380.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

View File

@ -3,7 +3,7 @@
* \file context.c
* @brief getdns context management functions
*
* Originally taken from the getdns API description pseudo implementation.
* Declarations taken from the getdns API description pseudo implementation.
*
*/
@ -189,6 +189,7 @@ create_from_ldns_list(struct getdns_context *context, ldns_rdf ** ldns_list,
return result;
}
/*---------------------------------------- set_os_defaults */
static getdns_return_t
set_os_defaults(struct getdns_context *context)
{
@ -210,8 +211,9 @@ set_os_defaults(struct getdns_context *context)
}
/** cleanup **/
ldns_resolver_deep_free(lr);
return GETDNS_RETURN_GOOD;
}
} /* set_os_defaults */
/* compare of transaction ids in DESCENDING order
so that 0 comes last
@ -351,7 +353,7 @@ getdns_context_create_with_extended_memory_functions(
GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
return GETDNS_RETURN_GOOD;
} /* getdns_context_create */
} /* getdns_context_create */
/*
* getdns_context_create

View File

@ -1,3 +1,39 @@
/**
*
* \file example-simple-answers.c
* @brief example using getdns to resolve a simple query
*
* Originally taken from the getdns API description pseudo implementation.
*
*/
/*
* Copyright (c) 2013, Versign, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -14,62 +50,118 @@ void this_callbackfn(struct getdns_context *this_context,
void *this_userarg,
getdns_transaction_t this_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 */
getdns_return_t this_ret;
uint32_t this_error;
size_t num_addresses;
struct getdns_list *just_the_addresses_ptr;
struct getdns_dict *this_address;
struct getdns_bindata *this_address_data;
size_t rec_count;
char *this_address_str;
UNUSED_PARAM(this_userarg);
UNUSED_PARAM(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;
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"
this_ret = getdns_dict_get_int(this_response, "status", &this_error);
if (this_ret != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "The dictionary does not contain \"status\" (this shouldn't have happened). Exiting\n");
getdns_dict_destroy(this_response);
return;
}
if (this_error != GETDNS_RESPSTATUS_GOOD)
{
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"
if (this_ret != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Trying to get the answers failed: %d\n", this_ret);
fprintf(stderr, "The dict does not contain \"just_address_answers\" (this shouldn't have happened), and returned %d. Exiting.\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 )
this_ret = getdns_list_get_length(just_the_addresses_ptr, &num_addresses);
if (this_ret != GETDNS_RETURN_GOOD)
{
struct getdns_dict * this_address;
this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address); // Ignore any error
fprintf(stderr, "The address list is invalid (this shouldn't have happened). Exiting\n");
getdns_dict_destroy(this_response);
return;
}
if (num_addresses == 0)
fprintf(stderr, "The address list has 0 records. Exiting\n");
/* Go through each record */
for (rec_count = 0; rec_count < num_addresses; ++rec_count)
{
this_ret = getdns_list_get_dict(just_the_addresses_ptr, rec_count, &this_address);
if(this_ret != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Record %d is invalid (this shouldn't have happened). skipping.\n", (int) rec_count);
continue;
}
/* 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
char *this_address_str = getdns_display_ip_address(this_address_data);
printf("The address is %s\n", this_address_str);
free(this_address_str);
this_ret = getdns_dict_get_bindata(this_address, "address_data", &this_address_data);
if(this_ret != GETDNS_RETURN_GOOD)
{
fprintf(stderr, "Record %d does not contain \"address_data\" (this shouldn't happen), skipping\n", (int) rec_count);
}
else
{
this_address_str = getdns_display_ip_address(this_address_data);
printf("The address is %s\n", this_address_str);
free(this_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);
}
int main()
getdns_dict_destroy(this_response);
} /* this_callbackfn */
/*---------------------------------------- main */
int
main(int argc, char *argv[])
{
/* Create the DNS context for this call */
char *this_name = "www.example.com";
char *this_userarg = "somestring";
int dispatch_return;
int exitval = EXIT_SUCCESS;
struct getdns_context *this_context = NULL;
getdns_return_t context_create_return = getdns_context_create(&this_context, 1);
struct event_base *this_event_base;
getdns_return_t dns_request_return;
getdns_transaction_t this_transaction_id;
getdns_return_t context_create_return;
if(argc > 1)
this_name = argv[1];
printf("resolving %s\n", this_name);
/* Create the DNS context for this call, use OS configs such as resolv.conf */
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)
{
@ -77,32 +169,37 @@ int main()
getdns_context_destroy(this_context);
return(GETDNS_RETURN_GENERIC_ERROR);
}
(void)getdns_extension_set_libevent_base(this_context, this_event_base);
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;
this_transaction_id = 0;
/* Make the call */
getdns_return_t dns_request_return = getdns_address(this_context, this_name,
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);
exitval = GETDNS_RETURN_GENERIC_ERROR;
}
else
{
/* Call the event loop */
int dispatch_return = event_base_dispatch(this_event_base);
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);
/* Assuming we get here, leave gracefully */
exit(EXIT_SUCCESS);
}
return exitval;
} /* main */
/* example-simple-answers.c */

View File

@ -48,9 +48,8 @@
/* declarations */
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
// static void ub_resolve_timeout(evutil_socket_t fd, short what, void *arg);
// static void ub_local_resolve_timeout(evutil_socket_t fd, short what,
// void *arg);
static void ub_resolve_timeout(void *arg);
static void ub_local_resolve_timeout(void *arg);
static void handle_network_request_error(getdns_network_req * netreq, int err);
static void handle_dns_request_complete(getdns_dns_req * dns_req);
@ -60,9 +59,7 @@ typedef struct netreq_cb_data
{
getdns_network_req *netreq;
int err;
ldns_buffer *result;
int sec;
char *bogus;
struct ub_result* ub_res;
} netreq_cb_data;
/* cancel, cleanup and send timeout to callback */
@ -84,29 +81,26 @@ ub_resolve_timeout(void *arg)
cb(context, GETDNS_CALLBACK_TIMEOUT, NULL, user_arg, trans_id);
}
// static void
// ub_local_resolve_timeout(evutil_socket_t fd, short what, void *arg)
// {
// netreq_cb_data *cb_data = (netreq_cb_data *) arg;
static void
ub_local_resolve_timeout(void *arg)
{
netreq_cb_data *cb_data = (netreq_cb_data *) arg;
// /* cleanup the local timer here since the memory may be
// * invalid after calling ub_resolve_callback
// */
// getdns_dns_req *dnsreq = cb_data->netreq->owner;
// event_free(dnsreq->local_cb_timer);
// dnsreq->local_cb_timer = NULL;
/* cleanup the local timer here since the memory may be
* invalid after calling ub_resolve_callback
*/
getdns_dns_req *dnsreq = cb_data->netreq->owner;
/* clear the timeout */
// /* just call ub_resolve_callback */
// ub_resolve_callback(cb_data->netreq, cb_data->err, cb_data->result,
// cb_data->sec, cb_data->bogus);
getdns_context_clear_timeout(dnsreq->context, dnsreq->local_timeout_id);
dnsreq->local_timeout_id = 0;
// /* cleanup the state */
// ldns_buffer_free(cb_data->result);
// if (cb_data->bogus) {
// free(cb_data->bogus);
// }
// free(cb_data);
// }
/* just call ub_resolve_callback */
ub_resolve_callback(cb_data->netreq, cb_data->err, cb_data->ub_res);
/* cleanup the state */
free(cb_data);
}
static void call_user_callback(getdns_dns_req *dns_req,
struct getdns_dict *response)
@ -212,6 +206,7 @@ ub_supporting_callback(void* arg, int err, struct ub_result* ub_res)
ldns_rr_list_free(keys);
ldns_pkt_free(p);
ub_resolve_free(ub_res);
done: if (response->err == 0 && response->result == NULL)
response->err = -1;
@ -247,19 +242,22 @@ static void submit_link(struct validation_chain *chain, char *name)
link->DS.unbound_id = -1;
ldns_rbtree_insert(&(chain->root), (ldns_rbnode_t *)link);
/* fprintf(stderr, "submitting for: %s\n", name); */
chain->todo++;
r = ub_resolve_async(chain->dns_req->context->unbound_ctx,
name, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &link->DNSKEY,
ub_supporting_callback, &link->DNSKEY.unbound_id);
if (r != 0)
link->DNSKEY.err = r;
name, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &link->DNSKEY,
ub_supporting_callback, &link->DNSKEY.unbound_id);
if (r != 0)
link->DNSKEY.err = r;
r = ub_resolve_async(chain->dns_req->context->unbound_ctx,
name, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, &link->DS,
ub_supporting_callback, &link->DS.unbound_id);
if (r != 0)
link->DS.err = r;
if (name[0] != '.' || name[1] != '\0') {
r = ub_resolve_async(chain->dns_req->context->unbound_ctx,
name, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, &link->DS,
ub_supporting_callback, &link->DS.unbound_id);
if (r != 0)
link->DS.err = r;
}
chain->todo--;
}
void destroy_chain_link(ldns_rbnode_t * node, void *arg)
@ -299,7 +297,6 @@ static void callback_on_complete_chain(struct validation_chain *chain)
((const char *)link->node.key)[1] != '\0' ))
todo++;
}
/* fprintf(stderr, "todo until validation: %d\n", (int)todo); */
if (todo == 0) {
getdns_dns_req *dns_req = chain->dns_req;
response = create_getdns_response(chain->dns_req);
@ -334,7 +331,7 @@ static void get_validation_chain(getdns_dns_req *dns_req)
chain->mf.mf.ext.realloc = dns_req->context->mf.mf.ext.realloc;
chain->mf.mf.ext.free = dns_req->context->mf.mf.ext.free;
chain->dns_req = dns_req;
chain->todo = 1;
chain->todo = 0;
while (netreq) {
size_t i;
@ -347,7 +344,6 @@ static void get_validation_chain(getdns_dns_req *dns_req)
}
netreq = netreq->next;
}
chain->todo--;
callback_on_complete_chain(chain);
}
@ -396,39 +392,21 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
* This most likely means that getdns_general has not returned
*/
if (netreq->state == NET_REQ_NOT_SENT) {
/* TODO!!!! */
/* just do a very short timer since this was called immediately.
* we can make this less hacky, but it gets interesting when multiple
* netreqs need to be issued and some resolve immediately vs. not.
*/
// struct timeval tv;
// getdns_dns_req *dnsreq = netreq->owner;
// netreq_cb_data *cb_data =
// (netreq_cb_data *) malloc(sizeof(netreq_cb_data));
getdns_dns_req *dnsreq = netreq->owner;
netreq_cb_data *cb_data =
(netreq_cb_data *) malloc(sizeof(netreq_cb_data));
cb_data->netreq = netreq;
cb_data->err = err;
cb_data->ub_res = ub_res;
// cb_data->netreq = netreq;
// cb_data->err = err;
// cb_data->sec = sec;
// cb_data->result = NULL;
// cb_data->bogus = NULL; /* unused but here in case we need it */
// if (result) {
// cb_data->result =
// ldns_buffer_new(ldns_buffer_limit(result));
// if (!cb_data->result) {
// cb_data->err = GETDNS_RETURN_GENERIC_ERROR;
// } else {
// /* copy */
// ldns_buffer_copy(cb_data->result, result);
// }
// }
// /* schedule the timeout */
// dnsreq->local_cb_timer =
// evtimer_new(dnsreq->ev_base, ub_local_resolve_timeout,
// cb_data);
// tv.tv_sec = 0;
// /* half ms */
// tv.tv_usec = 500;
// evtimer_add(dnsreq->local_cb_timer, &tv);
dnsreq->local_timeout_id = ldns_get_random();
getdns_context_schedule_timeout(dnsreq->context,
dnsreq->local_timeout_id, 1, ub_local_resolve_timeout, cb_data);
return;
}
netreq->state = NET_REQ_FINISHED;

View File

@ -96,6 +96,10 @@ dns_req_free(getdns_dns_req * req)
net_req = next;
}
if (req->local_timeout_id != 0) {
getdns_context_clear_timeout(context, req->local_timeout_id);
}
getdns_context_clear_timeout(context, req->trans_id);
/* free strduped name */
@ -132,6 +136,7 @@ dns_req_new(struct getdns_context *context,
/* will be set by caller */
result->user_pointer = NULL;
result->user_callback = NULL;
result->local_timeout_id = 0;
/* create the requests */
req = network_req_new(result,

View File

@ -10,11 +10,13 @@
#include "check_getdns_common.h"
#include "check_getdns_general.h"
#include "check_getdns_general_sync.h"
#include "check_getdns_address.h"
#include "check_getdns_address_sync.h"
#include "check_getdns_hostname.h"
#include "check_getdns_hostname_sync.h"
#include "check_getdns_context_create.h"
#include "check_getdns_context_destroy.h"
#include "check_getdns_cancel_callback.h"
#include "check_getdns_address.h"
#include "check_getdns_address_sync.h"
#include "check_getdns_list_get_length.h"
#include "check_getdns_list_get_data_type.h"
#include "check_getdns_list_get_dict.h"
@ -52,6 +54,8 @@ main (int argc, char** argv)
Suite *getdns_general_sync_suite(void);
Suite *getdns_address_suite(void);
Suite *getdns_address_sync_suite(void);
Suite *getdns_hostname_suite(void);
Suite *getdns_hostname_sync_suite(void);
Suite *getdns_context_create_suite(void);
Suite *getdns_context_destroy_suite(void);
Suite *getdns_cancel_callback_suite(void);
@ -83,6 +87,8 @@ main (int argc, char** argv)
srunner_add_suite(sr, getdns_general_sync_suite());
srunner_add_suite(sr, getdns_address_suite());
srunner_add_suite(sr, getdns_address_sync_suite());
srunner_add_suite(sr, getdns_hostname_suite());
srunner_add_suite(sr, getdns_hostname_sync_suite());
srunner_add_suite(sr, getdns_context_create_suite());
srunner_add_suite(sr, getdns_context_destroy_suite());
srunner_add_suite(sr, getdns_cancel_callback_suite());

View File

@ -0,0 +1,480 @@
#ifndef _check_getdns_hostname_h_
#define _check_getdns_hostname_h_
/*
**************************************************************************
* *
* T E S T S F O R G E T D N S _ H O S T N A M E *
* *
**************************************************************************
*/
START_TEST (getdns_hostname_1)
{
/*
* context = NULL
* expect: GETDNS_RETURN_BAD_CONTEXT
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
getdns_transaction_t transaction_id = 0;
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_BAD_CONTEXT, "Return code from getdns_hostname()");
DICT_DESTROY(address);
}
END_TEST
START_TEST (getdns_hostname_2)
{
/*
* address = NULL
* expect: GETDNS_RETURN_INVALID_PARAMETER
*/
struct getdns_context *context = NULL;
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, NULL, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_3)
{
/*
* dict in address does not contain getdns_bindata
* expect: GETDNS_RETURN_NO_SUCH_DICT_NAME
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_NO_SUCH_DICT_NAME, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_4)
{
/*
* dict in address does not contain two names
* expect: GETDNS_RETURN_NO_SUCH_DICT_NAME
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *) "IPv4" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_NO_SUCH_DICT_NAME, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_5)
{
/*
* dict in address contains names other than adddress_type
* and address_data.
* expect: GETDNS_RETURN_NO_SUCH_DICT_NAME
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_int(address, "not_address_type", 100),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_dict_set_bindata(address, "not_address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_NO_SUCH_DICT_NAME, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_6)
{
/*
* dict in address contains names address_type
* and address_data but data type is not bindata
* expect: GETDNS_RETURN_WRONG_TYPE_REQUESTED
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_int(address, "address_type", 100),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_dict_set_int(address, "address_data", 200),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_WRONG_TYPE_REQUESTED, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_7)
{
/*
* dict in address contains invalid address_type
* expect: GETDNS_RETURN_GENERIC_ERROR
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv5" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_GENERIC_ERROR, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_8)
{
/*
* dict in address contains invalid address_data
* expect: GETDNS_RETURN_GENERIC_ERROR
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 5, (void *)"\x08\x08\x08\x08\x08" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_GENERIC_ERROR, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_9)
{
/*
* callbackfn = NULL
* expect: GETDNS_RETURN_INVALID_PARAMETER
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
NULL, &transaction_id, NULL),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_10)
{
/*
* dict in address has resolvable IPv4 address
* expect: response with correct hostname
*/
void verify_getdns_hostname_10(struct extracted_response *ex_response);
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
verify_getdns_hostname_10, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_hostname_10(struct extracted_response *ex_response)
{
assert_noerror(ex_response);
assert_ptr_in_answer(ex_response);
}
START_TEST (getdns_hostname_11)
{
/*
* dict in address has unresolvable IPv4 address
* expect: response with no hostname
*/
void verify_getdns_hostname_11(struct extracted_response *ex_response);
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x01\x01\x01\x01" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
verify_getdns_hostname_11, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_hostname_11(struct extracted_response *ex_response)
{
assert_nxdomain(ex_response);
assert_nodata(ex_response);
assert_soa_in_authority(ex_response);
}
START_TEST (getdns_hostname_12)
{
/*
* dict in address has resolvable IPv6 address
* expect: response with correct hostname
*/
void verify_getdns_hostname_12(struct extracted_response *ex_response);
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv6" };
struct getdns_bindata address_data = { 16, (void *)"\x26\x07\xf8\xb0\x40\x06\x08\x02\x00\x00\x00\x00\x00\x00\x10\x04" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
verify_getdns_hostname_12, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_hostname_12(struct extracted_response *ex_response)
{
assert_noerror(ex_response);
assert_ptr_in_answer(ex_response);
}
START_TEST (getdns_hostname_13)
{
/*
* dict in address has unresolvable IPv4 address
* expect: response with no hostname
*/
void verify_getdns_hostname_13(struct extracted_response *ex_response);
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv6" };
struct getdns_bindata address_data = { 16, (void *)"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" };
struct event_base *event_base = NULL;
getdns_transaction_t transaction_id = 0;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
EVENT_BASE_CREATE;
ASSERT_RC(getdns_hostname(context, address, NULL,
verify_getdns_hostname_13, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname()");
RUN_EVENT_LOOP;
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_hostname_13(struct extracted_response *ex_response)
{
assert_nxdomain(ex_response);
assert_nodata(ex_response);
assert_soa_in_authority(ex_response);
}
Suite *
getdns_hostname_suite (void)
{
Suite *s = suite_create ("getdns_hostname()");
/* Negative test caseis */
TCase *tc_neg = tcase_create("Negative");
tcase_add_test(tc_neg, getdns_hostname_1);
tcase_add_test(tc_neg, getdns_hostname_2);
tcase_add_test(tc_neg, getdns_hostname_3);
tcase_add_test(tc_neg, getdns_hostname_4);
tcase_add_test(tc_neg, getdns_hostname_5);
tcase_add_test(tc_neg, getdns_hostname_6);
tcase_add_test(tc_neg, getdns_hostname_7);
tcase_add_test(tc_neg, getdns_hostname_8);
tcase_add_test(tc_neg, getdns_hostname_9);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_hostname_10);
tcase_add_test(tc_pos, getdns_hostname_11);
tcase_add_test(tc_pos, getdns_hostname_12);
tcase_add_test(tc_pos, getdns_hostname_13);
suite_add_tcase(s, tc_pos);
return s;
}
#endif

View File

@ -0,0 +1,402 @@
#ifndef _check_getdns_hostname_sync_h_
#define _check_getdns_hostname_sync_h_
/*
**************************************************************************
* *
* T E S T S F O R G E T D N S _ H O S T N A M E _ S Y N C *
* *
**************************************************************************
*/
START_TEST (getdns_hostname_sync_1)
{
/*
* context = NULL
* expect: GETDNS_RETURN_BAD_CONTEXT
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct getdns_dict *response = NULL;
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_BAD_CONTEXT, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
}
END_TEST
START_TEST (getdns_hostname_sync_2)
{
/*
* address = NULL
* expect: GETDNS_RETURN_INVALID_PARAMETER
*/
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_hostname_sync(context, NULL, NULL, &response),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_hostname_sync()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_3)
{
/*
* response = NULL
* expect: GETDNS_RETURN_INVALID_PARAMETER
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, NULL),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_4)
{
/*
* dict in address does not contain getdns_bindata
* expect: GETDNS_RETURN_NO_SUCH_DICT_NAME
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_NO_SUCH_DICT_NAME, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_5)
{
/*
* dict in address does not contain two names
* expect: GETDNS_RETURN_NO_SUCH_DICT_NAME
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *) "IPv4" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_NO_SUCH_DICT_NAME, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_6)
{
/*
* dict in address contains names other than adddress_type
* and address_data.
* expect: GETDNS_RETURN_NO_SUCH_DICT_NAME
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_int(address, "not_address_type", 100),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_dict_set_bindata(address, "not_address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_NO_SUCH_DICT_NAME, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_7)
{
/*
* dict in address contains names address_type
* and address_data but data type is not bindata
* expect: GETDNS_RETURN_WRONG_TYPE_REQUESTED
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_int(address, "address_type", 100),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_dict_set_int(address, "address_data", 200),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_WRONG_TYPE_REQUESTED, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_8)
{
/*
* dict in address contains invalid address_type
* expect: GETDNS_RETURN_WRONG_TYPE_REQUESTED
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv5" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_GENERIC_ERROR, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_9)
{
/*
* dict in address contains invalid address_data
* expect: GETDNS_RETURN_GENERIC_ERROR
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 5, (void *)"\x08\x08\x08\x08\x08" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_GENERIC_ERROR, "Return code from getdns_hostname_sync()");
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_10)
{
/*
* dict in address has resolvable IPv4 address
* expect: response with correct hostnam
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname_sync()");
EXTRACT_RESPONSE;
assert_noerror(&ex_response);
assert_ptr_in_answer(&ex_response);
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_11)
{
/*
* dict in address has unresolvable IPv4 address
* expect: response with no hostname
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x01\x01\x01\x01" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname_sync()");
EXTRACT_RESPONSE;
assert_nxdomain(&ex_response);
assert_nodata(&ex_response);
assert_soa_in_authority(&ex_response);
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_12)
{
/*
* dict in address has resolvable IPv6 address
* expect: response with correct hostnam
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv6" };
struct getdns_bindata address_data = { 16, (void *)"\x26\x07\xf8\xb0\x40\x06\x08\x02\x00\x00\x00\x00\x00\x00\x10\x04" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname_sync()");
EXTRACT_RESPONSE;
assert_noerror(&ex_response);
assert_ptr_in_answer(&ex_response);
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_hostname_sync_13)
{
/*
* dict in address has unresolvable IPv6 address
* expect: response with no hostname
*/
struct getdns_context *context = NULL;
struct getdns_dict *address = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv6" };
struct getdns_bindata address_data = { 16, (void *)"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" };
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
DICT_CREATE(address);
ASSERT_RC(getdns_dict_set_bindata(address, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(address, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_hostname_sync(context, address, NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_hostname_sync()");
EXTRACT_RESPONSE;
assert_nxdomain(&ex_response);
assert_nodata(&ex_response);
assert_soa_in_authority(&ex_response);
DICT_DESTROY(address);
CONTEXT_DESTROY;
}
END_TEST
Suite *
getdns_hostname_sync_suite (void)
{
Suite *s = suite_create ("getdns_hostname_sync()");
/* Negative test caseis */
TCase *tc_neg = tcase_create("Negative");
tcase_add_test(tc_neg, getdns_hostname_sync_1);
tcase_add_test(tc_neg, getdns_hostname_sync_2);
tcase_add_test(tc_neg, getdns_hostname_sync_3);
tcase_add_test(tc_neg, getdns_hostname_sync_4);
tcase_add_test(tc_neg, getdns_hostname_sync_5);
tcase_add_test(tc_neg, getdns_hostname_sync_6);
tcase_add_test(tc_neg, getdns_hostname_sync_7);
tcase_add_test(tc_neg, getdns_hostname_sync_8);
tcase_add_test(tc_neg, getdns_hostname_sync_9);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_hostname_sync_10);
tcase_add_test(tc_pos, getdns_hostname_sync_11);
tcase_add_test(tc_pos, getdns_hostname_sync_12);
tcase_add_test(tc_pos, getdns_hostname_sync_13);
suite_add_tcase(s, tc_pos);
return s;
}
#endif

View File

@ -1,3 +1,4 @@
#include "config.h"
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/event.h>
#else

View File

@ -175,6 +175,9 @@ typedef struct getdns_dns_req
/* the transaction id */
getdns_transaction_t trans_id;
/* local timeout id */
getdns_transaction_t local_timeout_id;
} getdns_dns_req;
#define MF_PLAIN ((void *)&plain_mem_funcs_user_arg)