qlibs:(dnsresolv)

πŸ“¦ version 31, in alpine 3.24

πŸ’– NAME πŸ’–

okay so this is qlibs:(dnsresolv) β€” the dns resolver routines, bestie. it's the whole DNS glow-up package ✨


✨ SYNTAX ✨

#include "dnsresolv.h"

int dns_ip4_packet(stralloc *out,const char *buf,unsigned int len);
int dns_ip4(stralloc *out,stralloc *fqdn);

int dns_ip6_packet(stralloc *out,const char *buf,unsigned int len);
int dns_ip6(stralloc *out,stralloc *fqdn);

int dns_mx(stralloc *out,stralloc *fqdn);
int dns_mx_packet(stralloc *out,const char *buf,unsigned int len);

void dns_name4_domain(char q[DNS_NAME4_DOMAIN],const char *ip[4]);
int dns_name4(stralloc *out,const char *ip[4]);

void dns_name6_domain(char q[DNS_NAME6_DOMAIN],const char *ip[16]);
int dns_name6(stralloc *out,const char *ip[16]);

int dns_name(stralloc *out,const char *ip[16]);
int dns_name_packet(stralloc *out,const char *buf,unsigned int len);

int dns_txt(stralloc *out,stralloc *fqdn);
int dns_txt_packet(stralloc *out,const char *buf,unsigned int len);

int dns_cname(stralloc *out,stralloc *fqdn);
int dns_cname_packet(stralloc *out,const char *buf,unsigned int len);

int dns_ip4_qualify(stralloc *out,stralloc *fqdn,const stralloc *udn);
int dns_ip6_qualify(stralloc *out,stralloc *fqdn,const stralloc *udn);
int dns_ip_qualify(stralloc *out,stralloc *fqdn,const stralloc *udn);

🌸 DESCRIPTION 🌸

okay so let's go function by function, because there's a LOT of them and they're all kinda iconic in their own way 🫢

🌟 the *_packet girlies (async girlbosses)

dns_ip[4|6]_packet is a low-level component of dns_ip[4|6], designed to support asynchronous DNS lookups. it reads a DNS packet of length len from buf, extracts the IP(4|6) addresses from the answer section of the packet, and puts the addresses into out. lowkey the backbone of the whole operation πŸ’…

dns_name[4|6]_packet is a low-level component of dns_name[4|6] designed to support asynchronous DNS lookups. it reads a DNS packet of length len from buf, β€” that's it, that's the sentence, the manpage really just trails off there, no cap 😭

🌟 the actual lookups

dns_ip[4|6] looks up 4/16-byte IPv6 addresses for the fully qualified domain name of fqdn. it puts the concatenation of the IPv[4|6] addresses into out and returns the number of received answers for fqdn, or 0 if none are replied. if the domain does not exist in DNS, or has no IP addresses, out will be empty.

and here's the fun part ✨ more generally, if fqdn is considered by dns_ip4 to be a dotted-decimal IPv4 address, it is provisioned as out without checking the DNS while returning 1. brackets may enclose the dotted-decimal IP address; they are ignored.

🌟 dns_name[4|6]_domain β€” the reverse girlies

dns_name[4|6]_domain is a low-level component of dns_name[4|6]. it converts an IP address such as 1.2.3.4 or 4321:0:1:2:3:4:567:89ab into a domain name such as 4.3.2.1.in-addr.arpa or b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa and places the packet-encoded domain name into q. q is zero terminated. q must have space for DNS_NAME[4|6]_DOMAIN bytes. slay πŸ’…

🌟 MX records

dns_mx_packet is a low-level component of dns_mx, designed to support asynchronous DNS lookups. it reads a DNS packet of length len from buf, extracts the MX records from the answer section of the packet, puts the result into out, and returns the number of replies received or -1 the same way as dns_mx.

dns_mx looks up MX records for the fully-qualified domain name in fqdn. it puts the MX records into out and returns the number of received records or 0. each MX record is a two-byte MX distance (big endian) followed by a \0-terminated dot-encoded domain name. if the domain does not exist in DNS, or has no MX records, out will be empty.

🌟 TXT records

dns_txt_packet is a low-level component of dns_txt, designed to support asynchronous DNS lookups. it reads a DNS packet of length len from buf, extracts the TXT records from the answer section of the packet, puts the result into out, and returns the number of replies or -1 the same way as dns_txt.

dns_txt looks up TXT records for the fully-qualified domain name in fqdn. it puts the concatenation of the TXT records into out and returns the number of replies received. if the domain does not exist in DNS, or has no TXT records, out will be empty.

🌟 CNAME records

dns_cname_packet is a low-level component of dns_cname, designed to support asynchronous DNS lookups. it reads a DNS packet of length len from buf, extracts the TXT records from the answer section of the packet, puts the result into out, and returns the number of replies received or -1 the same way as dns_cname. (yes it says TXT records there. i'm just the messenger πŸ™ˆ)

dns_cname looks up the canonical name for a given fqdn.

🌟 the qualify era πŸ‘‘

dns_ip[4|6]_qualify feeds the name udn through qualification and looks up their 4-byte/16-byte IP addresses. it puts the fully qualified domain name into fqdn and the concatenation of the IP addresses into out, while returning the number of encountered IP addresses.

dns_ip[4|6]_qualify evaluates the environment variables $DNSREWRITEFILE pointing to /etc/dnsrewrite and $LOCALDOMAIN and finally reading /etc/resolv.conf to build the Full Qualified Domain Name (FQDN) using the domain suffix for hostname. dns_ip_qualify returns out as IP[4|6] and FQDN. if the domain does not exist in DNS, or has no IP addresses, out will be empty and the return code is 0.

and bestie, here's a cute little special case πŸ’– in case dns_ip[4|6]_qualify is fed with an IP[4|6] addresses instead of domain names, it recognizes those not to be subject of qualification. the particular names localhost, ip4-loopback and ip6-loopback are treated locally and mapped to the respective IP[4|6] addresses (and vice versa) without facilitating a DNS lookup. no network, no stress, no problem ✨


πŸ¦‹ INPUT πŸ¦‹

for the high-level routines dns_ip[4|6], dns_ip_qualify[4|6], dns_name[4|6], dns_mx, dns_name, dns_txt and dns_cname the provided input variable stralloc fqdn needs to be un-terminated, thus the given string length is identical to the number of fqdn characters. so like, don't sneak a \0 in there, k? πŸŽ€


πŸŽ€ OUTPUT πŸŽ€

the returned IP addresses are given as character (byte) strings with 4 or 16 bytes:

  • dns_ip4 and dns_ip4_qualifiy return 4 byte IPv4 addresses
  • whereas dns_ip6 and dns_ip as well as dns_ip6_qualify and dns_ip_qualify return sets of 16 byte IPv6 addresses, where the potential IPv4 addresses are given in their IPv6-mapped-IPv4 representation.

πŸ’… RETURN CODES πŸ’…

the dns routines dns_cname*, dns_ip*, dns_mx*, dns_name* and dns_txt* return the number of answers received, which may be 0 and potentially -1 in case of a memory failure. here's the full set, no gatekeeping:

  • n>0 β€” n = number of answers received πŸ”₯
  • 0 β€” macro DNS_NXD β€” either NXDOMAIN or NODATA
  • -1 β€” macro DNS_MEM β€” out of memory (fatal) πŸ’€
  • -2 β€” macro DNS_ERR β€” parsing errors
  • -3 β€” macro DNS_COM β€” socket communicaton errror; SERVFAIL
  • -4 β€” macro DNS_INT β€” internal error
  • -5 β€” macro DNS_SOFT β€” DNS_ERR or DNS_COM
  • -6 β€” macro DNS_HARD β€” DNS loop problem (CNAME)

errno is set appropriately. in case of a failure, the respective output variables like out and fqdn may or may not change. and since a received reply may be empty, always check the length of the received output additionally. like, always. fr fr. πŸ™ˆ

ngl the "may or may not change" part is giving main character energy in the worst way β€” don't trust out after a failure, check the length too, periodt.

🌈 SEE ALSO 🌈

ip4(3), ip6(3), dnsstub(3)


and that's the whole page, bestie πŸ¦‹ this was qlibs:(dnsresolv) β€” go forth and resolve, you're gonna slay βœ¨πŸ’–πŸŽ€

πŸ“¦ where this page comes from