Validator(3)

πŸ“¦
version 2.2.3 Β· 3 versions
, in arch rolling

πŸ¦‹ Validator(3) β€” like, the whole vibe πŸ¦‹

okay so real talk, this is Validator(3), straight out of the User Contributed Perl Documentation section, and it's the manual page for the libval gateway. it's long, bestie, so we're doing this in parts β€” this is part 1, more is coming, don't go anywhere πŸ’…


✨ NAME ✨

Net::DNS::SEC::Validator β€” the interface to libval(3) plus all the related constants, structures and functions that come with it πŸŽ€


🌸 SYNOPSIS 🌸

here's the whole mood board, copied exactly, no cap:

  use Net::DNS::SEC::Validator;
  use Net::DNS::Packet;
  use Net::hostent;
  use Net::addrinfo;
  use Socket qw(:all);

  sub callback {

  }

  my $validator = new Net::DNS::SEC::Validator(policy => ":");
  $validator.map_ns("dnssec-tools.org", "127.0.0.1");
  my (@r) = $validator->getaddrinfo("good-A.test.dnssec-tools.org");
  my $r = $validator->res_query("dnssec-tools.org", "IN", "MX");
  my $h = $validator->gethostbyname("good-AAAA.test.dnssec-tools.org",
                                    AF_INET6);

  $validator->async_submit("badsign-a.test.dnssec-tools.org",
        "IN", "A", 0, \&callback, undef);
  do {
    my $ref = $val->async_gather($readfds, $timeout);
    my $ret = $ref->[0];
    my $readfds = $ref->[1];
    my $timeout = $ref->[2];

    if (! @$readfds) {
        last;
    }

    my @readyarr = IO::Select->new(@$readfds)->can_read($timeout);
    $ret = $validator->async_check(\@readyarr);

  } while(1);

like, look at that. it's giving "i know exactly what i'm doing" energy πŸ”₯


πŸ’œ DESCRIPTION πŸ’œ

so the Validator module gives you access to the libval(3) validating DNS resolver library β€” the whole thing. and it's not some clunky procedural mess either, the library functions are accessed through an object-oriented interface πŸ‘‘

the way this interface is designed, it's literally hiding some of the complexity of validating resolvers from you. you're welcome. and if you want to customize how the application-interface behaves, you can do that through configuration files provided by libval, and it throws back extensive error codes so you know exactly what went down 🫢

also, since Validator is basically a gateway to libval, the docs for libval have all the further details on how the Validator interfaces and parameters may be used. so like, iykyk, go read those too πŸ“š

and if you're wondering about DNSSEC and the associated resolver behavior β€” the deets live in the core DNSSEC RFCs (4033-4035). iconic numbers, honestly ⭐


to be continued… more parts coming, don't touch that dial πŸŽ€

πŸ’… INTERFACE πŸ’…

okay so this module supports both synchronous and asynchronous lookups β€” yes bestie, she does it all. Here's the API, laid out for you:

πŸŽ€ Validator Constructor πŸŽ€

This constructor builds a new validator object, and that object is what you use to make all the various resolver calls. The moment your validator object is created, a policy object gets created too. That policy object is the one handing out all the settings that control the various aspects of DNS resolution.

To create a validator object, use the Net::DNS::SEC::Validator->new() method. It takes a bunch of optional parameters, and we're about to go through every single one, don't worry πŸ’–

A policy object can be named with the policy parameter β€” that associates a label with a particular policy, so you can reference that policy again later. If you don't specify the label, it gets the default label from the libval dnsval.conf file. Easy.

The parameters to the constructor are passed as a hash, with both key and value given in the call. Besides the policy label, there are two sets of constructor parameters, and they're separated based on how they get stored and used in libval.

🌸 Context Options 🌸

This group of parameters lives in a val_context_opt structure in libval. That structure is defined in dnssec/validator/include/validator/validator.h. The context options below are the hash-key values you use in the constructor call.

  • dnsval_conf β€” the configuration policy for the libval library.
    • This file contains the validator policy. The default value is /usr/local/etc/dnssec-tools/dnsval.conf, but heads up: this may have been changed when libval was built and installed.
    • val_context_opt field: vc_val_conf
  • nslist β€” a list of name servers that should be used when resolving names.
    • This must be a white-space delimited list of IP or IPv6 addresses.
    • val_context_opt field: vc_nslist
  • polflags β€” a set of bitmapped policy flags.
    • The valid flags are defined in dnssec/validator/include/validator/validator.h. The default value is CTX_DYN_POL_RES_OVR.
    • val_context_opt field: vc_polflags
  • qflags β€” the set of default query flags.
    • The valid flags are defined in dnssec/validator/include/validator/validator.h. The default value is 0.
    • val_context_opt field: vc_qflags
  • resolv_conf β€” this file contains nameserver and search options for the libval library.
    • The default value is /usr/local/etc/dnssec-tools/resolv.conf, but (again, iykyk) this may have been changed when libval was built and installed.
    • val_context_opt field: vc_res_conf
  • root_hints β€” this file contains bootstrapping information for the name resolver.
    • The default value is /usr/local/etc/dnssec-tools/root.hints, but this may have been changed when libval was built and installed.
    • val_context_opt field: vc_root_conf
  • valpol β€” this supplies a customized piece of validator configuration to the default validator configuration, as an extension or an override.
    • This is null by default.
    • val_context_opt field: vc_valpol

⭐ Global Options ⭐

This group of parameters lives in a val_global_opt structure, which is itself stored in the gopt field of the val_context_opt structure. That structure is defined in dnssec/validator/include/validator/validator.h. The global options below are the hash-key values you use in the constructor call.

For all but the log_target field, a value of -1 means an "ignore" condition 🚫. What that means: the validator will not include dynamically supplied global options with a value of -1 when it creates its context. This is literally so an application can override just a subset of global options while using the global options supplied in the dnsval.conf file by default. Chef's kiss.

And even though libval uses the global options in a separate structure from the context options, they are all specified in the same hash when you pass them as parameters to the Validator constructor.

  • app_policy β€” this field is equivalent to the env-policy option in a dnsval.conf file. The legal values and their env-policy equivalences are:
    • VAL_POL_GOPT_DISABLE β†’ "disable"
    • VAL_POL_GOPT_ENABLE β†’ "enable"
    • VAL_POL_GOPT_OVERRIDE β†’ "override"
    • The default value is -1.
    • val_global_opt field: gopt.app_policy
  • closest_ta_only β€” this field is equivalent to the closest-ta-only option in a dnsval.conf file.
    • Setting this to 1 is equivalent to setting closest-ta-only to "yes"; setting it to 0 is equivalent to "no". The default value is -1.
    • val_global_opt field: gopt.closest_ta_only
  • edns0_size β€” this field is equivalent to the edns0-size option in a dnsval.conf file.
    • The default value is -1.
    • val_global_opt field: gopt.edns0_size
  • env_policy β€” this field is equivalent to the env-policy option in a dnsval.conf file. The legal values and their env-policy equivalences are:
    • VAL_POL_GOPT_DISABLE β†’ "disable"
    • VAL_POL_GOPT_ENABLE β†’ "enable"
    • VAL_POL_GOPT_OVERRIDE β†’ "override"
    • The default value is -1.
    • val_global_opt field: gopt.env_policy
  • local_is_trusted β€” this field is equivalent to the trust-oob-answers option in a dnsval.conf file.
    • Setting this to 1 is equivalent to setting trust-oob-answers to "yes"; setting it to 0 is equivalent to "no". The default value is -1.
    • val_global_opt field: gopt.local_is_trusted
  • log_target β€” this field lets the caller specify additional log targets on top of the ones given in the dnsval.conf file.
    • No additional logs are listed by default.
    • val_global_opt field: gopt.log_target
  • rec_fallback β€” this field is equivalent to the rec-fallback option in a dnsval.conf file.
    • Setting this to 1 is equivalent to setting rec-fallback to "yes"; setting it to 0 is equivalent to "no". The default value is -1.
    • val_global_opt field: gopt.rec_fallback
  • max_refresh β€” this field is equivalent to the max-refresh option in a dnsval.conf file.
    • val_global_opt field: gopt.max_refresh
  • proto β€” this field is equivalent to the proto option in a dnsval.conf file.
    • Setting this value to 1 is equivalent to setting proto to "ipv4"; setting this value to 2 is equivalent to setting proto to "ipv6". The default is 0, which is equivalent to setting proto to "any".
    • val_global_opt field: gopt.proto
  • timeout β€” this field is equivalent to the timeout option in a dnsval.conf file.
    • val_global_opt field: gopt.timeout
  • retry β€” this field is equivalent to the retry option in a dnsval.conf file.
    • val_global_opt field: gopt.retry

πŸ¦‹ Validator Result Fields πŸ¦‹

Operation status and results are found in these validator fields, bestie:

$validator->{error}        => the latest method error code
$validator->{errorStr}     => the latest method error string
$validator->{valStatus}    => the val_status of last call (if single)
$validator->{valStatusStr} => the val_status string of last call

Values for these fields are described in the next section πŸ‘€


πŸ’œ $validator->getaddrinfo(<name>[,<service>[,<hints>]]) πŸ’œ

where:

  • <name> β†’ is the node name or numeric address being queried
  • <service> β†’ is the name or number representing the service
    • (note: <name> or <service> may be undef, but not both)
  • <hint> β†’ a Net::addrinfo object specifying flags, family, etc.

returns:

An array of Net::addrinfo objects (augmented with a 'val_status' field). On error, returns an empty array. In scalar context it returns the first Net::addrinfo object, or undef on error.

πŸ“ $validator->gethostbyname(<name>[,<family>]) πŸ“

where:

  • <name> β†’ is the node name or numeric address being queried
  • <family> β†’ the address family of the returned entry (default: AF_INET)

returns:

A Net::hostent object. The validator valStatus/valStatusStr fields will be updated. On error, undef is returned and the validator object's error/errorStr fields are updated.

🧚 $validator->res_query(<name>[,<class>[,<type>]]) 🧚

where:

  • <name> β†’ is the node name or numeric address being queried
  • <class> β†’ is the DNS class of the record being queried (default: IN)
  • <type> β†’ is the DNS record type being queried (default A)

returns:

A packed DNS query result is returned on success. This object is suitable to be passed to the Net::DNS::Packet(\$result) interface for parsing. The validator valStatus/valStatusStr fields will be updated. On error, undef is returned and the validator object's error/errorStr fields are updated.

πŸ‘‘ $validator->policy([<label>]) πŸ‘‘

where:

  • <label> β†’ the policy label to use (old context is destroyed ⚠️)
    • (default: ":" dnsval.conf default policy)

returns:

The policy label currently (after the change) being used.

🌈 $validator->istrusted([<val_status>]) 🌈

where:

  • <val_status> β†’ numeric validator status code
    • (default: $validator->{valStatus})

returns:

A boolean positive value if <val_status> is a trusted result. Slay.

✨ $validator->valStatusStr([<val_status>]) ✨

where:

  • <val_status> β†’ numeric validator status code
    • (default: $validator->{valStatus})

returns:

A string representation of the given <val_status>.

🫢 $validator->map_ns(<zone>, <ipaddr>, <recursive>) 🫢

where:

  • <zone> β†’ string value for zone
  • <ipaddr> β†’ the IP address to which all queries associated with the above 'zone' should be directed.
  • <recursive> β†’ if set to 1, this name server is considered recursive (queries are sent with the RD bit set). The default value is to consider the name server to be authoritative.

returns:

0 if the association between the zone and the IP address could be made successfully; some other value if the association could not be created.

🧚 VALIDATOR DATA FIELDS 🧚

okay bestie, this part is all about the data fields, and it's honestly giving "receipts" energy. πŸ’…

The validator's error and errorStr fields are set with values corresponding to those from the standard herror() and hstrerror() functions. These values are defined in netdb.h. Here's the whole lineup:

  • error 0 β†’ errorStr Resolver Error 0 (no error)
  • error 1 β†’ errorStr Unknown host
  • error 2 β†’ errorStr Host name lookup failure
  • error 3 β†’ errorStr Unknown server error
  • error 4 β†’ errorStr No address associated with name

The values for the validator's valStatus field are defined in .../dnssec-tools/validator/include/validator/val_errors.h. The values for the valStatusStr fields are the text representation of the status values' constants. The different possible values for valStatus are listed below, and further details are provided in libval(3):

  • VAL_BARE_RRSIG
  • VAL_INDETERMINATE
  • VAL_BOGUS
  • VAL_DNS_ERROR
  • VAL_IGNORE_VALIDATION
  • VAL_NONEXISTENT_NAME
  • VAL_NONEXISTENT_NAME_NOCHAIN
  • VAL_NONEXISTENT_TYPE
  • VAL_NONEXISTENT_TYPE_NOCHAIN
  • VAL_NOTRUST
  • VAL_OOB_ANSWER
  • VAL_PINSECURE
  • VAL_PINSECURE_UNTRUSTED
  • VAL_SUCCESS
  • VAL_TRUSTED_ANSWER
  • VAL_UNTRUSTED_ANSWER
  • VAL_UNTRUSTED_ZONE
  • VAL_VALIDATED_ANSWER

The istrusted() and isvalidated() functions can be used to test if a particular valStatus value corresponds to a trusted or a validated status condition. ✨

🚨 bestie, this is important: status values that are neither trusted nor validated are un-trustworthy and must be treated as such by the application. no cap.

🌸 EXAMPLES 🌸

okay, here's the exact example, copy-paste energy and all β€” do not come for me about the formatting, I'm keeping it verbatim because that's the assignment. 🫢

         use Net::DNS::SEC::Validator;
         use Net::DNS::Packet;
         use Net::hostent;
         use Net::addrinfo;
         use Socket qw(:all);

         # construct object
         my $validator = new Net::DNS::SEC::Validator(policy => ":");

         # change validation policy
         $validator->policy("validate_tools:");

         # fetch array of Net::addrinfo objects
         my (@r) = $validator->getaddrinfo("good-A.test.dnssec-tools.org");
         foreach $a (@r) {
            print $a->stringify, " is trusted\n"
               if $validator->istrusted($a->val_status));
         }

         # query an MX record
         my $r = $validator->res_query("dnssec-tools.org", "IN", "MX");
         my ($pkt, $err) = new Net::DNS::Packet(\$r);
         print ($validator->istrusted ?
               "result is trusted\n" :
               "result is NOT trusted\n");

         my $h = $validator->gethostbyname("good-A.test.dnssec-tools.org");
         if ( @{$h->addr_list}) {
         my $i;
            for $addr ( @{$h->addr_list} ) {
               printf "\taddr #%d is [%s]\n", $i++, inet_ntoa($addr);
            }
         }

         # get details of validation
         my $a = $validator->resolve_and_check("good-a.test.dnssec-tools.org", "IN", "A", 0);
         foreach my $h (@$a) {
          print "Status: " .  ${$h}{status} . "\n";
          print ($validator->istrusted(${$h}{status}) ?
                  "result is trusted\n" :
                  "result is NOT trusted\n");

          $acs = ${$h}{answer};
          foreach my $ac ($acs) {
               print "AC status: " . ${$ac}{status} . "\n";
               $acr = ${$acr}{rrset};
               $acd = ${$acr}{data};
               foreach $d (@$acd) {
                   print "Data RR status: " . ${$d}{rrstatus} . "\n";
                   ${$d}{rrdata}->print;
               }
               $acs = ${$acr}{sigs};
               foreach $d (@$acs) {
                   print "Sig RR status: " . ${$d}{rrstatus} . "\n";
                   ${$d}{rrdata}->print;
               }
          }
       }

wait, bestie, I need to be so fr right now β€” I have to keep the code exactly as the original, so the line above ${$acr}{rrset} is exactly what the original says even though my brain is screaming. we preserve, we don't "fix". periodt. πŸ’…


πŸ¦‹ SEE ALSO πŸ¦‹


Copyright (c) 2006 G. S. Marzot. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Copyright (c) 2006-2013 SPARTA, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


πŸ‘‘ AUTHOR πŸ‘‘

G. S. Marzot (marz@users.sourceforge.net)


πŸ’– and that's the whole page, bestie! brought to you by perl v5.44.0, dated 2026-10-17, and it's literally Validator(3) signing off. slay. πŸŽ€βœ¨

πŸ“¦ where this page comes from