DNS::Unbound(3)
π DNS::Unbound(3) β the perl manual page, but make it make sense π¦
okay so this is a page from the User Contributed Perl Documentation section, and honestly? it's lowkey iconic. it's about DNS::Unbound, a Perl module that hits up libunbound to do your DNS queries. let's get into it bestie π
β¨ NAME β¨
DNS::Unbound β Query DNS recursively via libunbound <https://www.nlnetlabs.nl/documentation/unbound/libunbound/>
πΈ SYNOPSIS πΈ
my $dns = DNS::Unbound->new()->set_option( verbosity => 2 );
# This appears to be safe:
$dns->enable_threads();
my $verbosity = $dns->get_option( 'verbosity' );
$dns->set_option( verbosity => 1 + $verbosity );
Synchronous queries, i.e. the "just gimme the answer" vibe:
my $res_hr = $dns->resolve( 'cpan.org', 'NS' );
# See below about encodings in βdataβ.
my @ns = map { $dns->decode_name($_) } @{ $res_hr->data() };
Asynchronous queries use the "Promise" pattern <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises>. Assuming you're running an off-the-shelf event loop, you can do something like this:
my $dns = DNS::Unbound::AnyEvent->new();
my $query1 = $dns->resolve_async( 'usa.gov', 'A' )->then(
sub { my $data = shift()->data(); ... }, # success handler
sub { ... }, # failure handler
);
my $query2 = $dns->resolve_async( 'in-addr.arpa', 'NS' )->then(
sub { ... },
sub { ... },
);
You can also integrate with a custom event loop; see the "EVENT LOOPS" section below. slay π
π DESCRIPTION π
So typical DNS lookups involve sending a request to a local server that caches info from DNS. The caching makes it fast β but it also means updates to DNS aren't always available via that local server right away. Most applications don't need to care and so can enjoy the speed of cached results. no cap, that's the whole point of a cache.
Applications that need up-to-date DNS query results, though, need fully-recursive DNS queries. NLnet Labs's libunbound <https://www.nlnetlabs.nl/documentation/unbound/libunbound/> is a popular solution for such queries; the present Perl module is an interface to that library. it's giving "we went straight to the source" energy β¨
π¦ CHARACTER ENCODING π¦
DNS doesn't know about character encodings, so neither does Unbound. Thus, all strings given to this module must be byte strings. All returned strings will be byte strings as well. periodt.
π EVENT LOOPS π
This distribution includes the classes DNS::Unbound::AnyEvent, DNS::Unbound::IOAsync, and DNS::Unbound::Mojo, which provide out-of-the-box compatibility with those popular event loop interfaces. You should probably use one of these. fr fr, just use them.
You can also integrate with a custom event loop via the fd() method of this class: wait for that file descriptor to be readable, then call this class's perform() method.
π MEMORY LEAK DETECTION π
Objects in this namespace will, if left alive at global destruction, throw a warning about memory leaks. To silence these warnings, either allow all queries to complete, or cancel queries you no longer care about. don't leave them hanging bestie, it's rude π
π ERRORS π
This library throws 3 kinds of errors:
- Plain strings. Generally thrown in "simple" failure cases, e.g., invalid inputs.
DNS::Unbound::X::Unboundinstances. Thrown whenever Unbound gives an error.DNS::Unbound::X::ResolveErrorinstances. A subclass of the last kind, for (Unbound-reported) resolution failures. (This is NOT for DNS-reported failures.)
ok so note the shouty bit: the last one is NOT for DNS-reported failures. that distinction matters, iykyk.
β CONSTANTS β
The following from libunbound/context.h are defined here: UB_NOERROR, UB_SOCKET, UB_NOMEM, UB_SYNTAX, UB_SERVFAIL, UB_FORKFAIL, UB_AFTERFINAL, UB_INITFAIL, UB_PIPE, UB_READFILE, UB_NOID
π METHODS π
π§ CLASS->new()
Instantiates this class. fresh out of the box, main character energy.
π $result_obj = OBJ->resolve( $NAME, $TYPE [, $CLASS ] )
Runs a synchronous query for a given $NAME and $TYPE. $TYPE may be expressed numerically or, for convenience, as a string. $CLASS is optional and defaults to 1 ("IN"), which is probably what you want.
Returns a DNS::Unbound::Result instance.
NOTE: libunbound doesn't seem to offer effective controls for timing out a synchronous query. If timeouts are relevant for you, you probably need to use resolve_async() instead. π
πΈ $query_obj = OBJ->resolve_async( $NAME, $TYPE [, $CLASS ] );
Like resolve() but starts an asynchronous query rather than a synchronous one.
This returns an instance of DNS::Unbound::AsyncQuery (a subclass thereof, to be precise).
If you're using one of the special event interface subclasses (e.g., DNS::Unbound::IOAsync) then the returned promise will resolve as part of the event loop's normal operation. Otherwise, see below for the methods you'll need to use in tandem with this one to get your query result.
π«Ά OBJ->enable_threads()
Sets OBJ's asynchronous queries to use threads rather than forking. Off by default. Throws an exception if called after an asynchronous query has already been sent.
Returns OBJ.
π OBJ->set_option( $NAME => $VALUE )
Sets a configuration option. Returns OBJ.
Note that this is basically just a passthrough to the underlying ub_ctx_set_option() function and is thus subject to the same limitations as that function; for example, you can't set "verbosity" after the configuration has been "finalized". (So use debuglevel() for that instead.)
π¦ $value = OBJ->get_option( $NAME )
Gets a configuration option's value.
π OBJ->debuglevel( $LEVEL )
Sets the debug level (an integer). Returns OBJ.
As of libunbound v1.9.2, this is just a way to set the "verbosity" option regardless of whether the configuration is finalized.
β¨ OBJ->debugout( $FD_OR_FH )
Accepts a file descriptor or Perl filehandle and designates that as the destination for libunbound diagnostic information.
Returns OBJ.
π₯ $str = CLASS->unbound_version()
Gives the libunbound version string.
π§ METHODS FOR ALTERING RESOLVER LOGIC π§
The following parallel their equivalents in libunbound. They return OBJ and throw errors on failure.
OBJ->hosts( $FILENAME )OBJ->resolveconf( $FILENAME )
π CUSTOM EVENT LOOP INTEGRATION π
Unless otherwise noted, the following methods correspond to their equivalents in libunbound. They return the same values as the libunbound equivalents.
You don't need these if you use one of the event loop subclasses (which is recommended). like, genuinely recommended, don't do extra work for no reason.
OBJ->poll()OBJ->fd()OBJ->wait()OBJ->process()OBJ->count_pending_queries()β Returns the number of outstanding asynchronous queries.
π METHODS FOR DEALING WITH DNSSEC π
The following correspond to their equivalents in libunbound and will only work if the underlying libunbound version supports them.
They return OBJ and throw errors on failure.
OBJ->add_ta( $TA )OBJ->add_ta_autr( $PATH )β (Available only if libunbound supports it.)OBJ->add_ta_file( $PATH )OBJ->trustedkeys( $PATH )
π CONVENIENCE FUNCTIONS π
The following may be called either as object methods or as static functions (but not as class methods). In addition to these, Socket provides the inet_ntoa() and inet_ntop() functions for decoding the values of "A" and "AAAA" records.
NOTE: Consider parsingDNS::Unbound::Result'sanswer_packet()as a more robust, albeit heavier, way to parse query result data.Net::DNS::Packetand AnyEvent::DNS'sdns_unpack()are two good ways to parse DNS packets. heavier but sturdier, pick your vibe π
π $decoded = decode_name($encoded)
Decodes a DNS name. Useful for, e.g., "NS", "CNAME", and "PTR" query results.
Note that this function's return will normally include a trailing "." because of the trailing NUL byte in an encoded DNS name. This is normal and expected. don't come for it, it's supposed to be like that π
π $strings_ar = decode_character_strings($encoded)
Decodes a list of character-strings into component strings, returned as an array reference. Useful for "TXT" query results.
πΈ SEE ALSO πΈ
Net::DNS::Resolver::Recurse provides comparable logic to this module in pure Perl. Like Unbound, it is maintained by NLnet Labs <https://nlnetlabs.nl/>.
Net::DNS::Resolver::Unbound is another XS binding to Unbound, implemented as a subclass of Net::DNS::Resolver.
π LICENSE & COPYRIGHT π
Copyright 2019-2022 Gasper Software Consulting.
This library is licensed under the same terms as Perl itself.
π REPOSITORY π
<https://github.com/FGasper/p5-DNS-Unbound>
π«Ά THANK YOU π«Ά
Special thanks to ATOOMIC <https://metacpan.org/author/ATOOMIC> for making some helpful review notes. we love a helpful reviewer π
and that's the whole page bestie, you ate π
this was perl v5.42.2, dated 2026-02-15 β catch you on the next DNS::Unbound(3) πβ¨
π¦ where this page comes from
- alpine 3.24: perl-dns-unbound-doc 0.29-r3 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms