[ldns-users] ldns_dnssec_verify_denial() usage

Willem Toorop willem at nlnetlabs.nl
Mon Jun 18 14:52:58 UTC 2018

Op 18-06-18 om 16:08 schreef Vladimir Levijev:
> On Mon, Jun 18, 2018 at 3:34 PM Willem Toorop <willem at nlnetlabs.nl> wrote:
>> Op 15-06-18 om 15:31 schreef Jurijs Klopovskis:
>>> I have a question about using ldns_dnssec_verify_denial() and
>>> ldns_dnssec_verify_denial_nsec3() functions.
>>> Right now in out code we perform denial of existence checks with these
>>> functions only if ldns_verify() function has failed with
>>> Is this sane?
>> Did you start out with a ldns_pkt?
>> If there were no RRsets for qname and qtype in the pkt, you can skip
>> ldns_verify() and start looking for NSECs (for
>> ldns_dnssec_verify_denial() ) or NSEC3s (for
>> ldns_dnssec_verify_denial_nsec3() ) right away.
>> But even when you did found RRsets for qname and qtype and ldns_verify()
>> returned LDNS_STATUS_OK, you still have to check whether it validated a
>> wildcard match, in which case you have to verify that a more specific
>> qname/qtype did not exist.
>> Note that getdns has a more convenient higher level function for this:
>> https://getdnsapi.net/functions/getdns_validate_dnssec.html
>> https://getdnsapi.net/functions/getdns_validate_dnssec2.html
>> Which can take a whole DNS message/packet as input and return the DNSSEC
>> status, regardless of whether the reply is for a NOERROR, NXDOMAIN or
>> NODATA response.  Also wildcard responses are validated correctly
>> automatically with that function.  (and you don't have to handle NSECs
>> and NSEC3s differently either).
> Did I understand correctly that in case of getdns I do not have a way
> to specify the Name Server I want to query?

The default is full recursive, but you can configure getdns for stub
resolution mode in which case it will target the configured upstreams.
The below example will send A and AAAA queries (simultaneously) for
nlnetlabs.nl to

#include <getdns/getdns_extra.h>

int main(int argc, char **argv)
        getdns_context *context      = NULL;
        getdns_list    *upstreams    = NULL;
        getdns_dict    *response     = NULL;
        char           *response_str = NULL;
        getdns_return_t r;

        if ((r = getdns_context_create(&context, 0)))
                fprintf(stderr, "Could not create context");

        else if ((r = getdns_context_set_resolution_type(
            context, GETDNS_RESOLUTION_STUB)))
                fprintf(stderr, "Could not set resolution type");

        else if ((r = getdns_str2list("[]", &upstreams)))
                fprintf(stderr, "Error converting upstreams list");

        else if ((r = getdns_context_set_upstream_recursive_servers(
            context, upstreams)))
                fprintf(stderr, "Could not set upstreams");

        else if ((r = getdns_address_sync(
            context, "nlnetlabs.nl", NULL, &response)))
                fprintf(stderr, "Could not query");

        else if (!(response_str = getdns_pretty_print_dict(response)))
                fprintf(stderr, "Could not print response dict\n");
                printf("%s\n", response_str);

        if (response_str)
        if (response)
        if (upstreams)
        if (context)
        if (r)
                fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r));

        return r ? EXIT_FAILURE : EXIT_SUCCESS;

> Cheers,
> VL

More information about the ldns-users mailing list