Merge in develop.

This commit is contained in:
Neel Goyal 2014-01-31 14:50:38 -05:00
commit 81c5de26ea
17 changed files with 1644 additions and 291 deletions

View File

@ -80,7 +80,7 @@ $(distdir):
cp $(srcdir)/src/test/*.good $(distdir)/src/test
cp $(srcdir)/src/test/*.can $(distdir)/src/test
cp $(srcdir)/src/example/Makefile.in $(distdir)/src/example
cp $(srcdir)/src/example/*.c $(distdir)/src/example
cp $(srcdir)/src/example/*.[ch] $(distdir)/src/example
cp $(srcdir)/doc/Makefile.in $(distdir)/doc
cp $(srcdir)/doc/*.in $(distdir)/doc

View File

@ -34,7 +34,7 @@ CFLAGS=@CFLAGS@ -Wall -I$(srcdir)/ -I/usr/local/include -std=c99
LDFLAGS=@LDFLAGS@ @LIBS@
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
hostname.lo service.lo request-internal.lo validate_dnssec.lo \
util-internal.lo getdns_error.lo
util-internal.lo getdns_error.lo rr-dict.lo
ifeq ($(have_libevent),1)
GETDNS_OBJ += extension/libevent.lo
@ -52,9 +52,6 @@ default: all
all: libgetdns.la
test:
cd test && $(MAKE) $@
example:
cd example && $(MAKE) $@

View File

@ -40,6 +40,7 @@
#include "types-internal.h"
#include "util-internal.h"
#include "dict.h"
#include "rr-dict.h"
/*---------------------------------------- getdns_dict_find */
/**
@ -491,6 +492,18 @@ getdns_indent(size_t indent)
return spaces + 80 - (indent < 80 ? indent : 0);
} /* getdns_indent */
static int
priv_getdns_bindata_is_dname(struct getdns_bindata *bindata)
{
size_t i = 0, n_labels = 0;
while (i < bindata->size) {
i += bindata->data[i] + 1;
n_labels++;
}
return i == bindata->size && n_labels > 1 &&
bindata->data[bindata->size - 1] == 0;
}
/*---------------------------------------- getdns_pp_bindata */
/**
* private function to pretty print bindata to a ldns_buffer
@ -506,6 +519,7 @@ getdns_pp_bindata(ldns_buffer * buf, size_t indent,
{
size_t i, p = ldns_buffer_position(buf);
uint8_t *dptr;
char *dname;
if (ldns_buffer_printf(buf, " <bindata ") < 0)
return -1;
@ -516,9 +530,22 @@ getdns_pp_bindata(ldns_buffer * buf, size_t indent,
while (i < bindata->size - 1 && isprint(bindata->data[i]))
i++;
if (i >= bindata->size - 1) { /* all chars were printable */
if (ldns_buffer_printf(buf, "for \"%s\">", bindata->data) < 0)
if (bindata->size > 1 && i >= bindata->size - 1) { /* all printable? */
if (ldns_buffer_printf(buf, "of \"%s\">", bindata->data) < 0)
return -1;
} else if (bindata->size == 1 && *bindata->data == 0) {
if (ldns_buffer_printf(buf, "for .>") < 0)
return -1;
} else if (priv_getdns_bindata_is_dname(bindata)) {
dname = getdns_convert_dns_name_to_fqdn((char *)bindata->data);
if (ldns_buffer_printf(buf, "for %s>", dname) < 0) {
free(dname);
return -1;
}
free(dname);
} else {
if (ldns_buffer_printf(buf, "of 0x") < 0)
return -1;
@ -641,6 +668,7 @@ getdns_pp_dict(ldns_buffer * buf, size_t indent,
{
size_t i, length, p = ldns_buffer_position(buf);
struct getdns_dict_item *item;
const char *strval;
if (dict == NULL)
return 0;
@ -659,6 +687,14 @@ getdns_pp_dict(ldns_buffer * buf, size_t indent,
switch (item->dtype) {
case t_int:
if ((strcmp(item->node.key, "type") == 0 ||
strcmp(item->node.key, "type_covered") == 0) &&
(strval = priv_getdns_rr_type_name(item->data.n))) {
if (ldns_buffer_printf(
buf, " GETDNS_RRTYPE_%s", strval) < 0)
return -1;
break;
}
if (ldns_buffer_printf(buf, " %d", item->data.n) < 0)
return -1;
break;

View File

@ -301,6 +301,7 @@ static void callback_on_complete_chain(struct validation_chain *chain)
}
/* 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);
keys = ldns_rr_list_new();
@ -315,7 +316,7 @@ static void callback_on_complete_chain(struct validation_chain *chain)
getdns_list_destroy(getdns_keys);
ldns_rr_list_free(keys);
destroy_chain(context, chain);
call_user_callback(chain->dns_req, response);
call_user_callback(dns_req, response);
}
}

762
src/rr-dict.c Normal file
View File

@ -0,0 +1,762 @@
/**
*
* /brief getdns support functions for DNS Resource Records
*
* This file contains the tables with the information needed by getdns about
* individual RRs, such as their name and rdata fields and types.
* This information is provided via the response dict.
*
*/
/*
* 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 "rr-dict.h"
#include "types-internal.h"
#include "context.h"
#define ALEN(a) (sizeof(a)/sizeof(a[0]))
struct rdata_def {
const char *name;
int type;
};
struct rr_def {
const char *name;
const struct rdata_def *rdata;
int n_rdata_fields;
};
static struct rdata_def a_rdata[] = {
{ "ipv4_address" , t_bindata }};
static struct rdata_def ns_rdata[] = {
{ "nsdname" , t_bindata }};
static struct rdata_def md_rdata[] = {
{ "madname" , t_bindata }};
static struct rdata_def mf_rdata[] = {
{ "madname" , t_bindata }};
static struct rdata_def cname_rdata[] = {
{ "cname" , t_bindata }};
static struct rdata_def soa_rdata[] = {
{ "mname" , t_bindata },
{ "rname" , t_bindata },
{ "serial" , t_int },
{ "refresh" , t_int },
{ "refresh" , t_int },
{ "retry" , t_int },
{ "expire" , t_int }};
static struct rdata_def mb_rdata[] = {
{ "madname" , t_bindata }};
static struct rdata_def mg_rdata[] = {
{ "mgmname" , t_bindata }};
static struct rdata_def mr_rdata[] = {
{ "newname" , t_bindata }};
static struct rdata_def null_rdata[] = {
{ "anything" , t_bindata }};
static struct rdata_def wks_rdata[] = {
{ "address" , t_bindata },
{ "protocol" , t_int },
{ "bitmap" , t_bindata }};
static struct rdata_def ptr_rdata[] = {
{ "ptrdname" , t_bindata }};
static struct rdata_def hinfo_rdata[] = {
{ "cpu" , t_bindata }};
static struct rdata_def minfo_rdata[] = {
{ "rmailbx" , t_bindata }};
static struct rdata_def mx_rdata[] = {
{ "preference" , t_bindata }};
static struct rdata_def txt_rdata[] = {
{ "txt_strings" , t_list }};
static struct rdata_def rp_rdata[] = {
{ "mbox_dname" , t_bindata }};
static struct rdata_def afsdb_rdata[] = {
{ "subtype" , t_bindata }};
static struct rdata_def x25_rdata[] = {
{ "psdn_address" , t_bindata }};
static struct rdata_def isdn_rdata[] = {
{ "isdn_address" , t_bindata }};
static struct rdata_def rt_rdata[] = {
{ "preference" , t_bindata }};
static struct rdata_def nsap_rdata[] = {
{ "nsap" , t_bindata }};
static struct rdata_def sig_rdata[] = {
{ "sig_obsolete" , t_bindata }};
static struct rdata_def key_rdata[] = {
{ "key_obsolete" , t_bindata }};
static struct rdata_def px_rdata[] = {
{ "preference" , t_int },
{ "map822" , t_bindata },
{ "mapx400" , t_bindata }};
static struct rdata_def gpos_rdata[] = {
{ "longitude" , t_bindata },
{ "latitude" , t_bindata },
{ "altitude" , t_bindata }};
static struct rdata_def aaaa_rdata[] = {
{ "ipv6_address" , t_bindata }};
static struct rdata_def loc_rdata[] = {
{ "loc_obsolete" , t_bindata }};
static struct rdata_def nxt_rdata[] = {
{ "nxt_obsolete" , t_bindata }};
static struct rdata_def eid_rdata[] = {
{ "eid_unknown" , t_bindata }};
static struct rdata_def nimloc_rdata[] = {
{ "nimloc_unknown" , t_bindata }};
static struct rdata_def srv_rdata[] = {
{ "priority" , t_int },
{ "weight" , t_int },
{ "port" , t_int },
{ "target" , t_bindata }};
static struct rdata_def atma_rdata[] = {
{ "format" , t_bindata }};
static struct rdata_def naptr_rdata[] = {
{ "order" , t_int },
{ "preference" , t_int },
{ "flags" , t_bindata },
{ "service" , t_bindata },
{ "regexp" , t_bindata },
{ "replacement" , t_bindata }};
static struct rdata_def kx_rdata[] = {
{ "preference" , t_bindata }};
static struct rdata_def cert_rdata[] = {
{ "type" , t_int },
{ "key_tag" , t_int },
{ "algorithm" , t_int },
{ "certificate_or_crl" , t_bindata }};
static struct rdata_def a6_rdata[] = {
{ "a6_obsolete" , t_bindata }};
static struct rdata_def dname_rdata[] = {
{ "target" , t_bindata }};
static struct rdata_def sink_rdata[] = {
{ "sink_unknown" , t_bindata }};
static struct rdata_def opt_rdata[] = {
{ "options" , t_dict },
{ "option_code" , t_int },
{ "option_data" , t_bindata }};
static struct rdata_def apl_rdata[] = {
{ "apitems" , t_dict },
{ "address_family" , t_int },
{ "prefix" , t_int },
{ "n" , t_int },
{ "afdpart" , t_bindata }};
static struct rdata_def ds_rdata[] = {
{ "key_tag" , t_int },
{ "algorithm" , t_int },
{ "digest_type" , t_int },
{ "digest" , t_bindata }};
static struct rdata_def sshfp_rdata[] = {
{ "algorithm" , t_int },
{ "fp_type" , t_int },
{ "fingerprint" , t_bindata }};
static struct rdata_def ipseckey_rdata[] = {
{ "algorithm" , t_int },
{ "gateway_type" , t_int },
{ "precedence" , t_int },
{ "gateway" , t_bindata },
{ "public_key" , t_bindata }};
static struct rdata_def rrsig_rdata[] = {
{ "type_covered" , t_int },
{ "algorithm" , t_int },
{ "labels" , t_int },
{ "original_ttl" , t_int },
{ "signature_expiration" , t_int },
{ "signature_inception" , t_int },
{ "key_tag" , t_int },
{ "signers_name" , t_bindata },
{ "signature" , t_bindata }};
static struct rdata_def nsec_rdata[] = {
{ "next_domain_name" , t_bindata }};
static struct rdata_def dnskey_rdata[] = {
{ "flags" , t_int },
{ "protocol" , t_int },
{ "algorithm" , t_int },
{ "public_key" , t_bindata }};
static struct rdata_def dhcid_rdata[] = {
{ "dhcid_opaque" , t_bindata }};
static struct rdata_def nsec3_rdata[] = {
{ "hash_algorithm" , t_int },
{ "flags" , t_int },
{ "iterations" , t_int },
{ "salt" , t_bindata },
{ "next_hashed_owner_name" , t_bindata },
{ "type_bit_maps" , t_bindata }};
static struct rdata_def nsec3param_rdata[] = {
{ "hash_algorithm" , t_int },
{ "flags" , t_int },
{ "iterations" , t_int },
{ "salt" , t_bindata }};
static struct rdata_def tlsa_rdata[] = {
{ "certificate_usage" , t_int },
{ "selector" , t_int },
{ "matching_type" , t_int },
{ "certificate_association_data", t_bindata }};
static struct rdata_def hip_rdata[] = {
{ "pk_algorithm" , t_int },
{ "hit" , t_bindata },
{ "public_key" , t_bindata },
{ "rendezvous_servers" , t_list }};
static struct rdata_def ninfo_rdata[] = {
{ "ninfo_unknown" , t_bindata }};
static struct rdata_def rkey_rdata[] = {
{ "rkey_unknown" , t_bindata }};
static struct rdata_def talink_rdata[] = {
{ "talink_unknown" , t_bindata }};
static struct rdata_def cds_rdata[] = {
{ "cds_unknown" , t_bindata }};
static struct rdata_def spf_rdata[] = {
{ "text" , t_bindata }};
static struct rdata_def uinfo_rdata[] = {
{ "uinfo_unknown" , t_bindata }};
static struct rdata_def uid_rdata[] = {
{ "uid_unknown" , t_bindata }};
static struct rdata_def gid_rdata[] = {
{ "gid_unknown" , t_bindata }};
static struct rdata_def unspec_rdata[] = {
{ "unspec_unknown" , t_bindata }};
static struct rdata_def nid_rdata[] = {
{ "preference" , t_int },
{ "node_id" , t_bindata }};
static struct rdata_def l32_rdata[] = {
{ "preference" , t_int },
{ "locator32" , t_bindata }};
static struct rdata_def l64_rdata[] = {
{ "preference" , t_int },
{ "locator64" , t_bindata }};
static struct rdata_def lp_rdata[] = {
{ "preference" , t_int },
{ "fqdn" , t_bindata }};
static struct rdata_def eui48_rdata[] = {
{ "eui48_address" , t_bindata }};
static struct rdata_def eui64_rdata[] = {
{ "eui64_address" , t_bindata }};
static struct rdata_def tkey_rdata[] = {
{ "algorithm" , t_bindata },
{ "inception" , t_int },
{ "expiration" , t_int },
{ "mode" , t_int },
{ "error" , t_int },
{ "key_data" , t_bindata },
{ "other_data" , t_bindata }};
static struct rdata_def tsig_rdata[] = {
{ "algorithm" , t_bindata },
{ "time_signed" , t_bindata },
{ "fudge" , t_int },
{ "mac" , t_bindata },
{ "original_id" , t_int },
{ "error" , t_int },
{ "other_data" , t_bindata }};
static struct rdata_def mailb_rdata[] = {
{ "mailb_unknown" , t_bindata }};
static struct rdata_def maila_rdata[] = {
{ "maila_unknown" , t_bindata }};
static struct rdata_def uri_rdata[] = {
{ "priority" , t_int },
{ "weight" , t_int },
{ "target" , t_bindata }};
static struct rdata_def caa_rdata[] = {
{ "flags" , t_int },
{ "tag" , t_bindata },
{ "value" , t_bindata }};
static struct rdata_def ta_rdata[] = {
{ "ta_unknown" , t_bindata }};
static struct rdata_def dlv_rdata[] = {
{ "key_tag" , t_int },
{ "algorithm" , t_int },
{ "digest_type" , t_int },
{ "digest" , t_bindata }};
static struct rr_def rr_defs[] = {
{ NULL, NULL, 0 },
{ "A", a_rdata, ALEN( a_rdata) }, /* 1 - */
{ "NS", ns_rdata, ALEN( ns_rdata) },
{ "MD", md_rdata, ALEN( md_rdata) },
{ "MF", mf_rdata, ALEN( mf_rdata) },
{ "CNAME", cname_rdata, ALEN( cname_rdata) },
{ "SOA", soa_rdata, ALEN( soa_rdata) },
{ "MB", mb_rdata, ALEN( mb_rdata) },
{ "MG", mg_rdata, ALEN( mg_rdata) },
{ "MR", mr_rdata, ALEN( mr_rdata) },
{ "NULL", null_rdata, ALEN( null_rdata) },
{ "WKS", wks_rdata, ALEN( wks_rdata) },
{ "PTR", ptr_rdata, ALEN( ptr_rdata) },
{ "HINFO", hinfo_rdata, ALEN( hinfo_rdata) },
{ "MINFO", minfo_rdata, ALEN( minfo_rdata) },
{ "MX", mx_rdata, ALEN( mx_rdata) },
{ "TXT", txt_rdata, ALEN( txt_rdata) },
{ "RP", rp_rdata, ALEN( rp_rdata) },
{ "AFSDB", afsdb_rdata, ALEN( afsdb_rdata) },
{ "X25", x25_rdata, ALEN( x25_rdata) },
{ "ISDN", isdn_rdata, ALEN( isdn_rdata) },
{ "RT", rt_rdata, ALEN( rt_rdata) },
{ "NSAP", nsap_rdata, ALEN( nsap_rdata) }, /* - 22 */
{ NULL, NULL, 0 },
{ "SIG", sig_rdata, ALEN( sig_rdata) }, /* 24 - */
{ "KEY", key_rdata, ALEN( key_rdata) },
{ "PX", px_rdata, ALEN( px_rdata) },
{ "GPOS", gpos_rdata, ALEN( gpos_rdata) },
{ "AAAA", aaaa_rdata, ALEN( aaaa_rdata) },
{ "LOC", loc_rdata, ALEN( loc_rdata) },
{ "NXT", nxt_rdata, ALEN( nxt_rdata) },
{ "EID", eid_rdata, ALEN( eid_rdata) },
{ "NIMLOC", nimloc_rdata, ALEN( nimloc_rdata) },
{ "SRV", srv_rdata, ALEN( srv_rdata) },
{ "ATMA", atma_rdata, ALEN( atma_rdata) },
{ "NAPTR", naptr_rdata, ALEN( naptr_rdata) },
{ "KX", kx_rdata, ALEN( kx_rdata) },
{ "CERT", cert_rdata, ALEN( cert_rdata) },
{ "A6", a6_rdata, ALEN( a6_rdata) },
{ "DNAME", dname_rdata, ALEN( dname_rdata) },
{ "SINK", sink_rdata, ALEN( sink_rdata) },
{ "OPT", opt_rdata, ALEN( opt_rdata) },
{ "APL", apl_rdata, ALEN( apl_rdata) },
{ "DS", ds_rdata, ALEN( ds_rdata) },
{ "SSHFP", sshfp_rdata, ALEN( sshfp_rdata) },
{ "IPSECKEY", ipseckey_rdata, ALEN( ipseckey_rdata) },
{ "RRSIG", rrsig_rdata, ALEN( rrsig_rdata) },
{ "NSEC", nsec_rdata, ALEN( nsec_rdata) },
{ "DNSKEY", dnskey_rdata, ALEN( dnskey_rdata) },
{ "DHCID", dhcid_rdata, ALEN( dhcid_rdata) },
{ "NSEC3", nsec3_rdata, ALEN( nsec3_rdata) },
{ "NSEC3PARAM", nsec3param_rdata, ALEN(nsec3param_rdata) },
{ "TLSA", tlsa_rdata, ALEN( tlsa_rdata) }, /* - 52 */
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ "HIP", hip_rdata, ALEN( hip_rdata) }, /* 55 - */
{ "NINFO", ninfo_rdata, ALEN( ninfo_rdata) },
{ "RKEY", rkey_rdata, ALEN( rkey_rdata) },
{ "TALINK", talink_rdata, ALEN( talink_rdata) },
{ "CDS", cds_rdata, ALEN( cds_rdata) }, /* - 59 */
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ "SPF", spf_rdata, ALEN( spf_rdata) }, /* 99 - */
{ "UINFO", uinfo_rdata, ALEN( uinfo_rdata) },
{ "UID", uid_rdata, ALEN( uid_rdata) },
{ "GID", gid_rdata, ALEN( gid_rdata) },
{ "UNSPEC", unspec_rdata, ALEN( unspec_rdata) },
{ "NID", nid_rdata, ALEN( nid_rdata) },
{ "L32", l32_rdata, ALEN( l32_rdata) },
{ "L64", l64_rdata, ALEN( l64_rdata) },
{ "LP", lp_rdata, ALEN( lp_rdata) },
{ "EUI48", eui48_rdata, ALEN( eui48_rdata) },
{ "EUI64", eui64_rdata, ALEN( eui64_rdata) }, /* - 109 */
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ "TKEY", tkey_rdata, ALEN( tkey_rdata) }, /* 249 - */
{ "TSIG", tsig_rdata, ALEN( tsig_rdata) }, /* - 250 */
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
{ "MAILB", mailb_rdata, ALEN( mailb_rdata) }, /* 253 - */
{ "MAILA", maila_rdata, ALEN( maila_rdata) }, /* - 254 */
{ NULL, NULL, 0 },
{ "URI", uri_rdata, ALEN( uri_rdata) }, /* 256 - */
{ "CAA", caa_rdata, ALEN( caa_rdata) }, /* - 257 */
{ "TA", ta_rdata, ALEN( ta_rdata) }, /* 32768 */
{ "DLV", dlv_rdata, ALEN( dlv_rdata) } /* 32769 */
};
static const struct rr_def *
rr_def_lookup(uint16_t rr_type)
{
if (rr_type <= 257)
return &rr_defs[rr_type];
else if (rr_type == 32768)
return &rr_defs[258];
else if (rr_type == 32769)
return &rr_defs[259];
return rr_defs;
}
const char *
priv_getdns_rr_type_name(int rr_type)
{
return rr_def_lookup(rr_type)->name;
}
static getdns_return_t
priv_getdns_equip_dict_with_rdfs(struct getdns_dict *rdata, ldns_rr *rr)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
const struct rr_def *def;
struct getdns_bindata bindata;
size_t i;
int intval;
assert(rdata);
assert(rr);
def = rr_def_lookup(ldns_rr_get_type(rr));
for (i = 0; i < ldns_rr_rd_count(rr) && r == GETDNS_RETURN_GOOD; i++) {
if (i >= def->n_rdata_fields)
break;
switch (def->rdata[i].type) {
case t_bindata: bindata.size = ldns_rdf_size(ldns_rr_rdf(rr, i));
bindata.data = ldns_rdf_data(ldns_rr_rdf(rr, i));
r = getdns_dict_set_bindata(
rdata, (char *)def->rdata[i].name, &bindata);
break;
case t_int : switch (ldns_rdf_size(ldns_rr_rdf(rr, i))) {
case 1: intval = (uint8_t)*ldns_rdf_data(
ldns_rr_rdf(rr, i));
break;
case 2: intval = ldns_read_uint16(
ldns_rdf_data(ldns_rr_rdf(rr, i)));
break;
case 4: intval = ldns_read_uint32(
ldns_rdf_data(ldns_rr_rdf(rr, i)));
break;
default: intval = -1;
/* TODO Compare with LDNS rdf types */
break;
}
r = getdns_dict_set_int(
rdata, (char *)def->rdata[i].name, intval);
break;
default : break;
}
}
return r;
}
static getdns_return_t
priv_getdns_create_dict_from_rdfs(
struct getdns_context *context, ldns_rr *rr, struct getdns_dict** rdata)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
struct getdns_bindata rdata_raw;
uint8_t *data_ptr;
size_t i;
assert(context);
assert(rr);
assert(rdata);
*rdata = getdns_dict_create_with_context(context);
if (! *rdata)
return GETDNS_RETURN_MEMORY_ERROR;
do { /* break on error (to cleanup *rdata) */
/* Count and reserve "raw" rdata space */
rdata_raw.size = 0;
for (i = 0; i < ldns_rr_rd_count(rr); i++)
rdata_raw.size += ldns_rdf_size(ldns_rr_rdf(rr, i));
rdata_raw.data = GETDNS_XMALLOC(
context->mf, uint8_t, rdata_raw.size);
if (! rdata_raw.data) {
r = GETDNS_RETURN_MEMORY_ERROR;
break;
}
/* Copy rdata fields to rdata space */
data_ptr = rdata_raw.data;
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
(void) memcpy(data_ptr,
ldns_rdf_data(ldns_rr_rdf(rr, i)),
ldns_rdf_size(ldns_rr_rdf(rr, i)));
data_ptr += ldns_rdf_size(ldns_rr_rdf(rr, i));
}
/* Set "rdata_raw" attribute" */
r = getdns_dict_set_bindata(*rdata, "rdata_raw", &rdata_raw);
GETDNS_FREE(context->mf, rdata_raw.data);
if (r != GETDNS_RETURN_GOOD)
break;
/* Now set the RR type specific attributes */
r = priv_getdns_equip_dict_with_rdfs(*rdata, rr);
if (r == GETDNS_RETURN_GOOD)
return r;
} while(0);
getdns_dict_destroy(*rdata);
return r;
}
getdns_return_t
priv_getdns_create_dict_from_rr(
struct getdns_context *context, ldns_rr *rr, struct getdns_dict** rr_dict)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
struct getdns_bindata name;
struct getdns_dict *rdata;
assert(context);
assert(rr);
assert(rr_dict);
*rr_dict = getdns_dict_create_with_context(context);
if (! *rr_dict)
return GETDNS_RETURN_MEMORY_ERROR;
do { /* break on error (to cleanup *rr_dict) */
r = getdns_dict_set_int(*rr_dict,
"type", ldns_rr_get_type(rr));
if (r != GETDNS_RETURN_GOOD)
break;
r = getdns_dict_set_int(*rr_dict,
"class", ldns_rr_get_class(rr));
if (r != GETDNS_RETURN_GOOD)
break;
r = getdns_dict_set_int(*rr_dict, "ttl", ldns_rr_ttl(rr));
if (r != GETDNS_RETURN_GOOD)
break;
/* "name" attribute.
* ldns_rr_owner(rr) is already uncompressed!
*/
name.size = ldns_rdf_size(ldns_rr_owner(rr));
name.data = ldns_rdf_data(ldns_rr_owner(rr));
r = getdns_dict_set_bindata(*rr_dict, "name", &name);
if (r != GETDNS_RETURN_GOOD)
break;
/* The "rdata" dict... copies of copies of copies :( */
r = priv_getdns_create_dict_from_rdfs(context, rr, &rdata);
if (r != GETDNS_RETURN_GOOD)
break;
r = getdns_dict_set_dict(*rr_dict, "rdata", rdata);
if (r == GETDNS_RETURN_GOOD)
return r;
getdns_dict_destroy(rdata);
} while (0);
getdns_dict_destroy(*rr_dict);
return r;
}
getdns_return_t
priv_getdns_create_reply_question_dict(
struct getdns_context *context, ldns_pkt *pkt, struct getdns_dict** q_dict)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
ldns_rr *rr;
struct getdns_bindata qname;
assert(context);
assert(pkt);
assert(q_dict);
rr = ldns_rr_list_rr(ldns_pkt_question(pkt), 0);
if (! rr)
return GETDNS_RETURN_GENERIC_ERROR;
*q_dict = getdns_dict_create_with_context(context);
if (! *q_dict)
return GETDNS_RETURN_MEMORY_ERROR;
do { /* break on error (to cleanup *q_dict) */
r = getdns_dict_set_int(*q_dict,
"qtype", ldns_rr_get_type(rr));
if (r != GETDNS_RETURN_GOOD)
break;
r = getdns_dict_set_int(*q_dict,
"qclass", ldns_rr_get_class(rr));
if (r != GETDNS_RETURN_GOOD)
break;
/* "qname" attribute.
* ldns_rr_owner(rr) is already uncompressed!
*/
qname.size = ldns_rdf_size(ldns_rr_owner(rr));
qname.data = ldns_rdf_data(ldns_rr_owner(rr));
r = getdns_dict_set_bindata(*q_dict, "qname", &qname);
if (r == GETDNS_RETURN_GOOD)
return r;
} while (0);
getdns_dict_destroy(*q_dict);
return r;
}

48
src/rr-dict.h Normal file
View File

@ -0,0 +1,48 @@
/**
*
* /brief getdns support functions for DNS Resource Records
*/
/*
* 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.
*/
#ifndef RR_DICT_H_
#define RR_DICT_H_
#include <getdns/getdns.h>
#include <ldns/ldns.h>
getdns_return_t priv_getdns_create_dict_from_rr(
struct getdns_context *context, ldns_rr *rr, struct getdns_dict** rr_dict);
getdns_return_t priv_getdns_create_reply_question_dict(
struct getdns_context *context, ldns_pkt *pkt, struct getdns_dict** q_dict);
const char *priv_getdns_rr_type_name(int rr_type);
#endif
/* rrs.h */

View File

@ -40,13 +40,13 @@ tests_stub_async: tests_stub_async.o testmessages.o
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_stub_async.o testmessages.o
tests_stub_sync: tests_stub_sync.o
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_stub_sync.o
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_stub_sync.o
check_getdns_common: check_getdns_common.o
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ check_getdns_common.o
check_getdns: check_getdns.o check_getdns_common.o
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $^
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ check_getdns.o check_getdns_common.o
tests_dnssec: tests_dnssec.o testmessages.o
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dnssec.o testmessages.o

View File

@ -13,6 +13,7 @@
#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"
@ -34,6 +35,9 @@
#include "check_getdns_convert_ulabel_to_alabel.h"
#include "check_getdns_convert_alabel_to_ulabel.h"
#include "check_getdns_pretty_print_dict.h"
#include "check_getdns_display_ip_address.h"
#include "check_getdns_context_set_context_update_callback.h"
int
main (void)
@ -43,6 +47,7 @@ main (void)
Suite *getdns_general_suite(void);
Suite *getdns_general_sync_suite(void);
Suite *getdns_address_suite(void);
Suite *getdns_address_sync_suite(void);
Suite *getdns_context_create_suite(void);
Suite *getdns_context_destroy_suite(void);
@ -68,9 +73,12 @@ main (void)
Suite *getdns_convert_ulabel_to_alabel_suite(void);
Suite *getdns_convert_alabel_to_ulabel_suite(void);
Suite *getdns_pretty_print_dict_suite(void);
Suite *getdns_display_ip_address_suite(void);
Suite *getdns_context_set_context_update_callback_suite(void);
sr = srunner_create(getdns_general_suite());
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_context_create_suite());
srunner_add_suite(sr, getdns_context_destroy_suite());
@ -95,6 +103,8 @@ main (void)
srunner_add_suite(sr, getdns_convert_ulabel_to_alabel_suite());
srunner_add_suite(sr, getdns_convert_alabel_to_ulabel_suite());
srunner_add_suite(sr, getdns_pretty_print_dict_suite());
srunner_add_suite(sr,getdns_display_ip_address_suite());
srunner_add_suite(sr,getdns_context_set_context_update_callback_suite());
srunner_set_log(sr, "check_getdns.log");
srunner_run_all(sr, CK_NORMAL);

View File

@ -0,0 +1,241 @@
#ifndef _check_getdns_address_h_
#define _check_getdns_address_h_
/*
***************************************************
* *
* T E S T S F O R G E T D N S _ A D D R E S S *
* *
***************************************************
*/
START_TEST (getdns_address_1)
{
/*
* context = NULL
* expect: GETDNS_RETURN_BAD_CONTEXT
*/
struct getdns_context *context = NULL;
getdns_transaction_t transaction_id = 0;
ASSERT_RC(getdns_address(context, "google.com", NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_BAD_CONTEXT, "Return code from getdns_address()");
}
END_TEST
START_TEST (getdns_address_2)
{
/*
* name = 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_address(context, NULL, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_3)
{
/*
* name = invalid domain (too many octets)
* expect: GETDNS_RETURN_BAD_DOMAIN_NAME
*/
struct getdns_context *context = NULL; \
struct event_base *event_base = NULL; \
getdns_transaction_t transaction_id = 0;
const char *name = "oh.my.gosh.and.for.petes.sake.are.you.fricking.crazy.man.because.this.spectacular.and.elaborately.thought.out.domain.name.of.very.significant.length.is.just.too.darn.long.because.you.know.the rfc.states.that.two.hundred.fifty.five.characters.is.the.max.com";
CONTEXT_CREATE(TRUE);
EVENT_BASE_CREATE;
ASSERT_RC(getdns_address(context, name, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_BAD_DOMAIN_NAME, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_4)
{
/*
* name = invalid domain (label too long)
* expect: GETDNS_RETURN_BAD_DOMAIN_NAME
*/
struct getdns_context *context = NULL; \
struct event_base *event_base = NULL; \
getdns_transaction_t transaction_id = 0;
const char *name = "this.domain.hasalabelwhichexceedsthemaximumdnslabelsizeofsixtythreecharacters.com";
CONTEXT_CREATE(TRUE);
EVENT_BASE_CREATE;
ASSERT_RC(getdns_address(context, name, NULL,
NULL, &transaction_id, callbackfn),
GETDNS_RETURN_BAD_DOMAIN_NAME, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_5)
{
/*
* callbackfn = 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_address(context, "google.com", NULL,
NULL, &transaction_id, NULL),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_6)
{
/*
* name = "google.com"
* status = GETDNS_RESPSTATUS_GOOD
* rcode = 0
*/
void verify_getdns_address_6(struct extracted_response *ex_response);
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_address(context, "google.com", NULL,
verify_getdns_address_6, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_address_6(struct extracted_response *ex_response)
{
assert_noerror(ex_response);
//assert_soa_in_authority(ex_response);
assert_address_in_answer(ex_response, TRUE, TRUE);
}
START_TEST (getdns_address_7)
{
/*
* name = "localhost" name should be resolved from host file
* expect: NOERROR/NODATA response:
* status = GETDNS_RESPSTATUS_GOOD
* rcode = 0
* ancount = 1 (number of records in ANSWER section)
*/
void verify_getdns_address_7(struct extracted_response *ex_response);
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_address(context, "localhost", NULL,
verify_getdns_address_7, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_address_7(struct extracted_response *ex_response)
{
assert_noerror(ex_response);
assert_address_in_answer(ex_response, TRUE, TRUE);
//assert_nodata(ex_response);
}
START_TEST (getdns_address_8)
{
/*
* name = "hostnamedoesntexist" (name should not be resolved)
* expect: NOERROR response
* status = GETDNS_RESPSTATUS_GOOD
* rcode = 0
*/
void verify_getdns_address_8(struct extracted_response *ex_response);
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_address(context, "hostnamedoesntexist", NULL,
verify_getdns_address_8, &transaction_id, callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
}
END_TEST
void verify_getdns_address_8(struct extracted_response *ex_response)
{
assert_noerror(ex_response);
assert_soa_in_authority(ex_response);
}
Suite *
getdns_address_suite (void)
{
Suite *s = suite_create ("getdns_address()");
/* Negative test caseis */
TCase *tc_neg = tcase_create("Negative");
tcase_add_test(tc_neg, getdns_address_1);
tcase_add_test(tc_neg, getdns_address_2);
tcase_add_test(tc_neg, getdns_address_3);
tcase_add_test(tc_neg, getdns_address_4);
tcase_add_test(tc_neg, getdns_address_5);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_address_6);
tcase_add_test(tc_pos, getdns_address_7);
tcase_add_test(tc_pos, getdns_address_8);
suite_add_tcase(s, tc_pos);
return s;
}
#endif

View File

@ -1,12 +1,12 @@
#ifndef _check_getdns_address_h_
#define _check_getdns_address_h_
#ifndef _check_getdns_address_sync_h_
#define _check_getdns_address_sync_h_
/*
**************************************************************************
* *
* T E S T S F O R G E T D N S _ A D D R E S S _ S Y N C *
* *
**************************************************************************
**************************************************************
* *
* T E S T S F O R G E T D N S _ A D D R E S S _ S Y N C *
* *
**************************************************************
*/
START_TEST (getdns_address_sync_1)
@ -40,52 +40,34 @@
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_3)
START_TEST (getdns_address_sync_3)
{
/*
* name = invalid domain (label too long)
* expect: GETDNS_RETURN_BAD_DOMAIN_NAME
* name = NULL
* expect: GETDNS_RETURN_BAD_DOMAIN_NAME
*/
struct getdns_context *context = NULL;
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
const char *name = "this.domain.hasalabelwhichexceedsthemaximumdnslabelsizeofsixtythreecharacters.com";
const char *name = "oh.my.gosh.and.for.petes.sake.are.you.fricking.crazy.man.because.this.spectacular.and.elaborately.thought.out.domain.name.of.very.significant.length.is.just.too.darn.long.because.you.know.the rfc.states.that.two.hundred.fifty.five.characters.is.the.max.com";
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_address_sync(context, name, NULL, &response),
ASSERT_RC(getdns_address_sync(context, name, NULL, &response),
GETDNS_RETURN_BAD_DOMAIN_NAME, "Return code from getdns_address_sync()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_4)
{
/*
* response = NULL
* expect: GETDNS_RETURN_INVALID_PARAMETER
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_address_sync(context, "google.com", NULL, NULL),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_address_sync()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_5)
{
/*
* name = "google.com"
* expect: NOERROR response:
* status = GETDNS_RETURN_GOOD
* rcode = 0
todo: create zonefile with exact count
* ancount = tbd (number of records in ANSWER section)
*/
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
@ -97,13 +79,13 @@
EXTRACT_RESPONSE;
assert_noerror(&ex_response);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_6)
START_TEST (getdns_address_sync_5)
{
/*
* name = "localhost"
@ -124,43 +106,16 @@
EXTRACT_RESPONSE;
assert_noerror(&ex_response);
assert_noerror( &ex_response);
assert_address_in_answer(&ex_response, TRUE, TRUE);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_7)
{
/*
* name = "google.joe"
* status = GETDNS_RETURN_GOOD for NXDOMAIN
* expect: NXDOMAIN response with SOA record
* rcode = 0
todo: investigate that proper search order is set for resolution (is local being checked)
todo: create host file with exact count
* ancount >= 1 (number of records in ANSWER section)
* and one SOA record ("type": 6) in "answer" list
*/
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_address_sync(context, "google.joe", NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
EXTRACT_RESPONSE;
assert_nxdomain(&ex_response);
assert_nodata(&ex_response);
assert_soa_in_authority(&ex_response);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_8)
START_TEST (getdns_address_sync_6)
{
/*
* name = "hampster.com" need to replace this with domain from unbound zone
@ -180,93 +135,12 @@
EXTRACT_RESPONSE;
assert_noerror(&ex_response);
//assert_soa_in_authority(&ex_response);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_9)
{
/*
* name = "google.com" need to swap this out for max domain name length with max lable length`
* expect: NOERROR response with A records
* status = GETDNS_RESPSTATUS_GOOD
* rcode = 0
* ancount >= 11 (number of records in ANSWER section)
*/
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_address_sync(context, "google.com", NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
EXTRACT_RESPONSE;
assert_noerror(&ex_response);
assert_address_in_answer(&ex_response, TRUE, FALSE);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_10)
{
/*
* name = "75.101.146.66" need to change this to local unbound data
* status = GETDNS_RETURN_GOOD for NXDOMAIN
* expect: NXDOMAIN response with SOA record for NUMERICAL data
* rcode = 0
* ancount >= 1 (number of records in ANSWER section)
* and one SOA record ("type": 6) in "answer" list
*/
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_address_sync(context, "75.101.146.66", NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
EXTRACT_RESPONSE;
assert_nxdomain(&ex_response);
assert_nodata(&ex_response);
assert_soa_in_authority(&ex_response);
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_address_sync_11)
{
/*
* name = "2607:f8b0:4006:802::1007" need to change this to local unbound data
* status = GETDNS_RETURN_GOOD for NXDOMAIN
* expect: NXDOMAIN response with SOA record for NUMERICAL data
* rcode = 0
* ancount >= 1 (number of records in ANSWER section)
* and one SOA record ("type": 6) in "answer" list
*/
struct getdns_context *context = NULL;
struct getdns_dict *response = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_address_sync(context, "2607:f8b0:4006:802::1007", NULL, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
EXTRACT_RESPONSE;
assert_nxdomain(&ex_response);
assert_nodata(&ex_response);
assert_soa_in_authority(&ex_response);
CONTEXT_DESTROY;
}
END_TEST
Suite *
getdns_address_sync_suite (void)
{
@ -277,18 +151,13 @@
tcase_add_test(tc_neg, getdns_address_sync_1);
tcase_add_test(tc_neg, getdns_address_sync_2);
tcase_add_test(tc_neg, getdns_address_sync_3);
tcase_add_test(tc_neg, getdns_address_sync_4);
tcase_add_test(tc_neg, getdns_address_sync_5);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_address_sync_4);
tcase_add_test(tc_pos, getdns_address_sync_5);
tcase_add_test(tc_pos, getdns_address_sync_6);
tcase_add_test(tc_pos, getdns_address_sync_7);
tcase_add_test(tc_pos, getdns_address_sync_8);
tcase_add_test(tc_pos, getdns_address_sync_9);
tcase_add_test(tc_pos, getdns_address_sync_10);
tcase_add_test(tc_pos, getdns_address_sync_11);
suite_add_tcase(s, tc_pos);
return s;

View File

@ -10,6 +10,7 @@
int callback_called = 0;
int callback_completed = 0;
int callback_canceled = 0;
uint16_t expected_changed_item = 0;
/*
* extract_response extracts all of the various information
@ -270,3 +271,19 @@ void callbackfn(struct getdns_context *context,
fn(&ex_response);
}
//refactor later
/*
* callbackfn is the callback function given to all
* asynchronous query tests. It is expected to only
* be called for positive tests and will verify the
* response that is returned.
*/
void update_callbackfn(struct getdns_context *context,
uint16_t changed_item)
{
ck_assert_msg(changed_item == expected_changed_item,
"Expected changed_item == %d, got %d",
changed_item, expected_changed_item);
}

View File

@ -8,6 +8,7 @@
extern int callback_called;
extern int callback_completed;
extern int callback_canceled;
extern uint16_t expected_changed_item;
struct extracted_response {
uint32_t top_answer_type;
@ -174,4 +175,11 @@
void *userarg,
getdns_transaction_t transaction_id);
/*
* update_callbackfn is the callback function given to
* getdns_context_set_context_update_callback tests.
*/
void update_callbackfn(struct getdns_context *context,
uint16_t changed_item);
#endif

View File

@ -0,0 +1,362 @@
#ifndef _check_getdns_context_set_context_update_callback_h_
#define _check_getdns_context_set_context_update_callback_h_
/*
**************************************************************************
* *
* T E S T S F O R G E T D N S _ C O N T E X T _ S E T _ C O N T E X T _ U P D A T E _ C A L L B A C K *
* *
**************************************************************************
*/
START_TEST (getdns_context_set_context_update_callback_1)
{
/*
* context is NULL
* expect: GETDNS_RETURN_BAD_CONTEXT
*/
struct getdns_context *context = NULL;
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_BAD_CONTEXT, "Return code from getdns_context_set_context_update_callback()");
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_2)
{
/*
* value is NULL
* expect: GETDNS_RETURN_INVALID_PARAMETER
*/
struct getdns_context *context = NULL;
ASSERT_RC(getdns_context_set_context_update_callback(context, NULL),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_context_set_context_update_callback()");
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_5)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* getdns_context_set_resolution_type() to GETDNS_CONTEXT_STUB
* expect: GETDNS_CONTEXT_CODE_RESOLUTION_TYPE
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_RESOLUTION_TYPE;
ASSERT_RC(getdns_context_set_resolution_type(context, GETDNS_CONTEXT_STUB),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_resolution_type()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_6)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_namespaces() to change the order and/or number of namespaces to be queried
* expect: GETDNS_CONTEXT_CODE_NAMESPACES
*/
struct getdns_context *context = NULL;
uint16_t namespace_arr[2] = {GETDNS_CONTEXT_NAMESPACE_DNS, GETDNS_CONTEXT_NAMESPACE_LOCALNAMES};
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_NAMESPACES;
ASSERT_RC(getdns_context_set_namespaces(context, 2,namespace_arr),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_namespaces()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_7)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_dns_transport() to GETDNS_CONTEXT_UDP_ONLY
* expect: GETDNS_CONTEXT_CODE_DNS_TRANSPORT
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_DNS_TRANSPORT;
ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_CONTEXT_UDP_ONLY),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_8)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_limit_outstanding_queries() and set limit to 10
* expect: GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES;
ASSERT_RC(getdns_context_set_limit_outstanding_queries(context, 10),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_limit_outstanding_queries()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_9)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_timeout() and set timeout to 3 seconds
* expect: GETDNS_CONTEXT_CODE_TIMEOUT
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_TIMEOUT;
ASSERT_RC(getdns_context_set_timeout(context, 3),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_timeout()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_10)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_follow_redirects() to GETDNS_CONTEXT_DO_NOT_FOLLOW_REDIRECTS
* expect: GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS;
ASSERT_RC(getdns_context_set_follow_redirects(context, GETDNS_CONTEXT_DO_NOT_FOLLOW_REDIRECTS),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_follow_redirects()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_15)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_stub_resolution() providing where the API should send queries to
* expect: GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS
*/
struct getdns_context *context = NULL;
struct getdns_list *upstream_list = NULL;
struct getdns_dict *dict = NULL;
size_t index = 0;
struct getdns_bindata address_type = { 5, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x0A\x58\x1E\x52" };
CONTEXT_CREATE(TRUE);
LIST_CREATE(upstream_list);
DICT_CREATE(dict);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS;
ASSERT_RC(getdns_dict_set_bindata(dict, "address_type", &address_type),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_dict_set_bindata(dict, "address_data", &address_data),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_bindata()");
ASSERT_RC(getdns_list_set_dict(upstream_list, index, dict), GETDNS_RETURN_GOOD,
"Return code from getdns_list_set_dict()");
ASSERT_RC(getdns_context_set_upstream_recursive_servers(context, upstream_list),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_upstream_recursive_servers()");
CONTEXT_DESTROY;
LIST_DESTROY(upstream_list);
DICT_DESTROY(dict);
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_16)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_edns_maximum_udp_payload_size() setting max UDP payload to 512
* expect: GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE;
ASSERT_RC(getdns_context_set_edns_maximum_udp_payload_size(context, 512),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_maximum_udp_payload_size()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_17)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_edns_extended_rcode() setting extended rcode to 1
* expect: GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE;
ASSERT_RC(getdns_context_set_edns_extended_rcode(context, 1),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_extended_rcode()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_18)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_edns_version() setting edns version to 1
* expect: GETDNS_CONTEXT_CODE_EDNS_VERSION
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_EDNS_VERSION;
ASSERT_RC(getdns_context_set_edns_version(context, 1),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_version()");
CONTEXT_DESTROY;
}
END_TEST
START_TEST (getdns_context_set_context_update_callback_19)
{
/*
* Create a context by calling getdns_context_create()
* Define a callback routine for context changes and call getdns_context_set_context_update_callback() so that it gets called when there are context changes
* Call getdns_context_set_edns_do_bit() setting edns do bit to 1
* expect: GETDNS_CONTEXT_CODE_EDNS_DO_BIT
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
expected_changed_item = GETDNS_CONTEXT_CODE_EDNS_DO_BIT;
ASSERT_RC(getdns_context_set_edns_do_bit(context, 1),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_do_bit()");
CONTEXT_DESTROY;
}
END_TEST
Suite *
getdns_context_set_context_update_callback_suite (void)
{
Suite *s = suite_create ("getdns_context_set_context_update_callback()");
/* Negative test caseis */
TCase *tc_neg = tcase_create("Negative");
tcase_add_test(tc_neg, getdns_context_set_context_update_callback_1);
tcase_add_test(tc_neg, getdns_context_set_context_update_callback_2);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_5);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_6);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_7);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_8);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_9);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_10);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_15);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_16);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_17);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_18);
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_19);
suite_add_tcase(s, tc_pos);
return s;
}
#endif

View File

@ -0,0 +1,107 @@
#ifndef _check_getdns_display_ip_address_h_
#define _check_getdns_display_ip_address_h_
/*
**************************************************************************
* *
* T E S T S F O R G E T D N S _ D I S P L A Y _ I P _ A D D R E S S *
* *
**************************************************************************
*/
START_TEST (getdns_display_ip_address_1)
{
/*
* bindata_of_ipv4_or_ipv6_address = NULL
* expect: NULL
*/
//struct getdns_bindata bindata_of_ipv4_or_ipv6_address = NULL;
char *ptr = NULL;
ptr = getdns_display_ip_address(NULL);
ck_assert_msg(ptr == NULL, "Expected retrieved bindata == NULL, got: %p",
ptr);
}
END_TEST
START_TEST (getdns_display_ip_address_2)
{
/*
* bindata_of_ipv4_or_ipv6_address is getdns_bindata but not ip addresses
* expect: Unknown
*/
char *ptr = NULL;
struct getdns_bindata bindata_of_ipv4_or_ipv6_address = { 8, (void *)"bindata" };
ptr = getdns_display_ip_address(&bindata_of_ipv4_or_ipv6_address);
ck_assert_msg(ptr == NULL, "Expected pointer == NULL, got: %p",
ptr);
}
END_TEST
START_TEST (getdns_display_ip_address_3)
{
/*
* Create bindata containing 10.88.30.82"
* Call getdns_display_ip_address() passing bindata
* expect: 10.88.30.82
*/
char *ptr = NULL;
struct getdns_bindata bindata_of_ipv4_or_ipv6_address = { 4, (void *)"\x0A\x58\x1E\x52" };
ptr = getdns_display_ip_address(&bindata_of_ipv4_or_ipv6_address);
ck_assert_msg(strcmp(ptr, "10.88.30.82") == 0, "Expected pointer == “10.88.30.82”, got: %s",
ptr);
}
END_TEST
START_TEST (getdns_display_ip_address_4)
{
/*
* Create bindata containing 2607:f8b0:4006:802::1004
* Call getdns_display_ip_address() passing bindata
* expect: 2607:f8b0:4006:802::1004
*/
char *ptr = NULL;
struct getdns_bindata bindata_of_ipv4_or_ipv6_address = { 16, (void *)"\x26\x07\xf8\xb0\x40\x06\x08\x02\x00\x00\x00\x00\x00\x00\x10\x04" };
ptr = getdns_display_ip_address(&bindata_of_ipv4_or_ipv6_address);
ck_assert_msg(strcmp(ptr, "2607:f8b0:4006:802::1004") == 0, "Expected pointer == “2607:f8b0:4006:802::1004”, got: %s",
ptr);
}
END_TEST
Suite *
getdns_display_ip_address_suite (void)
{
Suite *s = suite_create ("getdns_display_ip_address()");
/* Negative test caseis */
TCase *tc_neg = tcase_create("Negative");
tcase_add_test(tc_neg, getdns_display_ip_address_1);
tcase_add_test(tc_neg, getdns_display_ip_address_2);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_display_ip_address_3);
tcase_add_test(tc_pos, getdns_display_ip_address_4);
suite_add_tcase(s, tc_pos);
return s;
}
#endif

View File

@ -43,7 +43,7 @@
index++;
ASSERT_RC(getdns_list_get_data_type(list, index, &answer),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_list_get_data_type()");
GETDNS_RETURN_NO_SUCH_LIST_ITEM, "Return code from getdns_list_get_data_type()");
LIST_DESTROY(list);
}
@ -84,7 +84,7 @@
LIST_CREATE(list);
ASSERT_RC(getdns_list_get_data_type(list, index, &answer),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_list_get_data_type()");
GETDNS_RETURN_NO_SUCH_LIST_ITEM, "Return code from getdns_list_get_data_type()");
LIST_DESTROY(list);
}
@ -218,11 +218,11 @@
tcase_add_test(tc_neg, getdns_list_get_data_type_1);
tcase_add_test(tc_neg, getdns_list_get_data_type_2);
tcase_add_test(tc_neg, getdns_list_get_data_type_3);
tcase_add_test(tc_neg, getdns_list_get_data_type_4);
suite_add_tcase(s, tc_neg);
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_list_get_data_type_4);
tcase_add_test(tc_pos, getdns_list_get_data_type_5);
tcase_add_test(tc_pos, getdns_list_get_data_type_6);
tcase_add_test(tc_pos, getdns_list_get_data_type_7);

View File

@ -44,6 +44,7 @@
#include <string.h>
#include "testmessages.h"
#include <getdns/getdns.h>
#include <getdns/getdns_ext_libevent.h>
/* Set up the callback function, which will also do the processing of the results */
void

View File

@ -42,6 +42,7 @@
#include "util-internal.h"
#include "types-internal.h"
#include <unbound.h>
#include "rr-dict.h"
/**
* this is a comprehensive list of extensions and their data types
@ -232,118 +233,6 @@ create_reply_header_dict(struct getdns_context *context, ldns_pkt * reply)
return result;
}
static struct getdns_dict *
create_reply_question_dict(struct getdns_context *context, ldns_pkt * reply)
{
/* { "qname": <bindata for "www.example.com">, "qtype": 1, "qclass": 1 } */
int r = 0;
ldns_rr *question = NULL;
char *qname;
struct getdns_dict *result = getdns_dict_create_with_context(context);
if (!result) {
return NULL;
}
question = ldns_rr_list_rr(ldns_pkt_question(reply), 0);
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_QTYPE,
(int) ldns_rr_get_type(question));
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_QCLASS,
(int) ldns_rr_get_class(question));
qname = convert_rdf_to_str(ldns_rr_owner(question));
if (qname) {
r |= getdns_dict_util_set_string(result, GETDNS_STR_KEY_QNAME,
qname);
free(qname);
} else {
r = 1;
}
if (r != 0) {
getdns_dict_destroy(result);
result = NULL;
}
return result;
}
static struct getdns_dict *
create_dict_from_rdf(struct getdns_context *context, ldns_rdf * rdf)
{
/*
* create a dict w/ rdata_raw and special fields if needed
* i.e.
* {
* "ipv4_address": <bindata of 0x0a0b0c01>
* "rdata_raw": <bindata of 0x0a0b0c01>
* }
*/
int r = 0;
struct getdns_bindata rbin = { ldns_rdf_size(rdf), ldns_rdf_data(rdf) };
struct getdns_dict *result = getdns_dict_create_with_context(context);
r |= getdns_dict_set_bindata(result, GETDNS_STR_KEY_RDATA_RAW, &rbin);
if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_AAAA) {
r |= getdns_dict_set_bindata(result, GETDNS_STR_KEY_V6_ADDR,
&rbin);
} else if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_A) {
r |= getdns_dict_set_bindata(result, GETDNS_STR_KEY_V4_ADDR,
&rbin);
}
if (r != 0) {
getdns_dict_destroy(result);
result = NULL;
}
return result;
}
static struct getdns_dict *
create_dict_from_rr(struct getdns_context *context, ldns_rr * rr)
{
/*
* {
* "name": <bindata for "www.example.com">,
* "type": 1,
* "class": 1,
* "ttl": 33000,
* "rdata":
* {
* "ipv4_address": <bindata of 0x0a0b0c01>
* "rdata_raw": <bindata of 0x0a0b0c01>
* }
* }
*/
int r = 0;
char *name = NULL;
struct getdns_dict *result = getdns_dict_create_with_context(context);
size_t rd_count = ldns_rr_rd_count(rr);
ldns_rdf *owner = ldns_rr_owner(rr);
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_TYPE,
(int) ldns_rr_get_type(rr));
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_CLASS,
(int) ldns_rr_get_class(rr));
r |= getdns_dict_set_int(result, GETDNS_STR_KEY_TTL, ldns_rr_ttl(rr));
if (owner) {
name = convert_rdf_to_str(owner);
if (name) {
r |= getdns_dict_util_set_string(result,
GETDNS_STR_KEY_NAME, name);
free(name);
} else {
r = 1;
}
}
/* create rdatas */
if (rd_count >= 1) {
struct getdns_dict *rdata = create_dict_from_rdf(context,
ldns_rr_rdf(rr, 0));
r |= getdns_dict_set_dict(result, GETDNS_STR_KEY_RDATA, rdata);
getdns_dict_destroy(rdata);
}
/* TODO - if more than one, is rdata a list? */
if (r != 0) {
getdns_dict_destroy(result);
result = NULL;
}
return result;
}
/* helper to convert an rr_list to getdns_list.
returns a list of objects where each object
is a result from create_dict_from_rr */
@ -352,16 +241,21 @@ create_list_from_rr_list(struct getdns_context *context, ldns_rr_list * rr_list)
{
size_t i = 0;
size_t idx = 0;
int r = 0;
int r = GETDNS_RETURN_GOOD;
struct getdns_list *result = getdns_list_create_with_context(context);
for (i = 0; i < ldns_rr_list_rr_count(rr_list); ++i) {
struct getdns_dict *rrdict;
for (i = 0; i < ldns_rr_list_rr_count(rr_list) && r == GETDNS_RETURN_GOOD;
++i) {
ldns_rr *rr = ldns_rr_list_rr(rr_list, i);
struct getdns_dict *rrdict = create_dict_from_rr(context, rr);
r |= getdns_list_add_item(result, &idx);
r |= getdns_list_set_dict(result, idx, rrdict);
r = priv_getdns_create_dict_from_rr(context, rr, &rrdict);
if (r != GETDNS_RETURN_GOOD)
break; /* Could not create, do not destroy */
r = getdns_list_add_item(result, &idx);
if (r == GETDNS_RETURN_GOOD)
r = getdns_list_set_dict(result, idx, rrdict);
getdns_dict_destroy(rrdict);
}
if (r != 0) {
if (r != GETDNS_RETURN_GOOD) {
getdns_list_destroy(result);
result = NULL;
}
@ -475,7 +369,7 @@ create_reply_dict(struct getdns_context *context, getdns_network_req * req,
getdns_dict_destroy(subdict);
/* question */
subdict = create_reply_question_dict(context, reply);
r |= priv_getdns_create_reply_question_dict(context, reply, &subdict);
r |= getdns_dict_set_dict(result, GETDNS_STR_KEY_QUESTION, subdict);
getdns_dict_destroy(subdict);