Zonema...::Util(3pm)

πŸ’– NAME πŸ’–

Zonemaster::Engine::Util β€” it's the utility drawer bestie 🧰✨ Little helper functions that all the other Zonemaster modules pull out when they need something. Think of it as the group chat's shared snack stash, except the snacks are Perl subs.

Oh and for the record, this whole page lives in the User Contributed Perl Documentation collection, filed under Zonema...::Util(3pm) β€” yes the name is truncated, no I don't know why, it's giving mystery. πŸ’…


🌸 SYNOPSIS 🌸

Okay so here's the vibe, look how easy:

use Zonemaster::Engine::Util;
info(TAG => { some => 'argument'});
my $ns = ns($name, $address);
my $name = name('whatever.example.org');

like... you just use it and the functions show up in your namespace, no extra steps, no drama. 😌✨


πŸŽ€ EXPORTED FUNCTIONS πŸŽ€

These are the freebies you get the second you use Zonemaster::Engine::Util;. No :tags, no begging, they're just there. Queen behavior honestly. πŸ‘‘

info($tag, $href)

Creates and returns a Zonemaster::Engine::Logger::Entry object. And not only that β€” the object is also dropped into the global logger object's list of entries. So it's a two-for-one: you get your shiny new entry back, AND the logger remembers it forever. It's giving main character who's also in every scene. πŸ’–

ns($name, $address)

Creates and returns a nameserver object with the given name and address. Name goes in, address goes in, nameserver object comes out. Slay. ✨

name($string_name_or_zone)

Creates and returns a Zonemaster::Engine::DNSName object for whatever argument you hand it. That's it. That's the function. Lowkey iconic in its simplicity. πŸ¦‹

zone($name)

Returns a Zonemaster::Engine::Zone object for the given name. Notice it says returns and not creates and returns β€” I'm just passing along what the page says, don't come for me. πŸ™ˆ

parse_hints($string)

Bestie this one has ✨lore✨. It takes a string in the root hints format and parses it into the shape that Zonemaster::Engine::Resolver->add_fake_addresses() is expecting. Translating one flavor of DNS into another. Bilingual queen. 🌈

What you get back: a hashref where the keys are domain names and the values are arrayrefs of IP addresses. Clean, structured, delicious. πŸ“

⚠️ Heads up: it throws an exception if the input isn't valid root hints text. Not a warning, not a gentle nudge β€” an exception. So wrap it or weep. 😭

So, root-hints context: a root hints file is a valid RFC 1035 zone file of the same type that IANA publishes to be used as a hint file for name servers (https://www.internic.net/domain/named.root).

But β€” and this is the part everyone skips β€” being a valid zone file is not enough. There are extra restrictions layered on top of the root hints format, and you gotta respect all of them:

  • The file must not contain any $TTL, $ORIGIN, $INCLUDE or $GENERATE directives. Nope. None. Not one. 🚫
  • The class field of all records must be IN or absent. If the class is absent, IN is assumed. (It's the default, it just is. πŸ’…)
  • The TTL field may be absent or present β€” either is fine. But the TTL value is ignored. We see it, we don't care about it. πŸ™ˆ
  • The RR type of all DNS records must be NS, A or AAAA. Those three. That's the whole guest list. ✨
  • The file must contain at least one NS record. Gotta have at least one, that's the whole point.
  • The owner name of all NS records must be ".". All of them. The root. Periodt. πŸ‘‘
  • For every NS record there must be at least one address record (A or AAAA) whose owner name is identical to the domain name in the RDATA of the NS record. They have to match up, like a friendship bracelet. 🫢
  • All address records (A or AAAA) must have an owner name that is identical to the domain name in the RDATA of some NS record in the zone. No orphan addresses, no randos, everyone has to belong to somebody. πŸ’œ

serial_gt($serial_a, $serial_b)

Checks if serial_a is greater than serial_b, according to serial number arithmetic as defined in RFC1982, section 3.2.

Returns a boolean. That's it. And before you're like "why is comparing two numbers a whole function" β€” it's serial arithmetic, bestie, the numbers wrap around, it's not normal math, don't try it at home. πŸ”₯

scramble_case

This routine provides a special effect:

sCraMBliNg tHe CaSe

...yeah. That's the whole description. It does the funny casing thing. It's giving unserious and I respect it deeply. πŸ˜­πŸ’–

should_run_test

Check if a test is blacklisted and should run or not. Basically a vibe check for tests: is this test allowed out tonight, or is it grounded? πŸš«βœ…

ipversion_ok

Check if IP version operations are permitted. And where does it look for that answer? Tests are done against the content of Zonemaster::Engine::Profile->effective. So it's reading your effective profile, not your vibes. πŸ“‹βœ¨

test_levels

WIP, here to please Pod::Coverage. It literally exists just so the coverage checker stops asking questions. It's the sub that shows up to the party so the headcount works out. πŸ’€


and that's the whole page bestie, you're officially fluent ✨

Signed, sealed, delivered by perl v5.40.1, dated 2026-03-21, and still filed under that mysteriously truncated Zonema...::Util(3pm) name. πŸŽ€πŸ¦‹ mwah, go write some tests πŸ’…

πŸ“¦ where this page comes from